Merge "Add VTS to check temperature and thresholds are set for SKIN type" into main
diff --git a/.gitignore b/.gitignore
index 1d74e21..6c7f477 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,4 @@
.vscode/
+
+# Vim temporary files
+**/*.swp
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 25246d8..92cafbd 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -11,6 +11,9 @@
},
{
"name": "VtsHalTvInputV1_0TargetTest"
+ },
+ {
+ "name": "CtsStrictJavaPackagesTestCases"
}
],
"auto-presubmit": [
diff --git a/audio/aidl/Android.bp b/audio/aidl/Android.bp
index 89d186c..3963ce3 100644
--- a/audio/aidl/Android.bp
+++ b/audio/aidl/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/aidl/TEST_MAPPING b/audio/aidl/TEST_MAPPING
index 81c99f7..e325001 100644
--- a/audio/aidl/TEST_MAPPING
+++ b/audio/aidl/TEST_MAPPING
@@ -4,9 +4,15 @@
"name": "VtsHalAudioCoreTargetTest"
},
{
+ "name": "audioeffect_tests"
+ },
+ {
"name": "audio_policy_config_xml_converter_tests"
},
{
+ "name": "trackplayerbase_tests"
+ },
+ {
"name": "VtsHalAudioEffectFactoryTargetTest"
},
{
@@ -51,5 +57,27 @@
{
"name": "VtsHalNSTargetTest"
}
+ ],
+ "postsubmit": [
+ {
+ "name": "VtsHalSpatializerTargetTest"
+ },
+ {
+ "name": "audiorecord_tests"
+ },
+ {
+ "name": "audiorouting_tests"
+ },
+ {
+ "name": "audiosystem_tests"
+ },
+ {
+ "name": "CtsVirtualDevicesTestCases",
+ "options" : [
+ {
+ "include-filter": "android.virtualdevice.cts.VirtualAudioTest"
+ }
+ ]
+ }
]
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl
index e14e9c0..07a85f8 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl
@@ -74,6 +74,7 @@
boolean supportsVariableLatency();
int getAAudioMixerBurstCount();
int getAAudioHardwareBurstMinUsec();
+ void prepareToDisconnectExternalDevice(int portId);
const int DEFAULT_AAUDIO_MIXER_BURST_COUNT = 2;
const int DEFAULT_AAUDIO_HARDWARE_BURST_MIN_DURATION_US = 1000;
@VintfStability
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Flags.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Flags.aidl
index bcbf870..046c220 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Flags.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Flags.aidl
@@ -43,6 +43,8 @@
boolean audioModeIndication;
boolean audioSourceIndication;
boolean bypass;
+ boolean sinkMetadataIndication;
+ boolean sourceMetadataIndication;
@Backing(type="byte") @VintfStability
enum Type {
INSERT = 0,
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/IEffect.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/IEffect.aidl
index 8c196e7..a1b00be 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/IEffect.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/IEffect.aidl
@@ -41,6 +41,7 @@
android.hardware.audio.effect.State getState();
void setParameter(in android.hardware.audio.effect.Parameter param);
android.hardware.audio.effect.Parameter getParameter(in android.hardware.audio.effect.Parameter.Id paramId);
+ android.hardware.audio.effect.IEffect.OpenEffectReturn reopen();
@FixedSize @VintfStability
parcelable Status {
int status;
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
index 7313b57..ff33c42 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
@@ -41,6 +41,8 @@
boolean offload;
android.hardware.audio.effect.Parameter.VolumeStereo volumeStereo;
android.hardware.audio.effect.Parameter.Specific specific;
+ android.hardware.audio.common.SinkMetadata sinkMetadata;
+ android.hardware.audio.common.SourceMetadata sourceMetadata;
@VintfStability
union Id {
android.hardware.audio.effect.VendorExtension vendorEffectTag;
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Spatializer.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Spatializer.aidl
index 9f97de0..98ecee0 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Spatializer.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Spatializer.aidl
@@ -35,12 +35,13 @@
@VintfStability
union Spatializer {
android.hardware.audio.effect.VendorExtension vendor;
- android.media.audio.common.Spatialization.Level spatializationLevel;
- android.media.audio.common.HeadTracking.Mode headTrackingMode;
android.media.audio.common.AudioChannelLayout[] supportedChannelLayout;
+ android.media.audio.common.Spatialization.Level spatializationLevel;
android.media.audio.common.Spatialization.Mode spatializationMode;
- float[6] headToStage;
- const int HEAD_TO_STAGE_VEC_SIZE = 6;
+ int headTrackingSensorId;
+ android.media.audio.common.HeadTracking.Mode headTrackingMode;
+ android.media.audio.common.HeadTracking.ConnectionMode headTrackingConnectionMode;
+ android.media.audio.common.HeadTracking.SensorData headTrackingSensorData;
@VintfStability
union Id {
android.hardware.audio.effect.VendorExtension vendorExtensionTag;
diff --git a/audio/aidl/android/hardware/audio/core/IModule.aidl b/audio/aidl/android/hardware/audio/core/IModule.aidl
index e736c32..3c5f7f6 100644
--- a/audio/aidl/android/hardware/audio/core/IModule.aidl
+++ b/audio/aidl/android/hardware/audio/core/IModule.aidl
@@ -206,8 +206,10 @@
* after successful connection of an external device.
*
* Handling of a disconnect is done in a reverse order:
- * 1. Reset port configuration using the 'resetAudioPortConfig' method.
- * 2. Release the connected device port by calling the 'disconnectExternalDevice'
+ * 1. Notify the HAL module to prepare for device disconnection using
+ * 'prepareToDisconnectExternalDevice' method.
+ * 2. Reset port configuration using the 'resetAudioPortConfig' method.
+ * 3. Release the connected device port by calling the 'disconnectExternalDevice'
* method. This also removes the audio routes associated with this
* device port.
*
@@ -234,11 +236,15 @@
* instance previously instantiated using the 'connectExternalDevice'
* method.
*
- * The framework will call this method before closing streams and resetting
- * patches. This call can be used by the HAL module to prepare itself to
- * device disconnection. If the HAL module indicates an error after the first
- * call, the framework will call this method once again after closing associated
- * streams and patches.
+ * On AIDL HAL v1, the framework will call this method before closing streams
+ * and resetting patches. This call can be used by the HAL module to prepare
+ * itself to device disconnection. If the HAL module indicates an error after
+ * the first call, the framework will call this method once again after closing
+ * associated streams and patches.
+ *
+ * On AIDL HAL v2 and later, the framework will call 'prepareToDisconnectExternalDevice'
+ * method to notify the HAL module to prepare itself for device disconnection. The
+ * framework will only call this method after closing associated streams and patches.
*
* @throws EX_ILLEGAL_ARGUMENT In the following cases:
* - If the port can not be found by the ID.
@@ -912,4 +918,23 @@
* @throw EX_UNSUPPORTED_OPERATION If the module does not support aaudio MMAP.
*/
int getAAudioHardwareBurstMinUsec();
+
+ /**
+ * Notify the HAL module to prepare for disconnecting an external device.
+ *
+ * This method is used to inform the HAL module that 'disconnectExternalDevice' will be
+ * called soon. The HAL module can rely on this method to abort active data operations
+ * early. The 'portId' must be of a connected device Port instance previously instantiated
+ * using 'connectExternalDevice' method. 'disconnectExternalDevice' method will be called
+ * soon after this method with the same 'portId'.
+ *
+ * Note: This method is called after the external device is disconnected. The system does
+ * not try to predict the disconnection event.
+ *
+ * @param portId The ID of the audio port corresponding to the disconnected device
+ * @throws EX_ILLEGAL_ARGUMENT In the following cases:
+ * - If the port can not be found by the ID.
+ * - If this is not a connected device port.
+ */
+ void prepareToDisconnectExternalDevice(int portId);
}
diff --git a/audio/aidl/android/hardware/audio/effect/Flags.aidl b/audio/aidl/android/hardware/audio/effect/Flags.aidl
index 28685c3..70668a3 100644
--- a/audio/aidl/android/hardware/audio/effect/Flags.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Flags.aidl
@@ -144,4 +144,18 @@
* Set to true if the effect instance bypass audio data (no processing).
*/
boolean bypass;
+
+ /**
+ * Effect instance sets this flag to true if it requires record AudioTrack metadata update. In
+ * this case the framework must call IEffect.setParameter to notify effect instance when there
+ * is a change in sinkMetadata.
+ */
+ boolean sinkMetadataIndication;
+
+ /**
+ * Effect instance sets this flag to true if it requires playback AudioTrack metadata update. In
+ * this case the framework must call IEffect.setParameter to notify effect instance when there
+ * is a change in sourceMetadata.
+ */
+ boolean sourceMetadataIndication;
}
diff --git a/audio/aidl/android/hardware/audio/effect/IEffect.aidl b/audio/aidl/android/hardware/audio/effect/IEffect.aidl
index 6097f34..266adec 100644
--- a/audio/aidl/android/hardware/audio/effect/IEffect.aidl
+++ b/audio/aidl/android/hardware/audio/effect/IEffect.aidl
@@ -54,7 +54,16 @@
}
/**
- * Return data structure of IEffect.open() interface.
+ * Return data structure of the IEffect.open() and IEffect.reopen() method.
+ *
+ * Contains Fast Message Queues (FMQs) for effect processing status and input/output data.
+ * The status FMQ remains valid and unchanged after opening, while input/output data FMQs can be
+ * modified with changes in input/output AudioConfig. If reallocation of data FMQ is necessary,
+ * the effect instance must release the existing data FMQs to signal the need to the audio
+ * framework.
+ * When the audio framework encounters a valid status FMQ and invalid input/output data FMQs,
+ * it must invoke the IEffect.reopen() method to request the effect instance to reallocate
+ * the FMQ and return to the audio framework.
*/
@VintfStability
parcelable OpenEffectReturn {
@@ -97,7 +106,7 @@
* client responsibility to make sure all parameter/buffer is correct if client wants to reopen
* a closed instance.
*
- * Effect instance close interface should always succeed unless:
+ * Effect instance close method should always succeed unless:
* 1. The effect instance is not in a proper state to be closed, for example it's still in
* State::PROCESSING state.
* 2. There is system/hardware related failure when close.
@@ -154,8 +163,8 @@
/**
* Get a parameter from the effect instance with parameter ID.
*
- * This interface must return the current parameter of the effect instance, if no parameter
- * has been set by client yet, the default value must be returned.
+ * This method must return the current parameter of the effect instance, if no parameter has
+ * been set by client yet, the default value must be returned.
*
* Must be available for the effect instance after open().
*
@@ -165,4 +174,24 @@
* @throws EX_ILLEGAL_ARGUMENT if the effect instance receive unsupported parameter tag.
*/
Parameter getParameter(in Parameter.Id paramId);
+
+ /**
+ * Reopen the effect instance, keeping all previous parameters unchanged, and reallocate only
+ * the Fast Message Queues (FMQs) allocated during the open time as needed.
+ *
+ * When the audio framework encounters a valid status FMQ and invalid data FMQ(s), it calls
+ * this method to reopen the effect and request the latest data FMQ.
+ * Upon receiving this call, if the effect instance's data FMQ(s) is invalid, it must reallocate
+ * the necessary data FMQ(s) and return them to the audio framework. All previous parameters and
+ * states keep unchanged.
+ * Once the audio framework successfully completes the call, it must validate the returned FMQs,
+ * deprecate all old FMQs, and exclusively use the FMQs returned from this method.
+ *
+ * @return The reallocated data FMQ and the original status FMQ.
+ *
+ * @throws EX_ILLEGAL_STATE if the effect instance is not in a proper state to reallocate FMQ.
+ * This may occur if the effect instance has already been closed or if there is no need to
+ * update any data FMQ.
+ */
+ OpenEffectReturn reopen();
}
diff --git a/audio/aidl/android/hardware/audio/effect/Parameter.aidl b/audio/aidl/android/hardware/audio/effect/Parameter.aidl
index 6ec7226..6fd9161 100644
--- a/audio/aidl/android/hardware/audio/effect/Parameter.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Parameter.aidl
@@ -16,6 +16,8 @@
package android.hardware.audio.effect;
+import android.hardware.audio.common.SinkMetadata;
+import android.hardware.audio.common.SourceMetadata;
import android.hardware.audio.effect.AcousticEchoCanceler;
import android.hardware.audio.effect.AutomaticGainControlV1;
import android.hardware.audio.effect.AutomaticGainControlV2;
@@ -198,4 +200,20 @@
Spatializer spatializer;
}
Specific specific;
+
+ /**
+ * SinkMetadata defines the metadata of record AudioTracks which the effect instance associate
+ * with.
+ * The effect engine is required to set Flags.sinkMetadataIndication to true if it wants to
+ * receive sinkMetadata update from the audio framework.
+ */
+ SinkMetadata sinkMetadata;
+
+ /**
+ * SourceMetadata defines the metadata of playback AudioTracks which the effect instance
+ * associate with.
+ * The effect engine is required to set Flags.sourceMetadataIndication to true if it wants to
+ * receive sourceMetadata update from the audio framework.
+ */
+ SourceMetadata sourceMetadata;
}
diff --git a/audio/aidl/android/hardware/audio/effect/Spatializer.aidl b/audio/aidl/android/hardware/audio/effect/Spatializer.aidl
index 4edb2e8..71e3ffe 100644
--- a/audio/aidl/android/hardware/audio/effect/Spatializer.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Spatializer.aidl
@@ -52,29 +52,38 @@
VendorExtension vendor;
/**
- * Level of spatialization.
- */
- Spatialization.Level spatializationLevel;
-
- /**
- * Head tracking mode for spatialization.
- */
- HeadTracking.Mode headTrackingMode;
-
- /**
* List of supported input channel layouts.
*/
AudioChannelLayout[] supportedChannelLayout;
/**
+ * Level of spatialization.
+ */
+ Spatialization.Level spatializationLevel;
+
+ /**
* Spatialization mode, Binaural or Transaural for example.
*/
Spatialization.Mode spatializationMode;
/**
- * Vector representing of the head-to-stage pose with six floats: first three are a translation
- * vector, and the last three are a rotation vector.
+ * Identifies the head tracking sensor using its unique sensor ID.
+ * The value corresponds to android.hardware.sensors.SensorInfo.sensorHandle.
*/
- const int HEAD_TO_STAGE_VEC_SIZE = 6;
- float[HEAD_TO_STAGE_VEC_SIZE] headToStage;
+ int headTrackingSensorId;
+
+ /**
+ * Head tracking mode for spatialization.
+ */
+ HeadTracking.Mode headTrackingMode;
+
+ /**
+ * Head tracking sensor connection mode for spatialization.
+ */
+ HeadTracking.ConnectionMode headTrackingConnectionMode;
+
+ /**
+ * Headtracking sensor data.
+ */
+ HeadTracking.SensorData headTrackingSensorData;
}
diff --git a/audio/aidl/android/hardware/audio/effect/state.gv b/audio/aidl/android/hardware/audio/effect/state.gv
index ce369ba..22c70c8 100644
--- a/audio/aidl/android/hardware/audio/effect/state.gv
+++ b/audio/aidl/android/hardware/audio/effect/state.gv
@@ -31,6 +31,8 @@
IDLE -> INIT[label = "IEffect.close()"];
INIT -> INIT[label = "IEffect.getState\nIEffect.getDescriptor"];
- IDLE -> IDLE[label = "IEffect.getParameter\nIEffect.setParameter\nIEffect.getDescriptor\nIEffect.command(RESET)"];
- PROCESSING -> PROCESSING[label = "IEffect.getParameter\nIEffect.setParameter\nIEffect.getDescriptor"];
+ IDLE -> IDLE[label = "IEffect.getParameter\nIEffect.setParameter\nIEffect.getDescriptor\nIEffect.command(RESET)\nIEffect.reopen"];
+ PROCESSING
+ -> PROCESSING
+ [label = "IEffect.getParameter\nIEffect.setParameter\nIEffect.getDescriptor\nIEffect.reopen"];
}
diff --git a/audio/aidl/common/Android.bp b/audio/aidl/common/Android.bp
index 85ece3b..5c0c685 100644
--- a/audio/aidl/common/Android.bp
+++ b/audio/aidl/common/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index 11bd7d3..41fc80b 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -94,6 +95,7 @@
"audio_policy_engine_configuration_aidl_default",
],
shared_libs: [
+ "android.hardware.bluetooth.audio-impl",
"libaudio_aidl_conversion_common_ndk",
"libaudioutils",
"libbluetooth_audio_session_aidl",
@@ -117,8 +119,6 @@
cc_binary {
name: "android.hardware.audio.service-aidl.example",
relative_install_path: "hw",
- init_rc: ["android.hardware.audio.service-aidl.example.rc"],
- vintf_fragments: ["android.hardware.audio.service-aidl.xml"],
defaults: [
"aidlaudioservice_defaults",
"latest_android_hardware_audio_core_sounddose_ndk_shared",
@@ -130,6 +130,7 @@
"libaudioserviceexampleimpl",
],
shared_libs: [
+ "android.hardware.bluetooth.audio-impl",
"libaudio_aidl_conversion_common_ndk",
"libbluetooth_audio_session_aidl",
"liblog",
@@ -144,6 +145,7 @@
"-Wthread-safety",
"-DBACKEND_NDK",
],
+ installable: false, //installed in apex com.android.hardware.audio
}
cc_test {
@@ -202,6 +204,7 @@
vendor: true,
shared_libs: [
"libaudioaidlcommon",
+ "libaudioutils",
"libbase",
"libbinder_ndk",
"libcutils",
@@ -227,6 +230,7 @@
filegroup {
name: "effectCommonFile",
srcs: [
+ "EffectContext.cpp",
"EffectThread.cpp",
"EffectImpl.cpp",
],
@@ -235,10 +239,9 @@
cc_binary {
name: "android.hardware.audio.effect.service-aidl.example",
relative_install_path: "hw",
- init_rc: ["android.hardware.audio.effect.service-aidl.example.rc"],
- vintf_fragments: ["android.hardware.audio.effect.service-aidl.xml"],
defaults: ["aidlaudioeffectservice_defaults"],
shared_libs: [
+ "libapexsupport",
"libtinyxml2",
],
srcs: [
@@ -246,6 +249,7 @@
"EffectFactory.cpp",
"EffectMain.cpp",
],
+ installable: false, //installed in apex com.android.hardware.audio.effect
}
cc_library_headers {
@@ -254,3 +258,22 @@
vendor_available: true,
host_supported: true,
}
+
+prebuilt_etc {
+ name: "android.hardware.audio.service-aidl.example.rc",
+ src: "android.hardware.audio.service-aidl.example.rc",
+ installable: false,
+}
+
+prebuilt_etc {
+ name: "android.hardware.audio.service-aidl.xml",
+ src: "android.hardware.audio.service-aidl.xml",
+ sub_dir: "vintf",
+ installable: false,
+}
+
+prebuilt_etc {
+ name: "audio_effects_config.xml",
+ src: "audio_effects_config.xml",
+ installable: false,
+}
diff --git a/audio/aidl/default/Configuration.cpp b/audio/aidl/default/Configuration.cpp
index 254eb46..54e2d18 100644
--- a/audio/aidl/default/Configuration.cpp
+++ b/audio/aidl/default/Configuration.cpp
@@ -110,6 +110,9 @@
AudioPortConfig config;
config.id = id;
config.portId = portId;
+ config.format = AudioFormatDescription{};
+ config.channelMask = AudioChannelLayout{};
+ config.sampleRate = Int{.value = 0};
config.gain = AudioGainConfig();
config.flags = isInput ? AudioIoFlags::make<AudioIoFlags::Tag::input>(flags)
: AudioIoFlags::make<AudioIoFlags::Tag::output>(flags);
@@ -320,10 +323,10 @@
// - no profiles specified
//
// Mix ports:
-// * "r_submix output", maximum 20 opened streams, maximum 10 active streams
-// - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
-// * "r_submix input", maximum 20 opened streams, maximum 10 active streams
-// - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+// * "r_submix output", maximum 10 opened streams, maximum 10 active streams
+// - profile PCM 16-bit; STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+// * "r_submix input", maximum 10 opened streams, maximum 10 active streams
+// - profile PCM 16-bit; STEREO; 8000, 11025, 16000, 32000, 44100, 48000
//
// Routes:
// "r_submix output" -> "Remote Submix Out"
@@ -355,12 +358,12 @@
// Mix ports
AudioPort rsubmixOutMix =
- createPort(c.nextPortId++, "r_submix output", 0, false, createPortMixExt(20, 10));
+ createPort(c.nextPortId++, "r_submix output", 0, false, createPortMixExt(10, 10));
rsubmixOutMix.profiles = remoteSubmixPcmAudioProfiles;
c.ports.push_back(rsubmixOutMix);
AudioPort rsubmixInMix =
- createPort(c.nextPortId++, "r_submix input", 0, true, createPortMixExt(20, 10));
+ createPort(c.nextPortId++, "r_submix input", 0, true, createPortMixExt(10, 10));
rsubmixInMix.profiles = remoteSubmixPcmAudioProfiles;
c.ports.push_back(rsubmixInMix);
diff --git a/audio/aidl/default/EffectConfig.cpp b/audio/aidl/default/EffectConfig.cpp
index 4a12f8a..a1fbefa 100644
--- a/audio/aidl/default/EffectConfig.cpp
+++ b/audio/aidl/default/EffectConfig.cpp
@@ -24,6 +24,10 @@
#include "effectFactory-impl/EffectConfig.h"
+#ifdef __ANDROID_APEX__
+#include <android/apexsupport.h>
+#endif
+
using aidl::android::media::audio::common::AudioSource;
using aidl::android::media::audio::common::AudioStreamType;
using aidl::android::media::audio::common::AudioUuid;
@@ -89,6 +93,24 @@
}
bool EffectConfig::resolveLibrary(const std::string& path, std::string* resolvedPath) {
+ if constexpr (__ANDROID_VENDOR_API__ >= 202404) {
+ AApexInfo *apexInfo;
+ if (AApexInfo_create(&apexInfo) == AAPEXINFO_OK) {
+ std::string apexName(AApexInfo_getName(apexInfo));
+ AApexInfo_destroy(apexInfo);
+ std::string candidatePath("/apex/");
+ candidatePath.append(apexName).append(kEffectLibApexPath).append(path);
+ LOG(DEBUG) << __func__ << " effect lib path " << candidatePath;
+ if (access(candidatePath.c_str(), R_OK) == 0) {
+ *resolvedPath = std::move(candidatePath);
+ return true;
+ }
+ }
+ } else {
+ LOG(DEBUG) << __func__ << " libapexsupport is not supported";
+ }
+
+ // If audio effects libs are not in vendor apex, locate them in kEffectLibPath
for (auto* libraryDirectory : kEffectLibPath) {
std::string candidatePath = std::string(libraryDirectory) + '/' + path;
if (access(candidatePath.c_str(), R_OK) == 0) {
diff --git a/audio/aidl/default/EffectContext.cpp b/audio/aidl/default/EffectContext.cpp
new file mode 100644
index 0000000..9575790
--- /dev/null
+++ b/audio/aidl/default/EffectContext.cpp
@@ -0,0 +1,247 @@
+/*
+ * 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.
+ */
+
+#include <memory>
+#define LOG_TAG "AHAL_EffectContext"
+#include "effect-impl/EffectContext.h"
+#include "include/effect-impl/EffectTypes.h"
+
+using aidl::android::hardware::audio::common::getChannelCount;
+using aidl::android::hardware::audio::common::getFrameSizeInBytes;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kReopenSupportedVersion;
+using aidl::android::media::audio::common::PcmType;
+using ::android::hardware::EventFlag;
+
+namespace aidl::android::hardware::audio::effect {
+
+EffectContext::EffectContext(size_t statusDepth, const Parameter::Common& common) {
+ LOG_ALWAYS_FATAL_IF(RetCode::SUCCESS != setCommon(common), "illegalCommonParameter");
+
+ // in/outBuffer size in float (FMQ data format defined for DataMQ)
+ size_t inBufferSizeInFloat = common.input.frameCount * mInputFrameSize / sizeof(float);
+ size_t outBufferSizeInFloat = common.output.frameCount * mOutputFrameSize / sizeof(float);
+
+ // only status FMQ use the EventFlag
+ mStatusMQ = std::make_shared<StatusMQ>(statusDepth, true /*configureEventFlagWord*/);
+ mInputMQ = std::make_shared<DataMQ>(inBufferSizeInFloat);
+ mOutputMQ = std::make_shared<DataMQ>(outBufferSizeInFloat);
+
+ if (!mStatusMQ->isValid() || !mInputMQ->isValid() || !mOutputMQ->isValid()) {
+ LOG(ERROR) << __func__ << " created invalid FMQ, statusMQ: " << mStatusMQ->isValid()
+ << " inputMQ: " << mInputMQ->isValid() << " outputMQ: " << mOutputMQ->isValid();
+ }
+
+ ::android::status_t status =
+ EventFlag::createEventFlag(mStatusMQ->getEventFlagWord(), &mEfGroup);
+ LOG_ALWAYS_FATAL_IF(status != ::android::OK || !mEfGroup, " create EventFlagGroup failed ");
+ mWorkBuffer.resize(std::max(inBufferSizeInFloat, outBufferSizeInFloat));
+}
+
+// reset buffer status by abandon input data in FMQ
+void EffectContext::resetBuffer() {
+ auto buffer = static_cast<float*>(mWorkBuffer.data());
+ if (mStatusMQ) {
+ std::vector<IEffect::Status> status(mStatusMQ->availableToRead());
+ }
+ if (mInputMQ) {
+ mInputMQ->read(buffer, mInputMQ->availableToRead());
+ }
+}
+
+void EffectContext::dupeFmqWithReopen(IEffect::OpenEffectReturn* effectRet) {
+ if (!mInputMQ) {
+ mInputMQ = std::make_shared<DataMQ>(mCommon.input.frameCount * mInputFrameSize /
+ sizeof(float));
+ }
+ if (!mOutputMQ) {
+ mOutputMQ = std::make_shared<DataMQ>(mCommon.output.frameCount * mOutputFrameSize /
+ sizeof(float));
+ }
+ dupeFmq(effectRet);
+}
+
+void EffectContext::dupeFmq(IEffect::OpenEffectReturn* effectRet) {
+ if (effectRet && mStatusMQ && mInputMQ && mOutputMQ) {
+ effectRet->statusMQ = mStatusMQ->dupeDesc();
+ effectRet->inputDataMQ = mInputMQ->dupeDesc();
+ effectRet->outputDataMQ = mOutputMQ->dupeDesc();
+ }
+}
+
+float* EffectContext::getWorkBuffer() {
+ return static_cast<float*>(mWorkBuffer.data());
+}
+
+size_t EffectContext::getWorkBufferSize() const {
+ return mWorkBuffer.size();
+}
+
+std::shared_ptr<EffectContext::StatusMQ> EffectContext::getStatusFmq() const {
+ return mStatusMQ;
+}
+
+std::shared_ptr<EffectContext::DataMQ> EffectContext::getInputDataFmq() const {
+ return mInputMQ;
+}
+
+std::shared_ptr<EffectContext::DataMQ> EffectContext::getOutputDataFmq() const {
+ return mOutputMQ;
+}
+
+size_t EffectContext::getInputFrameSize() const {
+ return mInputFrameSize;
+}
+
+size_t EffectContext::getOutputFrameSize() const {
+ return mOutputFrameSize;
+}
+
+int EffectContext::getSessionId() const {
+ return mCommon.session;
+}
+
+int EffectContext::getIoHandle() const {
+ return mCommon.ioHandle;
+}
+
+RetCode EffectContext::setOutputDevice(
+ const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>& device) {
+ mOutputDevice = device;
+ return RetCode::SUCCESS;
+}
+
+std::vector<aidl::android::media::audio::common::AudioDeviceDescription>
+EffectContext::getOutputDevice() {
+ return mOutputDevice;
+}
+
+RetCode EffectContext::setAudioMode(const aidl::android::media::audio::common::AudioMode& mode) {
+ mMode = mode;
+ return RetCode::SUCCESS;
+}
+aidl::android::media::audio::common::AudioMode EffectContext::getAudioMode() {
+ return mMode;
+}
+
+RetCode EffectContext::setAudioSource(
+ const aidl::android::media::audio::common::AudioSource& source) {
+ mSource = source;
+ return RetCode::SUCCESS;
+}
+
+aidl::android::media::audio::common::AudioSource EffectContext::getAudioSource() {
+ return mSource;
+}
+
+RetCode EffectContext::setVolumeStereo(const Parameter::VolumeStereo& volumeStereo) {
+ mVolumeStereo = volumeStereo;
+ return RetCode::SUCCESS;
+}
+
+Parameter::VolumeStereo EffectContext::getVolumeStereo() {
+ return mVolumeStereo;
+}
+
+RetCode EffectContext::setCommon(const Parameter::Common& common) {
+ LOG(VERBOSE) << __func__ << common.toString();
+ auto& input = common.input;
+ auto& output = common.output;
+
+ if (input.base.format.pcm != aidl::android::media::audio::common::PcmType::FLOAT_32_BIT ||
+ output.base.format.pcm != aidl::android::media::audio::common::PcmType::FLOAT_32_BIT) {
+ LOG(ERROR) << __func__ << " illegal IO, input "
+ << ::android::internal::ToString(input.base.format) << ", output "
+ << ::android::internal::ToString(output.base.format);
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+
+ if (auto ret = updateIOFrameSize(common); ret != RetCode::SUCCESS) {
+ return ret;
+ }
+
+ mInputChannelCount = getChannelCount(input.base.channelMask);
+ mOutputChannelCount = getChannelCount(output.base.channelMask);
+ if (mInputChannelCount == 0 || mOutputChannelCount == 0) {
+ LOG(ERROR) << __func__ << " illegal channel count input " << mInputChannelCount
+ << ", output " << mOutputChannelCount;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+
+ mCommon = common;
+ return RetCode::SUCCESS;
+}
+
+Parameter::Common EffectContext::getCommon() {
+ LOG(VERBOSE) << __func__ << mCommon.toString();
+ return mCommon;
+}
+
+EventFlag* EffectContext::getStatusEventFlag() {
+ return mEfGroup;
+}
+
+RetCode EffectContext::updateIOFrameSize(const Parameter::Common& common) {
+ const auto prevInputFrameSize = mInputFrameSize;
+ const auto prevOutputFrameSize = mOutputFrameSize;
+ mInputFrameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes(
+ common.input.base.format, common.input.base.channelMask);
+ mOutputFrameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes(
+ common.output.base.format, common.output.base.channelMask);
+
+ // workBuffer and data MQ not allocated yet, no need to update
+ if (mWorkBuffer.size() == 0 || !mInputMQ || !mOutputMQ) {
+ return RetCode::SUCCESS;
+ }
+ // IEffect::reopen introduced in android.hardware.audio.effect-V2
+ if (mVersion < kReopenSupportedVersion) {
+ LOG(WARNING) << __func__ << " skipped for HAL version " << mVersion;
+ return RetCode::SUCCESS;
+ }
+ bool needUpdateMq = false;
+ if (mInputFrameSize != prevInputFrameSize ||
+ mCommon.input.frameCount != common.input.frameCount) {
+ mInputMQ.reset();
+ needUpdateMq = true;
+ }
+ if (mOutputFrameSize != prevOutputFrameSize ||
+ mCommon.output.frameCount != common.output.frameCount) {
+ mOutputMQ.reset();
+ needUpdateMq = true;
+ }
+
+ if (needUpdateMq) {
+ mWorkBuffer.resize(std::max(common.input.frameCount * mInputFrameSize / sizeof(float),
+ common.output.frameCount * mOutputFrameSize / sizeof(float)));
+ return notifyDataMqUpdate();
+ }
+ return RetCode::SUCCESS;
+}
+
+RetCode EffectContext::notifyDataMqUpdate() {
+ if (!mEfGroup) {
+ LOG(ERROR) << __func__ << ": invalid EventFlag group";
+ return RetCode::ERROR_EVENT_FLAG_ERROR;
+ }
+
+ if (const auto ret = mEfGroup->wake(kEventFlagDataMqUpdate); ret != ::android::OK) {
+ LOG(ERROR) << __func__ << ": wake failure with ret " << ret;
+ return RetCode::ERROR_EVENT_FLAG_ERROR;
+ }
+ LOG(DEBUG) << __func__ << " : signal client for reopen";
+ return RetCode::SUCCESS;
+}
+} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/EffectImpl.cpp b/audio/aidl/default/EffectImpl.cpp
index c81c731..4d7b980 100644
--- a/audio/aidl/default/EffectImpl.cpp
+++ b/audio/aidl/default/EffectImpl.cpp
@@ -14,7 +14,10 @@
* limitations under the License.
*/
+#include <memory>
+#define ATRACE_TAG ATRACE_TAG_AUDIO
#define LOG_TAG "AHAL_EffectImpl"
+#include <utils/Trace.h>
#include "effect-impl/EffectImpl.h"
#include "effect-impl/EffectTypes.h"
#include "include/effect-impl/EffectTypes.h"
@@ -22,6 +25,7 @@
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::State;
using aidl::android::media::audio::common::PcmType;
+using ::android::hardware::EventFlag;
extern "C" binder_exception_t destroyEffect(const std::shared_ptr<IEffect>& instanceSp) {
State state;
@@ -45,40 +49,68 @@
RETURN_IF(common.input.base.format.pcm != common.output.base.format.pcm ||
common.input.base.format.pcm != PcmType::FLOAT_32_BIT,
EX_ILLEGAL_ARGUMENT, "dataMustBe32BitsFloat");
+
+ std::lock_guard lg(mImplMutex);
RETURN_OK_IF(mState != State::INIT);
- auto context = createContext(common);
- RETURN_IF(!context, EX_NULL_POINTER, "createContextFailed");
+ mImplContext = createContext(common);
+ RETURN_IF(!mImplContext, EX_NULL_POINTER, "nullContext");
+
+ int version = 0;
+ RETURN_IF(!getInterfaceVersion(&version).isOk(), EX_UNSUPPORTED_OPERATION,
+ "FailedToGetInterfaceVersion");
+ mImplContext->setVersion(version);
+ mEventFlag = mImplContext->getStatusEventFlag();
if (specific.has_value()) {
RETURN_IF_ASTATUS_NOT_OK(setParameterSpecific(specific.value()), "setSpecParamErr");
}
mState = State::IDLE;
- context->dupeFmq(ret);
- RETURN_IF(createThread(context, getEffectName()) != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
+ mImplContext->dupeFmq(ret);
+ RETURN_IF(createThread(getEffectName()) != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
"FailedToCreateWorker");
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus EffectImpl::close() {
- RETURN_OK_IF(mState == State::INIT);
- RETURN_IF(mState == State::PROCESSING, EX_ILLEGAL_STATE, "closeAtProcessing");
+ndk::ScopedAStatus EffectImpl::reopen(OpenEffectReturn* ret) {
+ std::lock_guard lg(mImplMutex);
+ RETURN_IF(mState == State::INIT, EX_ILLEGAL_STATE, "alreadyClosed");
+ // TODO: b/302036943 add reopen implementation
+ RETURN_IF(!mImplContext, EX_NULL_POINTER, "nullContext");
+ mImplContext->dupeFmqWithReopen(ret);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EffectImpl::close() {
+ {
+ std::lock_guard lg(mImplMutex);
+ RETURN_OK_IF(mState == State::INIT);
+ RETURN_IF(mState == State::PROCESSING, EX_ILLEGAL_STATE, "closeAtProcessing");
+ mState = State::INIT;
+ }
+
+ RETURN_IF(notifyEventFlag(kEventFlagNotEmpty) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
+ "notifyEventFlagFailed");
// stop the worker thread, ignore the return code
RETURN_IF(destroyThread() != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
"FailedToDestroyWorker");
- mState = State::INIT;
- RETURN_IF(releaseContext() != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
- "FailedToCreateWorker");
+
+ {
+ std::lock_guard lg(mImplMutex);
+ releaseContext();
+ mImplContext.reset();
+ }
LOG(DEBUG) << getEffectName() << __func__;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus EffectImpl::setParameter(const Parameter& param) {
+ std::lock_guard lg(mImplMutex);
LOG(VERBOSE) << getEffectName() << __func__ << " with: " << param.toString();
- const auto tag = param.getTag();
+ const auto& tag = param.getTag();
switch (tag) {
case Parameter::common:
case Parameter::deviceDescription:
@@ -100,8 +132,8 @@
}
ndk::ScopedAStatus EffectImpl::getParameter(const Parameter::Id& id, Parameter* param) {
- auto tag = id.getTag();
- switch (tag) {
+ std::lock_guard lg(mImplMutex);
+ switch (id.getTag()) {
case Parameter::Id::commonTag: {
RETURN_IF_ASTATUS_NOT_OK(getParameterCommon(id.get<Parameter::Id::commonTag>(), param),
"CommonParamNotSupported");
@@ -121,30 +153,30 @@
}
ndk::ScopedAStatus EffectImpl::setParameterCommon(const Parameter& param) {
- auto context = getContext();
- RETURN_IF(!context, EX_NULL_POINTER, "nullContext");
+ RETURN_IF(!mImplContext, EX_NULL_POINTER, "nullContext");
- auto tag = param.getTag();
+ const auto& tag = param.getTag();
switch (tag) {
case Parameter::common:
- RETURN_IF(context->setCommon(param.get<Parameter::common>()) != RetCode::SUCCESS,
+ RETURN_IF(mImplContext->setCommon(param.get<Parameter::common>()) != RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setCommFailed");
break;
case Parameter::deviceDescription:
- RETURN_IF(context->setOutputDevice(param.get<Parameter::deviceDescription>()) !=
+ RETURN_IF(mImplContext->setOutputDevice(param.get<Parameter::deviceDescription>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setDeviceFailed");
break;
case Parameter::mode:
- RETURN_IF(context->setAudioMode(param.get<Parameter::mode>()) != RetCode::SUCCESS,
+ RETURN_IF(mImplContext->setAudioMode(param.get<Parameter::mode>()) != RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setModeFailed");
break;
case Parameter::source:
- RETURN_IF(context->setAudioSource(param.get<Parameter::source>()) != RetCode::SUCCESS,
+ RETURN_IF(mImplContext->setAudioSource(param.get<Parameter::source>()) !=
+ RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setSourceFailed");
break;
case Parameter::volumeStereo:
- RETURN_IF(context->setVolumeStereo(param.get<Parameter::volumeStereo>()) !=
+ RETURN_IF(mImplContext->setVolumeStereo(param.get<Parameter::volumeStereo>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setVolumeStereoFailed");
break;
@@ -159,28 +191,27 @@
}
ndk::ScopedAStatus EffectImpl::getParameterCommon(const Parameter::Tag& tag, Parameter* param) {
- auto context = getContext();
- RETURN_IF(!context, EX_NULL_POINTER, "nullContext");
+ RETURN_IF(!mImplContext, EX_NULL_POINTER, "nullContext");
switch (tag) {
case Parameter::common: {
- param->set<Parameter::common>(context->getCommon());
+ param->set<Parameter::common>(mImplContext->getCommon());
break;
}
case Parameter::deviceDescription: {
- param->set<Parameter::deviceDescription>(context->getOutputDevice());
+ param->set<Parameter::deviceDescription>(mImplContext->getOutputDevice());
break;
}
case Parameter::mode: {
- param->set<Parameter::mode>(context->getAudioMode());
+ param->set<Parameter::mode>(mImplContext->getAudioMode());
break;
}
case Parameter::source: {
- param->set<Parameter::source>(context->getAudioSource());
+ param->set<Parameter::source>(mImplContext->getAudioSource());
break;
}
case Parameter::volumeStereo: {
- param->set<Parameter::volumeStereo>(context->getVolumeStereo());
+ param->set<Parameter::volumeStereo>(mImplContext->getVolumeStereo());
break;
}
default: {
@@ -192,30 +223,34 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus EffectImpl::getState(State* state) {
+ndk::ScopedAStatus EffectImpl::getState(State* state) NO_THREAD_SAFETY_ANALYSIS {
*state = mState;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus EffectImpl::command(CommandId command) {
- RETURN_IF(mState == State::INIT, EX_ILLEGAL_STATE, "CommandStateError");
+ std::lock_guard lg(mImplMutex);
+ RETURN_IF(mState == State::INIT, EX_ILLEGAL_STATE, "instanceNotOpen");
LOG(DEBUG) << getEffectName() << __func__ << ": receive command: " << toString(command)
<< " at state " << toString(mState);
switch (command) {
case CommandId::START:
- RETURN_IF(mState == State::INIT, EX_ILLEGAL_STATE, "instanceNotOpen");
RETURN_OK_IF(mState == State::PROCESSING);
RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
- startThread();
mState = State::PROCESSING;
+ RETURN_IF(notifyEventFlag(kEventFlagNotEmpty) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
+ "notifyEventFlagFailed");
+ startThread();
break;
case CommandId::STOP:
case CommandId::RESET:
RETURN_OK_IF(mState == State::IDLE);
+ mState = State::IDLE;
+ RETURN_IF(notifyEventFlag(kEventFlagNotEmpty) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
+ "notifyEventFlagFailed");
stopThread();
RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
- mState = State::IDLE;
break;
default:
LOG(ERROR) << getEffectName() << __func__ << " instance still processing";
@@ -227,19 +262,41 @@
}
ndk::ScopedAStatus EffectImpl::commandImpl(CommandId command) {
- auto context = getContext();
- RETURN_IF(!context, EX_NULL_POINTER, "nullContext");
+ RETURN_IF(!mImplContext, EX_NULL_POINTER, "nullContext");
if (command == CommandId::RESET) {
- context->resetBuffer();
+ mImplContext->resetBuffer();
}
return ndk::ScopedAStatus::ok();
}
+std::shared_ptr<EffectContext> EffectImpl::createContext(const Parameter::Common& common) {
+ return std::make_shared<EffectContext>(1 /* statusMqDepth */, common);
+}
+
+RetCode EffectImpl::releaseContext() {
+ if (mImplContext) {
+ mImplContext.reset();
+ }
+ return RetCode::SUCCESS;
+}
+
void EffectImpl::cleanUp() {
command(CommandId::STOP);
close();
}
+RetCode EffectImpl::notifyEventFlag(uint32_t flag) {
+ if (!mEventFlag) {
+ LOG(ERROR) << getEffectName() << __func__ << ": StatusEventFlag invalid";
+ return RetCode::ERROR_EVENT_FLAG_ERROR;
+ }
+ if (const auto ret = mEventFlag->wake(flag); ret != ::android::OK) {
+ LOG(ERROR) << getEffectName() << __func__ << ": wake failure with ret " << ret;
+ return RetCode::ERROR_EVENT_FLAG_ERROR;
+ }
+ return RetCode::SUCCESS;
+}
+
IEffect::Status EffectImpl::status(binder_status_t status, size_t consumed, size_t produced) {
IEffect::Status ret;
ret.status = status;
@@ -248,6 +305,51 @@
return ret;
}
+void EffectImpl::process() {
+ ATRACE_CALL();
+ /**
+ * wait for the EventFlag without lock, it's ok because the mEfGroup pointer will not change
+ * in the life cycle of workerThread (threadLoop).
+ */
+ uint32_t efState = 0;
+ if (!mEventFlag ||
+ ::android::OK != mEventFlag->wait(kEventFlagNotEmpty, &efState, 0 /* no timeout */,
+ true /* retry */) ||
+ !(efState & kEventFlagNotEmpty)) {
+ LOG(ERROR) << getEffectName() << __func__ << ": StatusEventFlag - " << mEventFlag
+ << " efState - " << std::hex << efState;
+ return;
+ }
+
+ {
+ std::lock_guard lg(mImplMutex);
+ if (mState != State::PROCESSING) {
+ LOG(DEBUG) << getEffectName() << " skip process in state: " << toString(mState);
+ return;
+ }
+ RETURN_VALUE_IF(!mImplContext, void(), "nullContext");
+ auto statusMQ = mImplContext->getStatusFmq();
+ auto inputMQ = mImplContext->getInputDataFmq();
+ auto outputMQ = mImplContext->getOutputDataFmq();
+ auto buffer = mImplContext->getWorkBuffer();
+ if (!inputMQ || !outputMQ) {
+ return;
+ }
+
+ assert(mImplContext->getWorkBufferSize() >=
+ std::max(inputMQ->availableToRead(), outputMQ->availableToWrite()));
+ auto processSamples = std::min(inputMQ->availableToRead(), outputMQ->availableToWrite());
+ if (processSamples) {
+ inputMQ->read(buffer, processSamples);
+ IEffect::Status status = effectProcessImpl(buffer, buffer, processSamples);
+ outputMQ->write(buffer, status.fmqProduced);
+ statusMQ->writeBlocking(&status, 1);
+ LOG(VERBOSE) << getEffectName() << __func__ << ": done processing, effect consumed "
+ << status.fmqConsumed << " produced " << status.fmqProduced;
+ }
+ }
+}
+
// A placeholder processing implementation to copy samples from input to output
IEffect::Status EffectImpl::effectProcessImpl(float* in, float* out, int samples) {
for (int i = 0; i < samples; i++) {
diff --git a/audio/aidl/default/EffectMain.cpp b/audio/aidl/default/EffectMain.cpp
index ca81204..a300cfd 100644
--- a/audio/aidl/default/EffectMain.cpp
+++ b/audio/aidl/default/EffectMain.cpp
@@ -21,15 +21,39 @@
#include <android/binder_process.h>
#include <system/audio_config.h>
+#ifdef __ANDROID_APEX__
+#include <android/apexsupport.h>
+#endif
+
/** Default name of effect configuration file. */
static const char* kDefaultConfigName = "audio_effects_config.xml";
+static inline std::string config_file_path() {
+ if constexpr (__ANDROID_VENDOR_API__ >= 202404) {
+ AApexInfo *apexInfo;
+ if (AApexInfo_create(&apexInfo) == AAPEXINFO_OK) {
+ std::string apexName(AApexInfo_getName(apexInfo));
+ AApexInfo_destroy(apexInfo);
+ std::string candidatePath("/apex/");
+ candidatePath.append(apexName).append("/etc/").append(kDefaultConfigName);
+ LOG(DEBUG) << __func__ << " effect lib path " << candidatePath;
+ if (access(candidatePath.c_str(), R_OK) == 0) {
+ return std::move(candidatePath);
+ }
+ }
+ } else {
+ LOG(DEBUG) << __func__ << " libapexsupport is not supported";
+ }
+ LOG(DEBUG) << __func__ << ": Unable to resolve config file path in APEX";
+ return android::audio_find_readable_configuration_file(kDefaultConfigName);
+}
+
int main() {
// This is a debug implementation, always enable debug logging.
android::base::SetMinimumLogSeverity(::android::base::DEBUG);
ABinderProcess_setThreadPoolMaxThreadCount(0);
- auto configFile = android::audio_find_readable_configuration_file(kDefaultConfigName);
+ auto configFile = config_file_path();
if (configFile == "") {
LOG(ERROR) << __func__ << ": config file " << kDefaultConfigName << " not found!";
return EXIT_FAILURE;
diff --git a/audio/aidl/default/EffectThread.cpp b/audio/aidl/default/EffectThread.cpp
index 47ba9f4..fdd4803 100644
--- a/audio/aidl/default/EffectThread.cpp
+++ b/audio/aidl/default/EffectThread.cpp
@@ -25,8 +25,6 @@
#include "effect-impl/EffectThread.h"
#include "effect-impl/EffectTypes.h"
-using ::android::hardware::EventFlag;
-
namespace aidl::android::hardware::audio::effect {
EffectThread::EffectThread() {
@@ -38,31 +36,18 @@
LOG(DEBUG) << __func__ << " done";
}
-RetCode EffectThread::createThread(std::shared_ptr<EffectContext> context, const std::string& name,
- int priority) {
+RetCode EffectThread::createThread(const std::string& name, int priority) {
if (mThread.joinable()) {
LOG(WARNING) << mName << __func__ << " thread already created, no-op";
return RetCode::SUCCESS;
}
+
mName = name;
mPriority = priority;
{
std::lock_guard lg(mThreadMutex);
mStop = true;
mExit = false;
- mThreadContext = std::move(context);
- auto statusMQ = mThreadContext->getStatusFmq();
- EventFlag* efGroup = nullptr;
- ::android::status_t status =
- EventFlag::createEventFlag(statusMQ->getEventFlagWord(), &efGroup);
- if (status != ::android::OK || !efGroup) {
- LOG(ERROR) << mName << __func__ << " create EventFlagGroup failed " << status
- << " efGroup " << efGroup;
- return RetCode::ERROR_THREAD;
- }
- mEfGroup.reset(efGroup);
- // kickoff and wait for commands (CommandId::START/STOP) or IEffect.close from client
- mEfGroup->wake(kEventFlagNotEmpty);
}
mThread = std::thread(&EffectThread::threadLoop, this);
@@ -75,16 +60,12 @@
std::lock_guard lg(mThreadMutex);
mStop = mExit = true;
}
- mCv.notify_one();
+ mCv.notify_one();
if (mThread.joinable()) {
mThread.join();
}
- {
- std::lock_guard lg(mThreadMutex);
- mThreadContext.reset();
- }
LOG(DEBUG) << mName << __func__;
return RetCode::SUCCESS;
}
@@ -96,7 +77,6 @@
mCv.notify_one();
}
- mEfGroup->wake(kEventFlagNotEmpty);
LOG(DEBUG) << mName << __func__;
return RetCode::SUCCESS;
}
@@ -108,7 +88,6 @@
mCv.notify_one();
}
- mEfGroup->wake(kEventFlagNotEmpty);
LOG(DEBUG) << mName << __func__;
return RetCode::SUCCESS;
}
@@ -117,13 +96,6 @@
pthread_setname_np(pthread_self(), mName.substr(0, kMaxTaskNameLen - 1).c_str());
setpriority(PRIO_PROCESS, 0, mPriority);
while (true) {
- /**
- * wait for the EventFlag without lock, it's ok because the mEfGroup pointer will not change
- * in the life cycle of workerThread (threadLoop).
- */
- uint32_t efState = 0;
- mEfGroup->wait(kEventFlagNotEmpty, &efState);
-
{
std::unique_lock l(mThreadMutex);
::android::base::ScopedLockAssertion lock_assertion(mThreadMutex);
@@ -132,27 +104,8 @@
LOG(INFO) << __func__ << " EXIT!";
return;
}
- process_l();
}
- }
-}
-
-void EffectThread::process_l() {
- RETURN_VALUE_IF(!mThreadContext, void(), "nullContext");
-
- auto statusMQ = mThreadContext->getStatusFmq();
- auto inputMQ = mThreadContext->getInputDataFmq();
- auto outputMQ = mThreadContext->getOutputDataFmq();
- auto buffer = mThreadContext->getWorkBuffer();
-
- auto processSamples = inputMQ->availableToRead();
- if (processSamples) {
- inputMQ->read(buffer, processSamples);
- IEffect::Status status = effectProcessImpl(buffer, buffer, processSamples);
- outputMQ->write(buffer, status.fmqProduced);
- statusMQ->writeBlocking(&status, 1);
- LOG(VERBOSE) << mName << __func__ << ": done processing, effect consumed "
- << status.fmqConsumed << " produced " << status.fmqProduced;
+ process();
}
}
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
index 66c2169..94aa4dc 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -93,32 +93,6 @@
return std::all_of(profiles.begin(), profiles.end(), isDynamicProfile);
}
-// Note: does not assign an ID to the config.
-bool generateDefaultPortConfig(const AudioPort& port, AudioPortConfig* config) {
- const bool allowDynamicConfig = port.ext.getTag() == AudioPortExt::device;
- *config = {};
- config->portId = port.id;
- for (const auto& profile : port.profiles) {
- if (isDynamicProfile(profile)) continue;
- config->format = profile.format;
- config->channelMask = *profile.channelMasks.begin();
- config->sampleRate = Int{.value = *profile.sampleRates.begin()};
- config->flags = port.flags;
- config->ext = port.ext;
- return true;
- }
- if (allowDynamicConfig) {
- config->format = AudioFormatDescription{};
- config->channelMask = AudioChannelLayout{};
- config->sampleRate = Int{.value = 0};
- config->flags = port.flags;
- config->ext = port.ext;
- return true;
- }
- LOG(ERROR) << __func__ << ": port " << port.id << " only has dynamic profiles";
- return false;
-}
-
bool findAudioProfile(const AudioPort& port, const AudioFormatDescription& format,
AudioProfile* profile) {
if (auto profilesIt =
@@ -204,10 +178,11 @@
}
auto& configs = getConfig().portConfigs;
auto portConfigIt = findById<AudioPortConfig>(configs, in_portConfigId);
+ const int32_t nominalLatencyMs = getNominalLatencyMs(*portConfigIt);
// Since this is a private method, it is assumed that
// validity of the portConfigId has already been checked.
- const int32_t minimumStreamBufferSizeFrames = calculateBufferSizeFrames(
- getNominalLatencyMs(*portConfigIt), portConfigIt->sampleRate.value().value);
+ const int32_t minimumStreamBufferSizeFrames =
+ calculateBufferSizeFrames(nominalLatencyMs, portConfigIt->sampleRate.value().value);
if (in_bufferSizeFrames < minimumStreamBufferSizeFrames) {
LOG(ERROR) << __func__ << ": insufficient buffer size " << in_bufferSizeFrames
<< ", must be at least " << minimumStreamBufferSizeFrames;
@@ -246,7 +221,7 @@
std::make_unique<StreamContext::CommandMQ>(1, true /*configureEventFlagWord*/),
std::make_unique<StreamContext::ReplyMQ>(1, true /*configureEventFlagWord*/),
portConfigIt->format.value(), portConfigIt->channelMask.value(),
- portConfigIt->sampleRate.value().value, flags, getNominalLatencyMs(*portConfigIt),
+ portConfigIt->sampleRate.value().value, flags, nominalLatencyMs,
portConfigIt->ext.get<AudioPortExt::mix>().handle,
std::make_unique<StreamContext::DataMQ>(frameSize * in_bufferSizeFrames),
asyncCallback, outEventCallback, mSoundDose.getInstance(), params);
@@ -332,6 +307,29 @@
return ndk::ScopedAStatus::ok();
}
+bool Module::generateDefaultPortConfig(const AudioPort& port, AudioPortConfig* config) {
+ const bool allowDynamicConfig = port.ext.getTag() == AudioPortExt::device;
+ for (const auto& profile : port.profiles) {
+ if (isDynamicProfile(profile)) continue;
+ config->format = profile.format;
+ config->channelMask = *profile.channelMasks.begin();
+ config->sampleRate = Int{.value = *profile.sampleRates.begin()};
+ config->flags = port.flags;
+ config->ext = port.ext;
+ return true;
+ }
+ if (allowDynamicConfig) {
+ config->format = AudioFormatDescription{};
+ config->channelMask = AudioChannelLayout{};
+ config->sampleRate = Int{.value = 0};
+ config->flags = port.flags;
+ config->ext = port.ext;
+ return true;
+ }
+ LOG(ERROR) << __func__ << ": port " << port.id << " only has dynamic profiles";
+ return false;
+}
+
void Module::populateConnectedProfiles() {
Configuration& config = getConfig();
for (const AudioPort& port : config.ports) {
@@ -621,10 +619,11 @@
std::vector<AudioRoute*> routesToMixPorts = getAudioRoutesForAudioPortImpl(templateId);
std::set<int32_t> routableMixPortIds = getRoutableAudioPortIds(templateId, &routesToMixPorts);
+ const int32_t nextPortId = getConfig().nextPortId++;
if (!mDebug.simulateDeviceConnections) {
// Even if the device port has static profiles, the HAL module might need to update
// them, or abort the connection process.
- RETURN_STATUS_IF_ERROR(populateConnectedDevicePort(&connectedPort));
+ RETURN_STATUS_IF_ERROR(populateConnectedDevicePort(&connectedPort, nextPortId));
} else if (hasDynamicProfilesOnly(connectedPort.profiles)) {
auto& connectedProfiles = getConfig().connectedProfiles;
if (auto connectedProfilesIt = connectedProfiles.find(templateId);
@@ -648,7 +647,7 @@
}
}
- connectedPort.id = getConfig().nextPortId++;
+ connectedPort.id = nextPortId;
auto [connectedPortsIt, _] =
mConnectedDevicePorts.insert(std::pair(connectedPort.id, std::set<int32_t>()));
LOG(DEBUG) << __func__ << ": template port " << templateId << " external device connected, "
@@ -762,6 +761,28 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus Module::prepareToDisconnectExternalDevice(int32_t in_portId) {
+ auto& ports = getConfig().ports;
+ auto portIt = findById<AudioPort>(ports, in_portId);
+ if (portIt == ports.end()) {
+ LOG(ERROR) << __func__ << ": port id " << in_portId << " not found";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ if (portIt->ext.getTag() != AudioPortExt::Tag::device) {
+ LOG(ERROR) << __func__ << ": port id " << in_portId << " is not a device port";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ auto connectedPortsIt = mConnectedDevicePorts.find(in_portId);
+ if (connectedPortsIt == mConnectedDevicePorts.end()) {
+ LOG(ERROR) << __func__ << ": port id " << in_portId << " is not a connected device port";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+
+ onPrepareToDisconnectExternalDevice(*portIt);
+
+ return ndk::ScopedAStatus::ok();
+}
+
ndk::ScopedAStatus Module::getAudioPatches(std::vector<AudioPatch>* _aidl_return) {
*_aidl_return = getConfig().patches;
LOG(DEBUG) << __func__ << ": returning " << _aidl_return->size() << " patches";
@@ -1017,6 +1038,18 @@
ndk::ScopedAStatus Module::setAudioPortConfig(const AudioPortConfig& in_requested,
AudioPortConfig* out_suggested, bool* _aidl_return) {
+ auto generate = [this](const AudioPort& port, AudioPortConfig* config) {
+ return generateDefaultPortConfig(port, config);
+ };
+ return setAudioPortConfigImpl(in_requested, generate, out_suggested, _aidl_return);
+}
+
+ndk::ScopedAStatus Module::setAudioPortConfigImpl(
+ const AudioPortConfig& in_requested,
+ const std::function<bool(const ::aidl::android::media::audio::common::AudioPort& port,
+ ::aidl::android::media::audio::common::AudioPortConfig* config)>&
+ fillPortConfig,
+ AudioPortConfig* out_suggested, bool* applied) {
LOG(DEBUG) << __func__ << ": requested " << in_requested.toString();
auto& configs = getConfig().portConfigs;
auto existing = configs.end();
@@ -1045,7 +1078,8 @@
*out_suggested = *existing;
} else {
AudioPortConfig newConfig;
- if (generateDefaultPortConfig(*portIt, &newConfig)) {
+ newConfig.portId = portIt->id;
+ if (fillPortConfig(*portIt, &newConfig)) {
*out_suggested = newConfig;
} else {
LOG(ERROR) << __func__ << ": unable generate a default config for port " << portId;
@@ -1150,17 +1184,17 @@
if (existing == configs.end() && requestedIsValid && requestedIsFullySpecified) {
out_suggested->id = getConfig().nextPortId++;
configs.push_back(*out_suggested);
- *_aidl_return = true;
+ *applied = true;
LOG(DEBUG) << __func__ << ": created new port config " << out_suggested->toString();
} else if (existing != configs.end() && requestedIsValid) {
*existing = *out_suggested;
- *_aidl_return = true;
+ *applied = true;
LOG(DEBUG) << __func__ << ": updated port config " << out_suggested->toString();
} else {
LOG(DEBUG) << __func__ << ": not applied; existing config ? " << (existing != configs.end())
<< "; requested is valid? " << requestedIsValid << ", fully specified? "
<< requestedIsFullySpecified;
- *_aidl_return = false;
+ *applied = false;
}
return ndk::ScopedAStatus::ok();
}
@@ -1512,7 +1546,7 @@
return mIsMmapSupported.value();
}
-ndk::ScopedAStatus Module::populateConnectedDevicePort(AudioPort* audioPort) {
+ndk::ScopedAStatus Module::populateConnectedDevicePort(AudioPort* audioPort, int32_t) {
if (audioPort->ext.getTag() != AudioPortExt::device) {
LOG(ERROR) << __func__ << ": not a device port: " << audioPort->toString();
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
@@ -1541,6 +1575,11 @@
LOG(DEBUG) << __func__ << ": do nothing and return";
}
+void Module::onPrepareToDisconnectExternalDevice(
+ const ::aidl::android::media::audio::common::AudioPort& audioPort __unused) {
+ LOG(DEBUG) << __func__ << ": do nothing and return";
+}
+
ndk::ScopedAStatus Module::onMasterMuteChanged(bool mute __unused) {
LOG(VERBOSE) << __func__ << ": do nothing and return ok";
return ndk::ScopedAStatus::ok();
diff --git a/audio/aidl/default/SoundDose.cpp b/audio/aidl/default/SoundDose.cpp
index 1c9e081..6c3a067 100644
--- a/audio/aidl/default/SoundDose.cpp
+++ b/audio/aidl/default/SoundDose.cpp
@@ -119,7 +119,8 @@
void SoundDose::MelCallback::onNewMelValues(const std::vector<float>& mels, size_t offset,
size_t length,
audio_port_handle_t deviceId
- __attribute__((__unused__))) const {
+ __attribute__((__unused__)),
+ bool attenuated __attribute__((__unused__))) const {
mSoundDose.onNewMelValues(mels, offset, length, deviceId);
}
diff --git a/audio/aidl/default/Stream.cpp b/audio/aidl/default/Stream.cpp
index e8c1693..807348f 100644
--- a/audio/aidl/default/Stream.cpp
+++ b/audio/aidl/default/Stream.cpp
@@ -16,14 +16,14 @@
#include <pthread.h>
+#define ATRACE_TAG ATRACE_TAG_AUDIO
#define LOG_TAG "AHAL_Stream"
+#include <Utils.h>
#include <android-base/logging.h>
#include <android/binder_ibinder_platform.h>
#include <utils/SystemClock.h>
+#include <utils/Trace.h>
-#include <Utils.h>
-
-#include "core-impl/Module.h"
#include "core-impl/Stream.h"
using aidl::android::hardware::audio::common::AudioOffloadMetadata;
@@ -180,17 +180,20 @@
StreamDescriptor::Reply reply{};
reply.status = STATUS_BAD_VALUE;
switch (command.getTag()) {
- case Tag::halReservedExit:
- if (const int32_t cookie = command.get<Tag::halReservedExit>();
- cookie == (mContext->getInternalCommandCookie() ^ getTid())) {
+ case Tag::halReservedExit: {
+ const int32_t cookie = command.get<Tag::halReservedExit>();
+ if (cookie == (mContext->getInternalCommandCookie() ^ getTid())) {
mDriver->shutdown();
setClosed();
- // This is an internal command, no need to reply.
- return Status::EXIT;
} else {
LOG(WARNING) << __func__ << ": EXIT command has a bad cookie: " << cookie;
}
- break;
+ if (cookie != 0) { // This is an internal command, no need to reply.
+ return Status::EXIT;
+ } else {
+ break;
+ }
+ }
case Tag::getStatus:
populateReply(&reply, mIsConnected);
break;
@@ -309,6 +312,7 @@
}
bool StreamInWorkerLogic::read(size_t clientSize, StreamDescriptor::Reply* reply) {
+ ATRACE_CALL();
StreamContext::DataMQ* const dataMQ = mContext->getDataMQ();
const size_t byteCount = std::min({clientSize, dataMQ->availableToWrite(), mDataBufferSize});
const bool isConnected = mIsConnected;
@@ -400,17 +404,20 @@
reply.status = STATUS_BAD_VALUE;
using Tag = StreamDescriptor::Command::Tag;
switch (command.getTag()) {
- case Tag::halReservedExit:
- if (const int32_t cookie = command.get<Tag::halReservedExit>();
- cookie == (mContext->getInternalCommandCookie() ^ getTid())) {
+ case Tag::halReservedExit: {
+ const int32_t cookie = command.get<Tag::halReservedExit>();
+ if (cookie == (mContext->getInternalCommandCookie() ^ getTid())) {
mDriver->shutdown();
setClosed();
- // This is an internal command, no need to reply.
- return Status::EXIT;
} else {
LOG(WARNING) << __func__ << ": EXIT command has a bad cookie: " << cookie;
}
- break;
+ if (cookie != 0) { // This is an internal command, no need to reply.
+ return Status::EXIT;
+ } else {
+ break;
+ }
+ }
case Tag::getStatus:
populateReply(&reply, mIsConnected);
break;
@@ -577,12 +584,13 @@
}
bool StreamOutWorkerLogic::write(size_t clientSize, StreamDescriptor::Reply* reply) {
+ ATRACE_CALL();
StreamContext::DataMQ* const dataMQ = mContext->getDataMQ();
const size_t readByteCount = dataMQ->availableToRead();
const size_t frameSize = mContext->getFrameSize();
bool fatal = false;
int32_t latency = mContext->getNominalLatencyMs();
- if (bool success = readByteCount > 0 ? dataMQ->read(&mDataBuffer[0], readByteCount) : true) {
+ if (readByteCount > 0 ? dataMQ->read(&mDataBuffer[0], readByteCount) : true) {
const bool isConnected = mIsConnected;
LOG(VERBOSE) << __func__ << ": reading of " << readByteCount << " bytes from data MQ"
<< " succeeded; connected? " << isConnected;
diff --git a/audio/aidl/default/XsdcConversion.cpp b/audio/aidl/default/XsdcConversion.cpp
index 9e30347..1720949 100644
--- a/audio/aidl/default/XsdcConversion.cpp
+++ b/audio/aidl/default/XsdcConversion.cpp
@@ -205,24 +205,28 @@
ConversionResult<AudioIoFlags> convertIoFlagsToAidl(
const std::vector<ap_xsd::AudioInOutFlag>& flags, const ap_xsd::Role role,
bool flagsForMixPort) {
- int flagMask = 0;
+ int legacyFlagMask = 0;
if ((role == ap_xsd::Role::sink && flagsForMixPort) ||
(role == ap_xsd::Role::source && !flagsForMixPort)) {
for (const ap_xsd::AudioInOutFlag& flag : flags) {
audio_input_flags_t legacyFlag;
if (::android::InputFlagConverter::fromString(ap_xsd::toString(flag), legacyFlag)) {
- flagMask |= static_cast<int>(legacyFlag);
+ legacyFlagMask |= static_cast<int>(legacyFlag);
}
}
- return AudioIoFlags::make<AudioIoFlags::Tag::input>(flagMask);
+ return AudioIoFlags::make<AudioIoFlags::Tag::input>(
+ VALUE_OR_FATAL(legacy2aidl_audio_input_flags_t_int32_t_mask(
+ static_cast<audio_input_flags_t>(legacyFlagMask))));
} else {
for (const ap_xsd::AudioInOutFlag& flag : flags) {
audio_output_flags_t legacyFlag;
if (::android::OutputFlagConverter::fromString(ap_xsd::toString(flag), legacyFlag)) {
- flagMask |= static_cast<int>(legacyFlag);
+ legacyFlagMask |= static_cast<int>(legacyFlag);
}
}
- return AudioIoFlags::make<AudioIoFlags::Tag::output>(flagMask);
+ return AudioIoFlags::make<AudioIoFlags::Tag::output>(
+ VALUE_OR_FATAL(legacy2aidl_audio_output_flags_t_int32_t_mask(
+ static_cast<audio_output_flags_t>(legacyFlagMask))));
}
}
diff --git a/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.cpp b/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.cpp
index 8727232..be0927c 100644
--- a/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.cpp
+++ b/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.cpp
@@ -76,7 +76,7 @@
.proxy = std::nullopt},
.flags = {.type = Flags::Type::PRE_PROC,
.insert = Flags::Insert::FIRST,
- .volume = Flags::Volume::CTRL},
+ .volume = Flags::Volume::NONE},
.name = AcousticEchoCancelerSw::kEffectName,
.implementor = "The Android Open Source Project"},
.capability = AcousticEchoCancelerSw::kCapability};
@@ -168,10 +168,6 @@
return mContext;
}
-std::shared_ptr<EffectContext> AcousticEchoCancelerSw::getContext() {
- return mContext;
-}
-
RetCode AcousticEchoCancelerSw::releaseContext() {
if (mContext) {
mContext.reset();
diff --git a/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.h b/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.h
index 73cf42b..95738f8 100644
--- a/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.h
+++ b/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.h
@@ -52,21 +52,23 @@
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
- ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
- ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
- Parameter::Specific* specific) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+ REQUIRES(mImplMutex) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+ REQUIRES(mImplMutex) override;
- std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
- std::shared_ptr<EffectContext> getContext() override;
- RetCode releaseContext() override;
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+ REQUIRES(mImplMutex) override;
+ RetCode releaseContext() REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; };
IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
private:
static const std::vector<Range::AcousticEchoCancelerRange> kRanges;
- std::shared_ptr<AcousticEchoCancelerSwContext> mContext;
+ std::shared_ptr<AcousticEchoCancelerSwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterAcousticEchoCanceler(const AcousticEchoCanceler::Tag& tag,
- Parameter::Specific* specific);
+ Parameter::Specific* specific)
+ REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/acousticEchoCanceler/Android.bp b/audio/aidl/default/acousticEchoCanceler/Android.bp
index bfb7212..46930e0 100644
--- a/audio/aidl/default/acousticEchoCanceler/Android.bp
+++ b/audio/aidl/default/acousticEchoCanceler/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -27,8 +28,6 @@
name: "libaecsw",
defaults: [
"aidlaudioeffectservice_defaults",
- "latest_android_media_audio_common_types_ndk_shared",
- "latest_android_hardware_audio_effect_ndk_shared",
],
srcs: [
"AcousticEchoCancelerSw.cpp",
@@ -36,6 +35,6 @@
],
relative_install_path: "soundfx",
visibility: [
- "//hardware/interfaces/audio/aidl/default",
+ "//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}
diff --git a/audio/aidl/default/alsa/ModuleAlsa.cpp b/audio/aidl/default/alsa/ModuleAlsa.cpp
index 8512631..9a2cce7 100644
--- a/audio/aidl/default/alsa/ModuleAlsa.cpp
+++ b/audio/aidl/default/alsa/ModuleAlsa.cpp
@@ -34,7 +34,7 @@
namespace aidl::android::hardware::audio::core {
-ndk::ScopedAStatus ModuleAlsa::populateConnectedDevicePort(AudioPort* audioPort) {
+ndk::ScopedAStatus ModuleAlsa::populateConnectedDevicePort(AudioPort* audioPort, int32_t) {
auto deviceProfile = alsa::getDeviceProfile(*audioPort);
if (!deviceProfile.has_value()) {
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
diff --git a/audio/aidl/default/android.hardware.audio.effect.service-aidl.example.rc b/audio/aidl/default/android.hardware.audio.effect.service-aidl.example.rc
deleted file mode 100644
index 5f859a1..0000000
--- a/audio/aidl/default/android.hardware.audio.effect.service-aidl.example.rc
+++ /dev/null
@@ -1,11 +0,0 @@
-service vendor.audio-effect-hal-aidl /vendor/bin/hw/android.hardware.audio.effect.service-aidl.example
- class hal
- user audioserver
- # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
- group audio media
- capabilities BLOCK_SUSPEND
- # setting RLIMIT_RTPRIO allows binder RT priority inheritance
- rlimit rtprio 10 10
- ioprio rt 4
- task_profiles ProcessCapacityHigh HighPerformance
- onrestart restart audioserver
diff --git a/audio/aidl/default/android.hardware.audio.effect.service-aidl.xml b/audio/aidl/default/android.hardware.audio.effect.service-aidl.xml
deleted file mode 100644
index 05a825d..0000000
--- a/audio/aidl/default/android.hardware.audio.effect.service-aidl.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<manifest version="1.0" type="device">
- <hal format="aidl">
- <name>android.hardware.audio.effect</name>
- <version>2</version>
- <fqname>IFactory/default</fqname>
- </hal>
-</manifest>
diff --git a/audio/aidl/default/android.hardware.audio.service-aidl.example.rc b/audio/aidl/default/android.hardware.audio.service-aidl.example.rc
index 757976f..c3e19ba 100644
--- a/audio/aidl/default/android.hardware.audio.service-aidl.example.rc
+++ b/audio/aidl/default/android.hardware.audio.service-aidl.example.rc
@@ -1,4 +1,5 @@
-service vendor.audio-hal-aidl /vendor/bin/hw/android.hardware.audio.service-aidl.example
+
+service vendor.audio-hal-aidl /apex/com.android.hardware.audio/bin/hw/android.hardware.audio.service-aidl.example
class hal
user audioserver
# media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
@@ -9,3 +10,15 @@
ioprio rt 4
task_profiles ProcessCapacityHigh HighPerformance
onrestart restart audioserver
+
+service vendor.audio-effect-hal-aidl /apex/com.android.hardware.audio/bin/hw/android.hardware.audio.effect.service-aidl.example
+ class hal
+ user audioserver
+ # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
+ group audio media
+ capabilities BLOCK_SUSPEND
+ # setting RLIMIT_RTPRIO allows binder RT priority inheritance
+ rlimit rtprio 10 10
+ ioprio rt 4
+ task_profiles ProcessCapacityHigh HighPerformance
+ onrestart restart audioserver
\ No newline at end of file
diff --git a/audio/aidl/default/android.hardware.audio.service-aidl.xml b/audio/aidl/default/android.hardware.audio.service-aidl.xml
index 2a51876..5278e4f 100644
--- a/audio/aidl/default/android.hardware.audio.service-aidl.xml
+++ b/audio/aidl/default/android.hardware.audio.service-aidl.xml
@@ -31,4 +31,9 @@
<fqname>IModule/usb</fqname>
</hal>
-->
+ <hal format="aidl">
+ <name>android.hardware.audio.effect</name>
+ <version>2</version>
+ <fqname>IFactory/default</fqname>
+ </hal>
</manifest>
diff --git a/audio/aidl/default/apex/com.android.hardware.audio/Android.bp b/audio/aidl/default/apex/com.android.hardware.audio/Android.bp
new file mode 100644
index 0000000..2ece7a1
--- /dev/null
+++ b/audio/aidl/default/apex/com.android.hardware.audio/Android.bp
@@ -0,0 +1,51 @@
+package {
+ default_team: "trendy_team_android_media_audio_framework",
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+apex {
+ name: "com.android.hardware.audio",
+ manifest: "manifest.json",
+ file_contexts: "file_contexts",
+ key: "com.android.hardware.key",
+ certificate: ":com.android.hardware.certificate",
+ updatable: false,
+ vendor: true,
+
+ binaries: [
+ "android.hardware.audio.service-aidl.example",
+ "android.hardware.audio.effect.service-aidl.example",
+ ],
+ native_shared_libs: [
+ "libaecsw",
+ "libagc1sw",
+ "libagc2sw",
+ "libbassboostsw",
+ "libbundleaidl",
+ "libdownmixaidl",
+ "libdynamicsprocessingaidl",
+ "libenvreverbsw",
+ "libequalizersw",
+ "libextensioneffect",
+ "libhapticgeneratoraidl",
+ "libloudnessenhanceraidl",
+ "libnssw",
+ "libpreprocessingaidl",
+ "libpresetreverbsw",
+ "libreverbaidl",
+ "libspatializersw",
+ "libvirtualizersw",
+ "libvisualizeraidl",
+ "libvolumesw",
+ ],
+ prebuilts: [
+ "android.hardware.audio.service-aidl.example.rc",
+ "android.hardware.audio.service-aidl.xml",
+ "audio_effects_config.xml",
+ ],
+}
diff --git a/audio/aidl/default/apex/com.android.hardware.audio/file_contexts b/audio/aidl/default/apex/com.android.hardware.audio/file_contexts
new file mode 100644
index 0000000..41a6ada
--- /dev/null
+++ b/audio/aidl/default/apex/com.android.hardware.audio/file_contexts
@@ -0,0 +1,4 @@
+(/.*)? u:object_r:vendor_file:s0
+/etc(/.*)? u:object_r:vendor_configs_file:s0
+/bin/hw/android\.hardware\.audio\.service-aidl\.example u:object_r:hal_audio_default_exec:s0
+/bin/hw/android\.hardware\.audio\.effect\.service-aidl\.example u:object_r:hal_audio_default_exec:s0
\ No newline at end of file
diff --git a/audio/aidl/default/apex/com.android.hardware.audio/manifest.json b/audio/aidl/default/apex/com.android.hardware.audio/manifest.json
new file mode 100644
index 0000000..42a2368
--- /dev/null
+++ b/audio/aidl/default/apex/com.android.hardware.audio/manifest.json
@@ -0,0 +1,4 @@
+{
+ "name": "com.android.hardware.audio",
+ "version": 1
+}
diff --git a/audio/aidl/default/audio_effects_config.xml b/audio/aidl/default/audio_effects_config.xml
index 00de797..827ff80 100644
--- a/audio/aidl/default/audio_effects_config.xml
+++ b/audio/aidl/default/audio_effects_config.xml
@@ -47,6 +47,7 @@
<library name="visualizer" path="libvisualizeraidl.so"/>
<library name="volumesw" path="libvolumesw.so"/>
<library name="extensioneffect" path="libextensioneffect.so"/>
+ <library name="spatializersw" path="libspatializersw.so"/>
</libraries>
<!-- list of effects to load.
@@ -96,8 +97,9 @@
<libsw library="bundle" uuid="ce772f20-847d-11df-bb17-0002a5d5c51b"/>
</effectProxy>
<effect name="extension_effect" library="extensioneffect" uuid="fa81dd00-588b-11ed-9b6a-0242ac120002" type="fa81de0e-588b-11ed-9b6a-0242ac120002"/>
- <effect name="acoustic_echo_canceler" library="aecsw" uuid="bb392ec0-8d4d-11e0-a896-0002a5d5c51b"/>
- <effect name="noise_suppression" library="nssw" uuid="c06c8400-8e06-11e0-9cb6-0002a5d5c51b"/>
+ <effect name="acoustic_echo_canceler" library="pre_processing" uuid="bb392ec0-8d4d-11e0-a896-0002a5d5c51b"/>
+ <effect name="noise_suppression" library="pre_processing" uuid="c06c8400-8e06-11e0-9cb6-0002a5d5c51b"/>
+ <effect name="spatializer" library="spatializersw" uuid="fa81a880-588b-11ed-9b6a-0242ac120002"/>
</effects>
<preprocess>
diff --git a/audio/aidl/default/automaticGainControlV1/Android.bp b/audio/aidl/default/automaticGainControlV1/Android.bp
index 4ae8e63..2fea719 100644
--- a/audio/aidl/default/automaticGainControlV1/Android.bp
+++ b/audio/aidl/default/automaticGainControlV1/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -27,8 +28,6 @@
name: "libagc1sw",
defaults: [
"aidlaudioeffectservice_defaults",
- "latest_android_media_audio_common_types_ndk_shared",
- "latest_android_hardware_audio_effect_ndk_shared",
],
srcs: [
"AutomaticGainControlV1Sw.cpp",
@@ -36,6 +35,6 @@
],
relative_install_path: "soundfx",
visibility: [
- "//hardware/interfaces/audio/aidl/default",
+ "//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}
diff --git a/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.cpp b/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.cpp
index ce10ae1..d865b7e 100644
--- a/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.cpp
+++ b/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.cpp
@@ -177,10 +177,6 @@
return mContext;
}
-std::shared_ptr<EffectContext> AutomaticGainControlV1Sw::getContext() {
- return mContext;
-}
-
RetCode AutomaticGainControlV1Sw::releaseContext() {
if (mContext) {
mContext.reset();
diff --git a/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.h b/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.h
index 7d2a69f..76b91ae 100644
--- a/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.h
+++ b/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.h
@@ -53,21 +53,24 @@
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
- ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
- ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
- Parameter::Specific* specific) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+ REQUIRES(mImplMutex) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+ REQUIRES(mImplMutex) override;
- std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
- std::shared_ptr<EffectContext> getContext() override;
- RetCode releaseContext() override;
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+ REQUIRES(mImplMutex) override;
+ RetCode releaseContext() REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; };
- IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+ IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+ REQUIRES(mImplMutex) override;
private:
static const std::vector<Range::AutomaticGainControlV1Range> kRanges;
- std::shared_ptr<AutomaticGainControlV1SwContext> mContext;
+ std::shared_ptr<AutomaticGainControlV1SwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterAutomaticGainControlV1(const AutomaticGainControlV1::Tag& tag,
- Parameter::Specific* specific);
+ Parameter::Specific* specific)
+ REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/automaticGainControlV2/Android.bp b/audio/aidl/default/automaticGainControlV2/Android.bp
index 631cf58..dda4e51 100644
--- a/audio/aidl/default/automaticGainControlV2/Android.bp
+++ b/audio/aidl/default/automaticGainControlV2/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -27,8 +28,6 @@
name: "libagc2sw",
defaults: [
"aidlaudioeffectservice_defaults",
- "latest_android_media_audio_common_types_ndk_shared",
- "latest_android_hardware_audio_effect_ndk_shared",
],
srcs: [
"AutomaticGainControlV2Sw.cpp",
@@ -36,6 +35,6 @@
],
relative_install_path: "soundfx",
visibility: [
- "//hardware/interfaces/audio/aidl/default",
+ "//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}
diff --git a/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.cpp b/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.cpp
index 1e336ac..3ff6e38 100644
--- a/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.cpp
+++ b/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.cpp
@@ -180,10 +180,6 @@
return mContext;
}
-std::shared_ptr<EffectContext> AutomaticGainControlV2Sw::getContext() {
- return mContext;
-}
-
RetCode AutomaticGainControlV2Sw::releaseContext() {
if (mContext) {
mContext.reset();
diff --git a/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.h b/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.h
index 9aa60ea..863d470 100644
--- a/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.h
+++ b/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.h
@@ -59,21 +59,24 @@
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
- ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
- ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
- Parameter::Specific* specific) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+ REQUIRES(mImplMutex) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+ REQUIRES(mImplMutex) override;
- std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
- std::shared_ptr<EffectContext> getContext() override;
- RetCode releaseContext() override;
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+ REQUIRES(mImplMutex) override;
+ RetCode releaseContext() REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; };
- IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+ IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+ REQUIRES(mImplMutex) override;
private:
static const std::vector<Range::AutomaticGainControlV2Range> kRanges;
- std::shared_ptr<AutomaticGainControlV2SwContext> mContext;
+ std::shared_ptr<AutomaticGainControlV2SwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterAutomaticGainControlV2(const AutomaticGainControlV2::Tag& tag,
- Parameter::Specific* specific);
+ Parameter::Specific* specific)
+ REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/bassboost/Android.bp b/audio/aidl/default/bassboost/Android.bp
index 82b2f20..42223b4 100644
--- a/audio/aidl/default/bassboost/Android.bp
+++ b/audio/aidl/default/bassboost/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -27,8 +28,6 @@
name: "libbassboostsw",
defaults: [
"aidlaudioeffectservice_defaults",
- "latest_android_media_audio_common_types_ndk_shared",
- "latest_android_hardware_audio_effect_ndk_shared",
],
srcs: [
"BassBoostSw.cpp",
@@ -36,6 +35,6 @@
],
relative_install_path: "soundfx",
visibility: [
- "//hardware/interfaces/audio/aidl/default",
+ "//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}
diff --git a/audio/aidl/default/bassboost/BassBoostSw.cpp b/audio/aidl/default/bassboost/BassBoostSw.cpp
index 6072d89..60adc30 100644
--- a/audio/aidl/default/bassboost/BassBoostSw.cpp
+++ b/audio/aidl/default/bassboost/BassBoostSw.cpp
@@ -151,10 +151,6 @@
return mContext;
}
-std::shared_ptr<EffectContext> BassBoostSw::getContext() {
- return mContext;
-}
-
RetCode BassBoostSw::releaseContext() {
if (mContext) {
mContext.reset();
diff --git a/audio/aidl/default/bassboost/BassBoostSw.h b/audio/aidl/default/bassboost/BassBoostSw.h
index 1132472..901e455 100644
--- a/audio/aidl/default/bassboost/BassBoostSw.h
+++ b/audio/aidl/default/bassboost/BassBoostSw.h
@@ -51,21 +51,23 @@
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
- ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
- ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
- Parameter::Specific* specific) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+ REQUIRES(mImplMutex) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+ REQUIRES(mImplMutex) override;
- std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
- std::shared_ptr<EffectContext> getContext() override;
- RetCode releaseContext() override;
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+ REQUIRES(mImplMutex) override;
+ RetCode releaseContext() REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; };
- IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+ IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+ REQUIRES(mImplMutex) override;
private:
static const std::vector<Range::BassBoostRange> kRanges;
- std::shared_ptr<BassBoostSwContext> mContext;
+ std::shared_ptr<BassBoostSwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterBassBoost(const BassBoost::Tag& tag,
- Parameter::Specific* specific);
+ Parameter::Specific* specific) REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/bluetooth/DevicePortProxy.cpp b/audio/aidl/default/bluetooth/DevicePortProxy.cpp
index 1be0875..d772c20 100644
--- a/audio/aidl/default/bluetooth/DevicePortProxy.cpp
+++ b/audio/aidl/default/bluetooth/DevicePortProxy.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "AHAL_BluetoothPortProxy"
+#define LOG_TAG "AHAL_BluetoothAudioPort"
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
@@ -254,12 +254,7 @@
return (mCookie != ::aidl::android::hardware::bluetooth::audio::kObserversCookieUndefined);
}
-bool BluetoothAudioPortAidl::getPreferredDataIntervalUs(size_t* interval_us) const {
- if (!interval_us) {
- LOG(ERROR) << __func__ << ": bad input arg";
- return false;
- }
-
+bool BluetoothAudioPortAidl::getPreferredDataIntervalUs(size_t& interval_us) const {
if (!inUse()) {
LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use";
return false;
@@ -272,16 +267,11 @@
return false;
}
- *interval_us = hal_audio_cfg.get<AudioConfiguration::pcmConfig>().dataIntervalUs;
+ interval_us = hal_audio_cfg.get<AudioConfiguration::pcmConfig>().dataIntervalUs;
return true;
}
-bool BluetoothAudioPortAidl::loadAudioConfig(PcmConfiguration* audio_cfg) const {
- if (!audio_cfg) {
- LOG(ERROR) << __func__ << ": bad input arg";
- return false;
- }
-
+bool BluetoothAudioPortAidl::loadAudioConfig(PcmConfiguration& audio_cfg) {
if (!inUse()) {
LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use";
return false;
@@ -293,15 +283,26 @@
LOG(ERROR) << __func__ << ": unsupported audio cfg tag";
return false;
}
- *audio_cfg = hal_audio_cfg.get<AudioConfiguration::pcmConfig>();
+ audio_cfg = hal_audio_cfg.get<AudioConfiguration::pcmConfig>();
LOG(VERBOSE) << __func__ << debugMessage() << ", state*=" << getState() << ", PcmConfig=["
- << audio_cfg->toString() << "]";
- if (audio_cfg->channelMode == ChannelMode::UNKNOWN) {
+ << audio_cfg.toString() << "]";
+ if (audio_cfg.channelMode == ChannelMode::UNKNOWN) {
return false;
}
return true;
}
+bool BluetoothAudioPortAidlOut::loadAudioConfig(PcmConfiguration& audio_cfg) {
+ if (!BluetoothAudioPortAidl::loadAudioConfig(audio_cfg)) return false;
+ // WAR to support Mono / 16 bits per sample as the Bluetooth stack requires
+ if (audio_cfg.channelMode == ChannelMode::MONO && audio_cfg.bitsPerSample == 16) {
+ mIsStereoToMono = true;
+ audio_cfg.channelMode = ChannelMode::STEREO;
+ LOG(INFO) << __func__ << ": force channels = to be AUDIO_CHANNEL_OUT_STEREO";
+ }
+ return true;
+}
+
bool BluetoothAudioPortAidl::standby() {
if (!inUse()) {
LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use";
@@ -435,7 +436,7 @@
retval = condWaitState(BluetoothStreamState::SUSPENDING);
} else {
LOG(ERROR) << __func__ << debugMessage() << ", state=" << getState()
- << " Hal fails";
+ << " failure to suspend stream";
}
}
}
diff --git a/audio/aidl/default/bluetooth/ModuleBluetooth.cpp b/audio/aidl/default/bluetooth/ModuleBluetooth.cpp
index 502b153..ac375a0 100644
--- a/audio/aidl/default/bluetooth/ModuleBluetooth.cpp
+++ b/audio/aidl/default/bluetooth/ModuleBluetooth.cpp
@@ -24,17 +24,73 @@
using aidl::android::hardware::audio::common::SinkMetadata;
using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::hardware::bluetooth::audio::ChannelMode;
+using aidl::android::hardware::bluetooth::audio::PcmConfiguration;
+using aidl::android::media::audio::common::AudioChannelLayout;
+using aidl::android::media::audio::common::AudioConfigBase;
using aidl::android::media::audio::common::AudioDeviceDescription;
using aidl::android::media::audio::common::AudioDeviceType;
+using aidl::android::media::audio::common::AudioFormatDescription;
+using aidl::android::media::audio::common::AudioFormatType;
+using aidl::android::media::audio::common::AudioIoFlags;
using aidl::android::media::audio::common::AudioOffloadInfo;
using aidl::android::media::audio::common::AudioPort;
+using aidl::android::media::audio::common::AudioPortConfig;
using aidl::android::media::audio::common::AudioPortExt;
+using aidl::android::media::audio::common::AudioProfile;
+using aidl::android::media::audio::common::Int;
using aidl::android::media::audio::common::MicrophoneInfo;
+using aidl::android::media::audio::common::PcmType;
using android::bluetooth::audio::aidl::BluetoothAudioPortAidl;
+using android::bluetooth::audio::aidl::BluetoothAudioPortAidlIn;
using android::bluetooth::audio::aidl::BluetoothAudioPortAidlOut;
+// TODO(b/312265159) bluetooth audio should be in its own process
+// Remove this and the shared_libs when that happens
+extern "C" binder_status_t createIBluetoothAudioProviderFactory();
+
namespace aidl::android::hardware::audio::core {
+namespace {
+
+PcmType pcmTypeFromBitsPerSample(int8_t bitsPerSample) {
+ if (bitsPerSample == 8)
+ return PcmType::UINT_8_BIT;
+ else if (bitsPerSample == 16)
+ return PcmType::INT_16_BIT;
+ else if (bitsPerSample == 24)
+ return PcmType::INT_24_BIT;
+ else if (bitsPerSample == 32)
+ return PcmType::INT_32_BIT;
+ ALOGE("Unsupported bitsPerSample: %d", bitsPerSample);
+ return PcmType::DEFAULT;
+}
+
+AudioChannelLayout channelLayoutFromChannelMode(ChannelMode mode) {
+ if (mode == ChannelMode::MONO) {
+ return AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
+ AudioChannelLayout::LAYOUT_MONO);
+ } else if (mode == ChannelMode::STEREO || mode == ChannelMode::DUALMONO) {
+ return AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
+ AudioChannelLayout::LAYOUT_STEREO);
+ }
+ ALOGE("Unsupported channel mode: %s", toString(mode).c_str());
+ return AudioChannelLayout{};
+}
+
+} // namespace
+
+ModuleBluetooth::ModuleBluetooth(std::unique_ptr<Module::Configuration>&& config)
+ : Module(Type::BLUETOOTH, std::move(config)) {
+ // TODO(b/312265159) bluetooth audio should be in its own process
+ // Remove this and the shared_libs when that happens
+ binder_status_t status = createIBluetoothAudioProviderFactory();
+ if (status != STATUS_OK) {
+ LOG(ERROR) << "Failed to create bluetooth audio provider factory. Status: "
+ << ::android::statusToString(status);
+ }
+}
+
ndk::ScopedAStatus ModuleBluetooth::getBluetoothA2dp(
std::shared_ptr<IBluetoothA2dp>* _aidl_return) {
*_aidl_return = getBtA2dp().getInstance();
@@ -80,66 +136,130 @@
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
+ndk::ScopedAStatus ModuleBluetooth::setAudioPortConfig(const AudioPortConfig& in_requested,
+ AudioPortConfig* out_suggested,
+ bool* _aidl_return) {
+ auto fillConfig = [this](const AudioPort& port, AudioPortConfig* config) {
+ if (port.ext.getTag() == AudioPortExt::device) {
+ CachedProxy proxy;
+ auto status = findOrCreateProxy(port, proxy);
+ if (status.isOk()) {
+ const auto& pcmConfig = proxy.pcmConfig;
+ LOG(DEBUG) << "setAudioPortConfig: suggesting port config from "
+ << pcmConfig.toString();
+ const auto pcmType = pcmTypeFromBitsPerSample(pcmConfig.bitsPerSample);
+ const auto channelMask = channelLayoutFromChannelMode(pcmConfig.channelMode);
+ if (pcmType != PcmType::DEFAULT && channelMask != AudioChannelLayout{}) {
+ config->format =
+ AudioFormatDescription{.type = AudioFormatType::PCM, .pcm = pcmType};
+ config->channelMask = channelMask;
+ config->sampleRate = Int{.value = pcmConfig.sampleRateHz};
+ config->flags = port.flags;
+ config->ext = port.ext;
+ return true;
+ }
+ }
+ }
+ return generateDefaultPortConfig(port, config);
+ };
+ return Module::setAudioPortConfigImpl(in_requested, fillConfig, out_suggested, _aidl_return);
+}
+
+ndk::ScopedAStatus ModuleBluetooth::checkAudioPatchEndpointsMatch(
+ const std::vector<AudioPortConfig*>& sources, const std::vector<AudioPortConfig*>& sinks) {
+ // Both sources and sinks must be non-empty, this is guaranteed by 'setAudioPatch'.
+ const bool isInput = sources[0]->ext.getTag() == AudioPortExt::device;
+ const int32_t devicePortId = isInput ? sources[0]->portId : sinks[0]->portId;
+ const auto proxyIt = mProxies.find(devicePortId);
+ if (proxyIt == mProxies.end()) return ndk::ScopedAStatus::ok();
+ const auto& pcmConfig = proxyIt->second.pcmConfig;
+ const AudioPortConfig* mixPortConfig = isInput ? sinks[0] : sources[0];
+ if (!StreamBluetooth::checkConfigParams(
+ pcmConfig, AudioConfigBase{.sampleRate = mixPortConfig->sampleRate->value,
+ .channelMask = *(mixPortConfig->channelMask),
+ .format = *(mixPortConfig->format)})) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ }
+ if (int32_t handle = mixPortConfig->ext.get<AudioPortExt::mix>().handle; handle > 0) {
+ mConnections.insert(std::pair(handle, devicePortId));
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+void ModuleBluetooth::onExternalDeviceConnectionChanged(const AudioPort& audioPort,
+ bool connected) {
+ if (!connected) mProxies.erase(audioPort.id);
+}
+
ndk::ScopedAStatus ModuleBluetooth::createInputStream(
StreamContext&& context, const SinkMetadata& sinkMetadata,
const std::vector<MicrophoneInfo>& microphones, std::shared_ptr<StreamIn>* result) {
+ CachedProxy proxy;
+ RETURN_STATUS_IF_ERROR(fetchAndCheckProxy(context, proxy));
return createStreamInstance<StreamInBluetooth>(result, std::move(context), sinkMetadata,
- microphones, getBtProfileManagerHandles());
+ microphones, getBtProfileManagerHandles(),
+ proxy.ptr, proxy.pcmConfig);
}
ndk::ScopedAStatus ModuleBluetooth::createOutputStream(
StreamContext&& context, const SourceMetadata& sourceMetadata,
const std::optional<AudioOffloadInfo>& offloadInfo, std::shared_ptr<StreamOut>* result) {
+ CachedProxy proxy;
+ RETURN_STATUS_IF_ERROR(fetchAndCheckProxy(context, proxy));
return createStreamInstance<StreamOutBluetooth>(result, std::move(context), sourceMetadata,
- offloadInfo, getBtProfileManagerHandles());
+ offloadInfo, getBtProfileManagerHandles(),
+ proxy.ptr, proxy.pcmConfig);
}
-ndk::ScopedAStatus ModuleBluetooth::populateConnectedDevicePort(AudioPort* audioPort) {
+ndk::ScopedAStatus ModuleBluetooth::populateConnectedDevicePort(AudioPort* audioPort,
+ int32_t nextPortId) {
if (audioPort->ext.getTag() != AudioPortExt::device) {
LOG(ERROR) << __func__ << ": not a device port: " << audioPort->toString();
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
+ if (!::aidl::android::hardware::bluetooth::audio::BluetoothAudioSession::IsAidlAvailable()) {
+ LOG(ERROR) << __func__ << ": IBluetoothAudioProviderFactory AIDL service not available";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+ }
const auto& devicePort = audioPort->ext.get<AudioPortExt::device>();
const auto& description = devicePort.device.type;
- // Since the configuration of the BT module is static, there is nothing to populate here.
- // However, this method must return an error when the device can not be connected,
- // this is determined by the status of BT profiles.
+ // This method must return an error when the device can not be connected.
if (description.connection == AudioDeviceDescription::CONNECTION_BT_A2DP) {
bool isA2dpEnabled = false;
if (!!mBluetoothA2dp) {
RETURN_STATUS_IF_ERROR((*mBluetoothA2dp).isEnabled(&isA2dpEnabled));
}
LOG(DEBUG) << __func__ << ": isA2dpEnabled: " << isA2dpEnabled;
- return isA2dpEnabled ? ndk::ScopedAStatus::ok()
- : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+ if (!isA2dpEnabled) return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
} else if (description.connection == AudioDeviceDescription::CONNECTION_BT_LE) {
bool isLeEnabled = false;
if (!!mBluetoothLe) {
RETURN_STATUS_IF_ERROR((*mBluetoothLe).isEnabled(&isLeEnabled));
}
LOG(DEBUG) << __func__ << ": isLeEnabled: " << isLeEnabled;
- return isLeEnabled ? ndk::ScopedAStatus::ok()
- : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+ if (!isLeEnabled) return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
} else if (description.connection == AudioDeviceDescription::CONNECTION_WIRELESS &&
description.type == AudioDeviceType::OUT_HEARING_AID) {
- // Hearing aids can use a number of profiles, thus the only way to check
- // connectivity is to try to talk to the BT HAL.
- if (!::aidl::android::hardware::bluetooth::audio::BluetoothAudioSession::
- IsAidlAvailable()) {
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- }
- std::shared_ptr<BluetoothAudioPortAidl> proxy = std::shared_ptr<BluetoothAudioPortAidl>(
- std::make_shared<BluetoothAudioPortAidlOut>());
- if (proxy->registerPort(description)) {
- LOG(DEBUG) << __func__ << ": registered hearing aid port";
- proxy->unregisterPort();
- return ndk::ScopedAStatus::ok();
- }
- LOG(DEBUG) << __func__ << ": failed to register hearing aid port";
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+ // Hearing aids can use a number of profiles, no single switch exists.
+ } else {
+ LOG(ERROR) << __func__ << ": unsupported device type: " << audioPort->toString();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
- LOG(ERROR) << __func__ << ": unsupported device type: " << audioPort->toString();
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ CachedProxy proxy;
+ RETURN_STATUS_IF_ERROR(createProxy(*audioPort, nextPortId, proxy));
+ // Since the device is already connected and configured by the BT stack, provide
+ // the current configuration instead of all possible profiles.
+ const auto& pcmConfig = proxy.pcmConfig;
+ audioPort->profiles.clear();
+ audioPort->profiles.push_back(
+ AudioProfile{.format = AudioFormatDescription{.type = AudioFormatType::PCM,
+ .pcm = pcmTypeFromBitsPerSample(
+ pcmConfig.bitsPerSample)},
+ .channelMasks = std::vector<AudioChannelLayout>(
+ {channelLayoutFromChannelMode(pcmConfig.channelMode)}),
+ .sampleRates = std::vector<int>({pcmConfig.sampleRateHz})});
+ LOG(DEBUG) << __func__ << ": " << audioPort->toString();
+ return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus ModuleBluetooth::onMasterMuteChanged(bool) {
@@ -152,4 +272,83 @@
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
+int32_t ModuleBluetooth::getNominalLatencyMs(const AudioPortConfig& portConfig) {
+ const auto connectionsIt = mConnections.find(portConfig.ext.get<AudioPortExt::mix>().handle);
+ if (connectionsIt != mConnections.end()) {
+ const auto proxyIt = mProxies.find(connectionsIt->second);
+ if (proxyIt != mProxies.end()) {
+ auto proxy = proxyIt->second.ptr;
+ size_t dataIntervalUs = 0;
+ if (!proxy->getPreferredDataIntervalUs(dataIntervalUs)) {
+ LOG(WARNING) << __func__ << ": could not fetch preferred data interval";
+ }
+ const bool isInput = portConfig.flags->getTag() == AudioIoFlags::input;
+ return isInput ? StreamInBluetooth::getNominalLatencyMs(dataIntervalUs)
+ : StreamOutBluetooth::getNominalLatencyMs(dataIntervalUs);
+ }
+ }
+ LOG(ERROR) << __func__ << ": no connection or proxy found for " << portConfig.toString();
+ return Module::getNominalLatencyMs(portConfig);
+}
+
+ndk::ScopedAStatus ModuleBluetooth::createProxy(const AudioPort& audioPort, int32_t instancePortId,
+ CachedProxy& proxy) {
+ const bool isInput = audioPort.flags.getTag() == AudioIoFlags::input;
+ proxy.ptr = isInput ? std::shared_ptr<BluetoothAudioPortAidl>(
+ std::make_shared<BluetoothAudioPortAidlIn>())
+ : std::shared_ptr<BluetoothAudioPortAidl>(
+ std::make_shared<BluetoothAudioPortAidlOut>());
+ const auto& devicePort = audioPort.ext.get<AudioPortExt::device>();
+ const auto device = devicePort.device.type;
+ bool registrationSuccess = false;
+ for (int i = 0; i < kCreateProxyRetries && !registrationSuccess; ++i) {
+ registrationSuccess = proxy.ptr->registerPort(device);
+ usleep(kCreateProxyRetrySleepMs * 1000);
+ }
+ if (!registrationSuccess) {
+ LOG(ERROR) << __func__ << ": failed to register BT port for " << device.toString();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+ }
+ if (!proxy.ptr->loadAudioConfig(proxy.pcmConfig)) {
+ LOG(ERROR) << __func__ << ": state=" << proxy.ptr->getState()
+ << ", failed to load audio config";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+ }
+ mProxies.insert(std::pair(instancePortId, proxy));
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ModuleBluetooth::fetchAndCheckProxy(const StreamContext& context,
+ CachedProxy& proxy) {
+ const auto connectionsIt = mConnections.find(context.getMixPortHandle());
+ if (connectionsIt != mConnections.end()) {
+ const auto proxyIt = mProxies.find(connectionsIt->second);
+ if (proxyIt != mProxies.end()) {
+ proxy = proxyIt->second;
+ mProxies.erase(proxyIt);
+ }
+ mConnections.erase(connectionsIt);
+ }
+ if (proxy.ptr != nullptr) {
+ if (!StreamBluetooth::checkConfigParams(
+ proxy.pcmConfig, AudioConfigBase{.sampleRate = context.getSampleRate(),
+ .channelMask = context.getChannelLayout(),
+ .format = context.getFormat()})) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+ }
+ }
+ // Not having a proxy is OK, it may happen in VTS tests when streams are opened on unconnected
+ // mix ports.
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ModuleBluetooth::findOrCreateProxy(const AudioPort& audioPort,
+ CachedProxy& proxy) {
+ if (auto proxyIt = mProxies.find(audioPort.id); proxyIt != mProxies.end()) {
+ proxy = proxyIt->second;
+ return ndk::ScopedAStatus::ok();
+ }
+ return createProxy(audioPort, audioPort.id, proxy);
+}
+
} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/bluetooth/StreamBluetooth.cpp b/audio/aidl/default/bluetooth/StreamBluetooth.cpp
index 0cee7f4..77e48df 100644
--- a/audio/aidl/default/bluetooth/StreamBluetooth.cpp
+++ b/audio/aidl/default/bluetooth/StreamBluetooth.cpp
@@ -14,13 +14,15 @@
* limitations under the License.
*/
-#define LOG_TAG "AHAL_StreamBluetooth"
+#include <algorithm>
+#define ATRACE_TAG ATRACE_TAG_AUDIO
+#define LOG_TAG "AHAL_StreamBluetooth"
#include <Utils.h>
#include <android-base/logging.h>
#include <audio_utils/clock.h>
+#include <utils/Trace.h>
-#include "BluetoothAudioSession.h"
#include "core-impl/StreamBluetooth.h"
using aidl::android::hardware::audio::common::frameCountFromDurationUs;
@@ -31,6 +33,7 @@
using aidl::android::hardware::bluetooth::audio::PcmConfiguration;
using aidl::android::hardware::bluetooth::audio::PresentationPosition;
using aidl::android::media::audio::common::AudioChannelLayout;
+using aidl::android::media::audio::common::AudioConfigBase;
using aidl::android::media::audio::common::AudioDevice;
using aidl::android::media::audio::common::AudioDeviceAddress;
using aidl::android::media::audio::common::AudioFormatDescription;
@@ -48,51 +51,33 @@
constexpr int kBluetoothDefaultInputBufferMs = 20;
constexpr int kBluetoothDefaultOutputBufferMs = 10;
// constexpr int kBluetoothSpatializerOutputBufferMs = 10;
+constexpr int kBluetoothDefaultRemoteDelayMs = 200;
-// pcm configuration params are not really used by the module
StreamBluetooth::StreamBluetooth(StreamContext* context, const Metadata& metadata,
- ModuleBluetooth::BtProfileHandles&& btHandles)
+ ModuleBluetooth::BtProfileHandles&& btHandles,
+ const std::shared_ptr<BluetoothAudioPortAidl>& btDeviceProxy,
+ const PcmConfiguration& pcmConfig)
: StreamCommonImpl(context, metadata),
- mSampleRate(getContext().getSampleRate()),
- mChannelLayout(getContext().getChannelLayout()),
- mFormat(getContext().getFormat()),
mFrameSizeBytes(getContext().getFrameSize()),
mIsInput(isInput(metadata)),
mBluetoothA2dp(std::move(std::get<ModuleBluetooth::BtInterface::BTA2DP>(btHandles))),
- mBluetoothLe(std::move(std::get<ModuleBluetooth::BtInterface::BTLE>(btHandles))) {
- mPreferredDataIntervalUs =
- (mIsInput ? kBluetoothDefaultInputBufferMs : kBluetoothDefaultOutputBufferMs) * 1000;
- mPreferredFrameCount = frameCountFromDurationUs(mPreferredDataIntervalUs, mSampleRate);
- mIsInitialized = false;
- mIsReadyToClose = false;
-}
+ mBluetoothLe(std::move(std::get<ModuleBluetooth::BtInterface::BTLE>(btHandles))),
+ mPreferredDataIntervalUs(pcmConfig.dataIntervalUs != 0
+ ? pcmConfig.dataIntervalUs
+ : (mIsInput ? kBluetoothDefaultInputBufferMs
+ : kBluetoothDefaultOutputBufferMs) *
+ 1000),
+ mPreferredFrameCount(
+ frameCountFromDurationUs(mPreferredDataIntervalUs, pcmConfig.sampleRateHz)),
+ mBtDeviceProxy(btDeviceProxy) {}
::android::status_t StreamBluetooth::init() {
- return ::android::OK; // defering this till we get AudioDeviceDescription
-}
-
-const StreamCommonInterface::ConnectedDevices& StreamBluetooth::getConnectedDevices() const {
std::lock_guard guard(mLock);
- return StreamCommonImpl::getConnectedDevices();
-}
-
-ndk::ScopedAStatus StreamBluetooth::setConnectedDevices(
- const std::vector<AudioDevice>& connectedDevices) {
- if (mIsInput && connectedDevices.size() > 1) {
- LOG(ERROR) << __func__ << ": wrong device size(" << connectedDevices.size()
- << ") for input stream";
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ if (mBtDeviceProxy == nullptr) {
+ // This is a normal situation in VTS tests.
+ LOG(INFO) << __func__ << ": no BT HAL proxy, stream is non-functional";
}
- for (const auto& connectedDevice : connectedDevices) {
- if (connectedDevice.address.getTag() != AudioDeviceAddress::mac) {
- LOG(ERROR) << __func__ << ": bad device address" << connectedDevice.address.toString();
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
- }
- }
- std::lock_guard guard(mLock);
- RETURN_STATUS_IF_ERROR(StreamCommonImpl::setConnectedDevices(connectedDevices));
- mIsInitialized = false; // updated connected device list, need initialization
- return ndk::ScopedAStatus::ok();
+ return ::android::OK;
}
::android::status_t StreamBluetooth::drain(StreamDescriptor::DrainMode) {
@@ -112,167 +97,108 @@
::android::status_t StreamBluetooth::transfer(void* buffer, size_t frameCount,
size_t* actualFrameCount, int32_t* latencyMs) {
std::lock_guard guard(mLock);
- if (!mIsInitialized || mIsReadyToClose) {
- // 'setConnectedDevices' has been called or stream is ready to close, so no transfers
+ if (mBtDeviceProxy == nullptr || mBtDeviceProxy->getState() == BluetoothStreamState::DISABLED) {
*actualFrameCount = 0;
*latencyMs = StreamDescriptor::LATENCY_UNKNOWN;
return ::android::OK;
}
*actualFrameCount = 0;
*latencyMs = 0;
- for (auto proxy : mBtDeviceProxies) {
- if (!proxy->start()) {
- LOG(ERROR) << __func__ << ": state = " << proxy->getState() << " failed to start ";
- return -EIO;
- }
- const size_t fc = std::min(frameCount, mPreferredFrameCount);
- const size_t bytesToTransfer = fc * mFrameSizeBytes;
- if (mIsInput) {
- const size_t totalRead = proxy->readData(buffer, bytesToTransfer);
- *actualFrameCount = std::max(*actualFrameCount, totalRead / mFrameSizeBytes);
- } else {
- const size_t totalWrite = proxy->writeData(buffer, bytesToTransfer);
- *actualFrameCount = std::max(*actualFrameCount, totalWrite / mFrameSizeBytes);
- }
- PresentationPosition presentation_position;
- if (!proxy->getPresentationPosition(presentation_position)) {
- LOG(ERROR) << __func__ << ": getPresentationPosition returned error ";
- return ::android::UNKNOWN_ERROR;
- }
- *latencyMs =
- std::max(*latencyMs, (int32_t)(presentation_position.remoteDeviceAudioDelayNanos /
- NANOS_PER_MILLISECOND));
+ if (!mBtDeviceProxy->start()) {
+ LOG(ERROR) << __func__ << ": state= " << mBtDeviceProxy->getState() << " failed to start";
+ return -EIO;
}
+ const size_t fc = std::min(frameCount, mPreferredFrameCount);
+ const size_t bytesToTransfer = fc * mFrameSizeBytes;
+ const size_t bytesTransferred = mIsInput ? mBtDeviceProxy->readData(buffer, bytesToTransfer)
+ : mBtDeviceProxy->writeData(buffer, bytesToTransfer);
+ *actualFrameCount = bytesTransferred / mFrameSizeBytes;
+ ATRACE_INT("BTdropped", bytesToTransfer - bytesTransferred);
+ PresentationPosition presentation_position;
+ if (!mBtDeviceProxy->getPresentationPosition(presentation_position)) {
+ presentation_position.remoteDeviceAudioDelayNanos =
+ kBluetoothDefaultRemoteDelayMs * NANOS_PER_MILLISECOND;
+ LOG(WARNING) << __func__ << ": getPresentationPosition failed, latency info is unavailable";
+ }
+ // TODO(b/317117580): incorporate logic from
+ // packages/modules/Bluetooth/system/audio_bluetooth_hw/stream_apis.cc
+ // out_calculate_feeding_delay_ms / in_calculate_starving_delay_ms
+ *latencyMs = std::max(*latencyMs, (int32_t)(presentation_position.remoteDeviceAudioDelayNanos /
+ NANOS_PER_MILLISECOND));
return ::android::OK;
}
-::android::status_t StreamBluetooth::initialize() {
- if (!::aidl::android::hardware::bluetooth::audio::BluetoothAudioSession::IsAidlAvailable()) {
- LOG(ERROR) << __func__ << ": IBluetoothAudioProviderFactory service not available";
- return ::android::UNKNOWN_ERROR;
- }
- if (StreamCommonImpl::getConnectedDevices().empty()) {
- LOG(ERROR) << __func__ << ", has no connected devices";
- return ::android::NO_INIT;
- }
- // unregister older proxies (if any)
- for (auto proxy : mBtDeviceProxies) {
- proxy->stop();
- proxy->unregisterPort();
- }
- mBtDeviceProxies.clear();
- for (auto it = StreamCommonImpl::getConnectedDevices().begin();
- it != StreamCommonImpl::getConnectedDevices().end(); ++it) {
- std::shared_ptr<BluetoothAudioPortAidl> proxy =
- mIsInput ? std::shared_ptr<BluetoothAudioPortAidl>(
- std::make_shared<BluetoothAudioPortAidlIn>())
- : std::shared_ptr<BluetoothAudioPortAidl>(
- std::make_shared<BluetoothAudioPortAidlOut>());
- if (proxy->registerPort(it->type)) {
- LOG(ERROR) << __func__ << ": cannot init HAL";
- return ::android::UNKNOWN_ERROR;
- }
- PcmConfiguration config;
- if (!proxy->loadAudioConfig(&config)) {
- LOG(ERROR) << __func__ << ": state=" << proxy->getState()
- << " failed to get audio config";
- return ::android::UNKNOWN_ERROR;
- }
- // TODO: Ensure minimum duration for spatialized output?
- // WAR to support Mono / 16 bits per sample as the Bluetooth stack required
- if (!mIsInput && config.channelMode == ChannelMode::MONO && config.bitsPerSample == 16) {
- proxy->forcePcmStereoToMono(true);
- config.channelMode = ChannelMode::STEREO;
- LOG(INFO) << __func__ << ": force channels = to be AUDIO_CHANNEL_OUT_STEREO";
- }
- if (!checkConfigParams(config)) {
- LOG(ERROR) << __func__ << " checkConfigParams failed";
- return ::android::UNKNOWN_ERROR;
- }
- mBtDeviceProxies.push_back(std::move(proxy));
- }
- mIsInitialized = true;
- return ::android::OK;
-}
-
-bool StreamBluetooth::checkConfigParams(
- ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& config) {
- if ((int)mSampleRate != config.sampleRateHz) {
- LOG(ERROR) << __func__ << ": Sample Rate mismatch, stream val = " << mSampleRate
- << " hal val = " << config.sampleRateHz;
+// static
+bool StreamBluetooth::checkConfigParams(const PcmConfiguration& pcmConfig,
+ const AudioConfigBase& config) {
+ if ((int)config.sampleRate != pcmConfig.sampleRateHz) {
+ LOG(ERROR) << __func__ << ": sample rate mismatch, stream value=" << config.sampleRate
+ << ", BT HAL value=" << pcmConfig.sampleRateHz;
return false;
}
- auto channelCount = aidl::android::hardware::audio::common::getChannelCount(mChannelLayout);
- if ((config.channelMode == ChannelMode::MONO && channelCount != 1) ||
- (config.channelMode == ChannelMode::STEREO && channelCount != 2)) {
- LOG(ERROR) << __func__ << ": Channel count mismatch, stream val = " << channelCount
- << " hal val = " << toString(config.channelMode);
+ const auto channelCount =
+ aidl::android::hardware::audio::common::getChannelCount(config.channelMask);
+ if ((pcmConfig.channelMode == ChannelMode::MONO && channelCount != 1) ||
+ (pcmConfig.channelMode == ChannelMode::STEREO && channelCount != 2)) {
+ LOG(ERROR) << __func__ << ": Channel count mismatch, stream value=" << channelCount
+ << ", BT HAL value=" << toString(pcmConfig.channelMode);
return false;
}
- if (mFormat.type != AudioFormatType::PCM) {
- LOG(ERROR) << __func__ << ": unexpected format type "
- << aidl::android::media::audio::common::toString(mFormat.type);
+ if (config.format.type != AudioFormatType::PCM) {
+ LOG(ERROR) << __func__
+ << ": unexpected stream format type: " << toString(config.format.type);
return false;
}
- int8_t bps = aidl::android::hardware::audio::common::getPcmSampleSizeInBytes(mFormat.pcm) * 8;
- if (bps != config.bitsPerSample) {
- LOG(ERROR) << __func__ << ": bits per sample mismatch, stream val = " << bps
- << " hal val = " << config.bitsPerSample;
+ const int8_t bitsPerSample =
+ aidl::android::hardware::audio::common::getPcmSampleSizeInBytes(config.format.pcm) * 8;
+ if (bitsPerSample != pcmConfig.bitsPerSample) {
+ LOG(ERROR) << __func__ << ": bits per sample mismatch, stream value=" << bitsPerSample
+ << ", BT HAL value=" << pcmConfig.bitsPerSample;
return false;
}
- if (config.dataIntervalUs > 0) {
- mPreferredDataIntervalUs =
- std::min((int32_t)mPreferredDataIntervalUs, config.dataIntervalUs);
- mPreferredFrameCount = frameCountFromDurationUs(mPreferredDataIntervalUs, mSampleRate);
- }
return true;
}
ndk::ScopedAStatus StreamBluetooth::prepareToClose() {
std::lock_guard guard(mLock);
- mIsReadyToClose = true;
+ if (mBtDeviceProxy != nullptr) {
+ if (mBtDeviceProxy->getState() != BluetoothStreamState::DISABLED) {
+ mBtDeviceProxy->stop();
+ }
+ }
return ndk::ScopedAStatus::ok();
}
::android::status_t StreamBluetooth::standby() {
std::lock_guard guard(mLock);
- if (!mIsInitialized) {
- if (auto status = initialize(); status != ::android::OK) return status;
- }
- for (auto proxy : mBtDeviceProxies) {
- if (!proxy->suspend()) {
- LOG(ERROR) << __func__ << ": state = " << proxy->getState() << " failed to stand by ";
- return -EIO;
- }
- }
+ if (mBtDeviceProxy != nullptr) mBtDeviceProxy->suspend();
return ::android::OK;
}
::android::status_t StreamBluetooth::start() {
std::lock_guard guard(mLock);
- if (!mIsInitialized) return initialize();
+ if (mBtDeviceProxy != nullptr) mBtDeviceProxy->start();
return ::android::OK;
}
void StreamBluetooth::shutdown() {
std::lock_guard guard(mLock);
- for (auto proxy : mBtDeviceProxies) {
- proxy->stop();
- proxy->unregisterPort();
+ if (mBtDeviceProxy != nullptr) {
+ mBtDeviceProxy->stop();
+ mBtDeviceProxy = nullptr;
}
- mBtDeviceProxies.clear();
}
ndk::ScopedAStatus StreamBluetooth::updateMetadataCommon(const Metadata& metadata) {
std::lock_guard guard(mLock);
- if (!mIsInitialized) return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ if (mBtDeviceProxy == nullptr) {
+ return ndk::ScopedAStatus::ok();
+ }
bool isOk = true;
if (isInput(metadata)) {
- isOk = mBtDeviceProxies[0]->updateSinkMetadata(std::get<SinkMetadata>(metadata));
+ isOk = mBtDeviceProxy->updateSinkMetadata(std::get<SinkMetadata>(metadata));
} else {
- for (auto proxy : mBtDeviceProxies) {
- if (!proxy->updateSourceMetadata(std::get<SourceMetadata>(metadata))) isOk = false;
- }
+ isOk = mBtDeviceProxy->updateSourceMetadata(std::get<SourceMetadata>(metadata));
}
return isOk ? ndk::ScopedAStatus::ok()
: ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
@@ -280,7 +206,6 @@
ndk::ScopedAStatus StreamBluetooth::bluetoothParametersUpdated() {
if (mIsInput) {
- LOG(WARNING) << __func__ << ": not handled";
return ndk::ScopedAStatus::ok();
}
auto applyParam = [](const std::shared_ptr<BluetoothAudioPortAidl>& proxy,
@@ -297,15 +222,10 @@
bool hasLeParam, enableLe;
auto btLe = mBluetoothLe.lock();
hasLeParam = btLe != nullptr && btLe->isEnabled(&enableLe).isOk();
- std::unique_lock lock(mLock);
- ::android::base::ScopedLockAssertion lock_assertion(mLock);
- if (!mIsInitialized) {
- LOG(WARNING) << __func__ << ": init not done";
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- }
- for (auto proxy : mBtDeviceProxies) {
- if ((hasA2dpParam && proxy->isA2dp() && !applyParam(proxy, enableA2dp)) ||
- (hasLeParam && proxy->isLeAudio() && !applyParam(proxy, enableLe))) {
+ std::lock_guard guard(mLock);
+ if (mBtDeviceProxy != nullptr) {
+ if ((hasA2dpParam && mBtDeviceProxy->isA2dp() && !applyParam(mBtDeviceProxy, enableA2dp)) ||
+ (hasLeParam && mBtDeviceProxy->isLeAudio() && !applyParam(mBtDeviceProxy, enableLe))) {
LOG(DEBUG) << __func__ << ": applyParam failed";
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
@@ -313,11 +233,20 @@
return ndk::ScopedAStatus::ok();
}
+// static
+int32_t StreamInBluetooth::getNominalLatencyMs(size_t dataIntervalUs) {
+ if (dataIntervalUs == 0) dataIntervalUs = kBluetoothDefaultInputBufferMs * 1000LL;
+ return dataIntervalUs / 1000LL;
+}
+
StreamInBluetooth::StreamInBluetooth(StreamContext&& context, const SinkMetadata& sinkMetadata,
const std::vector<MicrophoneInfo>& microphones,
- ModuleBluetooth::BtProfileHandles&& btProfileHandles)
+ ModuleBluetooth::BtProfileHandles&& btProfileHandles,
+ const std::shared_ptr<BluetoothAudioPortAidl>& btDeviceProxy,
+ const PcmConfiguration& pcmConfig)
: StreamIn(std::move(context), microphones),
- StreamBluetooth(&mContextInstance, sinkMetadata, std::move(btProfileHandles)) {}
+ StreamBluetooth(&mContextInstance, sinkMetadata, std::move(btProfileHandles), btDeviceProxy,
+ pcmConfig) {}
ndk::ScopedAStatus StreamInBluetooth::getActiveMicrophones(
std::vector<MicrophoneDynamicInfo>* _aidl_return __unused) {
@@ -325,11 +254,20 @@
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
+// static
+int32_t StreamOutBluetooth::getNominalLatencyMs(size_t dataIntervalUs) {
+ if (dataIntervalUs == 0) dataIntervalUs = kBluetoothDefaultOutputBufferMs * 1000LL;
+ return dataIntervalUs / 1000LL;
+}
+
StreamOutBluetooth::StreamOutBluetooth(StreamContext&& context,
const SourceMetadata& sourceMetadata,
const std::optional<AudioOffloadInfo>& offloadInfo,
- ModuleBluetooth::BtProfileHandles&& btProfileHandles)
+ ModuleBluetooth::BtProfileHandles&& btProfileHandles,
+ const std::shared_ptr<BluetoothAudioPortAidl>& btDeviceProxy,
+ const PcmConfiguration& pcmConfig)
: StreamOut(std::move(context), offloadInfo),
- StreamBluetooth(&mContextInstance, sourceMetadata, std::move(btProfileHandles)) {}
+ StreamBluetooth(&mContextInstance, sourceMetadata, std::move(btProfileHandles), btDeviceProxy,
+ pcmConfig) {}
} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/config/audioPolicy/Android.bp b/audio/aidl/default/config/audioPolicy/Android.bp
index 6d8a148..baa3762 100644
--- a/audio/aidl/default/config/audioPolicy/Android.bp
+++ b/audio/aidl/default/config/audioPolicy/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/aidl/default/config/audioPolicy/engine/Android.bp b/audio/aidl/default/config/audioPolicy/engine/Android.bp
index b2a7310..5d62bd6 100644
--- a/audio/aidl/default/config/audioPolicy/engine/Android.bp
+++ b/audio/aidl/default/config/audioPolicy/engine/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/aidl/default/downmix/Android.bp b/audio/aidl/default/downmix/Android.bp
index 6d15cdb..e5e8405 100644
--- a/audio/aidl/default/downmix/Android.bp
+++ b/audio/aidl/default/downmix/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -27,8 +28,6 @@
name: "libdownmixsw",
defaults: [
"aidlaudioeffectservice_defaults",
- "latest_android_media_audio_common_types_ndk_shared",
- "latest_android_hardware_audio_effect_ndk_shared",
],
srcs: [
"DownmixSw.cpp",
diff --git a/audio/aidl/default/downmix/DownmixSw.cpp b/audio/aidl/default/downmix/DownmixSw.cpp
index ce5fe20..19ab2e8 100644
--- a/audio/aidl/default/downmix/DownmixSw.cpp
+++ b/audio/aidl/default/downmix/DownmixSw.cpp
@@ -144,10 +144,6 @@
return mContext;
}
-std::shared_ptr<EffectContext> DownmixSw::getContext() {
- return mContext;
-}
-
RetCode DownmixSw::releaseContext() {
if (mContext) {
mContext.reset();
diff --git a/audio/aidl/default/downmix/DownmixSw.h b/audio/aidl/default/downmix/DownmixSw.h
index 3f8a09b..1a9f0f0 100644
--- a/audio/aidl/default/downmix/DownmixSw.h
+++ b/audio/aidl/default/downmix/DownmixSw.h
@@ -55,20 +55,23 @@
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
- ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
- ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
- Parameter::Specific* specific) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+ REQUIRES(mImplMutex) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+ REQUIRES(mImplMutex) override;
- std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
- std::shared_ptr<EffectContext> getContext() override;
- RetCode releaseContext() override;
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+ REQUIRES(mImplMutex) override;
+ RetCode releaseContext() REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; };
- IEffect::Status effectProcessImpl(float* in, float* out, int sample) override;
+ IEffect::Status effectProcessImpl(float* in, float* out, int sample)
+ REQUIRES(mImplMutex) override;
private:
- std::shared_ptr<DownmixSwContext> mContext;
+ std::shared_ptr<DownmixSwContext> mContext GUARDED_BY(mImplMutex);
- ndk::ScopedAStatus getParameterDownmix(const Downmix::Tag& tag, Parameter::Specific* specific);
+ ndk::ScopedAStatus getParameterDownmix(const Downmix::Tag& tag, Parameter::Specific* specific)
+ REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/dynamicProcessing/Android.bp b/audio/aidl/default/dynamicProcessing/Android.bp
index 1c0312d..ccd1aa0 100644
--- a/audio/aidl/default/dynamicProcessing/Android.bp
+++ b/audio/aidl/default/dynamicProcessing/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -27,8 +28,6 @@
name: "libdynamicsprocessingsw",
defaults: [
"aidlaudioeffectservice_defaults",
- "latest_android_media_audio_common_types_ndk_shared",
- "latest_android_hardware_audio_effect_ndk_shared",
],
srcs: [
"DynamicsProcessingSw.cpp",
diff --git a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp
index e8f90b2..36face1 100644
--- a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp
+++ b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp
@@ -260,10 +260,6 @@
return mContext;
}
-std::shared_ptr<EffectContext> DynamicsProcessingSw::getContext() {
- return mContext;
-}
-
RetCode DynamicsProcessingSw::releaseContext() {
if (mContext) {
mContext.reset();
@@ -282,6 +278,9 @@
}
RetCode DynamicsProcessingSwContext::setCommon(const Parameter::Common& common) {
+ if (auto ret = updateIOFrameSize(common); ret != RetCode::SUCCESS) {
+ return ret;
+ }
mCommon = common;
mChannelCount = ::aidl::android::hardware::audio::common::getChannelCount(
common.input.base.channelMask);
diff --git a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h
index 641cf71..98edca0 100644
--- a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h
+++ b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h
@@ -113,15 +113,17 @@
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
- ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
- ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
- Parameter::Specific* specific) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+ REQUIRES(mImplMutex) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+ REQUIRES(mImplMutex) override;
- std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
- std::shared_ptr<EffectContext> getContext() override;
- RetCode releaseContext() override;
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+ REQUIRES(mImplMutex) override;
+ RetCode releaseContext() REQUIRES(mImplMutex) override;
- IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+ IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+ REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; };
private:
@@ -130,9 +132,10 @@
static const Range::DynamicsProcessingRange kPreEqBandRange;
static const Range::DynamicsProcessingRange kPostEqBandRange;
static const std::vector<Range::DynamicsProcessingRange> kRanges;
- std::shared_ptr<DynamicsProcessingSwContext> mContext;
+ std::shared_ptr<DynamicsProcessingSwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterDynamicsProcessing(const DynamicsProcessing::Tag& tag,
- Parameter::Specific* specific);
+ Parameter::Specific* specific)
+ REQUIRES(mImplMutex);
}; // DynamicsProcessingSw
diff --git a/audio/aidl/default/envReverb/Android.bp b/audio/aidl/default/envReverb/Android.bp
index dd4219a..70da2bd 100644
--- a/audio/aidl/default/envReverb/Android.bp
+++ b/audio/aidl/default/envReverb/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -27,8 +28,6 @@
name: "libenvreverbsw",
defaults: [
"aidlaudioeffectservice_defaults",
- "latest_android_media_audio_common_types_ndk_shared",
- "latest_android_hardware_audio_effect_ndk_shared",
],
srcs: [
"EnvReverbSw.cpp",
@@ -36,6 +35,6 @@
],
relative_install_path: "soundfx",
visibility: [
- "//hardware/interfaces/audio/aidl/default",
+ "//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}
diff --git a/audio/aidl/default/envReverb/EnvReverbSw.cpp b/audio/aidl/default/envReverb/EnvReverbSw.cpp
index 73975c6..7937a6a 100644
--- a/audio/aidl/default/envReverb/EnvReverbSw.cpp
+++ b/audio/aidl/default/envReverb/EnvReverbSw.cpp
@@ -267,10 +267,6 @@
return mContext;
}
-std::shared_ptr<EffectContext> EnvReverbSw::getContext() {
- return mContext;
-}
-
RetCode EnvReverbSw::releaseContext() {
if (mContext) {
mContext.reset();
diff --git a/audio/aidl/default/envReverb/EnvReverbSw.h b/audio/aidl/default/envReverb/EnvReverbSw.h
index 5e31e2f..367462b 100644
--- a/audio/aidl/default/envReverb/EnvReverbSw.h
+++ b/audio/aidl/default/envReverb/EnvReverbSw.h
@@ -100,21 +100,23 @@
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
- ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
- ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
- Parameter::Specific* specific) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+ REQUIRES(mImplMutex) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+ REQUIRES(mImplMutex) override;
- std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
- std::shared_ptr<EffectContext> getContext() override;
- RetCode releaseContext() override;
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+ REQUIRES(mImplMutex) override;
+ RetCode releaseContext() REQUIRES(mImplMutex) override;
IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
std::string getEffectName() override { return kEffectName; }
private:
static const std::vector<Range::EnvironmentalReverbRange> kRanges;
- std::shared_ptr<EnvReverbSwContext> mContext;
+ std::shared_ptr<EnvReverbSwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterEnvironmentalReverb(const EnvironmentalReverb::Tag& tag,
- Parameter::Specific* specific);
+ Parameter::Specific* specific)
+ REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/equalizer/Android.bp b/audio/aidl/default/equalizer/Android.bp
index 3610563..da2663c 100644
--- a/audio/aidl/default/equalizer/Android.bp
+++ b/audio/aidl/default/equalizer/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -27,8 +28,6 @@
name: "libequalizersw",
defaults: [
"aidlaudioeffectservice_defaults",
- "latest_android_media_audio_common_types_ndk_shared",
- "latest_android_hardware_audio_effect_ndk_shared",
],
srcs: [
"EqualizerSw.cpp",
@@ -36,6 +35,6 @@
],
relative_install_path: "soundfx",
visibility: [
- "//hardware/interfaces/audio/aidl/default",
+ "//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}
diff --git a/audio/aidl/default/equalizer/EqualizerSw.cpp b/audio/aidl/default/equalizer/EqualizerSw.cpp
index b2add31..640b3ba 100644
--- a/audio/aidl/default/equalizer/EqualizerSw.cpp
+++ b/audio/aidl/default/equalizer/EqualizerSw.cpp
@@ -198,10 +198,6 @@
return mContext;
}
-std::shared_ptr<EffectContext> EqualizerSw::getContext() {
- return mContext;
-}
-
RetCode EqualizerSw::releaseContext() {
if (mContext) {
mContext.reset();
diff --git a/audio/aidl/default/equalizer/EqualizerSw.h b/audio/aidl/default/equalizer/EqualizerSw.h
index 56af3b5..caaa129 100644
--- a/audio/aidl/default/equalizer/EqualizerSw.h
+++ b/audio/aidl/default/equalizer/EqualizerSw.h
@@ -97,15 +97,17 @@
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
- ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
- ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
- Parameter::Specific* specific) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+ REQUIRES(mImplMutex) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+ REQUIRES(mImplMutex) override;
- std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
- std::shared_ptr<EffectContext> getContext() override;
- RetCode releaseContext() override;
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+ REQUIRES(mImplMutex) override;
+ RetCode releaseContext() REQUIRES(mImplMutex) override;
- IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+ IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+ REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; }
private:
@@ -113,7 +115,7 @@
static const std::vector<Equalizer::Preset> kPresets;
static const std::vector<Range::EqualizerRange> kRanges;
ndk::ScopedAStatus getParameterEqualizer(const Equalizer::Tag& tag,
- Parameter::Specific* specific);
+ Parameter::Specific* specific) REQUIRES(mImplMutex);
std::shared_ptr<EqualizerSwContext> mContext;
};
diff --git a/audio/aidl/default/extension/Android.bp b/audio/aidl/default/extension/Android.bp
index 4e5d352..79fd857 100644
--- a/audio/aidl/default/extension/Android.bp
+++ b/audio/aidl/default/extension/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -27,8 +28,6 @@
name: "libextensioneffect",
defaults: [
"aidlaudioeffectservice_defaults",
- "latest_android_media_audio_common_types_ndk_shared",
- "latest_android_hardware_audio_effect_ndk_shared",
],
srcs: [
"ExtensionEffect.cpp",
@@ -36,6 +35,6 @@
],
relative_install_path: "soundfx",
visibility: [
- "//hardware/interfaces/audio/aidl/default",
+ "//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}
diff --git a/audio/aidl/default/extension/ExtensionEffect.cpp b/audio/aidl/default/extension/ExtensionEffect.cpp
index 4a4d71b6..11916c8 100644
--- a/audio/aidl/default/extension/ExtensionEffect.cpp
+++ b/audio/aidl/default/extension/ExtensionEffect.cpp
@@ -123,10 +123,6 @@
return mContext;
}
-std::shared_ptr<EffectContext> ExtensionEffect::getContext() {
- return mContext;
-}
-
RetCode ExtensionEffect::releaseContext() {
if (mContext) {
mContext.reset();
diff --git a/audio/aidl/default/extension/ExtensionEffect.h b/audio/aidl/default/extension/ExtensionEffect.h
index e7a068b..b560860 100644
--- a/audio/aidl/default/extension/ExtensionEffect.h
+++ b/audio/aidl/default/extension/ExtensionEffect.h
@@ -54,18 +54,20 @@
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
- ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
- ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
- Parameter::Specific* specific) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+ REQUIRES(mImplMutex) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+ REQUIRES(mImplMutex) override;
- std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
- std::shared_ptr<EffectContext> getContext() override;
- RetCode releaseContext() override;
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+ REQUIRES(mImplMutex) override;
+ RetCode releaseContext() REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; };
- IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+ IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+ REQUIRES(mImplMutex) override;
private:
- std::shared_ptr<ExtensionEffectContext> mContext;
+ std::shared_ptr<ExtensionEffectContext> mContext GUARDED_BY(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/hapticGenerator/Android.bp b/audio/aidl/default/hapticGenerator/Android.bp
index 0df9a94..fdd4fc7 100644
--- a/audio/aidl/default/hapticGenerator/Android.bp
+++ b/audio/aidl/default/hapticGenerator/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -27,8 +28,6 @@
name: "libhapticgeneratorsw",
defaults: [
"aidlaudioeffectservice_defaults",
- "latest_android_media_audio_common_types_ndk_shared",
- "latest_android_hardware_audio_effect_ndk_shared",
],
srcs: [
"HapticGeneratorSw.cpp",
diff --git a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
index 27cdac8..7469ab9 100644
--- a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
+++ b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
@@ -158,10 +158,6 @@
return mContext;
}
-std::shared_ptr<EffectContext> HapticGeneratorSw::getContext() {
- return mContext;
-}
-
RetCode HapticGeneratorSw::releaseContext() {
if (mContext) {
mContext.reset();
diff --git a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
index 3bbe41a..47f3848 100644
--- a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
+++ b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
@@ -67,21 +67,24 @@
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
- ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
- ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
- Parameter::Specific* specific) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+ REQUIRES(mImplMutex) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+ REQUIRES(mImplMutex) override;
- std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
- std::shared_ptr<EffectContext> getContext() override;
- RetCode releaseContext() override;
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+ REQUIRES(mImplMutex) override;
+ RetCode releaseContext() REQUIRES(mImplMutex) override;
- IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+ IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+ REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; }
private:
- std::shared_ptr<HapticGeneratorSwContext> mContext;
+ std::shared_ptr<HapticGeneratorSwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterHapticGenerator(const HapticGenerator::Tag& tag,
- Parameter::Specific* specific);
+ Parameter::Specific* specific)
+ REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/core-impl/DevicePortProxy.h b/audio/aidl/default/include/core-impl/DevicePortProxy.h
index 17a8cf3..ccb23bb 100644
--- a/audio/aidl/default/include/core-impl/DevicePortProxy.h
+++ b/audio/aidl/default/include/core-impl/DevicePortProxy.h
@@ -73,12 +73,7 @@
* Bluetooth stack
*/
virtual bool loadAudioConfig(
- ::aidl::android::hardware::bluetooth::audio::PcmConfiguration*) const = 0;
-
- /**
- * WAR to support Mono mode / 16 bits per sample
- */
- virtual void forcePcmStereoToMono(bool) = 0;
+ ::aidl::android::hardware::bluetooth::audio::PcmConfiguration&) = 0;
/**
* When the Audio framework / HAL wants to change the stream state, it invokes
@@ -145,7 +140,7 @@
virtual bool isLeAudio() const = 0;
- virtual bool getPreferredDataIntervalUs(size_t*) const = 0;
+ virtual bool getPreferredDataIntervalUs(size_t&) const = 0;
virtual size_t writeData(const void*, size_t) const { return 0; }
@@ -162,10 +157,8 @@
void unregisterPort() override;
- bool loadAudioConfig(::aidl::android::hardware::bluetooth::audio::PcmConfiguration* audio_cfg)
- const override;
-
- void forcePcmStereoToMono(bool force) override { mIsStereoToMono = force; }
+ bool loadAudioConfig(
+ ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& audio_cfg) override;
bool standby() override;
bool start() override;
@@ -193,7 +186,7 @@
bool isLeAudio() const override;
- bool getPreferredDataIntervalUs(size_t* interval_us) const override;
+ bool getPreferredDataIntervalUs(size_t& interval_us) const override;
protected:
uint16_t mCookie;
@@ -228,6 +221,9 @@
class BluetoothAudioPortAidlOut : public BluetoothAudioPortAidl {
public:
+ bool loadAudioConfig(
+ ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& audio_cfg) override;
+
// The audio data path to the Bluetooth stack (Software encoding)
size_t writeData(const void* buffer, size_t bytes) const override;
};
diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h
index caf43f1..ce71d70 100644
--- a/audio/aidl/default/include/core-impl/Module.h
+++ b/audio/aidl/default/include/core-impl/Module.h
@@ -16,6 +16,7 @@
#pragma once
+#include <functional>
#include <iostream>
#include <map>
#include <memory>
@@ -70,6 +71,7 @@
const ::aidl::android::media::audio::common::AudioPort& in_templateIdAndAdditionalData,
::aidl::android::media::audio::common::AudioPort* _aidl_return) override;
ndk::ScopedAStatus disconnectExternalDevice(int32_t in_portId) override;
+ ndk::ScopedAStatus prepareToDisconnectExternalDevice(int32_t in_portId) override;
ndk::ScopedAStatus getAudioPatches(std::vector<AudioPatch>* _aidl_return) override;
ndk::ScopedAStatus getAudioPort(
int32_t in_portId,
@@ -187,7 +189,7 @@
// If the module is unable to populate the connected device port correctly, the returned error
// code must correspond to the errors of `IModule.connectedExternalDevice` method.
virtual ndk::ScopedAStatus populateConnectedDevicePort(
- ::aidl::android::media::audio::common::AudioPort* audioPort);
+ ::aidl::android::media::audio::common::AudioPort* audioPort, int32_t nextPortId);
// If the module finds that the patch endpoints configurations are not matched, the returned
// error code must correspond to the errors of `IModule.setAudioPatch` method.
virtual ndk::ScopedAStatus checkAudioPatchEndpointsMatch(
@@ -195,6 +197,8 @@
const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks);
virtual void onExternalDeviceConnectionChanged(
const ::aidl::android::media::audio::common::AudioPort& audioPort, bool connected);
+ virtual void onPrepareToDisconnectExternalDevice(
+ const ::aidl::android::media::audio::common::AudioPort& audioPort);
virtual ndk::ScopedAStatus onMasterMuteChanged(bool mute);
virtual ndk::ScopedAStatus onMasterVolumeChanged(float volume);
virtual std::vector<::aidl::android::media::audio::common::MicrophoneInfo> getMicrophoneInfos();
@@ -207,6 +211,7 @@
const int32_t rawSizeFrames =
aidl::android::hardware::audio::common::frameCountFromDurationMs(latencyMs,
sampleRateHz);
+ if (latencyMs >= 5) return rawSizeFrames;
int32_t powerOf2 = 1;
while (powerOf2 < rawSizeFrames) powerOf2 <<= 1;
return powerOf2;
@@ -224,12 +229,16 @@
std::set<int32_t> findConnectedPortConfigIds(int32_t portConfigId);
ndk::ScopedAStatus findPortIdForNewStream(
int32_t in_portConfigId, ::aidl::android::media::audio::common::AudioPort** port);
+ // Note: does not assign an ID to the config.
+ bool generateDefaultPortConfig(const ::aidl::android::media::audio::common::AudioPort& port,
+ ::aidl::android::media::audio::common::AudioPortConfig* config);
std::vector<AudioRoute*> getAudioRoutesForAudioPortImpl(int32_t portId);
Configuration& getConfig();
const ConnectedDevicePorts& getConnectedDevicePorts() const { return mConnectedDevicePorts; }
bool getMasterMute() const { return mMasterMute; }
bool getMasterVolume() const { return mMasterVolume; }
bool getMicMute() const { return mMicMute; }
+ const ModuleDebug& getModuleDebug() const { return mDebug; }
const Patches& getPatches() const { return mPatches; }
std::set<int32_t> getRoutableAudioPortIds(int32_t portId,
std::vector<AudioRoute*>* routes = nullptr);
@@ -240,6 +249,12 @@
template <typename C>
std::set<int32_t> portIdsFromPortConfigIds(C portConfigIds);
void registerPatch(const AudioPatch& patch);
+ ndk::ScopedAStatus setAudioPortConfigImpl(
+ const ::aidl::android::media::audio::common::AudioPortConfig& in_requested,
+ const std::function<bool(const ::aidl::android::media::audio::common::AudioPort& port,
+ ::aidl::android::media::audio::common::AudioPortConfig*
+ config)>& fillPortConfig,
+ ::aidl::android::media::audio::common::AudioPortConfig* out_suggested, bool* applied);
ndk::ScopedAStatus updateStreamsConnectedState(const AudioPatch& oldPatch,
const AudioPatch& newPatch);
};
diff --git a/audio/aidl/default/include/core-impl/ModuleAlsa.h b/audio/aidl/default/include/core-impl/ModuleAlsa.h
index 2774fe5..3392b41 100644
--- a/audio/aidl/default/include/core-impl/ModuleAlsa.h
+++ b/audio/aidl/default/include/core-impl/ModuleAlsa.h
@@ -33,7 +33,8 @@
protected:
// Extension methods of 'Module'.
ndk::ScopedAStatus populateConnectedDevicePort(
- ::aidl::android::media::audio::common::AudioPort* audioPort) override;
+ ::aidl::android::media::audio::common::AudioPort* audioPort,
+ int32_t nextPortId) override;
};
} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/ModuleBluetooth.h b/audio/aidl/default/include/core-impl/ModuleBluetooth.h
index a58798b..4e68d72 100644
--- a/audio/aidl/default/include/core-impl/ModuleBluetooth.h
+++ b/audio/aidl/default/include/core-impl/ModuleBluetooth.h
@@ -16,7 +16,10 @@
#pragma once
+#include <map>
+
#include "core-impl/Bluetooth.h"
+#include "core-impl/DevicePortProxy.h"
#include "core-impl/Module.h"
namespace aidl::android::hardware::audio::core {
@@ -28,10 +31,14 @@
std::weak_ptr<IBluetoothLe>>
BtProfileHandles;
- ModuleBluetooth(std::unique_ptr<Configuration>&& config)
- : Module(Type::BLUETOOTH, std::move(config)) {}
+ ModuleBluetooth(std::unique_ptr<Configuration>&& config);
private:
+ struct CachedProxy {
+ std::shared_ptr<::android::bluetooth::audio::aidl::BluetoothAudioPortAidl> ptr;
+ ::aidl::android::hardware::bluetooth::audio::PcmConfiguration pcmConfig;
+ };
+
ChildInterface<BluetoothA2dp>& getBtA2dp();
ChildInterface<BluetoothLe>& getBtLe();
BtProfileHandles getBtProfileManagerHandles();
@@ -41,6 +48,17 @@
ndk::ScopedAStatus getMicMute(bool* _aidl_return) override;
ndk::ScopedAStatus setMicMute(bool in_mute) override;
+ ndk::ScopedAStatus setAudioPortConfig(
+ const ::aidl::android::media::audio::common::AudioPortConfig& in_requested,
+ ::aidl::android::media::audio::common::AudioPortConfig* out_suggested,
+ bool* _aidl_return) override;
+
+ ndk::ScopedAStatus checkAudioPatchEndpointsMatch(
+ const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sources,
+ const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks)
+ override;
+ void onExternalDeviceConnectionChanged(
+ const ::aidl::android::media::audio::common::AudioPort& audioPort, bool connected);
ndk::ScopedAStatus createInputStream(
StreamContext&& context,
const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
@@ -53,12 +71,26 @@
offloadInfo,
std::shared_ptr<StreamOut>* result) override;
ndk::ScopedAStatus populateConnectedDevicePort(
- ::aidl::android::media::audio::common::AudioPort* audioPort) override;
+ ::aidl::android::media::audio::common::AudioPort* audioPort,
+ int32_t nextPortId) override;
ndk::ScopedAStatus onMasterMuteChanged(bool mute) override;
ndk::ScopedAStatus onMasterVolumeChanged(float volume) override;
+ int32_t getNominalLatencyMs(
+ const ::aidl::android::media::audio::common::AudioPortConfig& portConfig) override;
+ ndk::ScopedAStatus createProxy(
+ const ::aidl::android::media::audio::common::AudioPort& audioPort,
+ int32_t instancePortId, CachedProxy& proxy);
+ ndk::ScopedAStatus fetchAndCheckProxy(const StreamContext& context, CachedProxy& proxy);
+ ndk::ScopedAStatus findOrCreateProxy(
+ const ::aidl::android::media::audio::common::AudioPort& audioPort, CachedProxy& proxy);
+
+ static constexpr int kCreateProxyRetries = 5;
+ static constexpr int kCreateProxyRetrySleepMs = 75;
ChildInterface<BluetoothA2dp> mBluetoothA2dp;
ChildInterface<BluetoothLe> mBluetoothLe;
+ std::map<int32_t /*instantiated device port ID*/, CachedProxy> mProxies;
+ std::map<int32_t /*mix port handle*/, int32_t /*instantiated device port ID*/> mConnections;
};
} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/ModuleRemoteSubmix.h b/audio/aidl/default/include/core-impl/ModuleRemoteSubmix.h
index 9f8acc9..9d8c027 100644
--- a/audio/aidl/default/include/core-impl/ModuleRemoteSubmix.h
+++ b/audio/aidl/default/include/core-impl/ModuleRemoteSubmix.h
@@ -29,6 +29,10 @@
// IModule interfaces
ndk::ScopedAStatus getMicMute(bool* _aidl_return) override;
ndk::ScopedAStatus setMicMute(bool in_mute) override;
+ ndk::ScopedAStatus setAudioPortConfig(
+ const ::aidl::android::media::audio::common::AudioPortConfig& in_requested,
+ ::aidl::android::media::audio::common::AudioPortConfig* out_suggested,
+ bool* _aidl_return) override;
// Module interfaces
ndk::ScopedAStatus createInputStream(
@@ -43,7 +47,8 @@
offloadInfo,
std::shared_ptr<StreamOut>* result) override;
ndk::ScopedAStatus populateConnectedDevicePort(
- ::aidl::android::media::audio::common::AudioPort* audioPort) override;
+ ::aidl::android::media::audio::common::AudioPort* audioPort,
+ int32_t nextPortId) override;
ndk::ScopedAStatus checkAudioPatchEndpointsMatch(
const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sources,
const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks)
@@ -52,7 +57,7 @@
ndk::ScopedAStatus onMasterVolumeChanged(float volume) override;
int32_t getNominalLatencyMs(
const ::aidl::android::media::audio::common::AudioPortConfig& portConfig) override;
- // TODO(b/307586684): Report proper minimum stream buffer size by overriding 'setAudioPatch'.
+ binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
};
} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/ModuleUsb.h b/audio/aidl/default/include/core-impl/ModuleUsb.h
index 6ee8f8a..d9ac4f0 100644
--- a/audio/aidl/default/include/core-impl/ModuleUsb.h
+++ b/audio/aidl/default/include/core-impl/ModuleUsb.h
@@ -44,7 +44,8 @@
offloadInfo,
std::shared_ptr<StreamOut>* result) override;
ndk::ScopedAStatus populateConnectedDevicePort(
- ::aidl::android::media::audio::common::AudioPort* audioPort) override;
+ ::aidl::android::media::audio::common::AudioPort* audioPort,
+ int32_t nextPortId) override;
ndk::ScopedAStatus checkAudioPatchEndpointsMatch(
const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sources,
const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks)
diff --git a/audio/aidl/default/include/core-impl/SoundDose.h b/audio/aidl/default/include/core-impl/SoundDose.h
index 82c1077..f58e541 100644
--- a/audio/aidl/default/include/core-impl/SoundDose.h
+++ b/audio/aidl/default/include/core-impl/SoundDose.h
@@ -64,7 +64,7 @@
// ------------------------------------ MelCallback ----------------------------------------
void onNewMelValues(const std::vector<float>& mels, size_t offset, size_t length,
- audio_port_handle_t deviceId) const override;
+ audio_port_handle_t deviceId, bool attenuated) const override;
void onMomentaryExposure(float currentMel, audio_port_handle_t deviceId) const override;
SoundDose& mSoundDose; // must outlive MelCallback, not owning
diff --git a/audio/aidl/default/include/core-impl/Stream.h b/audio/aidl/default/include/core-impl/Stream.h
index aa9fb19..21e63f9 100644
--- a/audio/aidl/default/include/core-impl/Stream.h
+++ b/audio/aidl/default/include/core-impl/Stream.h
@@ -90,7 +90,7 @@
std::weak_ptr<sounddose::StreamDataProcessorInterface> streamDataProcessor,
DebugParameters debugParameters)
: mCommandMQ(std::move(commandMQ)),
- mInternalCommandCookie(std::rand()),
+ mInternalCommandCookie(std::rand() | 1 /* make sure it's not 0 */),
mReplyMQ(std::move(replyMQ)),
mFormat(format),
mChannelLayout(channelLayout),
diff --git a/audio/aidl/default/include/core-impl/StreamBluetooth.h b/audio/aidl/default/include/core-impl/StreamBluetooth.h
index 1258d38..35c3183 100644
--- a/audio/aidl/default/include/core-impl/StreamBluetooth.h
+++ b/audio/aidl/default/include/core-impl/StreamBluetooth.h
@@ -31,8 +31,16 @@
class StreamBluetooth : public StreamCommonImpl {
public:
- StreamBluetooth(StreamContext* context, const Metadata& metadata,
- ModuleBluetooth::BtProfileHandles&& btHandles);
+ static bool checkConfigParams(
+ const ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& pcmConfig,
+ const ::aidl::android::media::audio::common::AudioConfigBase& config);
+
+ StreamBluetooth(
+ StreamContext* context, const Metadata& metadata,
+ ModuleBluetooth::BtProfileHandles&& btHandles,
+ const std::shared_ptr<::android::bluetooth::audio::aidl::BluetoothAudioPortAidl>&
+ btDeviceProxy,
+ const ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& pcmConfig);
// Methods of 'DriverInterface'.
::android::status_t init() override;
::android::status_t drain(StreamDescriptor::DrainMode) override;
@@ -47,40 +55,35 @@
// Overridden methods of 'StreamCommonImpl', called on a Binder thread.
ndk::ScopedAStatus updateMetadataCommon(const Metadata& metadata) override;
ndk::ScopedAStatus prepareToClose() override;
- const ConnectedDevices& getConnectedDevices() const override;
- ndk::ScopedAStatus setConnectedDevices(const ConnectedDevices& devices) override;
ndk::ScopedAStatus bluetoothParametersUpdated() override;
private:
- // Audio Pcm Config
- const uint32_t mSampleRate;
- const ::aidl::android::media::audio::common::AudioChannelLayout mChannelLayout;
- const ::aidl::android::media::audio::common::AudioFormatDescription mFormat;
const size_t mFrameSizeBytes;
const bool mIsInput;
const std::weak_ptr<IBluetoothA2dp> mBluetoothA2dp;
const std::weak_ptr<IBluetoothLe> mBluetoothLe;
- size_t mPreferredDataIntervalUs;
- size_t mPreferredFrameCount;
-
+ const size_t mPreferredDataIntervalUs;
+ const size_t mPreferredFrameCount;
mutable std::mutex mLock;
- bool mIsInitialized GUARDED_BY(mLock);
- bool mIsReadyToClose GUARDED_BY(mLock);
- std::vector<std::shared_ptr<::android::bluetooth::audio::aidl::BluetoothAudioPortAidl>>
- mBtDeviceProxies GUARDED_BY(mLock);
-
- ::android::status_t initialize() REQUIRES(mLock);
- bool checkConfigParams(::aidl::android::hardware::bluetooth::audio::PcmConfiguration& config);
+ // The lock is also used to serialize calls to the proxy.
+ std::shared_ptr<::android::bluetooth::audio::aidl::BluetoothAudioPortAidl> mBtDeviceProxy
+ GUARDED_BY(mLock); // proxy may be null if the stream is not connected to a device
};
class StreamInBluetooth final : public StreamIn, public StreamBluetooth {
public:
friend class ndk::SharedRefBase;
+
+ static int32_t getNominalLatencyMs(size_t dataIntervalUs);
+
StreamInBluetooth(
StreamContext&& context,
const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones,
- ModuleBluetooth::BtProfileHandles&& btHandles);
+ ModuleBluetooth::BtProfileHandles&& btHandles,
+ const std::shared_ptr<::android::bluetooth::audio::aidl::BluetoothAudioPortAidl>&
+ btDeviceProxy,
+ const ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& pcmConfig);
private:
void onClose(StreamDescriptor::State) override { defaultOnClose(); }
@@ -92,12 +95,18 @@
class StreamOutBluetooth final : public StreamOut, public StreamBluetooth {
public:
friend class ndk::SharedRefBase;
+
+ static int32_t getNominalLatencyMs(size_t dataIntervalUs);
+
StreamOutBluetooth(
StreamContext&& context,
const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
offloadInfo,
- ModuleBluetooth::BtProfileHandles&& btHandles);
+ ModuleBluetooth::BtProfileHandles&& btHandles,
+ const std::shared_ptr<::android::bluetooth::audio::aidl::BluetoothAudioPortAidl>&
+ btDeviceProxy,
+ const ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& pcmConfig);
private:
void onClose(StreamDescriptor::State) override { defaultOnClose(); }
diff --git a/audio/aidl/default/include/core-impl/StreamPrimary.h b/audio/aidl/default/include/core-impl/StreamPrimary.h
index abc119c..8d5c57d 100644
--- a/audio/aidl/default/include/core-impl/StreamPrimary.h
+++ b/audio/aidl/default/include/core-impl/StreamPrimary.h
@@ -27,13 +27,18 @@
public:
StreamPrimary(StreamContext* context, const Metadata& metadata);
+ ::android::status_t start() override;
::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
int32_t* latencyMs) override;
+ ::android::status_t refinePosition(StreamDescriptor::Position* position) override;
protected:
std::vector<alsa::DeviceProfile> getDeviceProfiles() override;
const bool mIsAsynchronous;
+ int64_t mStartTimeNs = 0;
+ long mFramesSinceStart = 0;
+ bool mSkipNextTransfer = false;
};
class StreamInPrimary final : public StreamIn, public StreamSwitcher, public StreamInHwGainHelper {
diff --git a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
index 21592b3..b2cdc28 100644
--- a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
+++ b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
@@ -16,7 +16,6 @@
#pragma once
-#include <mutex>
#include <vector>
#include "core-impl/Stream.h"
@@ -56,13 +55,6 @@
r_submix::AudioConfig mStreamConfig;
std::shared_ptr<r_submix::SubmixRoute> mCurrentRoute = nullptr;
- // Mutex lock to protect vector of submix routes, each of these submix routes have their mutex
- // locks and none of the mutex locks should be taken together.
- static std::mutex sSubmixRoutesLock;
- static std::map<::aidl::android::media::audio::common::AudioDeviceAddress,
- std::shared_ptr<r_submix::SubmixRoute>>
- sSubmixRoutes GUARDED_BY(sSubmixRoutesLock);
-
// limit for number of read error log entries to avoid spamming the logs
static constexpr int kMaxReadErrorLogs = 5;
// The duration of kMaxReadFailureAttempts * READ_ATTEMPT_SLEEP_MS must be strictly inferior
@@ -71,6 +63,11 @@
static constexpr int kMaxReadFailureAttempts = 3;
// 5ms between two read attempts when pipe is empty
static constexpr int kReadAttemptSleepUs = 5000;
+
+ int64_t mStartTimeNs = 0;
+ long mFramesSinceStart = 0;
+ int mReadErrorCount = 0;
+ int mReadFailureCount = 0;
};
class StreamInRemoteSubmix final : public StreamIn, public StreamSwitcher {
diff --git a/audio/aidl/default/include/effect-impl/EffectContext.h b/audio/aidl/default/include/effect-impl/EffectContext.h
index 698e7a5..275378e 100644
--- a/audio/aidl/default/include/effect-impl/EffectContext.h
+++ b/audio/aidl/default/include/effect-impl/EffectContext.h
@@ -21,6 +21,7 @@
#include <Utils.h>
#include <android-base/logging.h>
#include <fmq/AidlMessageQueue.h>
+#include <fmq/EventFlag.h>
#include <aidl/android/hardware/audio/effect/BnEffect.h>
#include "EffectTypes.h"
@@ -36,119 +37,76 @@
float, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
DataMQ;
- EffectContext(size_t statusDepth, const Parameter::Common& common) {
- auto& input = common.input;
- auto& output = common.output;
-
- LOG_ALWAYS_FATAL_IF(
- input.base.format.pcm != aidl::android::media::audio::common::PcmType::FLOAT_32_BIT,
- "inputFormatNotFloat");
- LOG_ALWAYS_FATAL_IF(output.base.format.pcm !=
- aidl::android::media::audio::common::PcmType::FLOAT_32_BIT,
- "outputFormatNotFloat");
- mInputFrameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes(
- input.base.format, input.base.channelMask);
- mOutputFrameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes(
- output.base.format, output.base.channelMask);
- // in/outBuffer size in float (FMQ data format defined for DataMQ)
- size_t inBufferSizeInFloat = input.frameCount * mInputFrameSize / sizeof(float);
- size_t outBufferSizeInFloat = output.frameCount * mOutputFrameSize / sizeof(float);
-
- // only status FMQ use the EventFlag
- mStatusMQ = std::make_shared<StatusMQ>(statusDepth, true /*configureEventFlagWord*/);
- mInputMQ = std::make_shared<DataMQ>(inBufferSizeInFloat);
- mOutputMQ = std::make_shared<DataMQ>(outBufferSizeInFloat);
-
- if (!mStatusMQ->isValid() || !mInputMQ->isValid() || !mOutputMQ->isValid()) {
- LOG(ERROR) << __func__ << " created invalid FMQ";
+ EffectContext(size_t statusDepth, const Parameter::Common& common);
+ virtual ~EffectContext() {
+ if (mEfGroup) {
+ ::android::hardware::EventFlag::deleteEventFlag(&mEfGroup);
}
- mWorkBuffer.reserve(std::max(inBufferSizeInFloat, outBufferSizeInFloat));
- mCommon = common;
}
- virtual ~EffectContext() {}
- std::shared_ptr<StatusMQ> getStatusFmq() { return mStatusMQ; }
- std::shared_ptr<DataMQ> getInputDataFmq() { return mInputMQ; }
- std::shared_ptr<DataMQ> getOutputDataFmq() { return mOutputMQ; }
+ void setVersion(int version) { mVersion = version; }
+ std::shared_ptr<StatusMQ> getStatusFmq() const;
+ std::shared_ptr<DataMQ> getInputDataFmq() const;
+ std::shared_ptr<DataMQ> getOutputDataFmq() const;
- float* getWorkBuffer() { return static_cast<float*>(mWorkBuffer.data()); }
+ float* getWorkBuffer();
+ size_t getWorkBufferSize() const;
// reset buffer status by abandon input data in FMQ
- void resetBuffer() {
- auto buffer = static_cast<float*>(mWorkBuffer.data());
- std::vector<IEffect::Status> status(mStatusMQ->availableToRead());
- mInputMQ->read(buffer, mInputMQ->availableToRead());
- }
+ void resetBuffer();
+ void dupeFmq(IEffect::OpenEffectReturn* effectRet);
+ size_t getInputFrameSize() const;
+ size_t getOutputFrameSize() const;
+ int getSessionId() const;
+ int getIoHandle() const;
- void dupeFmq(IEffect::OpenEffectReturn* effectRet) {
- if (effectRet) {
- effectRet->statusMQ = mStatusMQ->dupeDesc();
- effectRet->inputDataMQ = mInputMQ->dupeDesc();
- effectRet->outputDataMQ = mOutputMQ->dupeDesc();
- }
- }
- size_t getInputFrameSize() { return mInputFrameSize; }
- size_t getOutputFrameSize() { return mOutputFrameSize; }
- int getSessionId() { return mCommon.session; }
- int getIoHandle() { return mCommon.ioHandle; }
+ virtual void dupeFmqWithReopen(IEffect::OpenEffectReturn* effectRet);
virtual RetCode setOutputDevice(
- const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>&
- device) {
- mOutputDevice = device;
- return RetCode::SUCCESS;
- }
+ const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>& device);
virtual std::vector<aidl::android::media::audio::common::AudioDeviceDescription>
- getOutputDevice() {
- return mOutputDevice;
- }
+ getOutputDevice();
- virtual RetCode setAudioMode(const aidl::android::media::audio::common::AudioMode& mode) {
- mMode = mode;
- return RetCode::SUCCESS;
- }
- virtual aidl::android::media::audio::common::AudioMode getAudioMode() { return mMode; }
+ virtual RetCode setAudioMode(const aidl::android::media::audio::common::AudioMode& mode);
+ virtual aidl::android::media::audio::common::AudioMode getAudioMode();
- virtual RetCode setAudioSource(const aidl::android::media::audio::common::AudioSource& source) {
- mSource = source;
- return RetCode::SUCCESS;
- }
- virtual aidl::android::media::audio::common::AudioSource getAudioSource() { return mSource; }
+ virtual RetCode setAudioSource(const aidl::android::media::audio::common::AudioSource& source);
+ virtual aidl::android::media::audio::common::AudioSource getAudioSource();
- virtual RetCode setVolumeStereo(const Parameter::VolumeStereo& volumeStereo) {
- mVolumeStereo = volumeStereo;
- return RetCode::SUCCESS;
- }
- virtual Parameter::VolumeStereo getVolumeStereo() { return mVolumeStereo; }
+ virtual RetCode setVolumeStereo(const Parameter::VolumeStereo& volumeStereo);
+ virtual Parameter::VolumeStereo getVolumeStereo();
- virtual RetCode setCommon(const Parameter::Common& common) {
- mCommon = common;
- LOG(VERBOSE) << __func__ << mCommon.toString();
- return RetCode::SUCCESS;
- }
- virtual Parameter::Common getCommon() {
- LOG(VERBOSE) << __func__ << mCommon.toString();
- return mCommon;
- }
+ virtual RetCode setCommon(const Parameter::Common& common);
+ virtual Parameter::Common getCommon();
+
+ virtual ::android::hardware::EventFlag* getStatusEventFlag();
protected:
- // common parameters
- size_t mInputFrameSize;
- size_t mOutputFrameSize;
- Parameter::Common mCommon;
- std::vector<aidl::android::media::audio::common::AudioDeviceDescription> mOutputDevice;
- aidl::android::media::audio::common::AudioMode mMode;
- aidl::android::media::audio::common::AudioSource mSource;
- Parameter::VolumeStereo mVolumeStereo;
+ int mVersion = 0;
+ size_t mInputFrameSize = 0;
+ size_t mOutputFrameSize = 0;
+ size_t mInputChannelCount = 0;
+ size_t mOutputChannelCount = 0;
+ Parameter::Common mCommon = {};
+ std::vector<aidl::android::media::audio::common::AudioDeviceDescription> mOutputDevice = {};
+ aidl::android::media::audio::common::AudioMode mMode =
+ aidl::android::media::audio::common::AudioMode::SYS_RESERVED_INVALID;
+ aidl::android::media::audio::common::AudioSource mSource =
+ aidl::android::media::audio::common::AudioSource::SYS_RESERVED_INVALID;
+ Parameter::VolumeStereo mVolumeStereo = {};
+ RetCode updateIOFrameSize(const Parameter::Common& common);
+ RetCode notifyDataMqUpdate();
private:
// fmq and buffers
- std::shared_ptr<StatusMQ> mStatusMQ;
- std::shared_ptr<DataMQ> mInputMQ;
- std::shared_ptr<DataMQ> mOutputMQ;
- // TODO handle effect process input and output
+ std::shared_ptr<StatusMQ> mStatusMQ = nullptr;
+ std::shared_ptr<DataMQ> mInputMQ = nullptr;
+ std::shared_ptr<DataMQ> mOutputMQ = nullptr;
+ // std::shared_ptr<IEffect::OpenEffectReturn> mRet;
// work buffer set by effect instances, the access and update are in same thread
- std::vector<float> mWorkBuffer;
+ std::vector<float> mWorkBuffer = {};
+
+ ::android::hardware::EventFlag* mEfGroup = nullptr;
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/effect-impl/EffectImpl.h b/audio/aidl/default/include/effect-impl/EffectImpl.h
index e7d081f..21f6502 100644
--- a/audio/aidl/default/include/effect-impl/EffectImpl.h
+++ b/audio/aidl/default/include/effect-impl/EffectImpl.h
@@ -43,38 +43,60 @@
OpenEffectReturn* ret) override;
virtual ndk::ScopedAStatus close() override;
virtual ndk::ScopedAStatus command(CommandId id) override;
+ virtual ndk::ScopedAStatus reopen(OpenEffectReturn* ret) override;
virtual ndk::ScopedAStatus getState(State* state) override;
virtual ndk::ScopedAStatus setParameter(const Parameter& param) override;
virtual ndk::ScopedAStatus getParameter(const Parameter::Id& id, Parameter* param) override;
- virtual ndk::ScopedAStatus setParameterCommon(const Parameter& param);
- virtual ndk::ScopedAStatus getParameterCommon(const Parameter::Tag& tag, Parameter* param);
+ virtual ndk::ScopedAStatus setParameterCommon(const Parameter& param) REQUIRES(mImplMutex);
+ virtual ndk::ScopedAStatus getParameterCommon(const Parameter::Tag& tag, Parameter* param)
+ REQUIRES(mImplMutex);
/* Methods MUST be implemented by each effect instances */
virtual ndk::ScopedAStatus getDescriptor(Descriptor* desc) = 0;
- virtual ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) = 0;
+ virtual ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+ REQUIRES(mImplMutex) = 0;
virtual ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
- Parameter::Specific* specific) = 0;
+ Parameter::Specific* specific)
+ REQUIRES(mImplMutex) = 0;
virtual std::string getEffectName() = 0;
- virtual IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+ virtual std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+ REQUIRES(mImplMutex);
+ virtual RetCode releaseContext() REQUIRES(mImplMutex) = 0;
/**
- * Effect context methods must be implemented by each effect.
- * Each effect can derive from EffectContext and define its own context, but must upcast to
- * EffectContext for EffectImpl to use.
+ * @brief effectProcessImpl is running in worker thread which created in EffectThread.
+ *
+ * EffectThread will make sure effectProcessImpl only be called after startThread() successful
+ * and before stopThread() successful.
+ *
+ * effectProcessImpl implementation must not call any EffectThread interface, otherwise it will
+ * cause deadlock.
+ *
+ * @param in address of input float buffer.
+ * @param out address of output float buffer.
+ * @param samples number of samples to process.
+ * @return IEffect::Status
*/
- virtual std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) = 0;
- virtual std::shared_ptr<EffectContext> getContext() = 0;
- virtual RetCode releaseContext() = 0;
+ virtual IEffect::Status effectProcessImpl(float* in, float* out, int samples) = 0;
+
+ /**
+ * process() get data from data MQs, and call effectProcessImpl() for effect data processing.
+ * Its important for the implementation to use mImplMutex for context synchronization.
+ */
+ void process() override;
protected:
- State mState = State::INIT;
+ State mState GUARDED_BY(mImplMutex) = State::INIT;
IEffect::Status status(binder_status_t status, size_t consumed, size_t produced);
void cleanUp();
+ std::mutex mImplMutex;
+ std::shared_ptr<EffectContext> mImplContext GUARDED_BY(mImplMutex);
+
/**
* Optional CommandId handling methods for effects to override.
* For CommandId::START, EffectImpl call commandImpl before starting the EffectThread
@@ -82,6 +104,9 @@
* For CommandId::STOP and CommandId::RESET, EffectImpl call commandImpl after stop the
* EffectThread processing.
*/
- virtual ndk::ScopedAStatus commandImpl(CommandId id);
+ virtual ndk::ScopedAStatus commandImpl(CommandId id) REQUIRES(mImplMutex);
+
+ RetCode notifyEventFlag(uint32_t flag);
+ ::android::hardware::EventFlag* mEventFlag;
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/effect-impl/EffectThread.h b/audio/aidl/default/include/effect-impl/EffectThread.h
index ae51ef7..3dbb0e6 100644
--- a/audio/aidl/default/include/effect-impl/EffectThread.h
+++ b/audio/aidl/default/include/effect-impl/EffectThread.h
@@ -36,8 +36,7 @@
virtual ~EffectThread();
// called by effect implementation.
- RetCode createThread(std::shared_ptr<EffectContext> context, const std::string& name,
- int priority = ANDROID_PRIORITY_URGENT_AUDIO);
+ RetCode createThread(const std::string& name, int priority = ANDROID_PRIORITY_URGENT_AUDIO);
RetCode destroyThread();
RetCode startThread();
RetCode stopThread();
@@ -46,32 +45,11 @@
void threadLoop();
/**
- * @brief effectProcessImpl is running in worker thread which created in EffectThread.
- *
- * Effect implementation should think about concurrency in the implementation if necessary.
- * Parameter setting usually implemented in context (derived from EffectContext), and some
- * parameter maybe used in the processing, then effect implementation should consider using a
- * mutex to protect these parameter.
- *
- * EffectThread will make sure effectProcessImpl only be called after startThread() successful
- * and before stopThread() successful.
- *
- * effectProcessImpl implementation must not call any EffectThread interface, otherwise it will
- * cause deadlock.
- *
- * @param in address of input float buffer.
- * @param out address of output float buffer.
- * @param samples number of samples to process.
- * @return IEffect::Status
- */
- virtual IEffect::Status effectProcessImpl(float* in, float* out, int samples) = 0;
-
- /**
* process() call effectProcessImpl() for effect data processing, it is necessary for the
* processing to be called under Effect thread mutex mThreadMutex, to avoid the effect state
* change before/during data processing, and keep the thread and effect state consistent.
*/
- virtual void process_l() REQUIRES(mThreadMutex);
+ virtual void process() = 0;
private:
static constexpr int kMaxTaskNameLen = 15;
@@ -80,16 +58,7 @@
std::condition_variable mCv;
bool mStop GUARDED_BY(mThreadMutex) = true;
bool mExit GUARDED_BY(mThreadMutex) = false;
- std::shared_ptr<EffectContext> mThreadContext GUARDED_BY(mThreadMutex);
- struct EventFlagDeleter {
- void operator()(::android::hardware::EventFlag* flag) const {
- if (flag) {
- ::android::hardware::EventFlag::deleteEventFlag(&flag);
- }
- }
- };
- std::unique_ptr<::android::hardware::EventFlag, EventFlagDeleter> mEfGroup;
std::thread mThread;
int mPriority;
std::string mName;
diff --git a/audio/aidl/default/include/effect-impl/EffectTypes.h b/audio/aidl/default/include/effect-impl/EffectTypes.h
index 4bda7be..9740d6e 100644
--- a/audio/aidl/default/include/effect-impl/EffectTypes.h
+++ b/audio/aidl/default/include/effect-impl/EffectTypes.h
@@ -46,7 +46,8 @@
ERROR_NULL_POINTER, /* NULL pointer */
ERROR_ALIGNMENT_ERROR, /* Memory alignment error */
ERROR_BLOCK_SIZE_EXCEED, /* Maximum block size exceeded */
- ERROR_EFFECT_LIB_ERROR
+ ERROR_EFFECT_LIB_ERROR, /* Effect implementation library error */
+ ERROR_EVENT_FLAG_ERROR /* Error with effect event flags */
};
static const int INVALID_AUDIO_SESSION_ID = -1;
@@ -67,6 +68,8 @@
return out << "ERROR_BLOCK_SIZE_EXCEED";
case RetCode::ERROR_EFFECT_LIB_ERROR:
return out << "ERROR_EFFECT_LIB_ERROR";
+ case RetCode::ERROR_EVENT_FLAG_ERROR:
+ return out << "ERROR_EVENT_FLAG_ERROR";
}
return out << "EnumError: " << code;
diff --git a/audio/aidl/default/include/effectFactory-impl/EffectConfig.h b/audio/aidl/default/include/effectFactory-impl/EffectConfig.h
index 344846a..7456b99 100644
--- a/audio/aidl/default/include/effectFactory-impl/EffectConfig.h
+++ b/audio/aidl/default/include/effectFactory-impl/EffectConfig.h
@@ -64,12 +64,16 @@
const ProcessingLibrariesMap& getProcessingMap() const;
private:
- static constexpr const char* kEffectLibPath[] =
#ifdef __LP64__
- {"/odm/lib64/soundfx", "/vendor/lib64/soundfx", "/system/lib64/soundfx"};
+#define SOUND_FX_PATH "/lib64/soundfx/"
#else
- {"/odm/lib/soundfx", "/vendor/lib/soundfx", "/system/lib/soundfx"};
+#define SOUND_FX_PATH "/lib/soundfx/"
#endif
+ static constexpr const char* kEffectLibPath[] =
+ { "/odm" SOUND_FX_PATH, "/vendor" SOUND_FX_PATH, "/system" SOUND_FX_PATH };
+
+ static constexpr const char* kEffectLibApexPath = SOUND_FX_PATH;
+#undef SOUND_FX_PATH
int mSkippedElements;
/* Parsed Libraries result */
diff --git a/audio/aidl/default/loudnessEnhancer/Android.bp b/audio/aidl/default/loudnessEnhancer/Android.bp
index 89a72fe..4b30484 100644
--- a/audio/aidl/default/loudnessEnhancer/Android.bp
+++ b/audio/aidl/default/loudnessEnhancer/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -27,8 +28,6 @@
name: "libloudnessenhancersw",
defaults: [
"aidlaudioeffectservice_defaults",
- "latest_android_media_audio_common_types_ndk_shared",
- "latest_android_hardware_audio_effect_ndk_shared",
],
srcs: [
"LoudnessEnhancerSw.cpp",
diff --git a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp
index 7954316..1e70716 100644
--- a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp
+++ b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp
@@ -147,10 +147,6 @@
return mContext;
}
-std::shared_ptr<EffectContext> LoudnessEnhancerSw::getContext() {
- return mContext;
-}
-
RetCode LoudnessEnhancerSw::releaseContext() {
if (mContext) {
mContext.reset();
diff --git a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h
index 25824f2..cf71a5f 100644
--- a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h
+++ b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h
@@ -54,20 +54,23 @@
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
- ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
- ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
- Parameter::Specific* specific) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+ REQUIRES(mImplMutex) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+ REQUIRES(mImplMutex) override;
- std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
- std::shared_ptr<EffectContext> getContext() override;
- RetCode releaseContext() override;
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+ REQUIRES(mImplMutex) override;
+ RetCode releaseContext() REQUIRES(mImplMutex) override;
- IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+ IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+ REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; }
private:
- std::shared_ptr<LoudnessEnhancerSwContext> mContext;
+ std::shared_ptr<LoudnessEnhancerSwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterLoudnessEnhancer(const LoudnessEnhancer::Tag& tag,
- Parameter::Specific* specific);
+ Parameter::Specific* specific)
+ REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/noiseSuppression/Android.bp b/audio/aidl/default/noiseSuppression/Android.bp
index dad3d49..66fe427 100644
--- a/audio/aidl/default/noiseSuppression/Android.bp
+++ b/audio/aidl/default/noiseSuppression/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -27,8 +28,6 @@
name: "libnssw",
defaults: [
"aidlaudioeffectservice_defaults",
- "latest_android_media_audio_common_types_ndk_shared",
- "latest_android_hardware_audio_effect_ndk_shared",
],
srcs: [
"NoiseSuppressionSw.cpp",
@@ -36,6 +35,6 @@
],
relative_install_path: "soundfx",
visibility: [
- "//hardware/interfaces/audio/aidl/default",
+ "//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}
diff --git a/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.cpp b/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.cpp
index 99f2caf..d304416 100644
--- a/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.cpp
+++ b/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.cpp
@@ -67,7 +67,7 @@
.proxy = std::nullopt},
.flags = {.type = Flags::Type::PRE_PROC,
.insert = Flags::Insert::FIRST,
- .volume = Flags::Volume::CTRL},
+ .volume = Flags::Volume::NONE},
.name = NoiseSuppressionSw::kEffectName,
.implementor = "The Android Open Source Project"}};
@@ -155,10 +155,6 @@
return mContext;
}
-std::shared_ptr<EffectContext> NoiseSuppressionSw::getContext() {
- return mContext;
-}
-
RetCode NoiseSuppressionSw::releaseContext() {
if (mContext) {
mContext.reset();
diff --git a/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h b/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h
index fc1e028..acef8ee 100644
--- a/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h
+++ b/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h
@@ -55,20 +55,23 @@
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
- ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
- ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
- Parameter::Specific* specific) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+ REQUIRES(mImplMutex) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+ REQUIRES(mImplMutex) override;
- std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
- std::shared_ptr<EffectContext> getContext() override;
- RetCode releaseContext() override;
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+ REQUIRES(mImplMutex) override;
+ RetCode releaseContext() REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; };
- IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+ IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+ REQUIRES(mImplMutex) override;
private:
- std::shared_ptr<NoiseSuppressionSwContext> mContext;
+ std::shared_ptr<NoiseSuppressionSwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterNoiseSuppression(const NoiseSuppression::Tag& tag,
- Parameter::Specific* specific);
+ Parameter::Specific* specific)
+ REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/presetReverb/Android.bp b/audio/aidl/default/presetReverb/Android.bp
index 18bdd17..15b4632 100644
--- a/audio/aidl/default/presetReverb/Android.bp
+++ b/audio/aidl/default/presetReverb/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -27,8 +28,6 @@
name: "libpresetreverbsw",
defaults: [
"aidlaudioeffectservice_defaults",
- "latest_android_media_audio_common_types_ndk_shared",
- "latest_android_hardware_audio_effect_ndk_shared",
],
srcs: [
"PresetReverbSw.cpp",
@@ -36,6 +35,6 @@
],
relative_install_path: "soundfx",
visibility: [
- "//hardware/interfaces/audio/aidl/default",
+ "//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}
diff --git a/audio/aidl/default/presetReverb/PresetReverbSw.cpp b/audio/aidl/default/presetReverb/PresetReverbSw.cpp
index 3f02eb7..2ac2010 100644
--- a/audio/aidl/default/presetReverb/PresetReverbSw.cpp
+++ b/audio/aidl/default/presetReverb/PresetReverbSw.cpp
@@ -161,10 +161,6 @@
return mContext;
}
-std::shared_ptr<EffectContext> PresetReverbSw::getContext() {
- return mContext;
-}
-
RetCode PresetReverbSw::releaseContext() {
if (mContext) {
mContext.reset();
diff --git a/audio/aidl/default/presetReverb/PresetReverbSw.h b/audio/aidl/default/presetReverb/PresetReverbSw.h
index 9ceee7c..61fc88c 100644
--- a/audio/aidl/default/presetReverb/PresetReverbSw.h
+++ b/audio/aidl/default/presetReverb/PresetReverbSw.h
@@ -56,21 +56,23 @@
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
- ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
- ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
- Parameter::Specific* specific) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+ REQUIRES(mImplMutex) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+ REQUIRES(mImplMutex) override;
- std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
- std::shared_ptr<EffectContext> getContext() override;
- RetCode releaseContext() override;
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+ REQUIRES(mImplMutex) override;
+ RetCode releaseContext() REQUIRES(mImplMutex) override;
- IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+ IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+ REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; }
private:
- std::shared_ptr<PresetReverbSwContext> mContext;
+ std::shared_ptr<PresetReverbSwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterPresetReverb(const PresetReverb::Tag& tag,
- Parameter::Specific* specific);
+ Parameter::Specific* specific) REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/primary/StreamPrimary.cpp b/audio/aidl/default/primary/StreamPrimary.cpp
index 7e3bdd4..7325a91 100644
--- a/audio/aidl/default/primary/StreamPrimary.cpp
+++ b/audio/aidl/default/primary/StreamPrimary.cpp
@@ -14,12 +14,11 @@
* limitations under the License.
*/
-#include <chrono>
-
#define LOG_TAG "AHAL_StreamPrimary"
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <audio_utils/clock.h>
+#include <error/Result.h>
#include <error/expected_utils.h>
#include "PrimaryMixer.h"
@@ -43,26 +42,52 @@
context->startStreamDataProcessor();
}
+::android::status_t StreamPrimary::start() {
+ RETURN_STATUS_IF_ERROR(StreamAlsa::start());
+ mStartTimeNs = ::android::uptimeNanos();
+ mFramesSinceStart = 0;
+ mSkipNextTransfer = false;
+ return ::android::OK;
+}
+
::android::status_t StreamPrimary::transfer(void* buffer, size_t frameCount,
size_t* actualFrameCount, int32_t* latencyMs) {
- auto start = std::chrono::steady_clock::now();
- if (auto status = StreamAlsa::transfer(buffer, frameCount, actualFrameCount, latencyMs);
- status != ::android::OK) {
- return status;
- }
// This is a workaround for the emulator implementation which has a host-side buffer
- // and this can result in reading faster than real time.
- if (mIsInput && !mIsAsynchronous) {
- auto recordDurationUs = std::chrono::duration_cast<std::chrono::microseconds>(
- std::chrono::steady_clock::now() - start);
- const long projectedVsObservedOffsetUs =
- *actualFrameCount * MICROS_PER_SECOND / mContext.getSampleRate() -
- recordDurationUs.count();
- if (projectedVsObservedOffsetUs > 0) {
- LOG(VERBOSE) << __func__ << ": sleeping for " << projectedVsObservedOffsetUs << " us";
- usleep(projectedVsObservedOffsetUs);
- }
+ // and is not being able to achieve real-time behavior similar to ADSPs (b/302587331).
+ if (!mSkipNextTransfer) {
+ RETURN_STATUS_IF_ERROR(
+ StreamAlsa::transfer(buffer, frameCount, actualFrameCount, latencyMs));
+ } else {
+ LOG(DEBUG) << __func__ << ": skipping transfer (" << frameCount << " frames)";
+ *actualFrameCount = frameCount;
+ if (mIsInput) memset(buffer, 0, frameCount * mFrameSizeBytes);
+ mSkipNextTransfer = false;
}
+ if (!mIsAsynchronous) {
+ const long bufferDurationUs =
+ (*actualFrameCount) * MICROS_PER_SECOND / mContext.getSampleRate();
+ const auto totalDurationUs =
+ (::android::uptimeNanos() - mStartTimeNs) / NANOS_PER_MICROSECOND;
+ mFramesSinceStart += *actualFrameCount;
+ const long totalOffsetUs =
+ mFramesSinceStart * MICROS_PER_SECOND / mContext.getSampleRate() - totalDurationUs;
+ LOG(VERBOSE) << __func__ << ": totalOffsetUs " << totalOffsetUs;
+ if (totalOffsetUs > 0) {
+ const long sleepTimeUs = std::min(totalOffsetUs, bufferDurationUs);
+ LOG(VERBOSE) << __func__ << ": sleeping for " << sleepTimeUs << " us";
+ usleep(sleepTimeUs);
+ } else {
+ mSkipNextTransfer = true;
+ }
+ } else {
+ LOG(VERBOSE) << __func__ << ": asynchronous transfer";
+ }
+ return ::android::OK;
+}
+
+::android::status_t StreamPrimary::refinePosition(StreamDescriptor::Position*) {
+ // Since not all data is actually sent to the HAL, use the position maintained by Stream class
+ // which accounts for all frames passed from / to the client.
return ::android::OK;
}
@@ -91,8 +116,8 @@
GetBoolProperty("ro.boot.audio.tinyalsa.simulate_input", false);
return kSimulateInput || device.type.type == AudioDeviceType::IN_TELEPHONY_RX ||
device.type.type == AudioDeviceType::IN_FM_TUNER ||
- device.type.connection == AudioDeviceDescription::CONNECTION_BUS ||
- (device.type.type == AudioDeviceType::IN_DEVICE && device.type.connection.empty());
+ device.type.connection == AudioDeviceDescription::CONNECTION_BUS /*deprecated */ ||
+ (device.type.type == AudioDeviceType::IN_BUS && device.type.connection.empty());
}
StreamSwitcher::DeviceSwitchBehavior StreamInPrimary::switchCurrentStream(
@@ -163,8 +188,8 @@
static const bool kSimulateOutput =
GetBoolProperty("ro.boot.audio.tinyalsa.ignore_output", false);
return kSimulateOutput || device.type.type == AudioDeviceType::OUT_TELEPHONY_TX ||
- device.type.connection == AudioDeviceDescription::CONNECTION_BUS ||
- (device.type.type == AudioDeviceType::OUT_DEVICE && device.type.connection.empty());
+ device.type.connection == AudioDeviceDescription::CONNECTION_BUS /*deprecated*/ ||
+ (device.type.type == AudioDeviceType::OUT_BUS && device.type.connection.empty());
}
StreamSwitcher::DeviceSwitchBehavior StreamOutPrimary::switchCurrentStream(
diff --git a/audio/aidl/default/r_submix/ModuleRemoteSubmix.cpp b/audio/aidl/default/r_submix/ModuleRemoteSubmix.cpp
index 3e8dd7c..b44f37b 100644
--- a/audio/aidl/default/r_submix/ModuleRemoteSubmix.cpp
+++ b/audio/aidl/default/r_submix/ModuleRemoteSubmix.cpp
@@ -16,6 +16,7 @@
#define LOG_TAG "AHAL_ModuleRemoteSubmix"
+#include <stdio.h>
#include <vector>
#include <android-base/logging.h>
@@ -27,13 +28,36 @@
using aidl::android::hardware::audio::common::SinkMetadata;
using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::media::audio::common::AudioDeviceAddress;
+using aidl::android::media::audio::common::AudioFormatType;
+using aidl::android::media::audio::common::AudioIoFlags;
using aidl::android::media::audio::common::AudioOffloadInfo;
using aidl::android::media::audio::common::AudioPort;
using aidl::android::media::audio::common::AudioPortConfig;
+using aidl::android::media::audio::common::AudioPortExt;
+using aidl::android::media::audio::common::AudioProfile;
+using aidl::android::media::audio::common::Int;
using aidl::android::media::audio::common::MicrophoneInfo;
namespace aidl::android::hardware::audio::core {
+namespace {
+
+std::optional<r_submix::AudioConfig> getRemoteEndConfig(const AudioPort& audioPort) {
+ const auto& deviceAddress = audioPort.ext.get<AudioPortExt::device>().device.address;
+ const bool isInput = audioPort.flags.getTag() == AudioIoFlags::input;
+ if (auto submixRoute = r_submix::SubmixRoute::findRoute(deviceAddress);
+ submixRoute != nullptr) {
+ if ((isInput && submixRoute->isStreamOutOpen()) ||
+ (!isInput && submixRoute->isStreamInOpen())) {
+ return submixRoute->getPipeConfig();
+ }
+ }
+ return {};
+}
+
+} // namespace
+
ndk::ScopedAStatus ModuleRemoteSubmix::getMicMute(bool* _aidl_return __unused) {
LOG(DEBUG) << __func__ << ": is not supported";
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
@@ -44,6 +68,26 @@
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
+ndk::ScopedAStatus ModuleRemoteSubmix::setAudioPortConfig(const AudioPortConfig& in_requested,
+ AudioPortConfig* out_suggested,
+ bool* _aidl_return) {
+ auto fillConfig = [this](const AudioPort& port, AudioPortConfig* config) {
+ if (port.ext.getTag() == AudioPortExt::device) {
+ if (auto pipeConfig = getRemoteEndConfig(port); pipeConfig.has_value()) {
+ LOG(DEBUG) << "setAudioPortConfig: suggesting port config from the remote end.";
+ config->format = pipeConfig->format;
+ config->channelMask = pipeConfig->channelLayout;
+ config->sampleRate = Int{.value = pipeConfig->sampleRate};
+ config->flags = port.flags;
+ config->ext = port.ext;
+ return true;
+ }
+ }
+ return generateDefaultPortConfig(port, config);
+ };
+ return Module::setAudioPortConfigImpl(in_requested, fillConfig, out_suggested, _aidl_return);
+}
+
ndk::ScopedAStatus ModuleRemoteSubmix::createInputStream(
StreamContext&& context, const SinkMetadata& sinkMetadata,
const std::vector<MicrophoneInfo>& microphones, std::shared_ptr<StreamIn>* result) {
@@ -58,8 +102,23 @@
offloadInfo);
}
-ndk::ScopedAStatus ModuleRemoteSubmix::populateConnectedDevicePort(AudioPort* audioPort) {
- // Find the corresponding mix port and copy its profiles.
+ndk::ScopedAStatus ModuleRemoteSubmix::populateConnectedDevicePort(AudioPort* audioPort, int32_t) {
+ if (audioPort->ext.getTag() != AudioPortExt::device) {
+ LOG(ERROR) << __func__ << ": not a device port: " << audioPort->toString();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ // If there is already a pipe with a stream for the port address, provide its configuration as
+ // the only option. Otherwise, find the corresponding mix port and copy its profiles.
+ if (auto pipeConfig = getRemoteEndConfig(*audioPort); pipeConfig.has_value()) {
+ audioPort->profiles.clear();
+ audioPort->profiles.push_back(AudioProfile{
+ .format = pipeConfig->format,
+ .channelMasks = std::vector<AudioChannelLayout>({pipeConfig->channelLayout}),
+ .sampleRates = std::vector<int>({pipeConfig->sampleRate})});
+ LOG(DEBUG) << __func__ << ": populated from remote end as: " << audioPort->toString();
+ return ndk::ScopedAStatus::ok();
+ }
+
// At this moment, the port has the same ID as the template port, see connectExternalDevice.
std::vector<AudioRoute*> routes = getAudioRoutesForAudioPortImpl(audioPort->id);
if (routes.empty()) {
@@ -78,6 +137,7 @@
RETURN_STATUS_IF_ERROR(getAudioPort(route->sinkPortId, &mixPort));
}
audioPort->profiles = mixPort.profiles;
+ LOG(DEBUG) << __func__ << ": populated from the mix port as: " << audioPort->toString();
return ndk::ScopedAStatus::ok();
}
@@ -112,7 +172,12 @@
static constexpr int32_t kMaxLatencyMs =
(r_submix::kDefaultPipeSizeInFrames * 1000) / r_submix::kDefaultSampleRateHz;
static constexpr int32_t kMinLatencyMs = kMaxLatencyMs / r_submix::kDefaultPipePeriodCount;
- return (kMaxLatencyMs + kMinLatencyMs) / 2;
+ return kMinLatencyMs;
+}
+
+binder_status_t ModuleRemoteSubmix::dump(int fd, const char** /*args*/, uint32_t /*numArgs*/) {
+ dprintf(fd, "\nSubmixRoutes:\n%s\n", r_submix::SubmixRoute::dumpRoutes().c_str());
+ return STATUS_OK;
}
} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
index fc61dcb..fa4135d 100644
--- a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
+++ b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
@@ -16,6 +16,9 @@
#define LOG_TAG "AHAL_StreamRemoteSubmix"
#include <android-base/logging.h>
+#include <audio_utils/clock.h>
+#include <error/Result.h>
+#include <error/expected_utils.h>
#include "core-impl/StreamRemoteSubmix.h"
@@ -40,50 +43,27 @@
mStreamConfig.sampleRate = context->getSampleRate();
}
-std::mutex StreamRemoteSubmix::sSubmixRoutesLock;
-std::map<AudioDeviceAddress, std::shared_ptr<SubmixRoute>> StreamRemoteSubmix::sSubmixRoutes;
-
::android::status_t StreamRemoteSubmix::init() {
- {
- std::lock_guard guard(sSubmixRoutesLock);
- auto routeItr = sSubmixRoutes.find(mDeviceAddress);
- if (routeItr != sSubmixRoutes.end()) {
- mCurrentRoute = routeItr->second;
- }
- }
- // If route is not available for this port, add it.
+ mCurrentRoute = SubmixRoute::findOrCreateRoute(mDeviceAddress, mStreamConfig);
if (mCurrentRoute == nullptr) {
- // Initialize the pipe.
- mCurrentRoute = std::make_shared<SubmixRoute>();
- if (::android::OK != mCurrentRoute->createPipe(mStreamConfig)) {
- LOG(ERROR) << __func__ << ": create pipe failed";
+ return ::android::NO_INIT;
+ }
+ if (!mCurrentRoute->isStreamConfigValid(mIsInput, mStreamConfig)) {
+ LOG(ERROR) << __func__ << ": invalid stream config";
+ return ::android::NO_INIT;
+ }
+ sp<MonoPipe> sink = mCurrentRoute->getSink();
+ if (sink == nullptr) {
+ LOG(ERROR) << __func__ << ": nullptr sink when opening stream";
+ return ::android::NO_INIT;
+ }
+ if ((!mIsInput || mCurrentRoute->isStreamInOpen()) && sink->isShutdown()) {
+ LOG(DEBUG) << __func__ << ": Shut down sink when opening stream";
+ if (::android::OK != mCurrentRoute->resetPipe()) {
+ LOG(ERROR) << __func__ << ": reset pipe failed";
return ::android::NO_INIT;
}
- {
- std::lock_guard guard(sSubmixRoutesLock);
- sSubmixRoutes.emplace(mDeviceAddress, mCurrentRoute);
- }
- } else {
- if (!mCurrentRoute->isStreamConfigValid(mIsInput, mStreamConfig)) {
- LOG(ERROR) << __func__ << ": invalid stream config";
- return ::android::NO_INIT;
- }
- sp<MonoPipe> sink = mCurrentRoute->getSink();
- if (sink == nullptr) {
- LOG(ERROR) << __func__ << ": nullptr sink when opening stream";
- return ::android::NO_INIT;
- }
- // If the sink has been shutdown or pipe recreation is forced, delete the pipe and
- // recreate it.
- if (sink->isShutdown()) {
- LOG(DEBUG) << __func__ << ": Non-nullptr shut down sink when opening stream";
- if (::android::OK != mCurrentRoute->resetPipe()) {
- LOG(ERROR) << __func__ << ": reset pipe failed";
- return ::android::NO_INIT;
- }
- }
}
-
mCurrentRoute->openStream(mIsInput);
return ::android::OK;
}
@@ -110,19 +90,14 @@
::android::status_t StreamRemoteSubmix::start() {
mCurrentRoute->exitStandby(mIsInput);
+ mStartTimeNs = ::android::uptimeNanos();
+ mFramesSinceStart = 0;
return ::android::OK;
}
ndk::ScopedAStatus StreamRemoteSubmix::prepareToClose() {
if (!mIsInput) {
- std::shared_ptr<SubmixRoute> route = nullptr;
- {
- std::lock_guard guard(sSubmixRoutesLock);
- auto routeItr = sSubmixRoutes.find(mDeviceAddress);
- if (routeItr != sSubmixRoutes.end()) {
- route = routeItr->second;
- }
- }
+ std::shared_ptr<SubmixRoute> route = SubmixRoute::findRoute(mDeviceAddress);
if (route != nullptr) {
sp<MonoPipe> sink = route->getSink();
if (sink == nullptr) {
@@ -149,9 +124,7 @@
if (!mCurrentRoute->hasAtleastOneStreamOpen()) {
mCurrentRoute->releasePipe();
LOG(DEBUG) << __func__ << ": pipe destroyed";
-
- std::lock_guard guard(sSubmixRoutesLock);
- sSubmixRoutes.erase(mDeviceAddress);
+ SubmixRoute::removeRoute(mDeviceAddress);
}
mCurrentRoute.reset();
}
@@ -161,8 +134,21 @@
*latencyMs = getDelayInUsForFrameCount(getStreamPipeSizeInFrames()) / 1000;
LOG(VERBOSE) << __func__ << ": Latency " << *latencyMs << "ms";
mCurrentRoute->exitStandby(mIsInput);
- return (mIsInput ? inRead(buffer, frameCount, actualFrameCount)
- : outWrite(buffer, frameCount, actualFrameCount));
+ RETURN_STATUS_IF_ERROR(mIsInput ? inRead(buffer, frameCount, actualFrameCount)
+ : outWrite(buffer, frameCount, actualFrameCount));
+ const long bufferDurationUs =
+ (*actualFrameCount) * MICROS_PER_SECOND / mContext.getSampleRate();
+ const auto totalDurationUs = (::android::uptimeNanos() - mStartTimeNs) / NANOS_PER_MICROSECOND;
+ mFramesSinceStart += *actualFrameCount;
+ const long totalOffsetUs =
+ mFramesSinceStart * MICROS_PER_SECOND / mContext.getSampleRate() - totalDurationUs;
+ LOG(VERBOSE) << __func__ << ": totalOffsetUs " << totalOffsetUs;
+ if (totalOffsetUs > 0) {
+ const long sleepTimeUs = std::min(totalOffsetUs, bufferDurationUs);
+ LOG(VERBOSE) << __func__ << ": sleeping for " << sleepTimeUs << " us";
+ usleep(sleepTimeUs);
+ }
+ return ::android::OK;
}
::android::status_t StreamRemoteSubmix::refinePosition(StreamDescriptor::Position* position) {
@@ -189,7 +175,7 @@
// Calculate the maximum size of the pipe buffer in frames for the specified stream.
size_t StreamRemoteSubmix::getStreamPipeSizeInFrames() {
- auto pipeConfig = mCurrentRoute->mPipeConfig;
+ auto pipeConfig = mCurrentRoute->getPipeConfig();
const size_t maxFrameSize = std::max(mStreamConfig.frameSize, pipeConfig.frameSize);
return (pipeConfig.frameCount * pipeConfig.frameSize) / maxFrameSize;
}
@@ -200,12 +186,7 @@
if (sink != nullptr) {
if (sink->isShutdown()) {
sink.clear();
- const auto delayUs = getDelayInUsForFrameCount(frameCount);
- LOG(DEBUG) << __func__ << ": pipe shutdown, ignoring the write, sleeping for "
- << delayUs << " us";
- // the pipe has already been shutdown, this buffer will be lost but we must
- // simulate timing so we don't drain the output faster than realtime
- usleep(delayUs);
+ LOG(DEBUG) << __func__ << ": pipe shutdown, ignoring the write";
*actualFrameCount = frameCount;
return ::android::OK;
}
@@ -214,6 +195,9 @@
return ::android::UNKNOWN_ERROR;
}
+ LOG(VERBOSE) << __func__ << ": " << mDeviceAddress.toString() << ", " << frameCount
+ << " frames";
+
const bool shouldBlockWrite = mCurrentRoute->shouldBlockWrite();
size_t availableToWrite = sink->availableToWrite();
// NOTE: sink has been checked above and sink and source life cycles are synchronized
@@ -236,6 +220,8 @@
availableToWrite = sink->availableToWrite();
if (!shouldBlockWrite && frameCount > availableToWrite) {
+ LOG(WARNING) << __func__ << ": writing " << availableToWrite << " vs. requested "
+ << frameCount;
// Truncate the request to avoid blocking.
frameCount = availableToWrite;
}
@@ -258,92 +244,65 @@
*actualFrameCount = 0;
return ::android::UNKNOWN_ERROR;
}
- LOG(VERBOSE) << __func__ << ": wrote " << writtenFrames << "frames";
+ if (writtenFrames > 0 && frameCount > (size_t)writtenFrames) {
+ LOG(WARNING) << __func__ << ": wrote " << writtenFrames << " vs. requested " << frameCount;
+ }
*actualFrameCount = writtenFrames;
return ::android::OK;
}
::android::status_t StreamRemoteSubmix::inRead(void* buffer, size_t frameCount,
size_t* actualFrameCount) {
+ // in any case, it is emulated that data for the entire buffer was available
+ memset(buffer, 0, mStreamConfig.frameSize * frameCount);
+ *actualFrameCount = frameCount;
+
// about to read from audio source
sp<MonoPipeReader> source = mCurrentRoute->getSource();
if (source == nullptr) {
- int readErrorCount = mCurrentRoute->notifyReadError();
- if (readErrorCount < kMaxReadErrorLogs) {
+ if (++mReadErrorCount < kMaxReadErrorLogs) {
LOG(ERROR) << __func__
<< ": no audio pipe yet we're trying to read! (not all errors will be "
"logged)";
- } else {
- LOG(ERROR) << __func__ << ": Read errors " << readErrorCount;
}
- const auto delayUs = getDelayInUsForFrameCount(frameCount);
- LOG(DEBUG) << __func__ << ": no source, ignoring the read, sleeping for " << delayUs
- << " us";
- usleep(delayUs);
- memset(buffer, 0, mStreamConfig.frameSize * frameCount);
- *actualFrameCount = frameCount;
return ::android::OK;
}
+ mReadErrorCount = 0;
+ LOG(VERBOSE) << __func__ << ": " << mDeviceAddress.toString() << ", " << frameCount
+ << " frames";
// read the data from the pipe
- int attempts = 0;
- const long delayUs = kReadAttemptSleepUs;
char* buff = (char*)buffer;
- size_t remainingFrames = frameCount;
- int availableToRead = source->availableToRead();
-
- while ((remainingFrames > 0) && (availableToRead > 0) && (attempts < kMaxReadFailureAttempts)) {
- LOG(VERBOSE) << __func__ << ": frames available to read " << availableToRead;
-
+ size_t actuallyRead = 0;
+ long remainingFrames = frameCount;
+ const int64_t deadlineTimeNs = ::android::uptimeNanos() +
+ getDelayInUsForFrameCount(frameCount) * NANOS_PER_MICROSECOND;
+ while (remainingFrames > 0) {
ssize_t framesRead = source->read(buff, remainingFrames);
-
LOG(VERBOSE) << __func__ << ": frames read " << framesRead;
-
if (framesRead > 0) {
remainingFrames -= framesRead;
buff += framesRead * mStreamConfig.frameSize;
- availableToRead -= framesRead;
- LOG(VERBOSE) << __func__ << ": (attempts = " << attempts << ") got " << framesRead
+ LOG(VERBOSE) << __func__ << ": got " << framesRead
<< " frames, remaining =" << remainingFrames;
- } else {
- attempts++;
- LOG(WARNING) << __func__ << ": read returned " << framesRead
- << " , read failure attempts = " << attempts << ", sleeping for "
- << delayUs << " us";
- usleep(delayUs);
+ actuallyRead += framesRead;
+ }
+ if (::android::uptimeNanos() >= deadlineTimeNs) break;
+ if (framesRead <= 0) {
+ LOG(VERBOSE) << __func__ << ": read returned " << framesRead
+ << ", read failure, sleeping for " << kReadAttemptSleepUs << " us";
+ usleep(kReadAttemptSleepUs);
}
}
- // done using the source
- source.clear();
-
- if (remainingFrames > 0) {
- const size_t remainingBytes = remainingFrames * mStreamConfig.frameSize;
- LOG(VERBOSE) << __func__ << ": clearing remaining_frames = " << remainingFrames;
- memset(((char*)buffer) + (mStreamConfig.frameSize * frameCount) - remainingBytes, 0,
- remainingBytes);
+ if (actuallyRead < frameCount) {
+ if (++mReadFailureCount < kMaxReadFailureAttempts) {
+ LOG(WARNING) << __func__ << ": read " << actuallyRead << " vs. requested " << frameCount
+ << " (not all errors will be logged)";
+ }
+ } else {
+ mReadFailureCount = 0;
}
-
- long readCounterFrames = mCurrentRoute->updateReadCounterFrames(frameCount);
- *actualFrameCount = frameCount;
-
- // compute how much we need to sleep after reading the data by comparing the wall clock with
- // the projected time at which we should return.
- // wall clock after reading from the pipe
- auto recordDurationUs = std::chrono::duration_cast<std::chrono::microseconds>(
- std::chrono::steady_clock::now() - mCurrentRoute->getRecordStartTime());
-
- // readCounterFrames contains the number of frames that have been read since the beginning of
- // recording (including this call): it's converted to usec and compared to how long we've been
- // recording for, which gives us how long we must wait to sync the projected recording time, and
- // the observed recording time.
- const long projectedVsObservedOffsetUs =
- getDelayInUsForFrameCount(readCounterFrames) - recordDurationUs.count();
-
- LOG(VERBOSE) << __func__ << ": record duration " << recordDurationUs.count()
- << " us, will wait: " << projectedVsObservedOffsetUs << " us";
- if (projectedVsObservedOffsetUs > 0) {
- usleep(projectedVsObservedOffsetUs);
- }
+ mCurrentRoute->updateReadCounterFrames(*actualFrameCount);
return ::android::OK;
}
diff --git a/audio/aidl/default/r_submix/SubmixRoute.cpp b/audio/aidl/default/r_submix/SubmixRoute.cpp
index ddac64d..325a012 100644
--- a/audio/aidl/default/r_submix/SubmixRoute.cpp
+++ b/audio/aidl/default/r_submix/SubmixRoute.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <mutex>
+
#define LOG_TAG "AHAL_SubmixRoute"
#include <android-base/logging.h>
#include <media/AidlConversionCppNdk.h>
@@ -23,9 +25,65 @@
#include "SubmixRoute.h"
using aidl::android::hardware::audio::common::getChannelCount;
+using aidl::android::media::audio::common::AudioDeviceAddress;
namespace aidl::android::hardware::audio::core::r_submix {
+// static
+SubmixRoute::RoutesMonitor SubmixRoute::getRoutes(bool tryLock) {
+ static std::mutex submixRoutesLock;
+ static RoutesMap submixRoutes;
+ return !tryLock ? RoutesMonitor(submixRoutesLock, submixRoutes)
+ : RoutesMonitor(submixRoutesLock, submixRoutes, tryLock);
+}
+
+// static
+std::shared_ptr<SubmixRoute> SubmixRoute::findOrCreateRoute(const AudioDeviceAddress& deviceAddress,
+ const AudioConfig& pipeConfig) {
+ auto routes = getRoutes();
+ auto routeItr = routes->find(deviceAddress);
+ if (routeItr != routes->end()) {
+ return routeItr->second;
+ }
+ auto route = std::make_shared<SubmixRoute>();
+ if (::android::OK != route->createPipe(pipeConfig)) {
+ LOG(ERROR) << __func__ << ": create pipe failed";
+ return nullptr;
+ }
+ routes->emplace(deviceAddress, route);
+ return route;
+}
+
+// static
+std::shared_ptr<SubmixRoute> SubmixRoute::findRoute(const AudioDeviceAddress& deviceAddress) {
+ auto routes = getRoutes();
+ auto routeItr = routes->find(deviceAddress);
+ if (routeItr != routes->end()) {
+ return routeItr->second;
+ }
+ return nullptr;
+}
+
+// static
+void SubmixRoute::removeRoute(const AudioDeviceAddress& deviceAddress) {
+ getRoutes()->erase(deviceAddress);
+}
+
+// static
+std::string SubmixRoute::dumpRoutes() {
+ auto routes = getRoutes(true /*tryLock*/);
+ std::string result;
+ if (routes->empty()) result.append(" <Empty>");
+ for (const auto& r : *(routes.operator->())) {
+ result.append(" - ")
+ .append(r.first.toString())
+ .append(": ")
+ .append(r.second->dump())
+ .append("\n");
+ }
+ return result;
+}
+
// Verify a submix input or output stream can be opened.
bool SubmixRoute::isStreamConfigValid(bool isInput, const AudioConfig& streamConfig) {
// If the stream is already open, don't open it again.
@@ -44,6 +102,7 @@
// Compare this stream config with existing pipe config, returning false if they do *not*
// match, true otherwise.
bool SubmixRoute::isStreamConfigCompatible(const AudioConfig& streamConfig) {
+ std::lock_guard guard(mLock);
if (streamConfig.channelLayout != mPipeConfig.channelLayout) {
LOG(ERROR) << __func__ << ": channel count mismatch, stream channels = "
<< streamConfig.channelLayout.toString()
@@ -81,11 +140,6 @@
return (mStreamInOpen || (mStreamInStandby && (mReadCounterFrames != 0)));
}
-int SubmixRoute::notifyReadError() {
- std::lock_guard guard(mLock);
- return ++mReadErrorCount;
-}
-
long SubmixRoute::updateReadCounterFrames(size_t frameCount) {
std::lock_guard guard(mLock);
mReadCounterFrames += frameCount;
@@ -103,7 +157,9 @@
}
mStreamInStandby = true;
mReadCounterFrames = 0;
- mReadErrorCount = 0;
+ if (mSink != nullptr) {
+ mSink->shutdown(false);
+ }
} else {
mStreamOutOpen = true;
}
@@ -112,8 +168,7 @@
void SubmixRoute::closeStream(bool isInput) {
std::lock_guard guard(mLock);
if (isInput) {
- mInputRefCount--;
- if (mInputRefCount == 0) {
+ if (--mInputRefCount == 0) {
mStreamInOpen = false;
if (mSink != nullptr) {
mSink->shutdown(true);
@@ -166,17 +221,14 @@
LOG(FATAL) << __func__ << ": Negotiation for the source failed, index = " << index;
return ::android::BAD_INDEX;
}
- LOG(VERBOSE) << __func__ << ": created pipe";
-
- mPipeConfig = streamConfig;
- mPipeConfig.frameCount = sink->maxFrames();
-
- LOG(VERBOSE) << __func__ << ": Pipe frame size : " << mPipeConfig.frameSize
- << ", pipe frames : " << mPipeConfig.frameCount;
+ LOG(VERBOSE) << __func__ << ": Pipe frame size : " << streamConfig.frameSize
+ << ", pipe frames : " << sink->maxFrames();
// Save references to the source and sink.
{
std::lock_guard guard(mLock);
+ mPipeConfig = streamConfig;
+ mPipeConfig.frameCount = sink->maxFrames();
mSink = std::move(sink);
mSource = std::move(source);
}
@@ -185,15 +237,15 @@
}
// Release references to the sink and source.
-void SubmixRoute::releasePipe() {
+AudioConfig SubmixRoute::releasePipe() {
std::lock_guard guard(mLock);
mSink.clear();
mSource.clear();
+ return mPipeConfig;
}
::android::status_t SubmixRoute::resetPipe() {
- releasePipe();
- return createPipe(mPipeConfig);
+ return createPipe(releasePipe());
}
void SubmixRoute::standby(bool isInput) {
@@ -214,9 +266,6 @@
if (mStreamInStandby || mStreamOutStandbyTransition) {
mStreamInStandby = false;
mStreamOutStandbyTransition = false;
- // keep track of when we exit input standby (== first read == start "real recording")
- // or when we start recording silence, and reset projected time
- mRecordStartTime = std::chrono::steady_clock::now();
mReadCounterFrames = 0;
}
} else {
@@ -227,4 +276,23 @@
}
}
+std::string SubmixRoute::dump() NO_THREAD_SAFETY_ANALYSIS {
+ const bool isLocked = mLock.try_lock();
+ std::string result = std::string(isLocked ? "" : "! ")
+ .append("Input ")
+ .append(mStreamInOpen ? "open" : "closed")
+ .append(mStreamInStandby ? ", standby" : ", active")
+ .append(", refcount: ")
+ .append(std::to_string(mInputRefCount))
+ .append(", framesRead: ")
+ .append(mSource ? std::to_string(mSource->framesRead()) : "<null>")
+ .append("; Output ")
+ .append(mStreamOutOpen ? "open" : "closed")
+ .append(mStreamOutStandby ? ", standby" : ", active")
+ .append(", framesWritten: ")
+ .append(mSink ? std::to_string(mSink->framesWritten()) : "<null>");
+ if (isLocked) mLock.unlock();
+ return result;
+}
+
} // namespace aidl::android::hardware::audio::core::r_submix
diff --git a/audio/aidl/default/r_submix/SubmixRoute.h b/audio/aidl/default/r_submix/SubmixRoute.h
index 92b95e9..5425f12 100644
--- a/audio/aidl/default/r_submix/SubmixRoute.h
+++ b/audio/aidl/default/r_submix/SubmixRoute.h
@@ -16,8 +16,8 @@
#pragma once
-#include <chrono>
#include <mutex>
+#include <string>
#include <android-base/thread_annotations.h>
#include <audio_utils/clock.h>
@@ -26,6 +26,7 @@
#include <media/nbaio/MonoPipeReader.h>
#include <aidl/android/media/audio/common/AudioChannelLayout.h>
+#include <aidl/android/media/audio/common/AudioDeviceAddress.h>
#include <aidl/android/media/audio/common/AudioFormatDescription.h>
using aidl::android::media::audio::common::AudioChannelLayout;
@@ -61,7 +62,14 @@
class SubmixRoute {
public:
- AudioConfig mPipeConfig;
+ static std::shared_ptr<SubmixRoute> findOrCreateRoute(
+ const ::aidl::android::media::audio::common::AudioDeviceAddress& deviceAddress,
+ const AudioConfig& pipeConfig);
+ static std::shared_ptr<SubmixRoute> findRoute(
+ const ::aidl::android::media::audio::common::AudioDeviceAddress& deviceAddress);
+ static void removeRoute(
+ const ::aidl::android::media::audio::common::AudioDeviceAddress& deviceAddress);
+ static std::string dumpRoutes();
bool isStreamInOpen() {
std::lock_guard guard(mLock);
@@ -83,14 +91,6 @@
std::lock_guard guard(mLock);
return mReadCounterFrames;
}
- int getReadErrorCount() {
- std::lock_guard guard(mLock);
- return mReadErrorCount;
- }
- std::chrono::time_point<std::chrono::steady_clock> getRecordStartTime() {
- std::lock_guard guard(mLock);
- return mRecordStartTime;
- }
sp<MonoPipe> getSink() {
std::lock_guard guard(mLock);
return mSink;
@@ -99,6 +99,10 @@
std::lock_guard guard(mLock);
return mSource;
}
+ AudioConfig getPipeConfig() {
+ std::lock_guard guard(mLock);
+ return mPipeConfig;
+ }
bool isStreamConfigValid(bool isInput, const AudioConfig& streamConfig);
void closeStream(bool isInput);
@@ -107,17 +111,35 @@
bool hasAtleastOneStreamOpen();
int notifyReadError();
void openStream(bool isInput);
- void releasePipe();
+ AudioConfig releasePipe();
::android::status_t resetPipe();
bool shouldBlockWrite();
void standby(bool isInput);
long updateReadCounterFrames(size_t frameCount);
+ std::string dump();
+
private:
+ using RoutesMap = std::map<::aidl::android::media::audio::common::AudioDeviceAddress,
+ std::shared_ptr<r_submix::SubmixRoute>>;
+ class RoutesMonitor {
+ public:
+ RoutesMonitor(std::mutex& mutex, RoutesMap& routes) : mLock(mutex), mRoutes(routes) {}
+ RoutesMonitor(std::mutex& mutex, RoutesMap& routes, bool /*tryLock*/)
+ : mLock(mutex, std::try_to_lock), mRoutes(routes) {}
+ RoutesMap* operator->() { return &mRoutes; }
+
+ private:
+ std::unique_lock<std::mutex> mLock;
+ RoutesMap& mRoutes;
+ };
+
+ static RoutesMonitor getRoutes(bool tryLock = false);
+
bool isStreamConfigCompatible(const AudioConfig& streamConfig);
std::mutex mLock;
-
+ AudioConfig mPipeConfig GUARDED_BY(mLock);
bool mStreamInOpen GUARDED_BY(mLock) = false;
int mInputRefCount GUARDED_BY(mLock) = 0;
bool mStreamInStandby GUARDED_BY(mLock) = true;
@@ -126,9 +148,6 @@
bool mStreamOutStandby GUARDED_BY(mLock) = true;
// how many frames have been requested to be read since standby
long mReadCounterFrames GUARDED_BY(mLock) = 0;
- int mReadErrorCount GUARDED_BY(mLock) = 0;
- // wall clock when recording starts
- std::chrono::time_point<std::chrono::steady_clock> mRecordStartTime GUARDED_BY(mLock);
// Pipe variables: they handle the ring buffer that "pipes" audio:
// - from the submix virtual audio output == what needs to be played
diff --git a/health/2.0/utils/libhealthstoragedefault/Android.bp b/audio/aidl/default/spatializer/Android.bp
similarity index 66%
rename from health/2.0/utils/libhealthstoragedefault/Android.bp
rename to audio/aidl/default/spatializer/Android.bp
index 3de8789..2c229fe 100644
--- a/health/2.0/utils/libhealthstoragedefault/Android.bp
+++ b/audio/aidl/default/spatializer/Android.bp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,10 +14,8 @@
* limitations under the License.
*/
-// Default implementation for (passthrough) clients that statically links to
-// android.hardware.health@2.0-impl but do no query for storage related
-// information.
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -26,13 +24,17 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
-cc_library_static {
- srcs: ["StorageHealthDefault.cpp"],
- name: "libhealthstoragedefault",
- vendor_available: true,
- recovery_available: true,
- cflags: ["-Werror"],
- shared_libs: [
- "android.hardware.health@2.0",
+cc_library_shared {
+ name: "libspatializersw",
+ defaults: [
+ "aidlaudioeffectservice_defaults",
+ ],
+ srcs: [
+ "SpatializerSw.cpp",
+ ":effectCommonFile",
+ ],
+ relative_install_path: "soundfx",
+ visibility: [
+ "//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}
diff --git a/audio/aidl/default/spatializer/SpatializerSw.cpp b/audio/aidl/default/spatializer/SpatializerSw.cpp
new file mode 100644
index 0000000..ef86ddb
--- /dev/null
+++ b/audio/aidl/default/spatializer/SpatializerSw.cpp
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AHAL_SpatializerSw"
+
+#include "SpatializerSw.h"
+
+#include <android-base/logging.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include <optional>
+
+using aidl::android::hardware::audio::common::getChannelCount;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidSpatializerSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidSpatializer;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::SpatializerSw;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::media::audio::common::AudioChannelLayout;
+using aidl::android::media::audio::common::AudioUuid;
+using aidl::android::media::audio::common::HeadTracking;
+using aidl::android::media::audio::common::Spatialization;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+ std::shared_ptr<IEffect>* instanceSpp) {
+ if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidSpatializerSw()) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ if (!instanceSpp) {
+ LOG(ERROR) << __func__ << " invalid input parameter!";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+
+ *instanceSpp = ndk::SharedRefBase::make<SpatializerSw>();
+ LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+ return EX_NONE;
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+ if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidSpatializerSw()) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ *_aidl_return = SpatializerSw::kDescriptor;
+ return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string SpatializerSw::kEffectName = "SpatializerSw";
+
+const std::vector<Range::SpatializerRange> SpatializerSw::kRanges = {
+ MAKE_RANGE(Spatializer, supportedChannelLayout, std::vector<AudioChannelLayout>{},
+ std::vector<AudioChannelLayout>{}),
+ MAKE_RANGE(Spatializer, spatializationLevel, Spatialization::Level::NONE,
+ Spatialization::Level::BED_PLUS_OBJECTS),
+ MAKE_RANGE(Spatializer, spatializationMode, Spatialization::Mode::BINAURAL,
+ Spatialization::Mode::TRANSAURAL),
+ MAKE_RANGE(Spatializer, headTrackingSensorId, std::numeric_limits<int>::min(),
+ std::numeric_limits<int>::max()),
+ MAKE_RANGE(Spatializer, headTrackingMode, HeadTracking::Mode::OTHER,
+ HeadTracking::Mode::RELATIVE_SCREEN),
+ MAKE_RANGE(Spatializer, headTrackingConnectionMode,
+ HeadTracking::ConnectionMode::FRAMEWORK_PROCESSED,
+ HeadTracking::ConnectionMode::DIRECT_TO_SENSOR_TUNNEL)};
+const Capability SpatializerSw::kCapability = {.range = {SpatializerSw::kRanges}};
+const Descriptor SpatializerSw::kDescriptor = {
+ .common = {.id = {.type = getEffectTypeUuidSpatializer(),
+ .uuid = getEffectImplUuidSpatializerSw()},
+ .flags = {.type = Flags::Type::INSERT,
+ .insert = Flags::Insert::FIRST,
+ .hwAcceleratorMode = Flags::HardwareAccelerator::NONE},
+ .name = SpatializerSw::kEffectName,
+ .implementor = "The Android Open Source Project"},
+ .capability = SpatializerSw::kCapability};
+
+ndk::ScopedAStatus SpatializerSw::getDescriptor(Descriptor* _aidl_return) {
+ LOG(DEBUG) << __func__ << kDescriptor.toString();
+ *_aidl_return = kDescriptor;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus SpatializerSw::setParameterSpecific(const Parameter::Specific& specific) {
+ RETURN_IF(Parameter::Specific::spatializer != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+ "EffectNotSupported");
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+ auto& param = specific.get<Parameter::Specific::spatializer>();
+ RETURN_IF(!inRange(param, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
+
+ return mContext->setParam(param.getTag(), param);
+}
+
+ndk::ScopedAStatus SpatializerSw::getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) {
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+ auto tag = id.getTag();
+ RETURN_IF(Parameter::Id::spatializerTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+ auto spatializerId = id.get<Parameter::Id::spatializerTag>();
+ auto spatializerTag = spatializerId.getTag();
+ switch (spatializerTag) {
+ case Spatializer::Id::commonTag: {
+ auto specificTag = spatializerId.get<Spatializer::Id::commonTag>();
+ std::optional<Spatializer> param = mContext->getParam(specificTag);
+ if (!param.has_value()) {
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "SpatializerTagNotSupported");
+ }
+ specific->set<Parameter::Specific::spatializer>(param.value());
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "SpatializerTagNotSupported");
+ }
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> SpatializerSw::createContext(const Parameter::Common& common) {
+ if (mContext) {
+ LOG(DEBUG) << __func__ << " context already exist";
+ } else {
+ mContext = std::make_shared<SpatializerSwContext>(1 /* statusFmqDepth */, common);
+ }
+ return mContext;
+}
+
+RetCode SpatializerSw::releaseContext() {
+ if (mContext) {
+ mContext.reset();
+ }
+ return RetCode::SUCCESS;
+}
+
+SpatializerSw::~SpatializerSw() {
+ cleanUp();
+ LOG(DEBUG) << __func__;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status SpatializerSw::effectProcessImpl(float* in, float* out, int samples) {
+ RETURN_VALUE_IF(!mContext, (IEffect::Status{EX_NULL_POINTER, 0, 0}), "nullContext");
+ return mContext->process(in, out, samples);
+}
+
+SpatializerSwContext::SpatializerSwContext(int statusDepth, const Parameter::Common& common)
+ : EffectContext(statusDepth, common) {
+ LOG(DEBUG) << __func__;
+}
+
+SpatializerSwContext::~SpatializerSwContext() {
+ LOG(DEBUG) << __func__;
+}
+
+template <typename TAG>
+std::optional<Spatializer> SpatializerSwContext::getParam(TAG tag) {
+ if (mParamsMap.find(tag) != mParamsMap.end()) {
+ return mParamsMap.at(tag);
+ }
+ return std::nullopt;
+}
+
+template <typename TAG>
+ndk::ScopedAStatus SpatializerSwContext::setParam(TAG tag, Spatializer spatializer) {
+ mParamsMap[tag] = spatializer;
+ return ndk::ScopedAStatus::ok();
+}
+
+IEffect::Status SpatializerSwContext::process(float* in, float* out, int samples) {
+ LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+ IEffect::Status status = {EX_ILLEGAL_ARGUMENT, 0, 0};
+
+ const auto inputChannelCount = getChannelCount(mCommon.input.base.channelMask);
+ const auto outputChannelCount = getChannelCount(mCommon.output.base.channelMask);
+ if (outputChannelCount < 2 || inputChannelCount < outputChannelCount) {
+ LOG(ERROR) << __func__ << " invalid channel count, in: " << inputChannelCount
+ << " out: " << outputChannelCount;
+ return status;
+ }
+
+ int iFrames = samples / inputChannelCount;
+ for (int i = 0; i < iFrames; i++) {
+ std::memcpy(out, in, outputChannelCount);
+ in += inputChannelCount;
+ out += outputChannelCount;
+ }
+ return {STATUS_OK, static_cast<int32_t>(iFrames * inputChannelCount),
+ static_cast<int32_t>(iFrames * outputChannelCount)};
+}
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/spatializer/SpatializerSw.h b/audio/aidl/default/spatializer/SpatializerSw.h
new file mode 100644
index 0000000..b321e83
--- /dev/null
+++ b/audio/aidl/default/spatializer/SpatializerSw.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "effect-impl/EffectContext.h"
+#include "effect-impl/EffectImpl.h"
+
+#include <fmq/AidlMessageQueue.h>
+
+#include <unordered_map>
+#include <vector>
+
+namespace aidl::android::hardware::audio::effect {
+
+class SpatializerSwContext final : public EffectContext {
+ public:
+ SpatializerSwContext(int statusDepth, const Parameter::Common& common);
+ ~SpatializerSwContext();
+
+ template <typename TAG>
+ std::optional<Spatializer> getParam(TAG tag);
+ template <typename TAG>
+ ndk::ScopedAStatus setParam(TAG tag, Spatializer spatializer);
+
+ IEffect::Status process(float* in, float* out, int samples);
+
+ private:
+ std::unordered_map<Spatializer::Tag, Spatializer> mParamsMap;
+};
+
+class SpatializerSw final : public EffectImpl {
+ public:
+ static const std::string kEffectName;
+ static const Capability kCapability;
+ static const Descriptor kDescriptor;
+ ~SpatializerSw();
+
+ ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+ REQUIRES(mImplMutex) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+ REQUIRES(mImplMutex) override;
+
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+ REQUIRES(mImplMutex) override;
+ RetCode releaseContext() REQUIRES(mImplMutex) override;
+
+ std::string getEffectName() override { return kEffectName; };
+ IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+ REQUIRES(mImplMutex) override;
+
+ private:
+ static const std::vector<Range::SpatializerRange> kRanges;
+ std::shared_ptr<SpatializerSwContext> mContext GUARDED_BY(mImplMutex) = nullptr;
+};
+} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/usb/ModuleUsb.cpp b/audio/aidl/default/usb/ModuleUsb.cpp
index f926e09..1d97bc4 100644
--- a/audio/aidl/default/usb/ModuleUsb.cpp
+++ b/audio/aidl/default/usb/ModuleUsb.cpp
@@ -87,12 +87,13 @@
offloadInfo);
}
-ndk::ScopedAStatus ModuleUsb::populateConnectedDevicePort(AudioPort* audioPort) {
+ndk::ScopedAStatus ModuleUsb::populateConnectedDevicePort(AudioPort* audioPort,
+ int32_t nextPortId) {
if (!isUsbDevicePort(*audioPort)) {
LOG(ERROR) << __func__ << ": port id " << audioPort->id << " is not a usb device port";
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
- return ModuleAlsa::populateConnectedDevicePort(audioPort);
+ return ModuleAlsa::populateConnectedDevicePort(audioPort, nextPortId);
}
ndk::ScopedAStatus ModuleUsb::checkAudioPatchEndpointsMatch(
diff --git a/audio/aidl/default/virtualizer/Android.bp b/audio/aidl/default/virtualizer/Android.bp
index ed0199d..91d2abb 100644
--- a/audio/aidl/default/virtualizer/Android.bp
+++ b/audio/aidl/default/virtualizer/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -27,8 +28,6 @@
name: "libvirtualizersw",
defaults: [
"aidlaudioeffectservice_defaults",
- "latest_android_media_audio_common_types_ndk_shared",
- "latest_android_hardware_audio_effect_ndk_shared",
],
srcs: [
"VirtualizerSw.cpp",
@@ -36,6 +35,6 @@
],
relative_install_path: "soundfx",
visibility: [
- "//hardware/interfaces/audio/aidl/default",
+ "//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}
diff --git a/audio/aidl/default/virtualizer/VirtualizerSw.cpp b/audio/aidl/default/virtualizer/VirtualizerSw.cpp
index 0e8435e..091b0b7 100644
--- a/audio/aidl/default/virtualizer/VirtualizerSw.cpp
+++ b/audio/aidl/default/virtualizer/VirtualizerSw.cpp
@@ -203,10 +203,6 @@
return mContext;
}
-std::shared_ptr<EffectContext> VirtualizerSw::getContext() {
- return mContext;
-}
-
RetCode VirtualizerSw::releaseContext() {
if (mContext) {
mContext.reset();
diff --git a/audio/aidl/default/virtualizer/VirtualizerSw.h b/audio/aidl/default/virtualizer/VirtualizerSw.h
index 5e114d9..9287838 100644
--- a/audio/aidl/default/virtualizer/VirtualizerSw.h
+++ b/audio/aidl/default/virtualizer/VirtualizerSw.h
@@ -59,24 +59,25 @@
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
- ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
- ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
- Parameter::Specific* specific) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+ REQUIRES(mImplMutex) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+ REQUIRES(mImplMutex) override;
- std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
- std::shared_ptr<EffectContext> getContext() override;
- RetCode releaseContext() override;
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+ REQUIRES(mImplMutex) override;
+ RetCode releaseContext() REQUIRES(mImplMutex) override;
IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
std::string getEffectName() override { return kEffectName; }
private:
static const std::vector<Range::VirtualizerRange> kRanges;
- std::shared_ptr<VirtualizerSwContext> mContext;
+ std::shared_ptr<VirtualizerSwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterVirtualizer(const Virtualizer::Tag& tag,
- Parameter::Specific* specific);
+ Parameter::Specific* specific) REQUIRES(mImplMutex);
ndk::ScopedAStatus getSpeakerAngles(const Virtualizer::SpeakerAnglesPayload payload,
- Parameter::Specific* specific);
+ Parameter::Specific* specific) REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/visualizer/Android.bp b/audio/aidl/default/visualizer/Android.bp
index 091daa2..af8f574 100644
--- a/audio/aidl/default/visualizer/Android.bp
+++ b/audio/aidl/default/visualizer/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -27,8 +28,6 @@
name: "libvisualizersw",
defaults: [
"aidlaudioeffectservice_defaults",
- "latest_android_media_audio_common_types_ndk_shared",
- "latest_android_hardware_audio_effect_ndk_shared",
],
srcs: [
"VisualizerSw.cpp",
diff --git a/audio/aidl/default/visualizer/VisualizerSw.cpp b/audio/aidl/default/visualizer/VisualizerSw.cpp
index 0909f25..54f7f1c 100644
--- a/audio/aidl/default/visualizer/VisualizerSw.cpp
+++ b/audio/aidl/default/visualizer/VisualizerSw.cpp
@@ -73,7 +73,7 @@
.proxy = std::nullopt},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
- .volume = Flags::Volume::CTRL},
+ .volume = Flags::Volume::NONE},
.name = VisualizerSw::kEffectName,
.implementor = "The Android Open Source Project"},
.capability = VisualizerSw::kCapability};
@@ -190,10 +190,6 @@
return mContext;
}
-std::shared_ptr<EffectContext> VisualizerSw::getContext() {
- return mContext;
-}
-
RetCode VisualizerSw::releaseContext() {
if (mContext) {
mContext.reset();
diff --git a/audio/aidl/default/visualizer/VisualizerSw.h b/audio/aidl/default/visualizer/VisualizerSw.h
index 995774e..819351a 100644
--- a/audio/aidl/default/visualizer/VisualizerSw.h
+++ b/audio/aidl/default/visualizer/VisualizerSw.h
@@ -19,20 +19,22 @@
#include <vector>
#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <system/audio_effects/effect_visualizer.h>
#include "effect-impl/EffectImpl.h"
namespace aidl::android::hardware::audio::effect {
class VisualizerSwContext final : public EffectContext {
public:
- static const int kMinCaptureSize = 0x80;
- static const int kMaxCaptureSize = 0x400;
- static const int kMaxLatencyMs = 3000;
- static const int kMaxCaptureBufSize = 0xffff;
+ // need align the min/max capture size to VISUALIZER_CAPTURE_SIZE_MIN and
+ // VISUALIZER_CAPTURE_SIZE_MAX because of limitation in audio_utils fixedfft.
+ static constexpr int32_t kMinCaptureSize = VISUALIZER_CAPTURE_SIZE_MIN;
+ static constexpr int32_t kMaxCaptureSize = VISUALIZER_CAPTURE_SIZE_MAX;
+ static constexpr int32_t kMaxLatencyMs = 3000;
VisualizerSwContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
- mCaptureSampleBuffer.resize(kMaxCaptureBufSize);
+ mCaptureSampleBuffer.resize(kMaxCaptureSize);
fill(mCaptureSampleBuffer.begin(), mCaptureSampleBuffer.end(), 0x80);
}
@@ -72,21 +74,23 @@
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
- ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
- ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
- Parameter::Specific* specific) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+ REQUIRES(mImplMutex) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+ REQUIRES(mImplMutex) override;
- std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
- std::shared_ptr<EffectContext> getContext() override;
- RetCode releaseContext() override;
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+ REQUIRES(mImplMutex) override;
+ RetCode releaseContext() REQUIRES(mImplMutex) override;
- IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+ IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+ REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; }
private:
static const std::vector<Range::VisualizerRange> kRanges;
- std::shared_ptr<VisualizerSwContext> mContext;
+ std::shared_ptr<VisualizerSwContext> mContext GUARDED_BY(mImplMutex);
ndk::ScopedAStatus getParameterVisualizer(const Visualizer::Tag& tag,
- Parameter::Specific* specific);
+ Parameter::Specific* specific) REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/volume/Android.bp b/audio/aidl/default/volume/Android.bp
index 418bb8d..a424f7e 100644
--- a/audio/aidl/default/volume/Android.bp
+++ b/audio/aidl/default/volume/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -27,8 +28,6 @@
name: "libvolumesw",
defaults: [
"aidlaudioeffectservice_defaults",
- "latest_android_media_audio_common_types_ndk_shared",
- "latest_android_hardware_audio_effect_ndk_shared",
],
srcs: [
"VolumeSw.cpp",
@@ -36,6 +35,6 @@
],
relative_install_path: "soundfx",
visibility: [
- "//hardware/interfaces/audio/aidl/default",
+ "//hardware/interfaces/audio/aidl/default:__subpackages__",
],
}
diff --git a/audio/aidl/default/volume/VolumeSw.cpp b/audio/aidl/default/volume/VolumeSw.cpp
index 8902584..dd019f6 100644
--- a/audio/aidl/default/volume/VolumeSw.cpp
+++ b/audio/aidl/default/volume/VolumeSw.cpp
@@ -160,10 +160,6 @@
return mContext;
}
-std::shared_ptr<EffectContext> VolumeSw::getContext() {
- return mContext;
-}
-
RetCode VolumeSw::releaseContext() {
if (mContext) {
mContext.reset();
diff --git a/audio/aidl/default/volume/VolumeSw.h b/audio/aidl/default/volume/VolumeSw.h
index 1432b2b..3fc0d97 100644
--- a/audio/aidl/default/volume/VolumeSw.h
+++ b/audio/aidl/default/volume/VolumeSw.h
@@ -57,21 +57,24 @@
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
- ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
- ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
- Parameter::Specific* specific) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
+ REQUIRES(mImplMutex) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
+ REQUIRES(mImplMutex) override;
- std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
- std::shared_ptr<EffectContext> getContext() override;
- RetCode releaseContext() override;
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)
+ REQUIRES(mImplMutex) override;
+ RetCode releaseContext() REQUIRES(mImplMutex) override;
- IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+ IEffect::Status effectProcessImpl(float* in, float* out, int samples)
+ REQUIRES(mImplMutex) override;
std::string getEffectName() override { return kEffectName; }
private:
static const std::vector<Range::VolumeRange> kRanges;
- std::shared_ptr<VolumeSwContext> mContext;
+ std::shared_ptr<VolumeSwContext> mContext GUARDED_BY(mImplMutex);
- ndk::ScopedAStatus getParameterVolume(const Volume::Tag& tag, Parameter::Specific* specific);
+ ndk::ScopedAStatus getParameterVolume(const Volume::Tag& tag, Parameter::Specific* specific)
+ REQUIRES(mImplMutex);
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/sounddose/vts/Android.bp b/audio/aidl/sounddose/vts/Android.bp
index 88be968..b852287 100644
--- a/audio/aidl/sounddose/vts/Android.bp
+++ b/audio/aidl/sounddose/vts/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/aidl/vts/Android.bp b/audio/aidl/vts/Android.bp
index ad816c7..5218fdd 100644
--- a/audio/aidl/vts/Android.bp
+++ b/audio/aidl/vts/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -36,16 +37,27 @@
"-Werror",
"-Wthread-safety",
],
+ test_config_template: "VtsHalAudioTargetTestTemplate.xml",
test_suites: [
"general-tests",
"vts",
],
srcs: [
- ":effectCommonFile",
"TestUtils.cpp",
],
}
+cc_defaults {
+ name: "VtsHalAudioEffectTargetTestDefaults",
+ defaults: [
+ "latest_android_hardware_audio_effect_ndk_static",
+ "VtsHalAudioTargetTestDefaults",
+ ],
+ srcs: [
+ ":effectCommonFile",
+ ],
+}
+
cc_test {
name: "VtsHalAudioCoreTargetTest",
defaults: [
@@ -61,108 +73,122 @@
"VtsHalAudioCoreConfigTargetTest.cpp",
"VtsHalAudioCoreModuleTargetTest.cpp",
],
- test_config: "VtsHalAudioCoreTargetTest.xml",
}
cc_test {
name: "VtsHalAudioEffectFactoryTargetTest",
- defaults: ["VtsHalAudioTargetTestDefaults"],
+ defaults: ["VtsHalAudioEffectTargetTestDefaults"],
srcs: ["VtsHalAudioEffectFactoryTargetTest.cpp"],
}
cc_test {
name: "VtsHalAudioEffectTargetTest",
- defaults: ["VtsHalAudioTargetTestDefaults"],
+ defaults: ["VtsHalAudioEffectTargetTestDefaults"],
srcs: ["VtsHalAudioEffectTargetTest.cpp"],
}
cc_test {
name: "VtsHalBassBoostTargetTest",
- defaults: ["VtsHalAudioTargetTestDefaults"],
+ defaults: ["VtsHalAudioEffectTargetTestDefaults"],
srcs: ["VtsHalBassBoostTargetTest.cpp"],
+ cflags: [
+ "-Wno-error=unused-parameter",
+ ],
+ static_libs: [
+ "libpffft",
+ ],
}
cc_test {
name: "VtsHalDownmixTargetTest",
- defaults: ["VtsHalAudioTargetTestDefaults"],
+ defaults: ["VtsHalAudioEffectTargetTestDefaults"],
srcs: ["VtsHalDownmixTargetTest.cpp"],
+ shared_libs: [
+ "libaudioutils",
+ ],
}
cc_test {
name: "VtsHalDynamicsProcessingTargetTest",
- defaults: ["VtsHalAudioTargetTestDefaults"],
+ defaults: ["VtsHalAudioEffectTargetTestDefaults"],
static_libs: ["libaudioaidlranges"],
srcs: ["VtsHalDynamicsProcessingTest.cpp"],
}
cc_test {
name: "VtsHalEnvironmentalReverbTargetTest",
- defaults: ["VtsHalAudioTargetTestDefaults"],
+ defaults: ["VtsHalAudioEffectTargetTestDefaults"],
srcs: ["VtsHalEnvironmentalReverbTargetTest.cpp"],
}
cc_test {
name: "VtsHalEqualizerTargetTest",
- defaults: ["VtsHalAudioTargetTestDefaults"],
+ defaults: ["VtsHalAudioEffectTargetTestDefaults"],
srcs: ["VtsHalEqualizerTargetTest.cpp"],
}
cc_test {
name: "VtsHalHapticGeneratorTargetTest",
- defaults: ["VtsHalAudioTargetTestDefaults"],
+ defaults: ["VtsHalAudioEffectTargetTestDefaults"],
srcs: ["VtsHalHapticGeneratorTargetTest.cpp"],
}
cc_test {
name: "VtsHalLoudnessEnhancerTargetTest",
- defaults: ["VtsHalAudioTargetTestDefaults"],
+ defaults: ["VtsHalAudioEffectTargetTestDefaults"],
srcs: ["VtsHalLoudnessEnhancerTargetTest.cpp"],
}
cc_test {
name: "VtsHalPresetReverbTargetTest",
- defaults: ["VtsHalAudioTargetTestDefaults"],
+ defaults: ["VtsHalAudioEffectTargetTestDefaults"],
srcs: ["VtsHalPresetReverbTargetTest.cpp"],
}
cc_test {
name: "VtsHalVirtualizerTargetTest",
- defaults: ["VtsHalAudioTargetTestDefaults"],
+ defaults: ["VtsHalAudioEffectTargetTestDefaults"],
srcs: ["VtsHalVirtualizerTargetTest.cpp"],
}
cc_test {
name: "VtsHalVisualizerTargetTest",
- defaults: ["VtsHalAudioTargetTestDefaults"],
+ defaults: ["VtsHalAudioEffectTargetTestDefaults"],
srcs: ["VtsHalVisualizerTargetTest.cpp"],
}
cc_test {
name: "VtsHalVolumeTargetTest",
- defaults: ["VtsHalAudioTargetTestDefaults"],
+ defaults: ["VtsHalAudioEffectTargetTestDefaults"],
srcs: ["VtsHalVolumeTargetTest.cpp"],
}
cc_test {
name: "VtsHalAECTargetTest",
- defaults: ["VtsHalAudioTargetTestDefaults"],
+ defaults: ["VtsHalAudioEffectTargetTestDefaults"],
srcs: ["VtsHalAECTargetTest.cpp"],
}
cc_test {
name: "VtsHalAGC1TargetTest",
- defaults: ["VtsHalAudioTargetTestDefaults"],
+ defaults: ["VtsHalAudioEffectTargetTestDefaults"],
srcs: ["VtsHalAGC1TargetTest.cpp"],
}
cc_test {
name: "VtsHalAGC2TargetTest",
- defaults: ["VtsHalAudioTargetTestDefaults"],
+ defaults: ["VtsHalAudioEffectTargetTestDefaults"],
srcs: ["VtsHalAGC2TargetTest.cpp"],
}
cc_test {
name: "VtsHalNSTargetTest",
- defaults: ["VtsHalAudioTargetTestDefaults"],
+ defaults: ["VtsHalAudioEffectTargetTestDefaults"],
srcs: ["VtsHalNSTargetTest.cpp"],
}
+
+cc_test {
+ name: "VtsHalSpatializerTargetTest",
+ defaults: ["VtsHalAudioEffectTargetTestDefaults"],
+ srcs: ["VtsHalSpatializerTargetTest.cpp"],
+}
diff --git a/audio/aidl/vts/EffectFactoryHelper.h b/audio/aidl/vts/EffectFactoryHelper.h
index a2499fd..7100431 100644
--- a/audio/aidl/vts/EffectFactoryHelper.h
+++ b/audio/aidl/vts/EffectFactoryHelper.h
@@ -21,8 +21,10 @@
#include <unordered_map>
#include <vector>
+#include <aidl/Vintf.h>
#include <android/binder_auto_utils.h>
+#include "AudioHalBinderServiceUtil.h"
#include "TestUtils.h"
using namespace android;
diff --git a/audio/aidl/vts/EffectHelper.h b/audio/aidl/vts/EffectHelper.h
index 2c8edf2..0be4e50 100644
--- a/audio/aidl/vts/EffectHelper.h
+++ b/audio/aidl/vts/EffectHelper.h
@@ -21,6 +21,7 @@
#include <string>
#include <type_traits>
#include <unordered_map>
+#include <utility>
#include <vector>
#include <Utils.h>
@@ -34,7 +35,6 @@
#include <system/audio_effects/aidl_effects_utils.h>
#include <system/audio_effects/effect_uuid.h>
-#include "AudioHalBinderServiceUtil.h"
#include "EffectFactoryHelper.h"
#include "TestUtils.h"
@@ -42,6 +42,7 @@
using aidl::android::hardware::audio::effect::CommandId;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kEventFlagDataMqUpdate;
using aidl::android::hardware::audio::effect::kEventFlagNotEmpty;
using aidl::android::hardware::audio::effect::Parameter;
using aidl::android::hardware::audio::effect::Range;
@@ -190,6 +191,16 @@
ASSERT_TRUE(dataMq->read(buffer.data(), expectFloats));
}
}
+ static void expectDataMqUpdateEventFlag(std::unique_ptr<StatusMQ>& statusMq) {
+ EventFlag* efGroup;
+ ASSERT_EQ(::android::OK,
+ EventFlag::createEventFlag(statusMq->getEventFlagWord(), &efGroup));
+ ASSERT_NE(nullptr, efGroup);
+ uint32_t efState = 0;
+ EXPECT_EQ(::android::OK, efGroup->wait(kEventFlagDataMqUpdate, &efState, 1'000'000 /*1ms*/,
+ true /* retry */));
+ EXPECT_TRUE(efState & kEventFlagDataMqUpdate);
+ }
static Parameter::Common createParamCommon(
int session = 0, int ioHandle = -1, int iSampleRate = 48000, int oSampleRate = 48000,
long iFrameCount = 0x100, long oFrameCount = 0x100,
@@ -263,12 +274,11 @@
return s;
}
- template <typename T, typename S, Range::Tag R, typename T::Tag tag, typename Functor>
+ template <typename T, typename S, Range::Tag R, typename T::Tag tag>
static std::set<S> getTestValueSet(
- std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList,
- Functor functor) {
+ std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> descList) {
std::set<S> result;
- for (const auto& [_, desc] : kFactoryDescList) {
+ for (const auto& [_, desc] : descList) {
if (desc.capability.range.getTag() == R) {
const auto& ranges = desc.capability.range.get<R>();
for (const auto& range : ranges) {
@@ -281,6 +291,42 @@
}
}
}
+ return result;
+ }
+
+ template <typename T, typename S, Range::Tag R, typename T::Tag tag, typename Functor>
+ static std::set<S> getTestValueSet(
+ std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> descList,
+ Functor functor) {
+ auto result = getTestValueSet<T, S, R, tag>(descList);
return functor(result);
}
+
+ static void processAndWriteToOutput(std::vector<float>& inputBuffer,
+ std::vector<float>& outputBuffer,
+ const std::shared_ptr<IEffect>& mEffect,
+ IEffect::OpenEffectReturn* mOpenEffectReturn) {
+ // Initialize AidlMessagequeues
+ auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(mOpenEffectReturn->statusMQ);
+ ASSERT_TRUE(statusMQ->isValid());
+ auto inputMQ = std::make_unique<EffectHelper::DataMQ>(mOpenEffectReturn->inputDataMQ);
+ ASSERT_TRUE(inputMQ->isValid());
+ auto outputMQ = std::make_unique<EffectHelper::DataMQ>(mOpenEffectReturn->outputDataMQ);
+ ASSERT_TRUE(outputMQ->isValid());
+
+ // Enabling the process
+ ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+ // Write from buffer to message queues and calling process
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, inputBuffer));
+
+ // Read the updated message queues into buffer
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 1, outputMQ,
+ outputBuffer.size(), outputBuffer));
+
+ // Disable the process
+ ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::RESET));
+ ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+ }
};
diff --git a/audio/aidl/vts/TestUtils.h b/audio/aidl/vts/TestUtils.h
index e9f3251..515b8a2 100644
--- a/audio/aidl/vts/TestUtils.h
+++ b/audio/aidl/vts/TestUtils.h
@@ -69,6 +69,23 @@
<< "\n but is has completed with: " << status;
}
+inline ::testing::AssertionResult assertIsOkOrUnknownTransaction(
+ const char* expr, const ::ndk::ScopedAStatus& status) {
+ if (status.getStatus() == STATUS_UNKNOWN_TRANSACTION) {
+ return ::testing::AssertionSuccess();
+ }
+ return assertIsOk(expr, status);
+}
+
+inline ::testing::AssertionResult assertResultOrUnknownTransaction(
+ const char* exp_expr, const char* act_expr, int32_t expected,
+ const ::ndk::ScopedAStatus& status) {
+ if (status.getStatus() == STATUS_UNKNOWN_TRANSACTION) {
+ return ::testing::AssertionSuccess();
+ }
+ return assertResult(exp_expr, act_expr, expected, status);
+}
+
} // namespace detail
} // namespace android::hardware::audio::common::testing
@@ -93,3 +110,15 @@
GTEST_SKIP() << "Skip data path for offload"; \
} \
})
+
+// Test that the transaction status 'isOk' if it is a known transaction
+#define EXPECT_IS_OK_OR_UNKNOWN_TRANSACTION(ret) \
+ EXPECT_PRED_FORMAT1( \
+ ::android::hardware::audio::common::testing::detail::assertIsOkOrUnknownTransaction, \
+ ret)
+
+// Test that the transaction status is as expected if it is a known transaction
+#define EXPECT_STATUS_OR_UNKNOWN_TRANSACTION(expected, ret) \
+ EXPECT_PRED_FORMAT2( \
+ ::android::hardware::audio::common::testing::detail::assertResultOrUnknownTransaction, \
+ expected, ret)
diff --git a/audio/aidl/vts/VtsHalAECTargetTest.cpp b/audio/aidl/vts/VtsHalAECTargetTest.cpp
index 39168b1..f972b84 100644
--- a/audio/aidl/vts/VtsHalAECTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAECTargetTest.cpp
@@ -18,7 +18,6 @@
#include <string>
#include <unordered_set>
-#include <aidl/Vintf.h>
#define LOG_TAG "VtsHalAECParamTest"
#include <android-base/logging.h>
diff --git a/audio/aidl/vts/VtsHalAGC1TargetTest.cpp b/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
index 6066025..75da589 100644
--- a/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-#include <aidl/Vintf.h>
#define LOG_TAG "VtsHalAGC1ParamTest"
#include <android-base/logging.h>
diff --git a/audio/aidl/vts/VtsHalAGC2TargetTest.cpp b/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
index 8793e4c..5f57a88 100644
--- a/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-#include <aidl/Vintf.h>
#define LOG_TAG "VtsHalAGC2ParamTest"
#include <android-base/logging.h>
#include <android/binder_enums.h>
diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
index 697aae9..7373073 100644
--- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -573,6 +573,8 @@
WithDevicePortConnectedState& operator=(const WithDevicePortConnectedState&) = delete;
~WithDevicePortConnectedState() {
if (mModule != nullptr) {
+ EXPECT_IS_OK_OR_UNKNOWN_TRANSACTION(mModule->prepareToDisconnectExternalDevice(getId()))
+ << "when preparing to disconnect device port ID " << getId();
EXPECT_IS_OK(mModule->disconnectExternalDevice(getId()))
<< "when disconnecting device port ID " << getId();
}
@@ -1753,6 +1755,9 @@
ScopedAStatus status = module->connectExternalDevice(portWithData, &connectedPort);
EXPECT_STATUS(EX_ILLEGAL_STATE, status) << "static port " << portWithData.toString();
if (status.isOk()) {
+ EXPECT_IS_OK_OR_UNKNOWN_TRANSACTION(
+ module->prepareToDisconnectExternalDevice(connectedPort.id))
+ << "when preparing to disconnect device port ID " << connectedPort.id;
EXPECT_IS_OK(module->disconnectExternalDevice(connectedPort.id))
<< "when disconnecting device port ID " << connectedPort.id;
}
@@ -1782,6 +1787,9 @@
invalidPort.id = portId;
EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->connectExternalDevice(invalidPort, &ignored))
<< "port ID " << portId << ", when setting CONNECTED state";
+ EXPECT_STATUS_OR_UNKNOWN_TRANSACTION(EX_ILLEGAL_ARGUMENT,
+ module->prepareToDisconnectExternalDevice(portId))
+ << "port ID " << portId << ", when preparing to disconnect";
EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->disconnectExternalDevice(portId))
<< "port ID " << portId << ", when setting DISCONNECTED state";
}
@@ -1792,6 +1800,9 @@
if (port.ext.getTag() != AudioPortExt::Tag::device) {
EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->connectExternalDevice(port, &ignored))
<< "non-device port ID " << port.id << " when setting CONNECTED state";
+ EXPECT_STATUS_OR_UNKNOWN_TRANSACTION(EX_ILLEGAL_ARGUMENT,
+ module->prepareToDisconnectExternalDevice(port.id))
+ << "non-device port ID " << port.id << " when preparing to disconnect";
EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->disconnectExternalDevice(port.id))
<< "non-device port ID " << port.id << " when setting DISCONNECTED state";
} else {
@@ -1800,6 +1811,10 @@
EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->connectExternalDevice(port, &ignored))
<< "for a permanently attached device port ID " << port.id
<< " when setting CONNECTED state";
+ EXPECT_STATUS_OR_UNKNOWN_TRANSACTION(
+ EX_ILLEGAL_ARGUMENT, module->prepareToDisconnectExternalDevice(port.id))
+ << "for a permanently attached device port ID " << port.id
+ << " when preparing to disconnect";
EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->disconnectExternalDevice(port.id))
<< "for a permanently attached device port ID " << port.id
<< " when setting DISCONNECTED state";
@@ -1817,6 +1832,9 @@
GTEST_SKIP() << "No external devices in the module.";
}
for (const auto& port : ports) {
+ EXPECT_STATUS_OR_UNKNOWN_TRANSACTION(EX_ILLEGAL_ARGUMENT,
+ module->prepareToDisconnectExternalDevice(port.id))
+ << "when preparing to disconnect already disconnected device port ID " << port.id;
EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->disconnectExternalDevice(port.id))
<< "when disconnecting already disconnected device port ID " << port.id;
AudioPort portWithData = GenerateUniqueDeviceAddress(port);
@@ -1851,6 +1869,10 @@
// Our test assumes that 'getAudioPort' returns at least one profile, and it
// is not a dynamic profile.
ASSERT_NO_FATAL_FAILURE(config.SetUp(module.get()));
+ EXPECT_IS_OK_OR_UNKNOWN_TRANSACTION(
+ module->prepareToDisconnectExternalDevice(portConnected.getId()))
+ << "when preparing to disconnect device port ID " << port.id
+ << " with active configuration " << config.getId();
EXPECT_STATUS(EX_ILLEGAL_STATE, module->disconnectExternalDevice(portConnected.getId()))
<< "when trying to disconnect device port ID " << port.id
<< " with active configuration " << config.getId();
@@ -4561,8 +4583,7 @@
static std::vector<std::string> getRemoteSubmixModuleInstance() {
auto instances = android::getAidlHalInstanceNames(IModule::descriptor);
for (auto instance : instances) {
- if (instance.find("r_submix") != std::string::npos)
- return (std::vector<std::string>{instance});
+ if (instance.ends_with("/r_submix")) return (std::vector<std::string>{instance});
}
return {};
}
@@ -4650,6 +4671,9 @@
// Turn off "debug" which enables connections simulation. Since devices of the remote
// submix module are virtual, there is no need for simulation.
ASSERT_NO_FATAL_FAILURE(SetUpImpl(GetParam(), false /*setUpDebug*/));
+ if (int32_t version; module->getInterfaceVersion(&version).isOk() && version < 2) {
+ GTEST_SKIP() << "V1 uses a deprecated remote submix device type encoding";
+ }
ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
}
};
diff --git a/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
index 523f20d..4e86ec3 100644
--- a/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
@@ -32,7 +32,6 @@
#include <aidl/android/hardware/audio/effect/IFactory.h>
-#include "AudioHalBinderServiceUtil.h"
#include "EffectFactoryHelper.h"
#include "TestUtils.h"
@@ -297,6 +296,25 @@
[&](const auto& proc) { return processingSet.find(proc) != processingSet.end(); }));
}
+// Make sure all effect instances have same HAL version number as IFactory.
+TEST_P(EffectFactoryTest, VersionNumberForAllEffectsEqualsToIFactory) {
+ std::vector<Descriptor> descs;
+ EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &descs));
+ EXPECT_NE(descs.size(), 0UL);
+
+ std::vector<std::shared_ptr<IEffect>> effects = createWithDescs(descs);
+ int factoryVersion = 0;
+ EXPECT_IS_OK(mEffectFactory->getInterfaceVersion(&factoryVersion));
+
+ for (const auto& effect : effects) {
+ int effectVersion = 0;
+ EXPECT_NE(nullptr, effect);
+ EXPECT_IS_OK(effect->getInterfaceVersion(&effectVersion));
+ EXPECT_EQ(factoryVersion, effectVersion);
+ }
+ ASSERT_NO_FATAL_FAILURE(destroyEffects(effects));
+}
+
INSTANTIATE_TEST_SUITE_P(EffectFactoryTest, EffectFactoryTest,
testing::ValuesIn(android::getAidlHalInstanceNames(IFactory::descriptor)),
android::PrintInstanceNameToString);
diff --git a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
index ca1cea9..5479825 100644
--- a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
@@ -16,13 +16,11 @@
#define LOG_TAG "VtsHalAudioEffectTargetTest"
-#include <chrono>
#include <memory>
#include <string>
#include <vector>
#include <aidl/Gtest.h>
-#include <aidl/Vintf.h>
#include <aidl/android/hardware/audio/effect/IEffect.h>
#include <aidl/android/hardware/audio/effect/IFactory.h>
#include <android-base/logging.h>
@@ -31,7 +29,6 @@
#include <android/binder_process.h>
#include <fmq/AidlMessageQueue.h>
-#include "AudioHalBinderServiceUtil.h"
#include "EffectFactoryHelper.h"
#include "EffectHelper.h"
#include "TestUtils.h"
@@ -596,8 +593,14 @@
Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::volumeStereo);
Parameter::VolumeStereo volume = {.left = 10.0, .right = 10.0};
- ASSERT_NO_FATAL_FAILURE(
- setAndGetParameter(id, Parameter::make<Parameter::volumeStereo>(volume)));
+ if (mDescriptor.common.flags.volume == Flags::Volume::CTRL) {
+ Parameter get;
+ EXPECT_IS_OK(mEffect->setParameter(volume));
+ EXPECT_IS_OK(mEffect->getParameter(id, &get));
+ } else {
+ ASSERT_NO_FATAL_FAILURE(
+ setAndGetParameter(id, Parameter::make<Parameter::volumeStereo>(volume)));
+ }
ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
@@ -605,6 +608,52 @@
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
}
+/**
+ * Verify DataMqUpdateEventFlag after common parameter setting.
+ * verify reopen sequence.
+ */
+TEST_P(AudioEffectDataPathTest, SetCommonParameterAndReopen) {
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+ Parameter::Common common = EffectHelper::createParamCommon(
+ 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+ kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+ IEffect::OpenEffectReturn ret;
+ ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt /* specific */, &ret, EX_NONE));
+ auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+ ASSERT_TRUE(statusMQ->isValid());
+ auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+ ASSERT_TRUE(inputMQ->isValid());
+ auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+ ASSERT_TRUE(outputMQ->isValid());
+
+ Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
+ common.input.frameCount++;
+ ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
+ ASSERT_TRUE(statusMQ->isValid());
+ expectDataMqUpdateEventFlag(statusMQ);
+ EXPECT_IS_OK(mEffect->reopen(&ret));
+ inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+ outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+ ASSERT_TRUE(statusMQ->isValid());
+ ASSERT_TRUE(inputMQ->isValid());
+ ASSERT_TRUE(outputMQ->isValid());
+
+ common.output.frameCount++;
+ ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
+ ASSERT_TRUE(statusMQ->isValid());
+ expectDataMqUpdateEventFlag(statusMQ);
+ EXPECT_IS_OK(mEffect->reopen(&ret));
+ inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+ outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+ ASSERT_TRUE(statusMQ->isValid());
+ ASSERT_TRUE(inputMQ->isValid());
+ ASSERT_TRUE(outputMQ->isValid());
+
+ ASSERT_NO_FATAL_FAILURE(close(mEffect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
/// Data processing test
// Send data to effects and expect it to be consumed by checking statusMQ.
// Effects exposing bypass flags or operating in offload mode will be skipped.
@@ -680,6 +729,59 @@
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
}
+// Send data to effects and expect it to be consumed after effect reopen (IO AudioConfig change).
+// Effects exposing bypass flags or operating in offload mode will be skipped.
+TEST_P(AudioEffectDataPathTest, ConsumeDataAfterReopen) {
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+ Parameter::Common common = EffectHelper::createParamCommon(
+ 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+ kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+ IEffect::OpenEffectReturn ret;
+ ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt /* specific */, &ret, EX_NONE));
+ auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+ ASSERT_TRUE(statusMQ->isValid());
+ auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+ ASSERT_TRUE(inputMQ->isValid());
+ auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+ ASSERT_TRUE(outputMQ->isValid());
+
+ std::vector<float> buffer;
+ ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+ EXPECT_NO_FATAL_FAILURE(
+ EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
+
+ // set a new common parameter with different IO frameCount, reopen
+ Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
+ common.input.frameCount += 4;
+ common.output.frameCount += 4;
+ ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
+ ASSERT_TRUE(statusMQ->isValid());
+ expectDataMqUpdateEventFlag(statusMQ);
+ EXPECT_IS_OK(mEffect->reopen(&ret));
+ inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+ outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+ ASSERT_TRUE(statusMQ->isValid());
+ ASSERT_TRUE(inputMQ->isValid());
+ ASSERT_TRUE(outputMQ->isValid());
+
+ // verify data consume again
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+ EXPECT_NO_FATAL_FAILURE(
+ EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
+
+ ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
+
+ ASSERT_NO_FATAL_FAILURE(close(mEffect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
// Send data to IDLE effects and expect it to be consumed after effect start.
// Effects exposing bypass flags or operating in offload mode will be skipped.
TEST_P(AudioEffectDataPathTest, SendDataAtIdleAndConsumeDataInProcessing) {
diff --git a/audio/aidl/vts/VtsHalAudioCoreTargetTest.xml b/audio/aidl/vts/VtsHalAudioTargetTestTemplate.xml
similarity index 86%
rename from audio/aidl/vts/VtsHalAudioCoreTargetTest.xml
rename to audio/aidl/vts/VtsHalAudioTargetTestTemplate.xml
index 9d3adc1..c92e852 100644
--- a/audio/aidl/vts/VtsHalAudioCoreTargetTest.xml
+++ b/audio/aidl/vts/VtsHalAudioTargetTestTemplate.xml
@@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<configuration description="Runs VtsHalAudioCoreTargetTest.">
+<configuration description="Runs {MODULE}.">
<option name="test-suite-tag" value="apct" />
<option name="test-suite-tag" value="apct-native" />
@@ -27,12 +27,12 @@
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
<option name="cleanup" value="true" />
- <option name="push" value="VtsHalAudioCoreTargetTest->/data/local/tmp/VtsHalAudioCoreTargetTest" />
+ <option name="push" value="{MODULE}->/data/local/tmp/{MODULE}" />
</target_preparer>
<test class="com.android.tradefed.testtype.GTest" >
<option name="native-test-device-path" value="/data/local/tmp" />
- <option name="module-name" value="VtsHalAudioCoreTargetTest" />
+ <option name="module-name" value="{MODULE}" />
<option name="native-test-timeout" value="10m" />
</test>
</configuration>
diff --git a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
index 2d9a233..b54b442 100644
--- a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
@@ -16,14 +16,15 @@
#include <limits.h>
-#include <aidl/Vintf.h>
#define LOG_TAG "VtsHalBassBoostTest"
+#include <aidl/Vintf.h>
#include <android-base/logging.h>
-
#include "EffectHelper.h"
+#include "pffft.hpp"
using namespace android;
+using aidl::android::hardware::audio::common::getChannelCount;
using aidl::android::hardware::audio::effect::BassBoost;
using aidl::android::hardware::audio::effect::Capability;
using aidl::android::hardware::audio::effect::Descriptor;
@@ -33,13 +34,11 @@
using aidl::android::hardware::audio::effect::Parameter;
using aidl::android::hardware::audio::effect::Range;
using android::hardware::audio::common::testing::detail::TestExecutionTracer;
-/**
- * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
- * VtsAudioEffectTargetTest.
- */
-enum ParamName { PARAM_INSTANCE_NAME, PARAM_STRENGTH };
-using BassBoostParamTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>;
+// minimal HAL interface version to run bassboost data path test
+constexpr int32_t kMinDataTestHalVersion = 2;
+static const std::vector<int32_t> kLayouts = {AudioChannelLayout::LAYOUT_STEREO,
+ AudioChannelLayout::LAYOUT_MONO};
/*
* Testing parameter range, assuming the parameter supported by effect is in this range.
* Parameter should be within the valid range defined in the documentation,
@@ -47,29 +46,29 @@
* otherwise expect EX_ILLEGAL_ARGUMENT.
*/
-class BassBoostParamTest : public ::testing::TestWithParam<BassBoostParamTestParam>,
- public EffectHelper {
+class BassBoostEffectHelper : public EffectHelper {
public:
- BassBoostParamTest() : mParamStrength(std::get<PARAM_STRENGTH>(GetParam())) {
- std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
- }
-
- void SetUp() override {
+ void SetUpBassBoost(int32_t layout = AudioChannelLayout::LAYOUT_STEREO) {
ASSERT_NE(nullptr, mFactory);
ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+ setFrameCounts(layout);
+
+ AudioChannelLayout channelLayout =
+ AudioChannelLayout::make<AudioChannelLayout::layoutMask>(layout);
Parameter::Specific specific = getDefaultParamSpecific();
Parameter::Common common = EffectHelper::createParamCommon(
- 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
- kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
- IEffect::OpenEffectReturn ret;
- ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+ 0 /* session */, 1 /* ioHandle */, kSamplingFrequency /* iSampleRate */,
+ kSamplingFrequency /* oSampleRate */, mInputFrameCount /* iFrameCount */,
+ mOutputFrameCount /* oFrameCount */, channelLayout, channelLayout);
+ ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &mOpenEffectReturn, EX_NONE));
ASSERT_NE(nullptr, mEffect);
}
- void TearDown() override {
+ void TearDownBassBoost() {
ASSERT_NO_FATAL_FAILURE(close(mEffect));
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+ mOpenEffectReturn = IEffect::OpenEffectReturn{};
}
Parameter::Specific getDefaultParamSpecific() {
@@ -79,58 +78,214 @@
return specific;
}
- static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
- std::shared_ptr<IFactory> mFactory;
- std::shared_ptr<IEffect> mEffect;
- Descriptor mDescriptor;
- int mParamStrength = 0;
+ void setFrameCounts(int32_t inputBufferLayout) {
+ int channelCount = getChannelCount(
+ AudioChannelLayout::make<AudioChannelLayout::layoutMask>(inputBufferLayout));
+ mInputFrameCount = kInputSize / channelCount;
+ mOutputFrameCount = kInputSize / channelCount;
+ }
- void SetAndGetBassBoostParameters() {
- for (auto& it : mTags) {
- auto& tag = it.first;
- auto& bb = it.second;
+ Parameter createBassBoostParam(int strength) {
+ return Parameter::make<Parameter::specific>(
+ Parameter::Specific::make<Parameter::Specific::bassBoost>(
+ BassBoost::make<BassBoost::strengthPm>(strength)));
+ }
- // validate parameter
- Descriptor desc;
- ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
- const bool valid = isParameterValid<BassBoost, Range::bassBoost>(it.second, desc);
- const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+ bool isStrengthValid(int strength) {
+ auto bb = BassBoost::make<BassBoost::strengthPm>(strength);
+ return isParameterValid<BassBoost, Range::bassBoost>(bb, mDescriptor);
+ }
- // set parameter
- Parameter expectParam;
- Parameter::Specific specific;
- specific.set<Parameter::Specific::bassBoost>(bb);
- expectParam.set<Parameter::specific>(specific);
- EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
+ void setAndVerifyParameters(int strength, binder_exception_t expected) {
+ auto expectedParam = createBassBoostParam(strength);
+ EXPECT_STATUS(expected, mEffect->setParameter(expectedParam)) << expectedParam.toString();
- // only get if parameter in range and set success
- if (expected == EX_NONE) {
- Parameter getParam;
- Parameter::Id id;
- BassBoost::Id bbId;
- bbId.set<BassBoost::Id::commonTag>(tag);
- id.set<Parameter::Id::bassBoostTag>(bbId);
- // if set success, then get should match
- EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
- EXPECT_EQ(expectParam, getParam);
- }
+ if (expected == EX_NONE) {
+ auto bbId = BassBoost::Id::make<BassBoost::Id::commonTag>(
+ BassBoost::Tag(BassBoost::strengthPm));
+ auto id = Parameter::Id::make<Parameter::Id::bassBoostTag>(bbId);
+ // get parameter
+ Parameter getParam;
+ // if set success, then get should match
+ EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
+ EXPECT_EQ(expectedParam, getParam) << "\nexpectedParam:" << expectedParam.toString()
+ << "\ngetParam:" << getParam.toString();
}
}
- void addStrengthParam(int strength) {
- BassBoost bb;
- bb.set<BassBoost::strengthPm>(strength);
- mTags.push_back({BassBoost::strengthPm, bb});
+ static constexpr int kSamplingFrequency = 44100;
+ static constexpr int kDurationMilliSec = 2000;
+ static constexpr int kInputSize = kSamplingFrequency * kDurationMilliSec / 1000;
+ long mInputFrameCount, mOutputFrameCount;
+ std::shared_ptr<IFactory> mFactory;
+ Descriptor mDescriptor;
+ std::shared_ptr<IEffect> mEffect;
+ IEffect::OpenEffectReturn mOpenEffectReturn;
+};
+
+/**
+ * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
+ * VtsAudioEffectTargetTest.
+ */
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_STRENGTH };
+using BassBoostParamTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>;
+
+class BassBoostParamTest : public ::testing::TestWithParam<BassBoostParamTestParam>,
+ public BassBoostEffectHelper {
+ public:
+ BassBoostParamTest() : mParamStrength(std::get<PARAM_STRENGTH>(GetParam())) {
+ std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
}
- private:
- std::vector<std::pair<BassBoost::Tag, BassBoost>> mTags;
- void CleanUp() { mTags.clear(); }
+ void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpBassBoost()); }
+ void TearDown() override { TearDownBassBoost(); }
+
+ int mParamStrength = 0;
};
TEST_P(BassBoostParamTest, SetAndGetStrength) {
- EXPECT_NO_FATAL_FAILURE(addStrengthParam(mParamStrength));
- SetAndGetBassBoostParameters();
+ if (isStrengthValid(mParamStrength)) {
+ ASSERT_NO_FATAL_FAILURE(setAndVerifyParameters(mParamStrength, EX_NONE));
+ } else {
+ ASSERT_NO_FATAL_FAILURE(setAndVerifyParameters(mParamStrength, EX_ILLEGAL_ARGUMENT));
+ }
+}
+
+enum DataParamName { DATA_INSTANCE_NAME, DATA_LAYOUT };
+
+using BassBoostDataTestParam =
+ std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t>;
+
+class BassBoostDataTest : public ::testing::TestWithParam<BassBoostDataTestParam>,
+ public BassBoostEffectHelper {
+ public:
+ BassBoostDataTest() : mChannelLayout(std::get<DATA_LAYOUT>(GetParam())) {
+ std::tie(mFactory, mDescriptor) = std::get<DATA_INSTANCE_NAME>(GetParam());
+ mStrengthValues = getTestValueSet<BassBoost, int, Range::bassBoost, BassBoost::strengthPm>(
+ {std::get<DATA_INSTANCE_NAME>(GetParam())}, expandTestValueBasic<int>);
+ }
+
+ void SetUp() override {
+ ASSERT_NO_FATAL_FAILURE(SetUpBassBoost(mChannelLayout));
+ if (int32_t version;
+ mEffect->getInterfaceVersion(&version).isOk() && version < kMinDataTestHalVersion) {
+ GTEST_SKIP() << "Skipping the data test for version: " << version << "\n";
+ }
+ }
+
+ void TearDown() override { TearDownBassBoost(); }
+
+ // Find FFT bin indices for testFrequencies and get bin center frequencies
+ void roundToFreqCenteredToFftBin(std::vector<int>& testFrequencies,
+ std::vector<int>& binOffsets) {
+ for (size_t i = 0; i < testFrequencies.size(); i++) {
+ binOffsets[i] = std::round(testFrequencies[i] / kBinWidth);
+ testFrequencies[i] = std::round(binOffsets[i] * kBinWidth);
+ }
+ }
+
+ // Generate multitone input between -1 to +1 using testFrequencies
+ void generateMultiTone(const std::vector<int>& testFrequencies, std::vector<float>& input) {
+ for (auto i = 0; i < kInputSize; i++) {
+ input[i] = 0;
+
+ for (size_t j = 0; j < testFrequencies.size(); j++) {
+ input[i] += sin(2 * M_PI * testFrequencies[j] * i / kSamplingFrequency);
+ }
+ input[i] /= testFrequencies.size();
+ }
+ }
+
+ // Use FFT transform to convert the buffer to frequency domain
+ // Compute its magnitude at binOffsets
+ std::vector<float> calculateMagnitude(const std::vector<float>& buffer,
+ const std::vector<int>& binOffsets) {
+ std::vector<float> fftInput(kNPointFFT);
+ PFFFT_Setup* inputHandle = pffft_new_setup(kNPointFFT, PFFFT_REAL);
+ pffft_transform_ordered(inputHandle, buffer.data(), fftInput.data(), nullptr,
+ PFFFT_FORWARD);
+ pffft_destroy_setup(inputHandle);
+ std::vector<float> bufferMag(binOffsets.size());
+ for (size_t i = 0; i < binOffsets.size(); i++) {
+ size_t k = binOffsets[i];
+ bufferMag[i] = sqrt((fftInput[k * 2] * fftInput[k * 2]) +
+ (fftInput[k * 2 + 1] * fftInput[k * 2 + 1]));
+ }
+
+ return bufferMag;
+ }
+
+ // Calculate gain difference between low frequency and high frequency magnitude
+ float calculateGainDiff(const std::vector<float>& inputMag,
+ const std::vector<float>& outputMag) {
+ std::vector<float> gains(inputMag.size());
+
+ for (size_t i = 0; i < inputMag.size(); i++) {
+ gains[i] = 20 * log10(outputMag[i] / inputMag[i]);
+ }
+
+ return gains[0] - gains[1];
+ }
+
+ static constexpr int kNPointFFT = 32768;
+ static constexpr float kBinWidth = (float)kSamplingFrequency / kNPointFFT;
+ std::set<int> mStrengthValues;
+ int32_t mChannelLayout;
+};
+
+TEST_P(BassBoostDataTest, IncreasingStrength) {
+ // Frequencies to generate multitone input
+ std::vector<int> testFrequencies = {100, 1000};
+
+ // FFT bin indices for testFrequencies
+ std::vector<int> binOffsets(testFrequencies.size());
+
+ std::vector<float> input(kInputSize);
+ std::vector<float> baseOutput(kInputSize);
+
+ std::vector<float> inputMag(testFrequencies.size());
+ float prevGain = -100;
+
+ roundToFreqCenteredToFftBin(testFrequencies, binOffsets);
+
+ generateMultiTone(testFrequencies, input);
+
+ inputMag = calculateMagnitude(input, binOffsets);
+
+ if (isStrengthValid(0)) {
+ ASSERT_NO_FATAL_FAILURE(setAndVerifyParameters(0, EX_NONE));
+ } else {
+ GTEST_SKIP() << "Strength not supported, skipping the test\n";
+ }
+
+ ASSERT_NO_FATAL_FAILURE(
+ processAndWriteToOutput(input, baseOutput, mEffect, &mOpenEffectReturn));
+
+ std::vector<float> baseMag(testFrequencies.size());
+ baseMag = calculateMagnitude(baseOutput, binOffsets);
+ float baseDiff = calculateGainDiff(inputMag, baseMag);
+
+ for (int strength : mStrengthValues) {
+ // Skipping the further steps for invalid strength values
+ if (!isStrengthValid(strength)) {
+ continue;
+ }
+
+ ASSERT_NO_FATAL_FAILURE(setAndVerifyParameters(strength, EX_NONE));
+
+ std::vector<float> output(kInputSize);
+ std::vector<float> outputMag(testFrequencies.size());
+
+ ASSERT_NO_FATAL_FAILURE(
+ processAndWriteToOutput(input, output, mEffect, &mOpenEffectReturn));
+
+ outputMag = calculateMagnitude(output, binOffsets);
+ float diff = calculateGainDiff(inputMag, outputMag);
+
+ ASSERT_GT(diff, prevGain);
+ ASSERT_GT(diff, baseDiff);
+ prevGain = diff;
+ }
}
std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
@@ -153,6 +308,22 @@
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BassBoostParamTest);
+INSTANTIATE_TEST_SUITE_P(
+ BassBoostTest, BassBoostDataTest,
+ ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, getEffectTypeUuidBassBoost())),
+ testing::ValuesIn(kLayouts)),
+ [](const testing::TestParamInfo<BassBoostDataTest::ParamType>& info) {
+ auto descriptor = std::get<DATA_INSTANCE_NAME>(info.param).second;
+ std::string layout = std::to_string(std::get<DATA_LAYOUT>(info.param));
+ std::string name = getPrefix(descriptor) + "_layout_" + layout;
+ std::replace_if(
+ name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+ return name;
+ });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BassBoostDataTest);
+
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer());
diff --git a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
index c01a9a2..360bf26 100644
--- a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
@@ -14,92 +14,120 @@
* limitations under the License.
*/
-#include <aidl/Vintf.h>
#define LOG_TAG "VtsHalDownmixTargetTest"
#include <android-base/logging.h>
+#include <audio_utils/ChannelMix.h>
#include "EffectHelper.h"
using namespace android;
+using aidl::android::hardware::audio::common::getChannelCount;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::Downmix;
using aidl::android::hardware::audio::effect::getEffectTypeUuidDownmix;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::IFactory;
using aidl::android::hardware::audio::effect::Parameter;
+using android::audio_utils::channels::ChannelMix;
using android::hardware::audio::common::testing::detail::TestExecutionTracer;
-/**
- * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
- * VtsAudioEffectTargetTest.
- */
-enum ParamName { PARAM_INSTANCE_NAME, PARAM_TYPE };
-using DownmixParamTestParam =
- std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, Downmix::Type>;
+
+// minimal HAL interface version to run downmix data path test
+constexpr int32_t kMinDataTestHalVersion = 2;
// Testing for enum values
-const std::vector<Downmix::Type> kTypeValues = {Downmix::Type::STRIP, Downmix::Type::FOLD};
+static const std::vector<Downmix::Type> kTypeValues = {ndk::enum_range<Downmix::Type>().begin(),
+ ndk::enum_range<Downmix::Type>().end()};
-class DownmixParamTest : public ::testing::TestWithParam<DownmixParamTestParam>,
- public EffectHelper {
+// Testing for supported layouts from AudioChannelLayout.h
+static const std::vector<int32_t> kLayoutValues = {
+ AudioChannelLayout::LAYOUT_STEREO, AudioChannelLayout::LAYOUT_2POINT1,
+ AudioChannelLayout::LAYOUT_TRI, AudioChannelLayout::LAYOUT_TRI_BACK,
+ AudioChannelLayout::LAYOUT_3POINT1, AudioChannelLayout::LAYOUT_2POINT0POINT2,
+ AudioChannelLayout::LAYOUT_2POINT1POINT2, AudioChannelLayout::LAYOUT_3POINT0POINT2,
+ AudioChannelLayout::LAYOUT_3POINT1POINT2, AudioChannelLayout::LAYOUT_QUAD,
+ AudioChannelLayout::LAYOUT_QUAD_SIDE, AudioChannelLayout::LAYOUT_SURROUND,
+ AudioChannelLayout::LAYOUT_PENTA, AudioChannelLayout::LAYOUT_5POINT1,
+ AudioChannelLayout::LAYOUT_5POINT1_SIDE, AudioChannelLayout::LAYOUT_5POINT1POINT2,
+ AudioChannelLayout::LAYOUT_5POINT1POINT4, AudioChannelLayout::LAYOUT_6POINT1,
+ AudioChannelLayout::LAYOUT_7POINT1, AudioChannelLayout::LAYOUT_7POINT1POINT2,
+ AudioChannelLayout::LAYOUT_7POINT1POINT4, AudioChannelLayout::LAYOUT_9POINT1POINT4,
+ AudioChannelLayout::LAYOUT_9POINT1POINT6, AudioChannelLayout::LAYOUT_13POINT_360RA,
+ AudioChannelLayout::LAYOUT_22POINT2};
+
+static const std::vector<int32_t> kChannels = {
+ AudioChannelLayout::CHANNEL_FRONT_LEFT,
+ AudioChannelLayout::CHANNEL_FRONT_RIGHT,
+ AudioChannelLayout::CHANNEL_FRONT_CENTER,
+ AudioChannelLayout::CHANNEL_LOW_FREQUENCY,
+ AudioChannelLayout::CHANNEL_BACK_LEFT,
+ AudioChannelLayout::CHANNEL_BACK_RIGHT,
+ AudioChannelLayout::CHANNEL_BACK_CENTER,
+ AudioChannelLayout::CHANNEL_SIDE_LEFT,
+ AudioChannelLayout::CHANNEL_SIDE_RIGHT,
+ AudioChannelLayout::CHANNEL_FRONT_LEFT_OF_CENTER,
+ AudioChannelLayout::CHANNEL_FRONT_RIGHT_OF_CENTER,
+ AudioChannelLayout::CHANNEL_TOP_CENTER,
+ AudioChannelLayout::CHANNEL_TOP_FRONT_LEFT,
+ AudioChannelLayout::CHANNEL_TOP_FRONT_CENTER,
+ AudioChannelLayout::CHANNEL_TOP_FRONT_RIGHT,
+ AudioChannelLayout::CHANNEL_TOP_BACK_LEFT,
+ AudioChannelLayout::CHANNEL_TOP_BACK_CENTER,
+ AudioChannelLayout::CHANNEL_TOP_BACK_RIGHT,
+ AudioChannelLayout::CHANNEL_TOP_SIDE_LEFT,
+ AudioChannelLayout::CHANNEL_TOP_SIDE_RIGHT,
+ AudioChannelLayout::CHANNEL_BOTTOM_FRONT_LEFT,
+ AudioChannelLayout::CHANNEL_BOTTOM_FRONT_CENTER,
+ AudioChannelLayout::CHANNEL_BOTTOM_FRONT_RIGHT,
+ AudioChannelLayout::CHANNEL_LOW_FREQUENCY_2,
+ AudioChannelLayout::CHANNEL_FRONT_WIDE_LEFT,
+ AudioChannelLayout::CHANNEL_FRONT_WIDE_RIGHT,
+};
+
+class DownmixEffectHelper : public EffectHelper {
public:
- DownmixParamTest() : mParamType(std::get<PARAM_TYPE>(GetParam())) {
- std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
- }
-
- void SetUp() override {
+ void SetUpDownmix(int32_t inputBufferLayout = AudioChannelLayout::LAYOUT_STEREO) {
ASSERT_NE(nullptr, mFactory);
ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+ AudioChannelLayout inputChannelLayout =
+ AudioChannelLayout::make<AudioChannelLayout::layoutMask>(inputBufferLayout);
+
Parameter::Specific specific = getDefaultParamSpecific();
Parameter::Common common = EffectHelper::createParamCommon(
0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
- kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
- IEffect::OpenEffectReturn ret;
- ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+ kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */,
+ inputChannelLayout);
+ ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &mOpenEffectReturn, EX_NONE));
ASSERT_NE(nullptr, mEffect);
}
- void TearDown() override {
+ void TearDownDownmix() {
ASSERT_NO_FATAL_FAILURE(close(mEffect));
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+ mOpenEffectReturn = IEffect::OpenEffectReturn{};
}
- static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
- std::shared_ptr<IFactory> mFactory;
- std::shared_ptr<IEffect> mEffect;
- Descriptor mDescriptor;
- Downmix::Type mParamType = Downmix::Type::STRIP;
-
- void SetAndGetDownmixParameters() {
- for (auto& it : mTags) {
- auto& tag = it.first;
- auto& dm = it.second;
-
- // set parameter
- Parameter expectParam;
- Parameter::Specific specific;
- specific.set<Parameter::Specific::downmix>(dm);
- expectParam.set<Parameter::specific>(specific);
- // All values are valid, set parameter should succeed
- EXPECT_STATUS(EX_NONE, mEffect->setParameter(expectParam)) << expectParam.toString();
-
- // get parameter
- Parameter getParam;
- Parameter::Id id;
- Downmix::Id dmId;
- dmId.set<Downmix::Id::commonTag>(tag);
- id.set<Parameter::Id::downmixTag>(dmId);
- EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
-
- EXPECT_EQ(expectParam, getParam);
- }
+ Parameter createDownmixParam(Downmix::Type type) {
+ return Parameter::make<Parameter::specific>(
+ Parameter::Specific::make<Parameter::Specific::downmix>(
+ Downmix::make<Downmix::type>(type)));
+ }
+ void setParameters(Downmix::Type type) {
+ // set parameter
+ auto param = createDownmixParam(type);
+ EXPECT_STATUS(EX_NONE, mEffect->setParameter(param)) << param.toString();
}
- void addTypeParam(Downmix::Type type) {
- Downmix dm;
- dm.set<Downmix::type>(type);
- mTags.push_back({Downmix::type, dm});
+ void validateParameters(Downmix::Type type) {
+ auto leId = Downmix::Id::make<Downmix::Id::commonTag>(Downmix::Tag(Downmix::type));
+ auto id = Parameter::Id::make<Parameter::Id::downmixTag>(leId);
+ // get parameter
+ Parameter getParam;
+ EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
+ auto expectedParam = createDownmixParam(type);
+ EXPECT_EQ(expectedParam, getParam) << "\nexpectedParam:" << expectedParam.toString()
+ << "\ngetParam:" << getParam.toString();
}
Parameter::Specific getDefaultParamSpecific() {
@@ -108,14 +136,286 @@
return specific;
}
- private:
- std::vector<std::pair<Downmix::Tag, Downmix>> mTags;
- void CleanUp() { mTags.clear(); }
+ void setDataTestParams(int32_t layoutType) {
+ mInputBuffer.resize(kBufferSize);
+
+ // Get the number of channels used
+ mInputChannelCount = getChannelCount(
+ AudioChannelLayout::make<AudioChannelLayout::layoutMask>(layoutType));
+
+ // In case of downmix, output is always configured to stereo layout.
+ mOutputBufferSize = (mInputBuffer.size() / mInputChannelCount) * kOutputChannelCount;
+ mOutputBuffer.resize(mOutputBufferSize);
+ }
+
+ // Generate mInputBuffer values between -kMaxDownmixSample to kMaxDownmixSample
+ void generateInputBuffer(size_t position, bool isStrip) {
+ size_t increment;
+ if (isStrip)
+ // Fill input at all the channels
+ increment = 1;
+ else
+ // Fill input at only one channel
+ increment = mInputChannelCount;
+
+ for (size_t i = position; i < mInputBuffer.size(); i += increment) {
+ mInputBuffer[i] =
+ ((static_cast<float>(std::rand()) / RAND_MAX) * 2 - 1) * kMaxDownmixSample;
+ }
+ }
+
+ bool isLayoutValid(int32_t inputLayout) {
+ if (inputLayout & kMaxChannelMask) {
+ return false;
+ }
+ return true;
+ }
+
+ static constexpr long kInputFrameCount = 100, kOutputFrameCount = 100;
+ std::shared_ptr<IFactory> mFactory;
+ Descriptor mDescriptor;
+ std::shared_ptr<IEffect> mEffect;
+ IEffect::OpenEffectReturn mOpenEffectReturn;
+
+ std::vector<float> mInputBuffer;
+ std::vector<float> mOutputBuffer;
+ size_t mInputChannelCount;
+ size_t mOutputBufferSize;
+ static constexpr size_t kBufferSize = 128;
+ static constexpr float kMaxDownmixSample = 1;
+ static constexpr int kOutputChannelCount = 2;
+ // Mask for layouts greater than MAX_INPUT_CHANNELS_SUPPORTED
+ static constexpr int32_t kMaxChannelMask =
+ ~((1 << ChannelMix<AUDIO_CHANNEL_OUT_STEREO>::MAX_INPUT_CHANNELS_SUPPORTED) - 1);
+};
+
+/**
+ * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
+ * VtsAudioEffectTargetTest.
+ */
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_TYPE };
+
+using DownmixParamTestParam =
+ std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, Downmix::Type>;
+
+class DownmixParamTest : public ::testing::TestWithParam<DownmixParamTestParam>,
+ public DownmixEffectHelper {
+ public:
+ DownmixParamTest() : mParamType(std::get<PARAM_TYPE>(GetParam())) {
+ std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+ }
+
+ void SetUp() override { SetUpDownmix(); }
+
+ void TearDown() override { TearDownDownmix(); }
+
+ const Downmix::Type mParamType;
};
TEST_P(DownmixParamTest, SetAndGetType) {
- EXPECT_NO_FATAL_FAILURE(addTypeParam(mParamType));
- SetAndGetDownmixParameters();
+ ASSERT_NO_FATAL_FAILURE(setParameters(mParamType));
+ ASSERT_NO_FATAL_FAILURE(validateParameters(mParamType));
+}
+
+enum FoldParamName { FOLD_INSTANCE_NAME, FOLD_INPUT_LAYOUT, FOLD_TEST_CHANNEL };
+
+using DownmixDataTestParamFold =
+ std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t>;
+
+class DownmixFoldDataTest : public ::testing::TestWithParam<DownmixDataTestParamFold>,
+ public DownmixEffectHelper {
+ public:
+ DownmixFoldDataTest() : mInputChannelLayout(std::get<FOLD_INPUT_LAYOUT>(GetParam())) {
+ std::tie(mFactory, mDescriptor) = std::get<FOLD_INSTANCE_NAME>(GetParam());
+ }
+
+ void SetUp() override {
+ SetUpDownmix(mInputChannelLayout);
+ if (int32_t version;
+ mEffect->getInterfaceVersion(&version).isOk() && version < kMinDataTestHalVersion) {
+ GTEST_SKIP() << "Skipping the data test for version: " << version << "\n";
+ }
+ if (!isLayoutValid(mInputChannelLayout)) {
+ GTEST_SKIP() << "Layout not supported \n";
+ }
+ setDataTestParams(mInputChannelLayout);
+ }
+
+ void TearDown() override { TearDownDownmix(); }
+
+ void checkAtLeft(int32_t position) {
+ for (size_t i = 0, j = position; i < mOutputBufferSize;
+ i += kOutputChannelCount, j += mInputChannelCount) {
+ // Validate Left channel has audio
+ if (mInputBuffer[j] != 0) {
+ ASSERT_NE(mOutputBuffer[i], 0);
+ } else {
+ // No change in output when input is 0
+ ASSERT_EQ(mOutputBuffer[i], mInputBuffer[j]);
+ }
+ // Validate Right channel has no audio
+ ASSERT_EQ(mOutputBuffer[i + 1], 0);
+ }
+ }
+
+ void checkAtRight(int32_t position) {
+ for (size_t i = 0, j = position; i < mOutputBufferSize;
+ i += kOutputChannelCount, j += mInputChannelCount) {
+ // Validate Left channel has no audio
+ ASSERT_EQ(mOutputBuffer[i], 0) << " at " << i;
+ // Validate Right channel has audio
+ if (mInputBuffer[j] != 0) {
+ ASSERT_NE(mOutputBuffer[i + 1], 0) << " at " << i;
+ } else {
+ // No change in output when input is 0
+ ASSERT_EQ(mOutputBuffer[i + 1], mInputBuffer[j]) << " at " << i;
+ }
+ }
+ }
+
+ void checkAtCenter(size_t position) {
+ for (size_t i = 0, j = position; i < mOutputBufferSize;
+ i += kOutputChannelCount, j += mInputChannelCount) {
+ // Validate both channels have audio
+ if (mInputBuffer[j] != 0) {
+ ASSERT_NE(mOutputBuffer[i], 0);
+ ASSERT_NE(mOutputBuffer[i + 1], 0);
+
+ } else {
+ // No change in output when input is 0
+ ASSERT_EQ(mOutputBuffer[i], mInputBuffer[j]);
+ ASSERT_EQ(mOutputBuffer[i + 1], mInputBuffer[j]);
+ }
+ }
+ }
+
+ void validateOutput(int32_t channel, size_t position) {
+ switch (channel) {
+ case AudioChannelLayout::CHANNEL_FRONT_LEFT:
+ case AudioChannelLayout::CHANNEL_BACK_LEFT:
+ case AudioChannelLayout::CHANNEL_SIDE_LEFT:
+ case AudioChannelLayout::CHANNEL_TOP_FRONT_LEFT:
+ case AudioChannelLayout::CHANNEL_BOTTOM_FRONT_LEFT:
+ case AudioChannelLayout::CHANNEL_TOP_BACK_LEFT:
+ case AudioChannelLayout::CHANNEL_FRONT_WIDE_LEFT:
+ case AudioChannelLayout::CHANNEL_TOP_SIDE_LEFT:
+ checkAtLeft(position);
+ break;
+
+ case AudioChannelLayout::CHANNEL_FRONT_RIGHT:
+ case AudioChannelLayout::CHANNEL_BACK_RIGHT:
+ case AudioChannelLayout::CHANNEL_SIDE_RIGHT:
+ case AudioChannelLayout::CHANNEL_TOP_FRONT_RIGHT:
+ case AudioChannelLayout::CHANNEL_BOTTOM_FRONT_RIGHT:
+ case AudioChannelLayout::CHANNEL_TOP_BACK_RIGHT:
+ case AudioChannelLayout::CHANNEL_FRONT_WIDE_RIGHT:
+ case AudioChannelLayout::CHANNEL_TOP_SIDE_RIGHT:
+ case AudioChannelLayout::CHANNEL_LOW_FREQUENCY_2:
+ checkAtRight(position);
+ break;
+
+ case AudioChannelLayout::CHANNEL_FRONT_CENTER:
+ case AudioChannelLayout::CHANNEL_BACK_CENTER:
+ case AudioChannelLayout::CHANNEL_TOP_FRONT_CENTER:
+ case AudioChannelLayout::CHANNEL_BOTTOM_FRONT_CENTER:
+ case AudioChannelLayout::CHANNEL_FRONT_LEFT_OF_CENTER:
+ case AudioChannelLayout::CHANNEL_FRONT_RIGHT_OF_CENTER:
+ case AudioChannelLayout::CHANNEL_TOP_CENTER:
+ case AudioChannelLayout::CHANNEL_TOP_BACK_CENTER:
+ checkAtCenter(position);
+ break;
+
+ case AudioChannelLayout::CHANNEL_LOW_FREQUENCY:
+ // If CHANNEL_LOW_FREQUENCY_2 is supported
+ if (mInputChannelLayout & AudioChannelLayout::CHANNEL_LOW_FREQUENCY_2) {
+ // Validate that only Left channel has audio
+ checkAtLeft(position);
+ } else {
+ // Validate that both channels have audio
+ checkAtCenter(position);
+ }
+ break;
+ }
+ }
+
+ std::set<int32_t> getInputChannelLayouts() {
+ std::set<int32_t> supportedChannels;
+ for (int32_t channel : kChannels) {
+ if ((mInputChannelLayout & channel) == channel) {
+ supportedChannels.insert(channel);
+ }
+ }
+ return supportedChannels;
+ }
+
+ int32_t mInputChannelLayout;
+};
+
+TEST_P(DownmixFoldDataTest, DownmixProcessData) {
+ // Set FOLD type parameter
+ ASSERT_NO_FATAL_FAILURE(setParameters(Downmix::Type::FOLD));
+
+ // Get all the channels from input layout
+ std::set<int32_t> supportedChannels = getInputChannelLayouts();
+
+ for (int32_t channel : supportedChannels) {
+ size_t position = std::distance(supportedChannels.begin(), supportedChannels.find(channel));
+ generateInputBuffer(position, false /*isStripe*/);
+ ASSERT_NO_FATAL_FAILURE(
+ processAndWriteToOutput(mInputBuffer, mOutputBuffer, mEffect, &mOpenEffectReturn));
+ validateOutput(channel, position);
+ std::fill(mInputBuffer.begin(), mInputBuffer.end(), 0);
+ }
+}
+
+enum StripParamName { STRIP_INSTANCE_NAME, STRIP_INPUT_LAYOUT };
+
+using DownmixStripDataTestParam =
+ std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t>;
+
+class DownmixStripDataTest : public ::testing::TestWithParam<DownmixStripDataTestParam>,
+ public DownmixEffectHelper {
+ public:
+ DownmixStripDataTest() : mInputChannelLayout(std::get<STRIP_INPUT_LAYOUT>(GetParam())) {
+ std::tie(mFactory, mDescriptor) = std::get<STRIP_INSTANCE_NAME>(GetParam());
+ }
+
+ void SetUp() override {
+ SetUpDownmix(mInputChannelLayout);
+ if (int32_t version;
+ mEffect->getInterfaceVersion(&version).isOk() && version < kMinDataTestHalVersion) {
+ GTEST_SKIP() << "Skipping the data test for version: " << version << "\n";
+ }
+ if (!isLayoutValid(mInputChannelLayout)) {
+ GTEST_SKIP() << "Layout not supported \n";
+ }
+ setDataTestParams(mInputChannelLayout);
+ }
+
+ void TearDown() override { TearDownDownmix(); }
+
+ void validateOutput() {
+ ASSERT_EQ(kBufferSize, mInputBuffer.size());
+ ASSERT_GE(kBufferSize, mOutputBufferSize);
+ for (size_t i = 0, j = 0; i < kBufferSize && j < mOutputBufferSize;
+ i += mInputChannelCount, j += kOutputChannelCount) {
+ ASSERT_EQ(mOutputBuffer[j], mInputBuffer[i]);
+ ASSERT_EQ(mOutputBuffer[j + 1], mInputBuffer[i + 1]);
+ }
+ }
+
+ int32_t mInputChannelLayout;
+};
+
+TEST_P(DownmixStripDataTest, DownmixProcessData) {
+ // Set STRIP type parameter
+ ASSERT_NO_FATAL_FAILURE(setParameters(Downmix::Type::STRIP));
+
+ // Generate input buffer, call process and compare outputs
+ generateInputBuffer(0 /*position*/, true /*isStripe*/);
+ ASSERT_NO_FATAL_FAILURE(
+ processAndWriteToOutput(mInputBuffer, mOutputBuffer, mEffect, &mOpenEffectReturn));
+ validateOutput();
}
INSTANTIATE_TEST_SUITE_P(
@@ -126,7 +426,7 @@
[](const testing::TestParamInfo<DownmixParamTest::ParamType>& info) {
auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
std::string type = std::to_string(static_cast<int>(std::get<PARAM_TYPE>(info.param)));
- std::string name = getPrefix(descriptor) + "_type" + type;
+ std::string name = getPrefix(descriptor) + "_type_" + type;
std::replace_if(
name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
return name;
@@ -134,6 +434,39 @@
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DownmixParamTest);
+INSTANTIATE_TEST_SUITE_P(
+ DownmixTest, DownmixFoldDataTest,
+ ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, getEffectTypeUuidDownmix())),
+ testing::ValuesIn(kLayoutValues)),
+ [](const testing::TestParamInfo<DownmixFoldDataTest::ParamType>& info) {
+ auto descriptor = std::get<FOLD_INSTANCE_NAME>(info.param).second;
+ std::string layout = std::to_string(std::get<FOLD_INPUT_LAYOUT>(info.param));
+ std::string name = getPrefix(descriptor) + "_fold_layout_" + layout;
+ std::replace_if(
+ name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+ return name;
+ });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DownmixFoldDataTest);
+
+INSTANTIATE_TEST_SUITE_P(
+ DownmixTest, DownmixStripDataTest,
+ ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, getEffectTypeUuidDownmix())),
+ testing::ValuesIn(kLayoutValues)),
+ [](const testing::TestParamInfo<DownmixStripDataTest::ParamType>& info) {
+ auto descriptor = std::get<STRIP_INSTANCE_NAME>(info.param).second;
+ std::string layout =
+ std::to_string(static_cast<int>(std::get<STRIP_INPUT_LAYOUT>(info.param)));
+ std::string name = getPrefix(descriptor) + "_strip_layout_" + layout;
+ std::replace_if(
+ name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+ return name;
+ });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DownmixStripDataTest);
+
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer());
diff --git a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
index 2650f49..3f7a76d 100644
--- a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
+++ b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
@@ -18,7 +18,6 @@
#include <string>
#include <unordered_set>
-#include <aidl/Vintf.h>
#define LOG_TAG "VtsHalDynamicsProcessingTest"
#include <android-base/logging.h>
diff --git a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
index 474b361..765c377 100644
--- a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-#include <aidl/Vintf.h>
#define LOG_TAG "VtsHalEnvironmentalReverbTest"
#include <android-base/logging.h>
diff --git a/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
index 09396d1..d7dbe38 100644
--- a/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
@@ -15,15 +15,10 @@
*/
#include <algorithm>
-#include <limits>
-#include <map>
-#include <memory>
-#include <optional>
#include <string>
#include <vector>
#include <aidl/Gtest.h>
-#include <aidl/Vintf.h>
#include <aidl/android/hardware/audio/effect/IEffect.h>
#include <aidl/android/hardware/audio/effect/IFactory.h>
#define LOG_TAG "VtsHalEqualizerTest"
@@ -34,7 +29,6 @@
#include <android/binder_process.h>
#include <gtest/gtest.h>
-#include "AudioHalBinderServiceUtil.h"
#include "EffectHelper.h"
#include "TestUtils.h"
diff --git a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
index 5a32398..d312111 100644
--- a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
@@ -18,7 +18,6 @@
#include <utility>
#include <vector>
-#include <aidl/Vintf.h>
#define LOG_TAG "VtsHalHapticGeneratorTargetTest"
#include <android-base/logging.h>
#include <android/binder_enums.h>
diff --git a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
index 925f9ec..7f0091f 100644
--- a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
@@ -16,7 +16,6 @@
#include <string>
-#include <aidl/Vintf.h>
#define LOG_TAG "VtsHalLoudnessEnhancerTest"
#include <android-base/logging.h>
diff --git a/audio/aidl/vts/VtsHalNSTargetTest.cpp b/audio/aidl/vts/VtsHalNSTargetTest.cpp
index 12d56b0..5c13512 100644
--- a/audio/aidl/vts/VtsHalNSTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalNSTargetTest.cpp
@@ -16,7 +16,6 @@
#include <unordered_set>
-#include <aidl/Vintf.h>
#include <aidl/android/hardware/audio/effect/NoiseSuppression.h>
#define LOG_TAG "VtsHalNSParamTest"
#include <android-base/logging.h>
diff --git a/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp b/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
index 57eda09..1453495 100644
--- a/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-#include <aidl/Vintf.h>
#define LOG_TAG "VtsHalPresetReverbTargetTest"
#include <android-base/logging.h>
#include <android/binder_enums.h>
diff --git a/audio/aidl/vts/VtsHalSpatializerTargetTest.cpp b/audio/aidl/vts/VtsHalSpatializerTargetTest.cpp
new file mode 100644
index 0000000..f0b51b9
--- /dev/null
+++ b/audio/aidl/vts/VtsHalSpatializerTargetTest.cpp
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "VtsHalSpatializerTest"
+#include <android-base/logging.h>
+
+#include "EffectHelper.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidSpatializer;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::Parameter;
+using aidl::android::hardware::audio::effect::Range;
+using aidl::android::hardware::audio::effect::Spatializer;
+using aidl::android::media::audio::common::HeadTracking;
+using aidl::android::media::audio::common::Spatialization;
+using android::hardware::audio::common::testing::detail::TestExecutionTracer;
+using ::android::internal::ToString;
+
+enum ParamName {
+ PARAM_INSTANCE_NAME,
+ PARAM_SPATIALIZATION_LEVEL,
+ PARAM_SPATIALIZATION_MODE,
+ PARAM_HEADTRACK_SENSORID,
+ PARAM_HEADTRACK_MODE,
+ PARAM_HEADTRACK_CONNECTION_MODE
+};
+
+using SpatializerParamTestParam =
+ std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, Spatialization::Level,
+ Spatialization::Mode, int /* sensor ID */, HeadTracking::Mode,
+ HeadTracking::ConnectionMode>;
+
+class SpatializerParamTest : public ::testing::TestWithParam<SpatializerParamTestParam>,
+ public EffectHelper {
+ public:
+ SpatializerParamTest()
+ : mSpatializerParams([&]() {
+ Spatialization::Level level = std::get<PARAM_SPATIALIZATION_LEVEL>(GetParam());
+ Spatialization::Mode mode = std::get<PARAM_SPATIALIZATION_MODE>(GetParam());
+ int sensorId = std::get<PARAM_HEADTRACK_SENSORID>(GetParam());
+ HeadTracking::Mode htMode = std::get<PARAM_HEADTRACK_MODE>(GetParam());
+ HeadTracking::ConnectionMode htConnectMode =
+ std::get<PARAM_HEADTRACK_CONNECTION_MODE>(GetParam());
+ std::map<Spatializer::Tag, Spatializer> params;
+ params[Spatializer::spatializationLevel] =
+ Spatializer::make<Spatializer::spatializationLevel>(level);
+ params[Spatializer::spatializationMode] =
+ Spatializer::make<Spatializer::spatializationMode>(mode);
+ params[Spatializer::headTrackingSensorId] =
+ Spatializer::make<Spatializer::headTrackingSensorId>(sensorId);
+ params[Spatializer::headTrackingMode] =
+ Spatializer::make<Spatializer::headTrackingMode>(htMode);
+ params[Spatializer::headTrackingConnectionMode] =
+ Spatializer::make<Spatializer::headTrackingConnectionMode>(htConnectMode);
+ return params;
+ }()) {
+ std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+ }
+
+ void SetUp() override {
+ ASSERT_NE(nullptr, mFactory);
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+ Parameter::Specific specific = getDefaultParamSpecific();
+ Parameter::Common common = EffectHelper::createParamCommon(
+ 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+ kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+ IEffect::OpenEffectReturn ret;
+ ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+ ASSERT_NE(nullptr, mEffect);
+ }
+
+ void TearDown() override {
+ ASSERT_NO_FATAL_FAILURE(close(mEffect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+ }
+
+ Parameter::Specific getDefaultParamSpecific() {
+ Spatializer spatializer = Spatializer::make<Spatializer::headTrackingSensorId>(0);
+ Parameter::Specific specific =
+ Parameter::Specific::make<Parameter::Specific::spatializer>(spatializer);
+ return specific;
+ }
+
+ static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+ std::shared_ptr<IFactory> mFactory;
+ std::shared_ptr<IEffect> mEffect;
+ Descriptor mDescriptor;
+ const std::map<Spatializer::Tag, Spatializer> mSpatializerParams;
+};
+
+TEST_P(SpatializerParamTest, SetAndGetParam) {
+ for (const auto& it : mSpatializerParams) {
+ auto& tag = it.first;
+ auto& spatializer = it.second;
+
+ // validate parameter
+ Descriptor desc;
+ ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
+ const bool valid = isParameterValid<Spatializer, Range::spatializer>(it.second, desc);
+ const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+
+ // set parameter
+ Parameter expectParam;
+ Parameter::Specific specific;
+ specific.set<Parameter::Specific::spatializer>(spatializer);
+ expectParam.set<Parameter::specific>(specific);
+ EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
+
+ // only get if parameter in range and set success
+ if (expected == EX_NONE) {
+ Parameter getParam;
+ Parameter::Id id;
+ Spatializer::Id spatializerId;
+ spatializerId.set<Spatializer::Id::commonTag>(tag);
+ id.set<Parameter::Id::spatializerTag>(spatializerId);
+ // if set success, then get should match
+ EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
+ EXPECT_EQ(expectParam, getParam);
+ }
+ }
+}
+
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
+INSTANTIATE_TEST_SUITE_P(
+ SpatializerTest, SpatializerParamTest,
+ ::testing::Combine(
+ testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, getEffectTypeUuidSpatializer())),
+ testing::ValuesIn(EffectHelper::getTestValueSet<
+ Spatializer, Spatialization::Level, Range::spatializer,
+ Spatializer::spatializationLevel>(kDescPair)),
+ testing::ValuesIn(EffectHelper::getTestValueSet<
+ Spatializer, Spatialization::Mode, Range::spatializer,
+ Spatializer::spatializationMode>(kDescPair)),
+ testing::ValuesIn(
+ EffectHelper::getTestValueSet<Spatializer, int, Range::spatializer,
+ Spatializer::headTrackingSensorId>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>)),
+ testing::ValuesIn(EffectHelper::getTestValueSet<
+ Spatializer, HeadTracking::Mode, Range::spatializer,
+ Spatializer::headTrackingMode>(kDescPair)),
+ testing::ValuesIn(EffectHelper::getTestValueSet<
+ Spatializer, HeadTracking::ConnectionMode, Range::spatializer,
+ Spatializer::headTrackingConnectionMode>(kDescPair))),
+ [](const testing::TestParamInfo<SpatializerParamTest::ParamType>& info) {
+ auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+ std::string level = ToString(std::get<PARAM_SPATIALIZATION_LEVEL>(info.param));
+ std::string mode = ToString(std::get<PARAM_SPATIALIZATION_MODE>(info.param));
+ std::string sensorId = ToString(std::get<PARAM_HEADTRACK_SENSORID>(info.param));
+ std::string htMode = ToString(std::get<PARAM_HEADTRACK_MODE>(info.param));
+ std::string htConnectMode =
+ ToString(std::get<PARAM_HEADTRACK_CONNECTION_MODE>(info.param));
+ std::string name = getPrefix(descriptor) + "_sensorID_" + level + "_mode_" + mode +
+ "_sensorID_" + sensorId + "_HTMode_" + htMode +
+ "_HTConnectionMode_" + htConnectMode;
+ std::replace_if(
+ name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+ return name;
+ });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SpatializerParamTest);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer());
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp b/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
index 3e39d3a..0c24f90 100644
--- a/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-#include <aidl/Vintf.h>
#define LOG_TAG "VtsHalVirtualizerTest"
#include <android-base/logging.h>
diff --git a/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp b/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
index 1b8352b..db83715 100644
--- a/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
@@ -16,7 +16,6 @@
#include <unordered_set>
-#include <aidl/Vintf.h>
#define LOG_TAG "VtsHalVisualizerTest"
#include <android-base/logging.h>
#include <android/binder_enums.h>
diff --git a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
index 257100b..aa2c05f 100644
--- a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-#include <aidl/Vintf.h>
#define LOG_TAG "VtsHalVolumeTest"
#include <android-base/logging.h>
diff --git a/audio/common/2.0/Android.bp b/audio/common/2.0/Android.bp
index f27eb93..450e04f 100644
--- a/audio/common/2.0/Android.bp
+++ b/audio/common/2.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/common/4.0/Android.bp b/audio/common/4.0/Android.bp
index ea88b06..8a0fe72 100644
--- a/audio/common/4.0/Android.bp
+++ b/audio/common/4.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/common/5.0/Android.bp b/audio/common/5.0/Android.bp
index a6bb331..02f66a3 100644
--- a/audio/common/5.0/Android.bp
+++ b/audio/common/5.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/common/6.0/Android.bp b/audio/common/6.0/Android.bp
index 91721fc..fd4a1f5 100644
--- a/audio/common/6.0/Android.bp
+++ b/audio/common/6.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/common/7.0/Android.bp b/audio/common/7.0/Android.bp
index 2f7665e..5ef59ad 100644
--- a/audio/common/7.0/Android.bp
+++ b/audio/common/7.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/common/7.0/example/Android.bp b/audio/common/7.0/example/Android.bp
index a85e4fa..1d54697 100644
--- a/audio/common/7.0/example/Android.bp
+++ b/audio/common/7.0/example/Android.bp
@@ -14,6 +14,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/common/7.1/Android.bp b/audio/common/7.1/Android.bp
index a257510..57ce2d7 100644
--- a/audio/common/7.1/Android.bp
+++ b/audio/common/7.1/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/common/all-versions/default/Android.bp b/audio/common/all-versions/default/Android.bp
index 9543674..2fcc3c4 100644
--- a/audio/common/all-versions/default/Android.bp
+++ b/audio/common/all-versions/default/Android.bp
@@ -14,6 +14,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/common/all-versions/default/service/Android.bp b/audio/common/all-versions/default/service/Android.bp
index d513062..e2e0a93 100644
--- a/audio/common/all-versions/default/service/Android.bp
+++ b/audio/common/all-versions/default/service/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/common/all-versions/test/utility/Android.bp b/audio/common/all-versions/test/utility/Android.bp
index c6a3963..7fd3688 100644
--- a/audio/common/all-versions/test/utility/Android.bp
+++ b/audio/common/all-versions/test/utility/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/common/all-versions/util/Android.bp b/audio/common/all-versions/util/Android.bp
index 91de6ec..f9ada08 100644
--- a/audio/common/all-versions/util/Android.bp
+++ b/audio/common/all-versions/util/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/core/all-versions/default/Android.bp b/audio/core/all-versions/default/Android.bp
index 3536561..c55eef4 100644
--- a/audio/core/all-versions/default/Android.bp
+++ b/audio/core/all-versions/default/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/core/all-versions/default/util/Android.bp b/audio/core/all-versions/default/util/Android.bp
index b96f2d2..08ddb59 100644
--- a/audio/core/all-versions/default/util/Android.bp
+++ b/audio/core/all-versions/default/util/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp
index 9d93bb0..9e398e4 100644
--- a/audio/core/all-versions/vts/functional/Android.bp
+++ b/audio/core/all-versions/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/effect/2.0/Android.bp b/audio/effect/2.0/Android.bp
index f2f5124..c236c16 100644
--- a/audio/effect/2.0/Android.bp
+++ b/audio/effect/2.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/effect/2.0/xml/Android.bp b/audio/effect/2.0/xml/Android.bp
index d015639..cddcfe9 100644
--- a/audio/effect/2.0/xml/Android.bp
+++ b/audio/effect/2.0/xml/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/effect/4.0/Android.bp b/audio/effect/4.0/Android.bp
index 1eb754a..cae91c1 100644
--- a/audio/effect/4.0/Android.bp
+++ b/audio/effect/4.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/effect/4.0/xml/Android.bp b/audio/effect/4.0/xml/Android.bp
index 8c03a35..a45eecc 100644
--- a/audio/effect/4.0/xml/Android.bp
+++ b/audio/effect/4.0/xml/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -9,9 +10,9 @@
genrule {
name: "audio_effects_conf_V4_0",
- srcs: ["audio_effects_conf.xsd"],
+ srcs: [":audio_effects_conf_V2_0"],
out: [
"audio_effects_conf_V4_0.xsd",
],
- cmd: "cp -f $(in) $(genDir)/audio_effects_conf_V4_0.xsd",
+ cmd: "cp -f $(in) $(out)",
}
diff --git a/audio/effect/4.0/xml/audio_effects_conf.xsd b/audio/effect/4.0/xml/audio_effects_conf.xsd
deleted file mode 120000
index 9d85fa7..0000000
--- a/audio/effect/4.0/xml/audio_effects_conf.xsd
+++ /dev/null
@@ -1 +0,0 @@
-../../2.0/xml/audio_effects_conf.xsd
\ No newline at end of file
diff --git a/audio/effect/5.0/Android.bp b/audio/effect/5.0/Android.bp
index 126964c..ef3a28b 100644
--- a/audio/effect/5.0/Android.bp
+++ b/audio/effect/5.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/effect/5.0/xml/Android.bp b/audio/effect/5.0/xml/Android.bp
index 7982e2a..7a0b958 100644
--- a/audio/effect/5.0/xml/Android.bp
+++ b/audio/effect/5.0/xml/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -9,6 +10,6 @@
xsd_config {
name: "audio_effects_conf_V5_0",
- srcs: ["audio_effects_conf.xsd"],
+ srcs: [":audio_effects_conf_V2_0"],
package_name: "audio.effects.V5_0",
}
diff --git a/audio/effect/5.0/xml/audio_effects_conf.xsd b/audio/effect/5.0/xml/audio_effects_conf.xsd
deleted file mode 120000
index 9d85fa7..0000000
--- a/audio/effect/5.0/xml/audio_effects_conf.xsd
+++ /dev/null
@@ -1 +0,0 @@
-../../2.0/xml/audio_effects_conf.xsd
\ No newline at end of file
diff --git a/audio/effect/6.0/Android.bp b/audio/effect/6.0/Android.bp
index 8d15d09..8c52ebc 100644
--- a/audio/effect/6.0/Android.bp
+++ b/audio/effect/6.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/effect/6.0/xml/Android.bp b/audio/effect/6.0/xml/Android.bp
index f139341..9e1533c 100644
--- a/audio/effect/6.0/xml/Android.bp
+++ b/audio/effect/6.0/xml/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/effect/7.0/Android.bp b/audio/effect/7.0/Android.bp
index 7399cdb..248655e 100644
--- a/audio/effect/7.0/Android.bp
+++ b/audio/effect/7.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/effect/7.0/xml/Android.bp b/audio/effect/7.0/xml/Android.bp
index 978e434..82ed18b 100644
--- a/audio/effect/7.0/xml/Android.bp
+++ b/audio/effect/7.0/xml/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/effect/all-versions/default/Android.bp b/audio/effect/all-versions/default/Android.bp
index a3c3ed6..cea085c 100644
--- a/audio/effect/all-versions/default/Android.bp
+++ b/audio/effect/all-versions/default/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/effect/all-versions/default/util/Android.bp b/audio/effect/all-versions/default/util/Android.bp
index 143094d..53dd9ac 100644
--- a/audio/effect/all-versions/default/util/Android.bp
+++ b/audio/effect/all-versions/default/util/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/effect/all-versions/vts/functional/Android.bp b/audio/effect/all-versions/vts/functional/Android.bp
index 3b15ed4..4c07aad 100644
--- a/audio/effect/all-versions/vts/functional/Android.bp
+++ b/audio/effect/all-versions/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/policy/1.0/vts/functional/Android.bp b/audio/policy/1.0/vts/functional/Android.bp
index cccb2fc..b32c223 100644
--- a/audio/policy/1.0/vts/functional/Android.bp
+++ b/audio/policy/1.0/vts/functional/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/policy/1.0/xml/Android.bp b/audio/policy/1.0/xml/Android.bp
index 403278c..d644570 100644
--- a/audio/policy/1.0/xml/Android.bp
+++ b/audio/policy/1.0/xml/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/audio/policy/1.0/xml/pfw_schemas/Android.bp b/audio/policy/1.0/xml/pfw_schemas/Android.bp
index 225c065..18284e9 100644
--- a/audio/policy/1.0/xml/pfw_schemas/Android.bp
+++ b/audio/policy/1.0/xml/pfw_schemas/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/automotive/audiocontrol/aidl/default/Android.bp b/automotive/audiocontrol/aidl/default/Android.bp
index 435c2d6..a48d228 100644
--- a/automotive/audiocontrol/aidl/default/Android.bp
+++ b/automotive/audiocontrol/aidl/default/Android.bp
@@ -27,11 +27,13 @@
init_rc: ["audiocontrol-default.rc"],
vintf_fragments: ["audiocontrol-default.xml"],
vendor: true,
+ defaults: [
+ "latest_android_hardware_audio_common_ndk_shared",
+ "latest_android_hardware_automotive_audiocontrol_ndk_shared",
+ ],
shared_libs: [
"android.hardware.audio.common@7.0-enums",
- "android.hardware.audio.common-V1-ndk",
"android.frameworks.automotive.powerpolicy-V2-ndk",
- "android.hardware.automotive.audiocontrol-V3-ndk",
"libbase",
"libbinder_ndk",
"libcutils",
diff --git a/automotive/audiocontrol/aidl/default/AudioControl.cpp b/automotive/audiocontrol/aidl/default/AudioControl.cpp
index cf7307d..7e7e145 100644
--- a/automotive/audiocontrol/aidl/default/AudioControl.cpp
+++ b/automotive/audiocontrol/aidl/default/AudioControl.cpp
@@ -244,15 +244,15 @@
template <typename aidl_type>
static inline std::string toString(const std::vector<aidl_type>& in_values) {
return std::accumulate(std::begin(in_values), std::end(in_values), std::string{},
- [](std::string& ls, const aidl_type& rs) {
- return ls += (ls.empty() ? "" : ",") + rs.toString();
+ [](const std::string& ls, const aidl_type& rs) {
+ return ls + (ls.empty() ? "" : ",") + rs.toString();
});
}
template <typename aidl_enum_type>
static inline std::string toEnumString(const std::vector<aidl_enum_type>& in_values) {
return std::accumulate(std::begin(in_values), std::end(in_values), std::string{},
- [](std::string& ls, const aidl_enum_type& rs) {
- return ls += (ls.empty() ? "" : ",") + toString(rs);
+ [](const std::string& ls, const aidl_enum_type& rs) {
+ return ls + (ls.empty() ? "" : ",") + toString(rs);
});
}
diff --git a/automotive/can/1.0/default/CanSocket.h b/automotive/can/1.0/default/CanSocket.h
index fd956b5..f3e8e60 100644
--- a/automotive/can/1.0/default/CanSocket.h
+++ b/automotive/can/1.0/default/CanSocket.h
@@ -22,6 +22,7 @@
#include <atomic>
#include <chrono>
+#include <functional>
#include <thread>
namespace android::hardware::automotive::can::V1_0::implementation {
diff --git a/automotive/can/1.0/default/libnetdevice/ifreqs.h b/automotive/can/1.0/default/libnetdevice/ifreqs.h
index d8d6fe0..aa7030b 100644
--- a/automotive/can/1.0/default/libnetdevice/ifreqs.h
+++ b/automotive/can/1.0/default/libnetdevice/ifreqs.h
@@ -18,6 +18,7 @@
#include <net/if.h>
+#include <atomic>
#include <string>
namespace android::netdevice::ifreqs {
diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
index aad07de..413b4b1 100644
--- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
+++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
@@ -27,6 +27,8 @@
#include <linux/rtnetlink.h>
#include <net/if.h>
+#include <algorithm>
+#include <iterator>
#include <sstream>
namespace android::netdevice {
@@ -102,7 +104,7 @@
static bool hasIpv4(std::string ifname) {
auto ifr = ifreqs::fromName(ifname);
- switch (const auto status = ifreqs::trySend(SIOCGIFADDR, ifr)) {
+ switch (ifreqs::trySend(SIOCGIFADDR, ifr)) {
case 0:
return true;
case EADDRNOTAVAIL:
diff --git a/automotive/can/1.0/default/libnl++/common.cpp b/automotive/can/1.0/default/libnl++/common.cpp
index 23c2d94..1287bb5 100644
--- a/automotive/can/1.0/default/libnl++/common.cpp
+++ b/automotive/can/1.0/default/libnl++/common.cpp
@@ -20,6 +20,8 @@
#include <net/if.h>
+#include <algorithm>
+
namespace android::nl {
unsigned int nametoindex(const std::string& ifname) {
diff --git a/automotive/can/aidl/default/tools/configurator/canprototools.cpp b/automotive/can/aidl/default/tools/configurator/canprototools.cpp
index 84edd94..ead53c1 100644
--- a/automotive/can/aidl/default/tools/configurator/canprototools.cpp
+++ b/automotive/can/aidl/default/tools/configurator/canprototools.cpp
@@ -48,23 +48,18 @@
char buff[n];
auto got = s.read(buff, n).gcount();
if (!s.good() && !s.eof()) return std::nullopt;
- return std::string(buff, 0, std::min(n, got));
+ return std::string(buff, got);
}
-/*
- parseConfigFile *used to* contain the body of parseConfigStream. However, it seems there's some
- sort of odd behavior with IstreamInputStream and/or TextFormat::Parse, which causes HW Address
- Sanitizer to flag a "tag-mismatch" in this function. Having the ifstream defined in a wrapper
- function seems to solve this problem. The exact cause of this problem is yet unknown, but probably
- lies somewhere in the protobuf implementation.
-*/
-static __attribute__((noinline)) std::optional<CanBusConfig> parseConfigStream(
- std::ifstream& cfg_stream) {
+std::optional<CanBusConfig> parseConfigFile(const std::string& filepath) {
+ std::ifstream cfg_stream(filepath);
+
+ // text headers that would be present in a plaintext proto config file.
static const std::array<std::string, 3> text_headers = {"buses", "#", "controller"};
auto cfg_file_snippet = readString(cfg_stream, 10);
if (!cfg_file_snippet.has_value()) {
- LOG(ERROR) << "Can't read config from stream (maybe failed to open file?)";
+ LOG(ERROR) << "Can't open " << filepath << " for reading";
return std::nullopt;
}
cfg_stream.seekg(0);
@@ -82,25 +77,16 @@
if (text_format) {
google::protobuf::io::IstreamInputStream pb_stream(&cfg_stream);
if (!google::protobuf::TextFormat::Parse(&pb_stream, &config)) {
- LOG(ERROR) << "Parsing text format config failed";
+ LOG(ERROR) << "Failed to parse (text format) " << filepath;
return std::nullopt;
}
} else if (!config.ParseFromIstream(&cfg_stream)) {
- LOG(ERROR) << "Parsing binary format config failed";
+ LOG(ERROR) << "Failed to parse (binary format) " << filepath;
return std::nullopt;
}
return config;
}
-std::optional<CanBusConfig> parseConfigFile(const std::string& filepath) {
- std::ifstream cfg_stream(filepath);
- auto cfg_maybe = parseConfigStream(cfg_stream);
- if (!cfg_maybe.has_value()) {
- LOG(ERROR) << "Failed to parse " << filepath;
- }
- return cfg_maybe;
-}
-
std::optional<BusConfig> fromPbBus(const Bus& pb_bus) {
BusConfig bus_cfg = {};
bus_cfg.name = pb_bus.name();
diff --git a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
index 03f256e..ff7f41c 100644
--- a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
+++ b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
@@ -2010,6 +2010,13 @@
// Test each reported camera
for (auto&& cam: cameraInfo) {
+ bool isLogicalCam = false;
+ getPhysicalCameraIds(cam.v1.cameraId, isLogicalCam);
+ if (isLogicalCam) {
+ LOG(INFO) << "Skip a logical device " << cam.v1.cameraId;
+ continue;
+ }
+
// Request exclusive access to the EVS display
sp<IEvsDisplay_1_0> pDisplay = pEnumerator->openDisplay();
ASSERT_NE(pDisplay, nullptr);
diff --git a/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp b/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp
index 8181e47..e3f7b5e 100644
--- a/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp
+++ b/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp
@@ -222,10 +222,9 @@
// Lock our output buffer for writing
uint8_t* pixels = nullptr;
- int32_t bytesPerStride = 0;
auto& mapper = ::android::GraphicBufferMapper::get();
mapper.lock(renderBufferHandle, GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_NEVER,
- ::android::Rect(mWidth, mHeight), (void**)&pixels, nullptr, &bytesPerStride);
+ ::android::Rect(mWidth, mHeight), (void**)&pixels);
// If we failed to lock the pixel buffer, we're about to crash, but log it first
if (!pixels) {
@@ -247,13 +246,6 @@
*(pixels++) = *(v_head++);
}
- const auto status =
- AMediaCodec_releaseOutputBuffer(mVideoCodec.get(), index, /* render = */ false);
- if (status != AMEDIA_OK) {
- LOG(ERROR) << __func__
- << ": Received error in releasing output buffer. Error code: " << status;
- }
-
// Release our output buffer
mapper.unlock(renderBufferHandle);
@@ -306,6 +298,12 @@
return;
}
onCodecOutputAvailable(codecOutputputBufferIdx, info);
+ const auto release_status = AMediaCodec_releaseOutputBuffer(
+ mVideoCodec.get(), codecOutputputBufferIdx, /* render = */ false);
+ if (release_status != AMEDIA_OK) {
+ LOG(ERROR) << __func__
+ << ": Received error in releasing output buffer. Error code: " << release_status;
+ }
}
void EvsVideoEmulatedCamera::initializeParameters() {
diff --git a/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp b/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp
index 3419b3c..477de31 100644
--- a/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp
+++ b/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp
@@ -1399,6 +1399,12 @@
// Test each reported camera
for (auto&& cam : mCameraInfo) {
+ bool isLogicalCam = false;
+ if (getPhysicalCameraIds(cam.id, isLogicalCam); isLogicalCam) {
+ LOG(INFO) << "Skip a logical device, " << cam.id;
+ continue;
+ }
+
// Request available display IDs
uint8_t targetDisplayId = 0;
std::vector<uint8_t> displayIds;
@@ -1973,6 +1979,13 @@
// Test each reported camera
for (auto&& cam : mCameraInfo) {
+ bool isLogicalCam = false;
+ getPhysicalCameraIds(cam.id, isLogicalCam);
+ if (isLogicalCam) {
+ LOG(INFO) << "Skip a logical device, " << cam.id;
+ continue;
+ }
+
// Read a target resolution from the metadata
Stream targetCfg = getFirstStreamConfiguration(
reinterpret_cast<camera_metadata_t*>(cam.metadata.data()));
@@ -2014,9 +2027,6 @@
}
}
- bool isLogicalCam = false;
- getPhysicalCameraIds(cam.id, isLogicalCam);
-
std::shared_ptr<IEvsCamera> pCam;
ASSERT_TRUE(mEnumerator->openCamera(cam.id, targetCfg, &pCam).isOk());
EXPECT_NE(pCam, nullptr);
@@ -2027,11 +2037,6 @@
// Request to import buffers
int delta = 0;
auto status = pCam->importExternalBuffers(buffers, &delta);
- if (isLogicalCam) {
- ASSERT_FALSE(status.isOk());
- continue;
- }
-
ASSERT_TRUE(status.isOk());
EXPECT_GE(delta, kBuffersToHold);
diff --git a/automotive/remoteaccess/TEST_MAPPING b/automotive/remoteaccess/TEST_MAPPING
new file mode 100644
index 0000000..81c16c1
--- /dev/null
+++ b/automotive/remoteaccess/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "auto-presubmit": [
+ {
+ "name": "VtsHalAutomotiveRemoteAccess_TargetTest"
+ }
+ ]
+}
diff --git a/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
index ccfa22d..5c5917b 100644
--- a/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
+++ b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
@@ -41,9 +41,10 @@
void clearRemoteTaskCallback();
void notifyApStateChange(in android.hardware.automotive.remoteaccess.ApState state);
boolean isTaskScheduleSupported();
+ android.hardware.automotive.remoteaccess.TaskType[] getSupportedTaskTypesForScheduling();
void scheduleTask(in android.hardware.automotive.remoteaccess.ScheduleInfo scheduleInfo);
void unscheduleTask(String clientId, String scheduleId);
void unscheduleAllTasks(String clientId);
boolean isTaskScheduled(String clientId, String scheduleId);
- List<android.hardware.automotive.remoteaccess.ScheduleInfo> getAllScheduledTasks(String clientId);
+ List<android.hardware.automotive.remoteaccess.ScheduleInfo> getAllPendingScheduledTasks(String clientId);
}
diff --git a/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl
index a929e10..ec8733a 100644
--- a/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl
+++ b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl
@@ -36,8 +36,10 @@
parcelable ScheduleInfo {
String clientId;
String scheduleId;
+ android.hardware.automotive.remoteaccess.TaskType taskType;
byte[] taskData;
int count;
long startTimeInEpochSeconds;
long periodicInSeconds;
+ const int MAX_TASK_DATA_SIZE_IN_BYTES = 10240;
}
diff --git a/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/TaskType.aidl b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/TaskType.aidl
new file mode 100644
index 0000000..da70626
--- /dev/null
+++ b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/TaskType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.automotive.remoteaccess;
+@Backing(type="int") @VintfStability
+enum TaskType {
+ CUSTOM = 0,
+ ENTER_GARAGE_MODE = 1,
+}
diff --git a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
index 4912651..f0468c4 100644
--- a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
+++ b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
@@ -19,12 +19,39 @@
import android.hardware.automotive.remoteaccess.ApState;
import android.hardware.automotive.remoteaccess.IRemoteTaskCallback;
import android.hardware.automotive.remoteaccess.ScheduleInfo;
+import android.hardware.automotive.remoteaccess.TaskType;
/**
- * Interface representing a remote wakeup client.
+ * The remote access HAL.
*
- * A wakeup client is a binary outside Android framework that communicates with
- * a wakeup server and receives wake up command.
+ * <p>This HAL represents an external system that is always on even when Android
+ * is powered off. It is capable of wakeing up and notifying Android when a
+ * remote task arrives.
+ *
+ * <p>For cloud-based remote access, a cloud server will issue the remote task
+ * to the external system, which will then be forwarded to Android. The client
+ * is expected to call {@code setRemoteTaskCallback} to register the remote
+ * task callback and uses the information returned from {@code getVehicleId},
+ * {@code getWakeupServiceName} and {@code getProcessorId} to register with
+ * a remote server.
+ *
+ * <p>For serverless remote access, the remote task comes from the external
+ * system alone and no server is involved. The external system may support
+ * scheduling a remote task to executed later through {@code scheduleTask}.
+ *
+ * <p>For both cloud-based and serverless remote access, the ideal use case
+ * is to wake up Android when the vehicle is not in use and then shutdown
+ * Android after the task is complete. However, user may access the vehicle
+ * during this period, and Android must not be shutdown if this happens.
+ *
+ * <p>If this interface is implemented, then VHAL property
+ * {@code VEHICLE_IN_USE} must be supported to represent whether the vehicle is
+ * currently in use. Android will check this before sending the shutdown
+ * request.
+ *
+ * <p>The external power controller system must also check whether vehicle is
+ * in use upon receiving the shutdown request and makes sure that an
+ * user-unexpected shutdown must not happen.
*/
@VintfStability
interface IRemoteAccess {
@@ -110,6 +137,17 @@
boolean isTaskScheduleSupported();
/**
+ * Returns the supported task types for scheduling.
+ *
+ * <p>If task scheduling is not supported, this returns an empty array.
+ *
+ * <p>Otherwise, at least {@code TaskType.CUSTOM} must be supported.
+ *
+ * @return An array of supported task types.
+ */
+ TaskType[] getSupportedTaskTypesForScheduling();
+
+ /**
* Schedules a task to be executed later even when the vehicle is off.
*
* <p>If {@link isTaskScheduleSupported} returns {@code false}. This is no-op.
@@ -127,6 +165,11 @@
*
* <p>Must return {@code EX_ILLEGAL_ARGUMENT} if a pending schedule with the same
* {@code scheduleId} for this client exists.
+ *
+ * <p>Must return {@code EX_ILLEGAL_ARGUMENT} if the task type is not supported.
+ *
+ * <p>Must return {@code EX_ILLEGLA_ARGUMENT} if the scheduleInfo is not valid (e.g. count is
+ * a negative number).
*/
void scheduleTask(in ScheduleInfo scheduleInfo);
@@ -161,5 +204,5 @@
*
* <p>The finished scheduled tasks will not be included.
*/
- List<ScheduleInfo> getAllScheduledTasks(String clientId);
+ List<ScheduleInfo> getAllPendingScheduledTasks(String clientId);
}
diff --git a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.aidl b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.aidl
index 2cd7a5d..ee6f900 100644
--- a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.aidl
+++ b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.aidl
@@ -22,7 +22,7 @@
@VintfStability
interface IRemoteTaskCallback {
/**
- * A callback that is called when a remote task is requested.
+ * A callback that is called when a custom type remote task is requested.
*
* The data is passed down from the remote server to the remote task client
* which is an Android application, and is not interpreted/parsed by the
diff --git a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl
index cf1437b..4f2537c 100644
--- a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl
+++ b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl
@@ -16,9 +16,12 @@
package android.hardware.automotive.remoteaccess;
+import android.hardware.automotive.remoteaccess.TaskType;
+
@VintfStability
@JavaDerive(equals=true, toString=true)
parcelable ScheduleInfo {
+ const int MAX_TASK_DATA_SIZE_IN_BYTES = 10240;
/**
* The ID used to identify the client this schedule is for. This must be one of the
* preconfigured remote access serverless client ID defined in car service resource
@@ -31,8 +34,16 @@
*/
String scheduleId;
/**
+ * The type for the task.
+ */
+ TaskType taskType;
+ /**
* The opaque task data that will be sent back to the remote task client app when the task is
* executed. It is not interpreted/parsed by the Android system.
+ *
+ * <p>This is only used for {@code TaskType.CUSTOM}.
+ *
+ * <p>The data size must be less than {@link MAX_TASK_DATA_SIZE_IN_BYTES}.
*/
byte[] taskData;
/**
diff --git a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/TaskType.aidl b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/TaskType.aidl
new file mode 100644
index 0000000..761eb15
--- /dev/null
+++ b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/TaskType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.remoteaccess;
+
+@VintfStability
+@Backing(type="int")
+enum TaskType {
+ /**
+ * A custom task that is opaque to anyone other than the remote task client app.
+ *
+ * <p>The opaque task data in the {@code ScheduleInfo} will be sent back to the app when the
+ * task is to be executed.
+ */
+ CUSTOM = 0,
+ /**
+ * Enters the garage mode if allowed.
+ *
+ * <p>Make the Android system enters garage mode if vehicle is currently not in use and
+ * entering garage mode is allowed (e.g. battery level is high enough).
+ *
+ * <p>This is based on best-effort and it is not guaranteed.
+ *
+ * <p>If allowed, the external system should set {@code AP_POWER_BOOTUP_REASON} to
+ * {@code SYSTEM_ENTER_GARAGE_MODE} and then boot up (or resume) the head unit.
+ */
+ ENTER_GARAGE_MODE = 1,
+}
diff --git a/automotive/remoteaccess/hal/default/Android.bp b/automotive/remoteaccess/hal/default/Android.bp
index 97ed2c1..be6a425 100644
--- a/automotive/remoteaccess/hal/default/Android.bp
+++ b/automotive/remoteaccess/hal/default/Android.bp
@@ -53,7 +53,9 @@
vintf_fragments: ["remoteaccess-default-service.xml"],
init_rc: ["remoteaccess-default-service.rc"],
cflags: [
- "-DGRPC_SERVICE_ADDRESS=\"10.0.2.2:50051\"",
+ // Uncomment this if running on emulator and connecting to a local grpc server
+ // running on host 127.0.0.1:50051 (TestWakeupClientServerHost)
+ // "-DGRPC_SERVICE_ADDRESS=\"10.0.2.2:50051\"",
],
}
diff --git a/automotive/remoteaccess/hal/default/fuzzer/fuzzer.cpp b/automotive/remoteaccess/hal/default/fuzzer/fuzzer.cpp
index 9224ebc..7707ee6 100644
--- a/automotive/remoteaccess/hal/default/fuzzer/fuzzer.cpp
+++ b/automotive/remoteaccess/hal/default/fuzzer/fuzzer.cpp
@@ -75,8 +75,9 @@
return Status::OK;
}
- Status GetAllScheduledTasks(ClientContext* context, const GetAllScheduledTasksRequest& request,
- GetAllScheduledTasksResponse* response) {
+ Status GetAllPendingScheduledTasks(ClientContext* context,
+ const GetAllPendingScheduledTasksRequest& request,
+ GetAllPendingScheduledTasksResponse* response) {
return Status::OK;
}
@@ -165,17 +166,19 @@
return nullptr;
}
- ClientAsyncResponseReaderInterface<GetAllScheduledTasksResponse>* AsyncGetAllScheduledTasksRaw(
+ ClientAsyncResponseReaderInterface<GetAllPendingScheduledTasksResponse>*
+ AsyncGetAllPendingScheduledTasksRaw(
[[maybe_unused]] ClientContext* context,
- [[maybe_unused]] const GetAllScheduledTasksRequest& request,
+ [[maybe_unused]] const GetAllPendingScheduledTasksRequest& request,
[[maybe_unused]] CompletionQueue* cq) {
return nullptr;
}
- ClientAsyncResponseReaderInterface<GetAllScheduledTasksResponse>*
- PrepareAsyncGetAllScheduledTasksRaw([[maybe_unused]] ClientContext* context,
- [[maybe_unused]] const GetAllScheduledTasksRequest& request,
- [[maybe_unused]] CompletionQueue* c) {
+ ClientAsyncResponseReaderInterface<GetAllPendingScheduledTasksResponse>*
+ PrepareAsyncGetAllPendingScheduledTasksRaw(
+ [[maybe_unused]] ClientContext* context,
+ [[maybe_unused]] const GetAllPendingScheduledTasksRequest& request,
+ [[maybe_unused]] CompletionQueue* c) {
return nullptr;
}
};
diff --git a/automotive/remoteaccess/hal/default/include/RemoteAccessService.h b/automotive/remoteaccess/hal/default/include/RemoteAccessService.h
index 1fc4037..8716e48 100644
--- a/automotive/remoteaccess/hal/default/include/RemoteAccessService.h
+++ b/automotive/remoteaccess/hal/default/include/RemoteAccessService.h
@@ -81,6 +81,9 @@
ndk::ScopedAStatus isTaskScheduleSupported(bool* out) override;
+ ndk::ScopedAStatus getSupportedTaskTypesForScheduling(
+ std::vector<aidl::android::hardware::automotive::remoteaccess::TaskType>* out) override;
+
ndk::ScopedAStatus scheduleTask(
const aidl::android::hardware::automotive::remoteaccess::ScheduleInfo& scheduleInfo)
override;
@@ -93,7 +96,7 @@
ndk::ScopedAStatus isTaskScheduled(const std::string& clientId, const std::string& scheduleId,
bool* out) override;
- ndk::ScopedAStatus getAllScheduledTasks(
+ ndk::ScopedAStatus getAllPendingScheduledTasks(
const std::string& clientId,
std::vector<aidl::android::hardware::automotive::remoteaccess::ScheduleInfo>* out)
override;
@@ -108,6 +111,8 @@
WakeupClient::StubInterface* mGrpcStub;
std::thread mThread;
+ // Whether the GRPC server exists. Only checked and set during init.
+ bool mGrpcServerExist = false;
std::mutex mLock;
std::condition_variable mCv;
std::shared_ptr<aidl::android::hardware::automotive::remoteaccess::IRemoteTaskCallback>
@@ -118,7 +123,7 @@
// A mutex to make sure startTaskLoop does not overlap with stopTaskLoop.
std::mutex mStartStopTaskLoopLock;
bool mTaskLoopRunning GUARDED_BY(mStartStopTaskLoopLock) = false;
- bool mGrpcConnected GUARDED_BY(mLock) = false;
+ bool mGrpcReadChannelOpen GUARDED_BY(mLock) = false;
std::unordered_map<std::string, size_t> mClientIdToTaskCount GUARDED_BY(mLock);
// Default wait time before retry connecting to remote access client is 10s.
@@ -140,9 +145,10 @@
void debugInjectTask(int fd, std::string_view clientId, std::string_view taskData);
void debugInjectTaskNextReboot(int fd, std::string_view clientId, std::string_view taskData,
const char* latencyInSecStr);
- void updateGrpcConnected(bool connected);
+ void updateGrpcReadChannelOpen(bool grpcReadChannelOpen);
android::base::Result<void> deliverRemoteTaskThroughCallback(const std::string& clientId,
std::string_view taskData);
+ bool isTaskScheduleSupported();
};
} // namespace remoteaccess
diff --git a/automotive/remoteaccess/hal/default/proto/wakeup_client.proto b/automotive/remoteaccess/hal/default/proto/wakeup_client.proto
index e061016..14ba0a5 100644
--- a/automotive/remoteaccess/hal/default/proto/wakeup_client.proto
+++ b/automotive/remoteaccess/hal/default/proto/wakeup_client.proto
@@ -99,7 +99,8 @@
*
* <p>The finished scheduled tasks will not be included.
*/
- rpc GetAllScheduledTasks(GetAllScheduledTasksRequest) returns (GetAllScheduledTasksResponse) {}
+ rpc GetAllPendingScheduledTasks(GetAllPendingScheduledTasksRequest)
+ returns (GetAllPendingScheduledTasksResponse) {}
}
message GetRemoteTasksRequest {}
@@ -154,10 +155,10 @@
bool isTaskScheduled = 1;
}
-message GetAllScheduledTasksRequest {
+message GetAllPendingScheduledTasksRequest {
string clientId = 1;
}
-message GetAllScheduledTasksResponse {
+message GetAllPendingScheduledTasksResponse {
repeated GrpcScheduleInfo allScheduledTasks = 1;
}
diff --git a/automotive/remoteaccess/hal/default/src/RemoteAccessImpl.cpp b/automotive/remoteaccess/hal/default/src/RemoteAccessImpl.cpp
index d4ba864..28c5cd5 100644
--- a/automotive/remoteaccess/hal/default/src/RemoteAccessImpl.cpp
+++ b/automotive/remoteaccess/hal/default/src/RemoteAccessImpl.cpp
@@ -30,10 +30,9 @@
constexpr char SERVICE_NAME[] = "android.hardware.automotive.remoteaccess.IRemoteAccess/default";
int main(int /* argc */, char* /* argv */[]) {
-#ifndef GRPC_SERVICE_ADDRESS
- LOG(ERROR) << "GRPC_SERVICE_ADDRESS is not defined, exiting";
- exit(1);
-#endif
+ android::hardware::automotive::remoteaccess::WakeupClient::StubInterface* grpcStub = nullptr;
+
+#ifdef GRPC_SERVICE_ADDRESS
LOG(INFO) << "Registering RemoteAccessService as service, server: " << GRPC_SERVICE_ADDRESS
<< "...";
grpc::ChannelArguments grpcargs = {};
@@ -47,11 +46,18 @@
android::netdevice::waitFor({GRPC_SERVICE_IFNAME},
android::netdevice::WaitCondition::PRESENT_AND_UP);
LOG(INFO) << "Waiting for interface: " << GRPC_SERVICE_IFNAME << " done";
-#endif
+#endif // #ifdef GRPC_SERVICE_IFNAME
auto channel = grpc::CreateChannel(GRPC_SERVICE_ADDRESS, grpc::InsecureChannelCredentials());
auto clientStub = android::hardware::automotive::remoteaccess::WakeupClient::NewStub(channel);
+
+ grpcStub = clientStub.get();
+
+#else
+ LOG(INFO) << "GRPC_SERVICE_ADDRESS is not defined, work in fake mode";
+#endif // #ifdef GRPC_SERVICE_ADDRESS
+
auto service = ndk::SharedRefBase::make<
- android::hardware::automotive::remoteaccess::RemoteAccessService>(clientStub.get());
+ android::hardware::automotive::remoteaccess::RemoteAccessService>(grpcStub);
binder_exception_t err = AServiceManager_addService(service->asBinder().get(), SERVICE_NAME);
if (err != EX_NONE) {
diff --git a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
index 0944d86..dbd5bed 100644
--- a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
+++ b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
@@ -40,6 +40,7 @@
using ::aidl::android::hardware::automotive::remoteaccess::ApState;
using ::aidl::android::hardware::automotive::remoteaccess::IRemoteTaskCallback;
using ::aidl::android::hardware::automotive::remoteaccess::ScheduleInfo;
+using ::aidl::android::hardware::automotive::remoteaccess::TaskType;
using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
using ::android::base::Error;
using ::android::base::ParseInt;
@@ -102,6 +103,10 @@
RemoteAccessService::RemoteAccessService(WakeupClient::StubInterface* grpcStub)
: mGrpcStub(grpcStub) {
+ if (mGrpcStub != nullptr) {
+ mGrpcServerExist = true;
+ }
+
std::ifstream debugTaskFile;
debugTaskFile.open(DEBUG_TASK_FILE, std::ios::in);
if (!debugTaskFile.is_open()) {
@@ -176,9 +181,9 @@
mTaskLoopRunning = false;
}
-void RemoteAccessService::updateGrpcConnected(bool connected) {
+void RemoteAccessService::updateGrpcReadChannelOpen(bool grpcReadChannelOpen) {
std::lock_guard<std::mutex> lockGuard(mLock);
- mGrpcConnected = connected;
+ mGrpcReadChannelOpen = grpcReadChannelOpen;
}
Result<void> RemoteAccessService::deliverRemoteTaskThroughCallback(const std::string& clientId,
@@ -212,7 +217,7 @@
mGetRemoteTasksContext.reset(new ClientContext());
reader = mGrpcStub->GetRemoteTasks(mGetRemoteTasksContext.get(), request);
}
- updateGrpcConnected(true);
+ updateGrpcReadChannelOpen(true);
GetRemoteTasksResponse response;
while (reader->Read(&response)) {
ALOGI("Receiving one task from remote task client");
@@ -224,7 +229,7 @@
continue;
}
}
- updateGrpcConnected(false);
+ updateGrpcReadChannelOpen(false);
Status status = reader->Finish();
mGetRemoteTasksContext.reset();
@@ -297,6 +302,11 @@
}
ScopedAStatus RemoteAccessService::notifyApStateChange(const ApState& newState) {
+ if (!mGrpcServerExist) {
+ ALOGW("GRPC server does not exist, do nothing");
+ return ScopedAStatus::ok();
+ }
+
ClientContext context;
NotifyWakeupRequiredRequest request = {};
request.set_iswakeuprequired(newState.isWakeupRequired);
@@ -314,15 +324,61 @@
return ScopedAStatus::ok();
}
+bool RemoteAccessService::isTaskScheduleSupported() {
+ if (!mGrpcServerExist) {
+ ALOGW("GRPC server does not exist, task scheduling not supported");
+ return false;
+ }
+
+ return true;
+}
+
ScopedAStatus RemoteAccessService::isTaskScheduleSupported(bool* out) {
- *out = true;
+ *out = isTaskScheduleSupported();
+ return ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RemoteAccessService::getSupportedTaskTypesForScheduling(
+ std::vector<TaskType>* out) {
+ out->clear();
+ if (!isTaskScheduleSupported()) {
+ ALOGW("Task scheduleing is not supported, return empty task types");
+ return ScopedAStatus::ok();
+ }
+
+ // TODO(b/316233421): support ENTER_GARAGE_MODE type.
+ out->push_back(TaskType::CUSTOM);
return ScopedAStatus::ok();
}
ScopedAStatus RemoteAccessService::scheduleTask(const ScheduleInfo& scheduleInfo) {
+ if (!isTaskScheduleSupported()) {
+ ALOGW("Task scheduleing is not supported, return exception");
+ return ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "task scheduling is not supported");
+ }
+
ClientContext context;
ScheduleTaskRequest request = {};
ScheduleTaskResponse response = {};
+
+ if (scheduleInfo.count < 0) {
+ return ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "count must be >= 0");
+ }
+ if (scheduleInfo.startTimeInEpochSeconds < 0) {
+ return ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "startTimeInEpochSeconds must be >= 0");
+ }
+ if (scheduleInfo.periodicInSeconds < 0) {
+ return ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "periodicInSeconds must be >= 0");
+ }
+ if (scheduleInfo.taskData.size() > scheduleInfo.MAX_TASK_DATA_SIZE_IN_BYTES) {
+ return ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "task data too big");
+ }
+
request.mutable_scheduleinfo()->set_clientid(scheduleInfo.clientId);
request.mutable_scheduleinfo()->set_scheduleid(scheduleInfo.scheduleId);
request.mutable_scheduleinfo()->set_data(scheduleInfo.taskData.data(),
@@ -340,7 +396,8 @@
case ErrorCode::OK:
return ScopedAStatus::ok();
case ErrorCode::INVALID_ARG:
- return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ return ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "received invalid_arg from grpc server");
default:
// Should not happen.
return ScopedAStatus::fromServiceSpecificErrorWithMessage(
@@ -352,6 +409,11 @@
ScopedAStatus RemoteAccessService::unscheduleTask(const std::string& clientId,
const std::string& scheduleId) {
+ if (!isTaskScheduleSupported()) {
+ ALOGW("Task scheduleing is not supported, do nothing");
+ return ScopedAStatus::ok();
+ }
+
ClientContext context;
UnscheduleTaskRequest request = {};
UnscheduleTaskResponse response = {};
@@ -365,6 +427,11 @@
}
ScopedAStatus RemoteAccessService::unscheduleAllTasks(const std::string& clientId) {
+ if (!isTaskScheduleSupported()) {
+ ALOGW("Task scheduleing is not supported, do nothing");
+ return ScopedAStatus::ok();
+ }
+
ClientContext context;
UnscheduleAllTasksRequest request = {};
UnscheduleAllTasksResponse response = {};
@@ -378,6 +445,12 @@
ScopedAStatus RemoteAccessService::isTaskScheduled(const std::string& clientId,
const std::string& scheduleId, bool* out) {
+ if (!isTaskScheduleSupported()) {
+ ALOGW("Task scheduleing is not supported, return false");
+ *out = false;
+ return ScopedAStatus::ok();
+ }
+
ClientContext context;
IsTaskScheduledRequest request = {};
IsTaskScheduledResponse response = {};
@@ -391,13 +464,19 @@
return ScopedAStatus::ok();
}
-ScopedAStatus RemoteAccessService::getAllScheduledTasks(const std::string& clientId,
- std::vector<ScheduleInfo>* out) {
+ScopedAStatus RemoteAccessService::getAllPendingScheduledTasks(const std::string& clientId,
+ std::vector<ScheduleInfo>* out) {
+ if (!isTaskScheduleSupported()) {
+ ALOGW("Task scheduleing is not supported, return empty array");
+ out->clear();
+ return ScopedAStatus::ok();
+ }
+
ClientContext context;
- GetAllScheduledTasksRequest request = {};
- GetAllScheduledTasksResponse response = {};
+ GetAllPendingScheduledTasksRequest request = {};
+ GetAllPendingScheduledTasksResponse response = {};
request.set_clientid(clientId);
- Status status = mGrpcStub->GetAllScheduledTasks(&context, request, &response);
+ Status status = mGrpcStub->GetAllPendingScheduledTasks(&context, request, &response);
if (!status.ok()) {
return rpcStatusToScopedAStatus(status, "Failed to call isTaskScheduled");
}
@@ -533,9 +612,11 @@
dprintf(fd,
"\nRemoteAccess HAL status \n"
"Remote task callback registered: %s\n"
- "Task receiving GRPC connection established: %s\n"
+ "GRPC server exist: %s\n"
+ "GRPC read channel for receiving tasks open: %s\n"
"Received task count by clientId: \n%s\n",
- boolToString(mRemoteTaskCallback.get()).c_str(), boolToString(mGrpcConnected).c_str(),
+ boolToString(mRemoteTaskCallback.get()).c_str(), boolToString(mGrpcServerExist).c_str(),
+ boolToString(mGrpcReadChannelOpen).c_str(),
clientIdToTaskCountToStringLocked().c_str());
}
diff --git a/automotive/remoteaccess/hal/default/test/RemoteAccessServiceUnitTest.cpp b/automotive/remoteaccess/hal/default/test/RemoteAccessServiceUnitTest.cpp
index c0038c2..7992a50 100644
--- a/automotive/remoteaccess/hal/default/test/RemoteAccessServiceUnitTest.cpp
+++ b/automotive/remoteaccess/hal/default/test/RemoteAccessServiceUnitTest.cpp
@@ -48,6 +48,7 @@
using ::aidl::android::hardware::automotive::remoteaccess::ApState;
using ::aidl::android::hardware::automotive::remoteaccess::BnRemoteTaskCallback;
using ::aidl::android::hardware::automotive::remoteaccess::ScheduleInfo;
+using ::aidl::android::hardware::automotive::remoteaccess::TaskType;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
using ::grpc::ClientAsyncReaderInterface;
@@ -61,6 +62,7 @@
using ::ndk::ScopedAStatus;
using ::testing::_;
using ::testing::DoAll;
+using ::testing::ElementsAre;
using ::testing::Return;
using ::testing::SetArgPointee;
@@ -93,9 +95,9 @@
MOCK_METHOD(Status, IsTaskScheduled,
(ClientContext * context, const IsTaskScheduledRequest& request,
IsTaskScheduledResponse* response));
- MOCK_METHOD(Status, GetAllScheduledTasks,
- (ClientContext * context, const GetAllScheduledTasksRequest& request,
- GetAllScheduledTasksResponse* response));
+ MOCK_METHOD(Status, GetAllPendingScheduledTasks,
+ (ClientContext * context, const GetAllPendingScheduledTasksRequest& request,
+ GetAllPendingScheduledTasksResponse* response));
// Async methods which we do not care.
MOCK_METHOD(ClientAsyncReaderInterface<GetRemoteTasksResponse>*, AsyncGetRemoteTasksRaw,
(ClientContext * context, const GetRemoteTasksRequest& request, CompletionQueue* cq,
@@ -139,13 +141,13 @@
PrepareAsyncIsTaskScheduledRaw,
(ClientContext * context, const IsTaskScheduledRequest& request,
CompletionQueue* cq));
- MOCK_METHOD(ClientAsyncResponseReaderInterface<GetAllScheduledTasksResponse>*,
- AsyncGetAllScheduledTasksRaw,
- (ClientContext * context, const GetAllScheduledTasksRequest& request,
+ MOCK_METHOD(ClientAsyncResponseReaderInterface<GetAllPendingScheduledTasksResponse>*,
+ AsyncGetAllPendingScheduledTasksRaw,
+ (ClientContext * context, const GetAllPendingScheduledTasksRequest& request,
CompletionQueue* cq));
- MOCK_METHOD(ClientAsyncResponseReaderInterface<GetAllScheduledTasksResponse>*,
- PrepareAsyncGetAllScheduledTasksRaw,
- (ClientContext * context, const GetAllScheduledTasksRequest& request,
+ MOCK_METHOD(ClientAsyncResponseReaderInterface<GetAllPendingScheduledTasksResponse>*,
+ PrepareAsyncGetAllPendingScheduledTasksRaw,
+ (ClientContext * context, const GetAllPendingScheduledTasksRequest& request,
CompletionQueue* cq));
};
@@ -434,6 +436,14 @@
EXPECT_TRUE(out);
}
+TEST_F(RemoteAccessServiceUnitTest, TestGetSupportedTaskTypesForScheduling) {
+ std::vector<TaskType> out;
+ ScopedAStatus status = getService()->getSupportedTaskTypesForScheduling(&out);
+
+ EXPECT_TRUE(status.isOk());
+ EXPECT_THAT(out, ElementsAre(TaskType::CUSTOM));
+}
+
TEST_F(RemoteAccessServiceUnitTest, TestScheduleTask) {
ScheduleTaskRequest grpcRequest = {};
EXPECT_CALL(*getGrpcWakeupClientStub(), ScheduleTask)
@@ -463,7 +473,71 @@
EXPECT_EQ(grpcRequest.scheduleinfo().periodicinseconds(), kTestPeriodicInSeconds);
}
-TEST_F(RemoteAccessServiceUnitTest, TestScheduleTask_InvalidArg) {
+TEST_F(RemoteAccessServiceUnitTest, TestScheduleTask_InvalidCount) {
+ ScheduleInfo scheduleInfo = {
+ .clientId = kTestClientId,
+ .scheduleId = kTestScheduleId,
+ .taskData = kTestData,
+ .count = -1,
+ .startTimeInEpochSeconds = kTestStartTimeInEpochSeconds,
+ .periodicInSeconds = kTestPeriodicInSeconds,
+ };
+
+ ScopedAStatus status = getService()->scheduleTask(scheduleInfo);
+
+ ASSERT_FALSE(status.isOk());
+ ASSERT_EQ(status.getExceptionCode(), EX_ILLEGAL_ARGUMENT);
+}
+
+TEST_F(RemoteAccessServiceUnitTest, TestScheduleTask_InvalidStartTimeInEpochSeconds) {
+ ScheduleInfo scheduleInfo = {
+ .clientId = kTestClientId,
+ .scheduleId = kTestScheduleId,
+ .taskData = kTestData,
+ .count = kTestCount,
+ .startTimeInEpochSeconds = -1,
+ .periodicInSeconds = kTestPeriodicInSeconds,
+ };
+
+ ScopedAStatus status = getService()->scheduleTask(scheduleInfo);
+
+ ASSERT_FALSE(status.isOk());
+ ASSERT_EQ(status.getExceptionCode(), EX_ILLEGAL_ARGUMENT);
+}
+
+TEST_F(RemoteAccessServiceUnitTest, TestScheduleTask_InvalidPeriodicInSeconds) {
+ ScheduleInfo scheduleInfo = {
+ .clientId = kTestClientId,
+ .scheduleId = kTestScheduleId,
+ .taskData = kTestData,
+ .count = kTestCount,
+ .startTimeInEpochSeconds = kTestStartTimeInEpochSeconds,
+ .periodicInSeconds = -1,
+ };
+
+ ScopedAStatus status = getService()->scheduleTask(scheduleInfo);
+
+ ASSERT_FALSE(status.isOk());
+ ASSERT_EQ(status.getExceptionCode(), EX_ILLEGAL_ARGUMENT);
+}
+
+TEST_F(RemoteAccessServiceUnitTest, TestScheduleTask_TaskDataTooLarge) {
+ ScheduleInfo scheduleInfo = {
+ .clientId = kTestClientId,
+ .scheduleId = kTestScheduleId,
+ .taskData = std::vector<uint8_t>(ScheduleInfo::MAX_TASK_DATA_SIZE_IN_BYTES + 1),
+ .count = kTestCount,
+ .startTimeInEpochSeconds = kTestStartTimeInEpochSeconds,
+ .periodicInSeconds = kTestPeriodicInSeconds,
+ };
+
+ ScopedAStatus status = getService()->scheduleTask(scheduleInfo);
+
+ ASSERT_FALSE(status.isOk());
+ ASSERT_EQ(status.getExceptionCode(), EX_ILLEGAL_ARGUMENT);
+}
+
+TEST_F(RemoteAccessServiceUnitTest, TestScheduleTask_InvalidArgFromGrpcServer) {
EXPECT_CALL(*getGrpcWakeupClientStub(), ScheduleTask)
.WillOnce([]([[maybe_unused]] ClientContext* context,
[[maybe_unused]] const ScheduleTaskRequest& request,
@@ -563,13 +637,13 @@
EXPECT_EQ(grpcRequest.scheduleid(), kTestScheduleId);
}
-TEST_F(RemoteAccessServiceUnitTest, testGetAllScheduledTasks) {
+TEST_F(RemoteAccessServiceUnitTest, testGetAllPendingScheduledTasks) {
std::vector<ScheduleInfo> result;
- GetAllScheduledTasksRequest grpcRequest = {};
- EXPECT_CALL(*getGrpcWakeupClientStub(), GetAllScheduledTasks)
+ GetAllPendingScheduledTasksRequest grpcRequest = {};
+ EXPECT_CALL(*getGrpcWakeupClientStub(), GetAllPendingScheduledTasks)
.WillOnce([&grpcRequest]([[maybe_unused]] ClientContext* context,
- const GetAllScheduledTasksRequest& request,
- GetAllScheduledTasksResponse* response) {
+ const GetAllPendingScheduledTasksRequest& request,
+ GetAllPendingScheduledTasksResponse* response) {
grpcRequest = request;
GrpcScheduleInfo* newInfo = response->add_allscheduledtasks();
newInfo->set_clientid(kTestClientId);
@@ -581,7 +655,7 @@
return Status();
});
- ScopedAStatus status = getService()->getAllScheduledTasks(kTestClientId, &result);
+ ScopedAStatus status = getService()->getAllPendingScheduledTasks(kTestClientId, &result);
ASSERT_TRUE(status.isOk());
EXPECT_EQ(grpcRequest.clientid(), kTestClientId);
diff --git a/automotive/remoteaccess/test_grpc_server/impl/include/TestWakeupClientServiceImpl.h b/automotive/remoteaccess/test_grpc_server/impl/include/TestWakeupClientServiceImpl.h
index 2aab904..41cc5d0 100644
--- a/automotive/remoteaccess/test_grpc_server/impl/include/TestWakeupClientServiceImpl.h
+++ b/automotive/remoteaccess/test_grpc_server/impl/include/TestWakeupClientServiceImpl.h
@@ -78,6 +78,7 @@
void waitForTask();
void stopWait();
bool isEmpty();
+ bool isStopped();
private:
friend class TaskTimeoutMessageHandler;
@@ -87,7 +88,7 @@
GUARDED_BY(mLock);
// A variable to notify mTasks is not empty.
std::condition_variable mTasksNotEmptyCv;
- std::atomic<bool> mStopped;
+ std::atomic<bool> mStopped = false;
android::sp<Looper> mLooper;
android::sp<TaskTimeoutMessageHandler> mTaskTimeoutMessageHandler;
std::atomic<int> mTaskIdCounter = 0;
@@ -138,9 +139,9 @@
const IsTaskScheduledRequest* request,
IsTaskScheduledResponse* response) override;
- grpc::Status GetAllScheduledTasks(grpc::ServerContext* context,
- const GetAllScheduledTasksRequest* request,
- GetAllScheduledTasksResponse* response) override;
+ grpc::Status GetAllPendingScheduledTasks(
+ grpc::ServerContext* context, const GetAllPendingScheduledTasksRequest* request,
+ GetAllPendingScheduledTasksResponse* response) override;
/**
* Starts generating fake tasks for the specific client repeatedly.
@@ -214,7 +215,7 @@
std::atomic<bool> mRemoteTaskConnectionAlive = false;
std::mutex mLock;
bool mGeneratingFakeTask GUARDED_BY(mLock);
- std::atomic<bool> mServerStopped;
+ std::atomic<bool> mServerStopped = false;
std::unordered_map<std::string, std::unordered_map<std::string, ScheduleInfo>>
mInfoByScheduleIdByClientId GUARDED_BY(mLock);
diff --git a/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp b/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp
index 1db991c..eed3495 100644
--- a/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp
+++ b/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp
@@ -105,6 +105,10 @@
});
}
+bool TaskQueue::isStopped() {
+ return mStopped;
+}
+
void TaskQueue::stopWait() {
mStopped = true;
{
@@ -241,7 +245,7 @@
while (true) {
mTaskQueue->waitForTask();
- if (mServerStopped) {
+ if (mTaskQueue->isStopped()) {
// Server stopped, exit the loop.
printf("Server stopped exit loop\n");
break;
@@ -250,11 +254,13 @@
while (true) {
auto maybeTask = mTaskQueue->maybePopOne();
if (!maybeTask.has_value()) {
+ printf("no task left\n");
// No task left, loop again and wait for another task(s).
break;
}
// Loop through all the task in the queue but obtain lock for each element so we don't
// hold lock while writing the response.
+ printf("Sending one remote task\n");
const GetRemoteTasksResponse& response = maybeTask.value();
if (!writer->Write(response)) {
// Broken stream, maybe the client is shutting down.
@@ -469,11 +475,11 @@
return Status::OK;
}
-Status TestWakeupClientServiceImpl::GetAllScheduledTasks(ServerContext* context,
- const GetAllScheduledTasksRequest* request,
- GetAllScheduledTasksResponse* response) {
+Status TestWakeupClientServiceImpl::GetAllPendingScheduledTasks(
+ ServerContext* context, const GetAllPendingScheduledTasksRequest* request,
+ GetAllPendingScheduledTasksResponse* response) {
const std::string& clientId = request->clientid();
- printf("GetAllScheduledTasks called with client Id: %s\n", clientId.c_str());
+ printf("GetAllPendingScheduledTasks called with client Id: %s\n", clientId.c_str());
response->clear_allscheduledtasks();
{
std::unique_lock lk(mLock);
diff --git a/automotive/remoteaccess/test_grpc_server/impl/test/TestWakeupClientServiceImplUnitTest.cpp b/automotive/remoteaccess/test_grpc_server/impl/test/TestWakeupClientServiceImplUnitTest.cpp
index 960020d..63458ae 100644
--- a/automotive/remoteaccess/test_grpc_server/impl/test/TestWakeupClientServiceImplUnitTest.cpp
+++ b/automotive/remoteaccess/test_grpc_server/impl/test/TestWakeupClientServiceImplUnitTest.cpp
@@ -280,7 +280,7 @@
EXPECT_EQ(getRemoteTaskResponses().size(), 0);
}
-TEST_F(TestWakeupClientServiceImplUnitTest, TestGetAllScheduledTasks) {
+TEST_F(TestWakeupClientServiceImplUnitTest, TestGetAllPendingScheduledTasks) {
std::string scheduleId1 = "scheduleId1";
std::string scheduleId2 = "scheduleId2";
int64_t time1 = getNow();
@@ -296,19 +296,19 @@
ASSERT_TRUE(status.ok());
ClientContext context;
- GetAllScheduledTasksRequest request;
- GetAllScheduledTasksResponse response;
+ GetAllPendingScheduledTasksRequest request;
+ GetAllPendingScheduledTasksResponse response;
request.set_clientid("invalid client Id");
- status = getStub()->GetAllScheduledTasks(&context, request, &response);
+ status = getStub()->GetAllPendingScheduledTasks(&context, request, &response);
ASSERT_TRUE(status.ok());
EXPECT_EQ(response.allscheduledtasks_size(), 0);
ClientContext context2;
- GetAllScheduledTasksRequest request2;
- GetAllScheduledTasksResponse response2;
+ GetAllPendingScheduledTasksRequest request2;
+ GetAllPendingScheduledTasksResponse response2;
request2.set_clientid(kTestClientId);
- status = getStub()->GetAllScheduledTasks(&context2, request2, &response2);
+ status = getStub()->GetAllPendingScheduledTasks(&context2, request2, &response2);
ASSERT_TRUE(status.ok());
ASSERT_EQ(response2.allscheduledtasks_size(), 2);
diff --git a/health/2.0/utils/libhealthstoragedefault/Android.bp b/automotive/remoteaccess/vts/Android.bp
similarity index 62%
copy from health/2.0/utils/libhealthstoragedefault/Android.bp
copy to automotive/remoteaccess/vts/Android.bp
index 3de8789..8acd6a1 100644
--- a/health/2.0/utils/libhealthstoragedefault/Android.bp
+++ b/automotive/remoteaccess/vts/Android.bp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,9 +14,6 @@
* limitations under the License.
*/
-// Default implementation for (passthrough) clients that statically links to
-// android.hardware.health@2.0-impl but do no query for storage related
-// information.
package {
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
@@ -26,13 +23,28 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
-cc_library_static {
- srcs: ["StorageHealthDefault.cpp"],
- name: "libhealthstoragedefault",
- vendor_available: true,
- recovery_available: true,
- cflags: ["-Werror"],
- shared_libs: [
- "android.hardware.health@2.0",
+cc_test {
+ name: "VtsHalAutomotiveRemoteAccess_TargetTest",
+ srcs: [
+ "src/*.cpp",
],
+ static_libs: [
+ "android.hardware.automotive.remoteaccess-V2-ndk",
+ "libgtest",
+ "libgmock",
+ ],
+ shared_libs: [
+ "libbinder_ndk",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ "automotive-tests",
+ "automotive-general-tests",
+ ],
+ defaults: [
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ require_root: true,
+ disable_framework: true,
}
diff --git a/automotive/remoteaccess/vts/src/VtsHalAutomotiveRemoteAccess_TargetTest.cpp b/automotive/remoteaccess/vts/src/VtsHalAutomotiveRemoteAccess_TargetTest.cpp
new file mode 100644
index 0000000..0fb743e
--- /dev/null
+++ b/automotive/remoteaccess/vts/src/VtsHalAutomotiveRemoteAccess_TargetTest.cpp
@@ -0,0 +1,453 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "VtsHalAutomotiveRemoteAccess"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/automotive/remoteaccess/ApState.h>
+#include <aidl/android/hardware/automotive/remoteaccess/BnRemoteTaskCallback.h>
+#include <aidl/android/hardware/automotive/remoteaccess/IRemoteAccess.h>
+#include <aidl/android/hardware/automotive/remoteaccess/ScheduleInfo.h>
+#include <aidl/android/hardware/automotive/remoteaccess/TaskType.h>
+#include <android-base/thread_annotations.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <algorithm>
+#include <chrono>
+#include <string>
+#include <thread>
+#include <vector>
+
+using ::aidl::android::hardware::automotive::remoteaccess::ApState;
+using ::aidl::android::hardware::automotive::remoteaccess::BnRemoteTaskCallback;
+using ::aidl::android::hardware::automotive::remoteaccess::IRemoteAccess;
+using ::aidl::android::hardware::automotive::remoteaccess::ScheduleInfo;
+using ::aidl::android::hardware::automotive::remoteaccess::TaskType;
+using ::android::getAidlHalInstanceNames;
+using ::android::PrintInstanceNameToString;
+using ::android::base::ScopedLockAssertion;
+using ::ndk::ScopedAStatus;
+using ::ndk::SharedRefBase;
+using ::ndk::SpAIBinder;
+using ::testing::UnorderedElementsAre;
+
+namespace {
+
+const std::string TEST_CLIENT_ID = "TEST CLIENT ID";
+const std::string TEST_SCHEDULE_ID = "TEST SCHEDULE ID";
+const std::string TEST_SCHEDULE_ID_1 = "TEST SCHEDULE ID 1";
+const std::string TEST_SCHEDULE_ID_2 = "TEST SCHEDULE ID 2";
+const std::vector<uint8_t> TEST_TASK_DATA =
+ std::vector<uint8_t>({static_cast<uint8_t>(0xde), static_cast<uint8_t>(0xad),
+ static_cast<uint8_t>(0xbe), static_cast<uint8_t>(0xef)});
+const int32_t JOB_DELAY_IN_SECONDS = 5;
+
+} // namespace
+
+class VtsHalAutomotiveRemoteAccessTargetTest : public testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ const std::string& name = GetParam();
+ mHal = IRemoteAccess::fromBinder(SpAIBinder(AServiceManager_waitForService(name.c_str())));
+ ASSERT_NE(mHal, nullptr) << "Failed to connect to remote access HAL: " << name;
+ }
+
+ virtual void TearDown() override {
+ if (mHal != nullptr) {
+ mHal->clearRemoteTaskCallback();
+ mHal->unscheduleAllTasks(TEST_CLIENT_ID);
+ }
+ }
+
+ protected:
+ std::shared_ptr<IRemoteAccess> mHal;
+
+ bool isTaskScheduleSupported();
+ int32_t getInterfaceVersion();
+ ScheduleInfo getTestScheduleInfo(int32_t delayInSeconds, int32_t count,
+ int32_t periodicInSeconds);
+ void setTaskCallbackAndReadyForTask(std::shared_ptr<BnRemoteTaskCallback> testCallback);
+};
+
+class TestRemoteTaskCallback final : public BnRemoteTaskCallback {
+ public:
+ ScopedAStatus onRemoteTaskRequested(const std::string& clientId,
+ const std::vector<uint8_t>& data) override {
+ {
+ std::unique_lock<std::mutex> lockGuard(mLock);
+ mClientIds.push_back(clientId);
+ mDataList.push_back(data);
+ }
+ mCv.notify_one();
+ return ScopedAStatus::ok();
+ }
+
+ const std::vector<std::string> getCalledClientIds() {
+ std::lock_guard<std::mutex> lockGuard(mLock);
+ return mClientIds;
+ }
+
+ const std::vector<std::vector<uint8_t>> getCalledDataList() {
+ std::lock_guard<std::mutex> lockGuard(mLock);
+ return mDataList;
+ }
+
+ bool waitForCallbacks(size_t count, int32_t timeoutInSeconds) {
+ std::unique_lock lk(mLock);
+ return mCv.wait_for(lk, std::chrono::seconds(timeoutInSeconds), [this, count] {
+ ScopedLockAssertion lockAssertion(mLock);
+ return mClientIds.size() >= count;
+ });
+ }
+
+ private:
+ std::mutex mLock;
+ std::vector<std::string> mClientIds GUARDED_BY(mLock);
+ std::vector<std::vector<uint8_t>> mDataList GUARDED_BY(mLock);
+ std::condition_variable mCv;
+};
+
+TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testGetVehicleId) {
+ std::string vehicleId;
+
+ ScopedAStatus status = mHal->getVehicleId(&vehicleId);
+
+ ASSERT_TRUE(status.isOk()) << "Failed to call getVehicleId";
+ ASSERT_FALSE(vehicleId.empty()) << "Vehicle ID must not be empty";
+}
+
+TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testGetWakeupServiceName) {
+ std::string wakeupServiceName;
+
+ ScopedAStatus status = mHal->getWakeupServiceName(&wakeupServiceName);
+
+ ASSERT_TRUE(status.isOk()) << "Failed to call getWakeupServiceName";
+ ASSERT_FALSE(wakeupServiceName.empty()) << "Wakeup service name must not be empty";
+}
+
+TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testGetProcessorId) {
+ std::string processorId;
+
+ ScopedAStatus status = mHal->getProcessorId(&processorId);
+
+ ASSERT_TRUE(status.isOk()) << "Failed to call getProcessorId";
+}
+
+TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testSetClearRemoteTaskCallback) {
+ std::shared_ptr<TestRemoteTaskCallback> testCallback =
+ SharedRefBase::make<TestRemoteTaskCallback>();
+
+ ScopedAStatus status = mHal->setRemoteTaskCallback(testCallback);
+
+ ASSERT_TRUE(status.isOk()) << "Failed to call setRemoteTaskCallback";
+
+ status = mHal->clearRemoteTaskCallback();
+
+ ASSERT_TRUE(status.isOk()) << "Failed to call clearRemoteTaskCallback";
+}
+
+TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testNotifyApStateChange) {
+ ApState apState = ApState{
+ .isReadyForRemoteTask = false,
+ .isWakeupRequired = false,
+ };
+
+ ScopedAStatus status = mHal->notifyApStateChange(apState);
+
+ ASSERT_TRUE(status.isOk()) << "Failed to call notifyApStateChange with state: "
+ << apState.toString();
+
+ apState = ApState{
+ .isReadyForRemoteTask = true,
+ .isWakeupRequired = false,
+ };
+
+ ASSERT_TRUE(status.isOk()) << "Failed to call notifyApStateChange with state: "
+ << apState.toString();
+}
+
+int32_t VtsHalAutomotiveRemoteAccessTargetTest::getInterfaceVersion() {
+ int32_t interfaceVersion = 0;
+ mHal->getInterfaceVersion(&interfaceVersion);
+ return interfaceVersion;
+}
+
+TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testIsTaskScheduleSupported) {
+ if (getInterfaceVersion() < 2) {
+ GTEST_SKIP() << "Require RemoteAccess HAL v2";
+ }
+
+ bool supported;
+
+ ScopedAStatus status = mHal->isTaskScheduleSupported(&supported);
+
+ ASSERT_TRUE(status.isOk()) << "Failed to call isTaskScheduleSupported";
+}
+
+bool VtsHalAutomotiveRemoteAccessTargetTest::isTaskScheduleSupported() {
+ bool supported = false;
+ mHal->isTaskScheduleSupported(&supported);
+ return supported;
+}
+
+TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testGetSupportedTaskTypesForScheduling) {
+ if (getInterfaceVersion() < 2) {
+ GTEST_SKIP() << "Require RemoteAccess HAL v2";
+ }
+
+ std::vector<TaskType> supportedTaskTypes;
+
+ ScopedAStatus status = mHal->getSupportedTaskTypesForScheduling(&supportedTaskTypes);
+
+ ASSERT_TRUE(status.isOk()) << "Failed to call getSupportedTaskTypesForScheduling";
+
+ if (!isTaskScheduleSupported()) {
+ ASSERT_TRUE(supportedTaskTypes.empty())
+ << "getSupportedTaskTypesForScheduling must return empty array "
+ << "if isTaskScheduleSupported is false";
+ return;
+ }
+
+ ASSERT_TRUE(std::find(supportedTaskTypes.begin(), supportedTaskTypes.end(), TaskType::CUSTOM) !=
+ supportedTaskTypes.end())
+ << "getSupportedTaskTypesForScheduling must contain TaskType::CUSTOM";
+}
+
+ScheduleInfo VtsHalAutomotiveRemoteAccessTargetTest::getTestScheduleInfo(
+ int32_t delayInSeconds, int32_t count, int32_t periodicInSeconds) {
+ auto nowInEpochSeconds = std::chrono::duration_cast<std::chrono::seconds>(
+ std::chrono::system_clock::now().time_since_epoch())
+ .count();
+
+ return ScheduleInfo{
+ .clientId = TEST_CLIENT_ID,
+ .scheduleId = TEST_SCHEDULE_ID,
+ .taskType = TaskType::CUSTOM,
+ .taskData = TEST_TASK_DATA,
+ .count = count,
+ .startTimeInEpochSeconds = nowInEpochSeconds + delayInSeconds,
+ .periodicInSeconds = periodicInSeconds,
+ };
+}
+
+void VtsHalAutomotiveRemoteAccessTargetTest::setTaskCallbackAndReadyForTask(
+ std::shared_ptr<BnRemoteTaskCallback> testCallback) {
+ mHal->setRemoteTaskCallback(testCallback);
+ // Notify isReadForRemoteTask to be true.
+ mHal->notifyApStateChange(ApState{
+ .isReadyForRemoteTask = true,
+ .isWakeupRequired = false,
+ });
+}
+
+TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testScheduleTask) {
+ if (getInterfaceVersion() < 2) {
+ GTEST_SKIP() << "Require RemoteAccess HAL v2";
+ }
+
+ std::shared_ptr<TestRemoteTaskCallback> testCallback =
+ SharedRefBase::make<TestRemoteTaskCallback>();
+ setTaskCallbackAndReadyForTask(testCallback);
+
+ int32_t count = 2;
+ ScheduleInfo scheduleInfo = getTestScheduleInfo(
+ /*delayInSeconds=*/JOB_DELAY_IN_SECONDS, count, /*periodicInSeconds=*/1);
+ ScopedAStatus status = mHal->scheduleTask(scheduleInfo);
+
+ if (!isTaskScheduleSupported()) {
+ ASSERT_FALSE(status.isOk()) << "scheduleTask must return EX_ILLEGAL_ARGUMENT "
+ << "if isTaskScheduleSupported is false";
+ ASSERT_EQ(status.getExceptionCode(), EX_ILLEGAL_ARGUMENT)
+ << "scheduleTask must return EX_ILLEGAL_ARGUMENT "
+ << "if isTaskScheduleSupported is false";
+ return;
+ }
+
+ ASSERT_TRUE(status.isOk()) << "Failed to call scheduleTask with scheduleInfo: "
+ << scheduleInfo.toString();
+
+ int32_t timeoutInSeconds = JOB_DELAY_IN_SECONDS + 5;
+ bool gotCallbacks = testCallback->waitForCallbacks(count, timeoutInSeconds);
+ // unschedule the task before checking the result.
+ mHal->unscheduleTask(TEST_CLIENT_ID, TEST_SCHEDULE_ID);
+
+ ASSERT_TRUE(gotCallbacks) << "Callbacks is not called enough times before timeout: "
+ << timeoutInSeconds << "s";
+ std::vector<std::vector<uint8_t>> dataList = testCallback->getCalledDataList();
+ std::vector<std::string> clientIds = testCallback->getCalledClientIds();
+
+ for (size_t i = 0; i < dataList.size(); i++) {
+ EXPECT_EQ(dataList[i], TEST_TASK_DATA) << "Must receive expected task data";
+ EXPECT_EQ(clientIds[i], TEST_CLIENT_ID) << "Must receive expected client id";
+ }
+}
+
+TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testUnscheduleTask) {
+ if (getInterfaceVersion() < 2) {
+ GTEST_SKIP() << "Require RemoteAccess HAL v2";
+ }
+
+ std::shared_ptr<TestRemoteTaskCallback> testCallback =
+ SharedRefBase::make<TestRemoteTaskCallback>();
+ setTaskCallbackAndReadyForTask(testCallback);
+
+ ScheduleInfo scheduleInfo = getTestScheduleInfo(
+ /*delayInSeconds=*/JOB_DELAY_IN_SECONDS, /*count=*/1, /*periodicInSeconds=*/0);
+ mHal->scheduleTask(scheduleInfo);
+ ScopedAStatus status = mHal->unscheduleTask(TEST_CLIENT_ID, TEST_SCHEDULE_ID);
+
+ ASSERT_TRUE(status.isOk()) << "Failed to call unscheduleTask";
+
+ // If not cancelled, should be called in 5s, wait for 6s and make sure no task arrives.
+ std::this_thread::sleep_for(std::chrono::seconds(JOB_DELAY_IN_SECONDS + 1));
+
+ ASSERT_TRUE(testCallback->getCalledClientIds().empty())
+ << "Remote task callback must not be called if the task is cancelled";
+}
+
+TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testUnscheduleAllTasks) {
+ if (getInterfaceVersion() < 2) {
+ GTEST_SKIP() << "Require RemoteAccess HAL v2";
+ }
+
+ std::shared_ptr<TestRemoteTaskCallback> testCallback =
+ SharedRefBase::make<TestRemoteTaskCallback>();
+ setTaskCallbackAndReadyForTask(testCallback);
+
+ ScheduleInfo scheduleInfo = getTestScheduleInfo(
+ /*delayInSeconds=*/JOB_DELAY_IN_SECONDS, /*count=*/1, /*periodicInSeconds=*/0);
+ mHal->scheduleTask(scheduleInfo);
+ ScopedAStatus status = mHal->unscheduleAllTasks(TEST_CLIENT_ID);
+
+ ASSERT_TRUE(status.isOk()) << "Failed to call unscheduleAllTasks";
+
+ // If not cancelled, should be called in 5s, wait for 6s and make sure no task arrives.
+ std::this_thread::sleep_for(std::chrono::seconds(JOB_DELAY_IN_SECONDS + 1));
+
+ ASSERT_TRUE(testCallback->getCalledClientIds().empty())
+ << "Remote task callback must not be called if the task is cancelled";
+}
+
+TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testIsTaskScheduled) {
+ if (getInterfaceVersion() < 2) {
+ GTEST_SKIP() << "Require RemoteAccess HAL v2";
+ }
+
+ std::shared_ptr<TestRemoteTaskCallback> testCallback =
+ SharedRefBase::make<TestRemoteTaskCallback>();
+ setTaskCallbackAndReadyForTask(testCallback);
+
+ ScheduleInfo scheduleInfo = getTestScheduleInfo(
+ /*delayInSeconds=*/JOB_DELAY_IN_SECONDS, /*count=*/1, /*periodicInSeconds=*/0);
+ mHal->scheduleTask(scheduleInfo);
+
+ bool scheduled;
+ ScopedAStatus status = mHal->isTaskScheduled(TEST_CLIENT_ID, TEST_SCHEDULE_ID, &scheduled);
+
+ ASSERT_TRUE(status.isOk()) << "Failed to call unscheduleTask";
+
+ if (!isTaskScheduleSupported()) {
+ ASSERT_FALSE(scheduled) << "isTaskScheduled must return false "
+ << "if isTaskScheduleSupported is false";
+ return;
+ }
+
+ ASSERT_TRUE(scheduled) << "isTaskScheduled must return true if the task is scheduled";
+
+ mHal->unscheduleAllTasks(TEST_CLIENT_ID);
+ status = mHal->isTaskScheduled(TEST_CLIENT_ID, TEST_SCHEDULE_ID, &scheduled);
+
+ ASSERT_TRUE(status.isOk()) << "Failed to call unscheduleTask";
+ ASSERT_FALSE(scheduled) << "isTaskScheduled must return false if the task is not scheduled";
+}
+
+TEST_P(VtsHalAutomotiveRemoteAccessTargetTest, testGetAllPendingScheduledTasks) {
+ if (getInterfaceVersion() < 2) {
+ GTEST_SKIP() << "Require RemoteAccess HAL v2";
+ }
+
+ std::shared_ptr<TestRemoteTaskCallback> testCallback =
+ SharedRefBase::make<TestRemoteTaskCallback>();
+ setTaskCallbackAndReadyForTask(testCallback);
+
+ auto nowInEpochSeconds = std::chrono::duration_cast<std::chrono::seconds>(
+ std::chrono::system_clock::now().time_since_epoch())
+ .count();
+
+ ScheduleInfo scheduleInfo1 = ScheduleInfo{
+ .clientId = TEST_CLIENT_ID,
+ .scheduleId = TEST_SCHEDULE_ID_1,
+ .taskType = TaskType::CUSTOM,
+ .taskData = TEST_TASK_DATA,
+ .count = 1,
+ .startTimeInEpochSeconds = nowInEpochSeconds + 5,
+ .periodicInSeconds = 0,
+ };
+ ScheduleInfo scheduleInfo2 = ScheduleInfo{
+ .clientId = TEST_CLIENT_ID,
+ .scheduleId = TEST_SCHEDULE_ID_2,
+ .taskType = TaskType::CUSTOM,
+ .taskData = TEST_TASK_DATA,
+ .count = 10,
+ .startTimeInEpochSeconds = nowInEpochSeconds + 10,
+ .periodicInSeconds = 1,
+ };
+ mHal->scheduleTask(scheduleInfo1);
+ mHal->scheduleTask(scheduleInfo2);
+
+ std::vector<ScheduleInfo> outScheduleInfo;
+ ScopedAStatus status = mHal->getAllPendingScheduledTasks(TEST_CLIENT_ID, &outScheduleInfo);
+
+ ASSERT_TRUE(status.isOk()) << "Failed to call getAllPendingScheduledTasks";
+
+ if (!isTaskScheduleSupported()) {
+ ASSERT_TRUE(outScheduleInfo.empty())
+ << "Must return empty array for getAllPendingScheduledTasks "
+ << "if isTaskScheduleSupported is false";
+ return;
+ }
+
+ ASSERT_THAT(outScheduleInfo, UnorderedElementsAre(scheduleInfo1, scheduleInfo2))
+ << "expected all pending schedule info mismatch";
+
+ mHal->unscheduleTask(TEST_CLIENT_ID, TEST_SCHEDULE_ID_1);
+
+ status = mHal->getAllPendingScheduledTasks(TEST_CLIENT_ID, &outScheduleInfo);
+
+ ASSERT_TRUE(status.isOk()) << "Failed to call getAllPendingScheduledTasks";
+
+ ASSERT_THAT(outScheduleInfo, UnorderedElementsAre(scheduleInfo2))
+ << "expected all pending schedule info mismatch";
+}
+
+// It is possible that no remote access HAL is registered.
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VtsHalAutomotiveRemoteAccessTargetTest);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, VtsHalAutomotiveRemoteAccessTargetTest,
+ testing::ValuesIn(getAidlHalInstanceNames(IRemoteAccess::descriptor)),
+ PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ // Starts a process pool for callbacks.
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/RecurrentTimer.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/RecurrentTimer.h
index 0ed8742..0f5987e 100644
--- a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/RecurrentTimer.h
+++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/RecurrentTimer.h
@@ -122,21 +122,29 @@
}
std::unique_lock<std::mutex> g(mLock);
+ // mStopRequested might be set to true after we enter the loop. Must check inside
+ // the lock to make sure the value will not change before we start the wait.
+ if (mStopRequested) {
+ return;
+ }
mCond.wait_until(g, nextEventTime); // nextEventTime can be nanoseconds::max()
}
}
void stop() {
- mStopRequested = true;
{
std::lock_guard<std::mutex> g(mLock);
mCookieToEventsMap.clear();
+ // Even though this is atomic, this must be set inside the lock to make sure we will
+ // not change this after we check mStopRequested, but before we start the wait.
+ mStopRequested = true;
}
mCond.notify_one();
if (mTimerThread.joinable()) {
mTimerThread.join();
}
}
+
private:
mutable std::mutex mLock;
std::thread mTimerThread;
diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehiclePropertyStore.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehiclePropertyStore.h
index 6a02cf3..abbcd35 100644
--- a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehiclePropertyStore.h
+++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehiclePropertyStore.h
@@ -70,6 +70,16 @@
* example wasn't registered. */
bool writeValue(const VehiclePropValue& propValue, bool updateStatus);
+ /*
+ * Stores provided value. Returns true if value was written returns false if config for
+ * example wasn't registered.
+ *
+ * The property value's timestamp will be set to the current ElapsedRealTimeNano.
+ */
+ bool writeValueWithCurrentTimestamp(VehiclePropValue* propValuePtr, bool updateStatus);
+
+ std::unique_ptr<VehiclePropValue> refreshTimestamp(int32_t propId, int32_t areaId);
+
void removeValue(const VehiclePropValue& propValue);
void removeValuesForProperty(int32_t propId);
@@ -94,6 +104,8 @@
std::unordered_map<int32_t /* VehicleProperty */, RecordConfig> mConfigs;
PropertyMap mPropertyValues; // Sorted map of RecordId : VehiclePropValue.
+
+ bool writeValueLocked(const VehiclePropValue& propValue, bool updateStatus);
};
} // namespace V2_0
diff --git a/automotive/vehicle/2.0/default/common/src/VehiclePropertyStore.cpp b/automotive/vehicle/2.0/default/common/src/VehiclePropertyStore.cpp
index 6087bfa..c12904e 100644
--- a/automotive/vehicle/2.0/default/common/src/VehiclePropertyStore.cpp
+++ b/automotive/vehicle/2.0/default/common/src/VehiclePropertyStore.cpp
@@ -15,6 +15,7 @@
*/
#define LOG_TAG "VehiclePropertyStore"
#include <log/log.h>
+#include <utils/SystemClock.h>
#include <common/include/vhal_v2_0/VehicleUtils.h>
#include "VehiclePropertyStore.h"
@@ -41,9 +42,7 @@
mConfigs.insert({ config.prop, RecordConfig { config, tokenFunc } });
}
-bool VehiclePropertyStore::writeValue(const VehiclePropValue& propValue,
- bool updateStatus) {
- MuxGuard g(mLock);
+bool VehiclePropertyStore::writeValueLocked(const VehiclePropValue& propValue, bool updateStatus) {
if (!mConfigs.count(propValue.prop)) return false;
RecordId recId = getRecordIdLocked(propValue);
@@ -68,6 +67,36 @@
return true;
}
+bool VehiclePropertyStore::writeValue(const VehiclePropValue& propValue, bool updateStatus) {
+ MuxGuard g(mLock);
+
+ return writeValueLocked(propValue, updateStatus);
+}
+
+bool VehiclePropertyStore::writeValueWithCurrentTimestamp(VehiclePropValue* propValuePtr,
+ bool updateStatus) {
+ MuxGuard g(mLock);
+
+ propValuePtr->timestamp = elapsedRealtimeNano();
+ return writeValueLocked(*propValuePtr, updateStatus);
+}
+
+std::unique_ptr<VehiclePropValue> VehiclePropertyStore::refreshTimestamp(int32_t propId,
+ int32_t areaId) {
+ MuxGuard g(mLock);
+ RecordId recId = getRecordIdLocked(VehiclePropValue{
+ .prop = propId,
+ .areaId = areaId,
+ });
+ auto it = mPropertyValues.find(recId);
+ if (it == mPropertyValues.end()) {
+ return nullptr;
+ }
+
+ it->second.timestamp = elapsedRealtimeNano();
+ return std::make_unique<VehiclePropValue>(it->second);
+}
+
void VehiclePropertyStore::removeValue(const VehiclePropValue& propValue) {
MuxGuard g(mLock);
RecordId recId = getRecordIdLocked(propValue);
diff --git a/automotive/vehicle/2.0/default/common/src/VehicleUtils.cpp b/automotive/vehicle/2.0/default/common/src/VehicleUtils.cpp
index c16b29a..03a9df5 100644
--- a/automotive/vehicle/2.0/default/common/src/VehicleUtils.cpp
+++ b/automotive/vehicle/2.0/default/common/src/VehicleUtils.cpp
@@ -30,7 +30,7 @@
std::unique_ptr<VehiclePropValue> createVehiclePropValue(
VehiclePropertyType type, size_t vecSize) {
- auto val = std::unique_ptr<VehiclePropValue>(new VehiclePropValue);
+ auto val = std::unique_ptr<VehiclePropValue>(new VehiclePropValue());
switch (type) {
case VehiclePropertyType::INT32: // fall through
case VehiclePropertyType::INT32_VEC: // fall through
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/BackportedPropertyHelper.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/BackportedPropertyHelper.h
new file mode 100644
index 0000000..78ae940
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/BackportedPropertyHelper.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// This file contains backported system property definitions and backported enums.
+
+#pragma once
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+namespace backportedproperty {
+
+/**
+ * Characterization of inputs used for computing location.
+ *
+ * This property must indicate what (if any) data and sensor inputs are considered by the system
+ * when computing the vehicle's location that is shared with Android through the GNSS HAL.
+ *
+ * The value must return a collection of bit flags. The bit flags are defined in
+ * LocationCharacterization. The value must also include exactly one of DEAD_RECKONED or
+ * RAW_GNSS_ONLY among its collection of bit flags.
+ *
+ * When this property is not supported, it is assumed that no additional sensor inputs are fused
+ * into the GNSS updates provided through the GNSS HAL. That is unless otherwise specified
+ * through the GNSS HAL interfaces.
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ */
+constexpr int32_t LOCATION_CHARACTERIZATION = 0x31400C10;
+
+/**
+ * Used by LOCATION_CHARACTERIZATION to enumerate the supported bit flags.
+ *
+ * These flags are used to indicate to what transformations are performed on the
+ * GNSS data before the location data is sent, so that location processing
+ * algorithms can take into account prior fusion.
+ *
+ * This enum can be extended in future releases to include additional bit flags.
+ */
+enum class LocationCharacterization : int32_t {
+ /**
+ * Prior location samples have been used to refine the raw GNSS data (e.g. a
+ * Kalman Filter).
+ */
+ PRIOR_LOCATIONS = 0x1,
+ /**
+ * Gyroscope data has been used to refine the raw GNSS data.
+ */
+ GYROSCOPE_FUSION = 0x2,
+ /**
+ * Accelerometer data has been used to refine the raw GNSS data.
+ */
+ ACCELEROMETER_FUSION = 0x4,
+ /**
+ * Compass data has been used to refine the raw GNSS data.
+ */
+ COMPASS_FUSION = 0x8,
+ /**
+ * Wheel speed has been used to refine the raw GNSS data.
+ */
+ WHEEL_SPEED_FUSION = 0x10,
+ /**
+ * Steering angle has been used to refine the raw GNSS data.
+ */
+ STEERING_ANGLE_FUSION = 0x20,
+ /**
+ * Car speed has been used to refine the raw GNSS data.
+ */
+ CAR_SPEED_FUSION = 0x40,
+ /**
+ * Some effort is made to dead-reckon location. In particular, this means that
+ * relative changes in location have meaning when no GNSS satellite is
+ * available.
+ */
+ DEAD_RECKONED = 0x80,
+ /**
+ * Location is based on GNSS satellite signals without sufficient fusion of
+ * other sensors for complete dead reckoning. This flag should be set when
+ * relative changes to location cannot be relied on when no GNSS satellite is
+ * available.
+ */
+ RAW_GNSS_ONLY = 0x100,
+};
+
+} // namespace backportedproperty
+} // namespace V2_0
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index cfa3b0c..4846bfb 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -17,6 +17,7 @@
#ifndef android_hardware_automotive_vehicle_V2_0_impl_DefaultConfig_H_
#define android_hardware_automotive_vehicle_V2_0_impl_DefaultConfig_H_
+#include "BackportedPropertyHelper.h"
#include "PropertyUtils.h"
#include <map>
@@ -29,6 +30,9 @@
namespace impl {
+using ::android::hardware::automotive::vehicle::V2_0::backportedproperty::LOCATION_CHARACTERIZATION;
+using ::android::hardware::automotive::vehicle::V2_0::backportedproperty::LocationCharacterization;
+
struct ConfigDeclaration {
VehiclePropConfig config;
@@ -938,7 +942,10 @@
(int)VehicleVendorPermission::PERMISSION_NOT_ACCESSIBLE,
VENDOR_EXTENSION_FLOAT_PROPERTY,
(int)VehicleVendorPermission::PERMISSION_DEFAULT,
- (int)VehicleVendorPermission::PERMISSION_DEFAULT},
+ (int)VehicleVendorPermission::PERMISSION_DEFAULT,
+ LOCATION_CHARACTERIZATION,
+ (int)VehicleVendorPermission::PERMISSION_GET_VENDOR_CATEGORY_INFO,
+ (int)VehicleVendorPermission::PERMISSION_NOT_ACCESSIBLE},
},
.initialValue = {.int32Values = {1}}},
@@ -1131,6 +1138,15 @@
// GsrComplianceRequirementType::GSR_COMPLIANCE_REQUIRED_V1
.initialValue = {.int32Values = {1}},
},
+ {
+ .config =
+ {
+ .prop = LOCATION_CHARACTERIZATION,
+ .access = VehiclePropertyAccess::READ,
+ .changeMode = VehiclePropertyChangeMode::STATIC,
+ },
+ .initialValue = {.int32Values = {toInt(LocationCharacterization::RAW_GNSS_ONLY)}},
+ },
#ifdef ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
// Vendor propetry for E2E ClusterHomeService testing.
{
@@ -1195,29 +1211,131 @@
},
// All supported property IDs. This list is checked by
// DefaultConfigSupportedPropertyIds_test.
- .initialValue =
- {.int32Values =
- {291504388, 289472773, 291504390, 289472775, 289407240, 289407241,
- 289472780, 286261505, 286261506, 289407235, 289472779, 291504647,
- 289408517, 356518832, 356516106, 291504644, 291504649, 291504656,
- 291504901, 291504903, 287310600, 291504905, 287310602, 287310603,
- 291504908, 291504904, 392168201, 392168202, 289408514, 289408001,
- 287310850, 287310851, 287310853, 289408513, 289475088, 289475104,
- 289475120, 354419984, 320865540, 320865556, 354419975, 354419976,
- 354419986, 354419973, 354419974, 354419978, 354419977, 356517120,
- 356517121, 356582673, 356517139, 289408269, 356517131, 358614275,
- 291570965, 291505923, 289408270, 289408512, 287310855, 289408000,
- 289408008, 289408009, 289407747, 291504900, 568332561, 371198722,
- 373295872, 320867268, 322964416, 290521862, 287310858, 287310859,
- 289475072, 289475073, 289409539, 299896064, 299896065, 299896066,
- 299896067, 289410560, 289410561, 289410562, 289410563, 289410576,
- 289410577, 289410578, 289410579, 289476368, 299895808, 639631617,
- 627048706, 591397123, 554696964, 289410873, 289410874, 287313669,
- 299896583, 299896584, 299896585, 299896586, 299896587, 286265121,
- 286265122, 286265123, 290457094, 290459441, 299896626, 290459443,
- 289410868, 289476405, 299896630, 289410871, 292556600, 557853201,
- 559950353, 555756049, 554707473, 289410887, 557846324, 557911861,
- 568332086, 557846327, 560992056, 289476424}},
+ .initialValue = {.int32Values = {291504388,
+ 289472773,
+ 291504390,
+ 289472775,
+ 289407240,
+ 289407241,
+ 289472780,
+ 286261505,
+ 286261506,
+ 289407235,
+ 289472779,
+ 291504647,
+ 289408517,
+ 356518832,
+ 356516106,
+ 291504644,
+ 291504649,
+ 291504656,
+ 291504901,
+ 291504903,
+ 287310600,
+ 291504905,
+ 287310602,
+ 287310603,
+ 291504908,
+ 291504904,
+ 392168201,
+ 392168202,
+ 289408514,
+ 289408001,
+ 287310850,
+ 287310851,
+ 287310853,
+ 289408513,
+ 289475088,
+ 289475104,
+ 289475120,
+ 354419984,
+ 320865540,
+ 320865556,
+ 354419975,
+ 354419976,
+ 354419986,
+ 354419973,
+ 354419974,
+ 354419978,
+ 354419977,
+ 356517120,
+ 356517121,
+ 356582673,
+ 356517139,
+ 289408269,
+ 356517131,
+ 358614275,
+ 291570965,
+ 291505923,
+ 289408270,
+ 289408512,
+ 287310855,
+ 289408000,
+ 289408008,
+ 289408009,
+ 289407747,
+ 291504900,
+ 568332561,
+ 371198722,
+ 373295872,
+ 320867268,
+ 322964416,
+ 290521862,
+ 287310858,
+ 287310859,
+ 289475072,
+ 289475073,
+ 289409539,
+ 299896064,
+ 299896065,
+ 299896066,
+ 299896067,
+ 289410560,
+ 289410561,
+ 289410562,
+ 289410563,
+ 289410576,
+ 289410577,
+ 289410578,
+ 289410579,
+ 289476368,
+ 299895808,
+ 639631617,
+ 627048706,
+ 591397123,
+ 554696964,
+ 289410873,
+ 289410874,
+ 287313669,
+ 299896583,
+ 299896584,
+ 299896585,
+ 299896586,
+ 299896587,
+ 286265121,
+ 286265122,
+ 286265123,
+ 290457094,
+ 290459441,
+ 299896626,
+ 290459443,
+ 289410868,
+ 289476405,
+ 299896630,
+ 289410871,
+ 292556600,
+ 557853201,
+ 559950353,
+ 555756049,
+ 554707473,
+ 289410887,
+ 557846324,
+ 557911861,
+ 568332086,
+ 557846327,
+ 560992056,
+ 289476424,
+ LOCATION_CHARACTERIZATION}},
},
#endif // ENABLE_GET_PROP_CONFIGS_BY_MULTIPLE_REQUESTS
};
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp
index 318e9dd..82e357f 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp
@@ -57,12 +57,6 @@
return nullptr;
}
-VehicleHal::VehiclePropValuePtr addTimestamp(VehicleHal::VehiclePropValuePtr v) {
- if (v.get()) {
- v->timestamp = elapsedRealtimeNano();
- }
- return v;
-}
} // namespace
VehicleHal::VehiclePropValuePtr DefaultVehicleHal::createVhalHeartBeatProp() {
@@ -102,7 +96,7 @@
*outStatus = StatusCode::INTERNAL_ERROR;
}
}
- return addTimestamp(std::move(v));
+ return v;
}
VehicleHal::VehiclePropValuePtr DefaultVehicleHal::get(const VehiclePropValue& requestedPropValue,
@@ -118,13 +112,13 @@
if (propId == OBD2_FREEZE_FRAME) {
v = getValuePool()->obtainComplex();
*outStatus = fillObd2FreezeFrame(mPropStore, requestedPropValue, v.get());
- return addTimestamp(std::move(v));
+ return v;
}
if (propId == OBD2_FREEZE_FRAME_INFO) {
v = getValuePool()->obtainComplex();
*outStatus = fillObd2DtcInfo(mPropStore, v.get());
- return addTimestamp(std::move(v));
+ return v;
}
auto internalPropValue = mPropStore->readValueOrNull(requestedPropValue);
@@ -139,7 +133,7 @@
} else {
*outStatus = StatusCode::TRY_AGAIN;
}
- return addTimestamp(std::move(v));
+ return v;
}
std::vector<VehiclePropConfig> DefaultVehicleHal::listProperties() {
@@ -486,26 +480,46 @@
void DefaultVehicleHal::onContinuousPropertyTimer(const std::vector<int32_t>& properties) {
auto& pool = *getValuePool();
-
for (int32_t property : properties) {
- VehiclePropValuePtr v;
+ std::vector<VehiclePropValuePtr> events;
if (isContinuousProperty(property)) {
- auto internalPropValue = mPropStore->readValueOrNull(property);
- if (internalPropValue != nullptr) {
- v = pool.obtain(*internalPropValue);
+ const VehiclePropConfig* config = mPropStore->getConfigOrNull(property);
+ std::vector<int32_t> areaIds;
+ if (isGlobalProp(property)) {
+ areaIds.push_back(0);
+ } else {
+ for (auto& c : config->areaConfigs) {
+ areaIds.push_back(c.areaId);
+ }
+ }
+
+ for (int areaId : areaIds) {
+ auto refreshedProp = mPropStore->refreshTimestamp(property, areaId);
+ VehiclePropValuePtr v = nullptr;
+ if (refreshedProp != nullptr) {
+ v = pool.obtain(*refreshedProp);
+ }
+ if (v.get()) {
+ events.push_back(std::move(v));
+ }
}
} else if (property == static_cast<int32_t>(VehicleProperty::VHAL_HEARTBEAT)) {
// VHAL_HEARTBEAT is not a continuous value, but it needs to be updated periodically.
// So, the update is done through onContinuousPropertyTimer.
- v = doInternalHealthCheck();
+ auto v = doInternalHealthCheck();
+ if (!v.get()) {
+ // Internal health check failed.
+ continue;
+ }
+ mPropStore->writeValueWithCurrentTimestamp(v.get(), /*updateStatus=*/true);
+ events.push_back(std::move(v));
} else {
ALOGE("Unexpected onContinuousPropertyTimer for property: 0x%x", property);
continue;
}
- if (v.get()) {
- v->timestamp = elapsedRealtimeNano();
- doHalEvent(std::move(v));
+ for (VehiclePropValuePtr& event : events) {
+ doHalEvent(std::move(event));
}
}
}
@@ -556,7 +570,7 @@
void DefaultVehicleHal::onPropertyValue(const VehiclePropValue& value, bool updateStatus) {
VehiclePropValuePtr updatedPropValue = getValuePool()->obtain(value);
- if (mPropStore->writeValue(*updatedPropValue, updateStatus)) {
+ if (mPropStore->writeValueWithCurrentTimestamp(updatedPropValue.get(), updateStatus)) {
doHalEvent(std::move(updatedPropValue));
}
}
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp
index edd4484..c876836 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp
@@ -81,8 +81,13 @@
using ::android::hardware::automotive::vehicle::V2_0::impl::OBD2_FREEZE_FRAME_CLEAR;
using ::android::hardware::automotive::vehicle::V2_0::impl::OBD2_FREEZE_FRAME_INFO;
using ::android::hardware::automotive::vehicle::V2_0::impl::OBD2_LIVE_FRAME;
+using ::android::hardware::automotive::vehicle::V2_0::impl::WHEEL_FRONT_LEFT;
+using ::android::hardware::automotive::vehicle::V2_0::impl::WHEEL_FRONT_RIGHT;
+using ::android::hardware::automotive::vehicle::V2_0::impl::WHEEL_REAR_LEFT;
+using ::android::hardware::automotive::vehicle::V2_0::impl::WHEEL_REAR_RIGHT;
using ::testing::HasSubstr;
+using ::testing::UnorderedElementsAre;
using VehiclePropValuePtr = recyclable_ptr<VehiclePropValue>;
@@ -152,7 +157,7 @@
TEST_F(DefaultVhalImplTest, testListProperties) {
std::vector<VehiclePropConfig> configs = mHal->listProperties();
- EXPECT_EQ((size_t)124, configs.size());
+ EXPECT_EQ((size_t)125, configs.size());
}
TEST_F(DefaultVhalImplTest, testGetDefaultPropertyFloat) {
@@ -346,6 +351,38 @@
EXPECT_EQ(1.0f, lastEvent->value.floatValues[0]);
}
+TEST_F(DefaultVhalImplTest, testSubscribeContinuous_withMultipleAreaIds) {
+ // Clear existing events.
+ mEventQueue.flush();
+ int propId = toInt(VehicleProperty::TIRE_PRESSURE);
+
+ auto status = mHal->subscribe(propId, 1);
+
+ ASSERT_EQ(StatusCode::OK, status);
+
+ std::vector<VehiclePropValuePtr> receivedEvents;
+ // Wait for 2 updates, each for 4 area IDs.
+ waitForEvents(&receivedEvents, 4 * 2);
+
+ std::vector<int> areasForUpdate1;
+ std::vector<int> areasForUpdate2;
+
+ for (size_t i = 0; i < receivedEvents.size(); i++) {
+ ASSERT_EQ(receivedEvents[i]->prop, propId);
+
+ if (i < 4) {
+ areasForUpdate1.push_back(receivedEvents[i]->areaId);
+ } else {
+ areasForUpdate2.push_back(receivedEvents[i]->areaId);
+ }
+ }
+
+ ASSERT_THAT(areasForUpdate1, UnorderedElementsAre(WHEEL_FRONT_LEFT, WHEEL_FRONT_RIGHT,
+ WHEEL_REAR_LEFT, WHEEL_REAR_RIGHT));
+ ASSERT_THAT(areasForUpdate2, UnorderedElementsAre(WHEEL_FRONT_LEFT, WHEEL_FRONT_RIGHT,
+ WHEEL_REAR_LEFT, WHEEL_REAR_RIGHT));
+}
+
TEST_F(DefaultVhalImplTest, testSubscribeInvalidProp) {
EXPECT_EQ(StatusCode::INVALID_ARG, mHal->subscribe(toInt(VehicleProperty::INFO_MAKE), 10));
}
@@ -1318,7 +1355,6 @@
ASSERT_EQ((size_t)1, events.size());
ASSERT_EQ((size_t)1, events[0]->value.int32Values.size());
EXPECT_EQ(2022, events[0]->value.int32Values[0]);
- EXPECT_EQ(1000, events[0]->timestamp);
VehiclePropValue value;
StatusCode status;
@@ -1352,7 +1388,6 @@
ASSERT_EQ((size_t)1, events.size());
EXPECT_EQ(0, events[0]->value.int32Values[0]);
EXPECT_EQ(DOOR_1_LEFT, events[0]->areaId);
- EXPECT_EQ(1000, events[0]->timestamp);
VehiclePropValue value;
StatusCode status;
@@ -1391,7 +1426,6 @@
ASSERT_EQ((size_t)1, events.size());
ASSERT_EQ((size_t)1, events[0]->value.floatValues.size());
EXPECT_EQ(10.5, events[0]->value.floatValues[0]);
- EXPECT_EQ(1000, events[0]->timestamp);
VehiclePropValue value;
StatusCode status;
diff --git a/automotive/vehicle/2.0/default/tests/fuzzer/VehicleManager_fuzzer.cpp b/automotive/vehicle/2.0/default/tests/fuzzer/VehicleManager_fuzzer.cpp
index 8a085e5..4d0995d 100644
--- a/automotive/vehicle/2.0/default/tests/fuzzer/VehicleManager_fuzzer.cpp
+++ b/automotive/vehicle/2.0/default/tests/fuzzer/VehicleManager_fuzzer.cpp
@@ -76,30 +76,20 @@
using ::android::hardware::automotive::vehicle::V2_0::vms::VmsLayerOffering;
using ::android::hardware::automotive::vehicle::V2_0::vms::VmsOffers;
-constexpr const char kCarMake[] = "Default Car";
-constexpr VehicleProperty kVehicleProp[] = {VehicleProperty::INVALID,
- VehicleProperty::HVAC_FAN_SPEED,
- VehicleProperty::INFO_MAKE,
- VehicleProperty::DISPLAY_BRIGHTNESS,
- VehicleProperty::INFO_FUEL_CAPACITY,
- VehicleProperty::HVAC_SEAT_TEMPERATURE};
-constexpr DiagnosticIntegerSensorIndex kDiagnosticIntIndex[] = {
- DiagnosticIntegerSensorIndex::FUEL_SYSTEM_STATUS,
- DiagnosticIntegerSensorIndex::MALFUNCTION_INDICATOR_LIGHT_ON,
- DiagnosticIntegerSensorIndex::NUM_OXYGEN_SENSORS_PRESENT,
- DiagnosticIntegerSensorIndex::FUEL_TYPE};
-constexpr DiagnosticFloatSensorIndex kDiagnosticFloatIndex[] = {
- DiagnosticFloatSensorIndex::CALCULATED_ENGINE_LOAD,
- DiagnosticFloatSensorIndex::SHORT_TERM_FUEL_TRIM_BANK1,
- DiagnosticFloatSensorIndex::LONG_TERM_FUEL_TRIM_BANK1,
- DiagnosticFloatSensorIndex::THROTTLE_POSITION};
-constexpr size_t kVehiclePropArrayLength = std::size(kVehicleProp);
-constexpr size_t kIntSensorArrayLength = std::size(kDiagnosticIntIndex);
-constexpr size_t kFloatSensorArrayLength = std::size(kDiagnosticFloatIndex);
-constexpr VmsMessageType kAvailabilityMessageType[] = {VmsMessageType::AVAILABILITY_CHANGE,
- VmsMessageType::AVAILABILITY_RESPONSE};
-constexpr VmsMessageType kSubscriptionMessageType[] = {VmsMessageType::SUBSCRIPTIONS_CHANGE,
- VmsMessageType::SUBSCRIPTIONS_RESPONSE};
+std::string kCarMake;
+constexpr int32_t kMaxCaseMessage = 8;
+constexpr int32_t kMaxRuns = 20;
+constexpr int32_t kMaxSize = 1000;
+constexpr int32_t kMinSize = 0;
+constexpr int32_t kMaxFileSize = 100;
+float kFloatValue;
+std::vector<int32_t> kVec32;
+std::vector<int64_t> kVec64;
+std::vector<uint8_t> kVec8;
+std::vector<float> kVecFloat;
+static const std::vector<std::string> kSampleDtcs = {"P0070",
+ "P0102"
+ "P0123"};
MockedVehicleHal::VehiclePropValuePtr MockedVehicleHal::get(
const VehiclePropValue& requestedPropValue, StatusCode* outStatus) {
@@ -113,23 +103,23 @@
switch (property) {
case VehicleProperty::INFO_MAKE:
- pValue = getValuePool()->obtainString(kCarMake);
+ pValue = getValuePool()->obtainString(kCarMake.c_str());
break;
case VehicleProperty::INFO_FUEL_CAPACITY:
if (mFuelCapacityAttemptsLeft-- > 0) {
*outStatus = StatusCode::TRY_AGAIN;
} else {
- pValue = getValuePool()->obtainFloat(42.42);
+ pValue = getValuePool()->obtainFloat(kFloatValue);
}
break;
default:
if (requestedPropValue.prop == kCustomComplexProperty) {
pValue = getValuePool()->obtainComplex();
- pValue->value.int32Values = hidl_vec<int32_t>{10, 20};
- pValue->value.int64Values = hidl_vec<int64_t>{30, 40};
- pValue->value.floatValues = hidl_vec<float_t>{1.1, 2.2};
- pValue->value.bytes = hidl_vec<uint8_t>{1, 2, 3};
- pValue->value.stringValue = kCarMake;
+ pValue->value.int32Values = hidl_vec<int32_t>{kVec32};
+ pValue->value.int64Values = hidl_vec<int64_t>{kVec64};
+ pValue->value.floatValues = hidl_vec<float_t>{kVecFloat};
+ pValue->value.bytes = hidl_vec<uint8_t>{kVec8};
+ pValue->value.stringValue = kCarMake.c_str();
break;
}
auto key = makeKey(toInt(property), areaId);
@@ -145,28 +135,72 @@
return pValue;
}
+void VehicleHalManagerFuzzer::initValue() {
+ kCarMake = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxFileSize);
+ kFloatValue = mFuzzedDataProvider->ConsumeFloatingPoint<float>();
+ fillParameter<int32_t>(mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize),
+ kVec32);
+ fillParameter<int64_t>(mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize),
+ kVec64);
+ fillParameter<uint8_t>(mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize),
+ kVec8);
+ size_t size = mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ for (size_t i = 0; i < size; ++i) {
+ kVecFloat.push_back(mFuzzedDataProvider->ConsumeFloatingPoint<float>());
+ }
+}
+
void VehicleHalManagerFuzzer::process(const uint8_t* data, size_t size) {
mFuzzedDataProvider = new FuzzedDataProvider(data, size);
- invokeDebug();
- invokePropConfigs();
- invokeSubscribe();
- invokeSetAndGetValues();
- invokeObd2SensorStore();
- invokeVmsUtils();
- invokeVehiclePropStore();
- invokeWatchDogClient();
+ initValue();
+ /* Limited while loop runs to prevent timeouts caused
+ * by repeated calls to high-execution-time APIs.
+ */
+ size_t maxRuns = mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxRuns);
+ size_t itr = 0;
+ while (mFuzzedDataProvider->remaining_bytes() && ++itr <= maxRuns) {
+ auto invokeVehicleHalManagerFuzzer =
+ mFuzzedDataProvider->PickValueInArray<const std::function<void()>>({
+ [&]() { invokeDebug(); },
+ [&]() { invokePropConfigs(); },
+ [&]() { invokeSubscribe(); },
+ [&]() { invokeSetAndGetValues(); },
+ [&]() { invokeObd2SensorStore(); },
+ [&]() { invokeVmsUtils(); },
+ [&]() { invokeVehiclePropStore(); },
+ [&]() { invokeWatchDogClient(); },
+ });
+ invokeVehicleHalManagerFuzzer();
+ }
}
void VehicleHalManagerFuzzer::invokeDebug() {
- hidl_string debugOption = mFuzzedDataProvider->PickValueInArray(
- {"--help", "--list", "--get", "--set", "", "invalid"});
hidl_handle fd = {};
native_handle_t* rawHandle = native_handle_create(/*numFds=*/1, /*numInts=*/0);
fd.setTo(native_handle_clone(rawHandle), /*shouldOwn=*/true);
+ int32_t size = mFuzzedDataProvider->ConsumeIntegralInRange<int32_t>(kMinSize, kMaxFileSize);
+ hidl_vec<hidl_string> options(size);
- mManager->debug(fd, {});
- mManager->debug(fd, {debugOption});
+ for (int32_t idx = 0; idx < size; ++idx) {
+ if (idx == 0 && mFuzzedDataProvider->ConsumeBool()) {
+ options[idx] = mFuzzedDataProvider->PickValueInArray(
+ {"--help", "--list", "--get", "--set", "", "invalid"});
+ } else if (idx == 2 && mFuzzedDataProvider->ConsumeBool()) {
+ options[idx] =
+ mFuzzedDataProvider->PickValueInArray({"-i", "-i64", "-f", "-s", "-b", "-a"});
+ } else if (mFuzzedDataProvider->ConsumeBool()) {
+ options[idx] = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxSize);
+ } else {
+ options[idx] = std::to_string(mFuzzedDataProvider->ConsumeIntegral<int32_t>());
+ }
+ }
+
+ if (mFuzzedDataProvider->ConsumeBool()) {
+ mManager->debug(fd, {});
+ } else {
+ mManager->debug(fd, options);
+ }
native_handle_delete(rawHandle);
}
@@ -175,178 +209,245 @@
int32_t vehicleProp2 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
hidl_vec<int32_t> properties = {vehicleProp1, vehicleProp2};
+ auto invokePropConfigsAPI = mFuzzedDataProvider->PickValueInArray<const std::function<void()>>({
+ [&]() {
+ mManager->getPropConfigs(
+ properties, []([[maybe_unused]] StatusCode status,
+ [[maybe_unused]] const hidl_vec<VehiclePropConfig>& c) {});
+ },
+ [&]() {
+ mManager->getPropConfigs(
+ {mFuzzedDataProvider->ConsumeIntegral<int32_t>()},
+ []([[maybe_unused]] StatusCode status,
+ [[maybe_unused]] const hidl_vec<VehiclePropConfig>& c) {});
+ },
+ [&]() {
+ mManager->getAllPropConfigs(
+ []([[maybe_unused]] const hidl_vec<VehiclePropConfig>& propConfigs) {});
+ },
- mManager->getPropConfigs(properties,
- []([[maybe_unused]] StatusCode status,
- [[maybe_unused]] const hidl_vec<VehiclePropConfig>& c) {});
-
- mManager->getPropConfigs({toInt(kVehicleProp[abs(vehicleProp1) % kVehiclePropArrayLength])},
- []([[maybe_unused]] StatusCode status,
- [[maybe_unused]] const hidl_vec<VehiclePropConfig>& c) {});
-
- mManager->getAllPropConfigs(
- []([[maybe_unused]] const hidl_vec<VehiclePropConfig>& propConfigs) {});
+ });
+ invokePropConfigsAPI();
}
void VehicleHalManagerFuzzer::invokeSubscribe() {
- int32_t vehicleProp1 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
int32_t vehicleProp2 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
int32_t vehicleProp3 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
- const auto prop1 = toInt(kVehicleProp[abs(vehicleProp1) % kVehiclePropArrayLength]);
sp<MockedVehicleCallback> cb = new MockedVehicleCallback();
+ VehiclePropertyType type =
+ static_cast<VehiclePropertyType>(mFuzzedDataProvider->ConsumeIntegral<int32_t>());
- hidl_vec<SubscribeOptions> options = {
- SubscribeOptions{.propId = prop1, .flags = SubscribeFlags::EVENTS_FROM_CAR}};
+ auto invokeSubscribeAPI = mFuzzedDataProvider->PickValueInArray<const std::function<void()>>({
+ [&]() {
+ size_t size =
+ mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ hidl_vec<SubscribeOptions> options(size);
+ for (size_t idx = 0; idx < size; ++idx) {
+ options[idx] = {SubscribeOptions{
+ .propId = mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
+ .flags = static_cast<SubscribeFlags>(
+ mFuzzedDataProvider->ConsumeIntegral<int32_t>())}};
+ }
+ mManager->subscribe(cb, options);
+ },
+ [&]() {
+ auto unsubscribedValue = mObjectPool->obtain(type);
+ if (!unsubscribedValue) {
+ return;
+ }
+ unsubscribedValue->prop = vehicleProp2;
+ unsubscribedValue->value.int32Values[0] = INT32_MAX;
+ mHal->sendPropEvent(std::move(unsubscribedValue));
+ cb->waitForExpectedEvents(mFuzzedDataProvider->ConsumeIntegral<size_t>());
+ },
+ [&]() {
+ const auto prop1 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+ mManager->unsubscribe(cb, prop1);
+ },
+ [&]() {
+ mHal->sendHalError(StatusCode::TRY_AGAIN, vehicleProp3,
+ mFuzzedDataProvider->ConsumeIntegral<int32_t>() /*areaId=*/);
+ },
- mManager->subscribe(cb, options);
-
- auto unsubscribedValue = mObjectPool->obtain(VehiclePropertyType::INT32);
- unsubscribedValue->prop = toInt(kVehicleProp[abs(vehicleProp2) % kVehiclePropArrayLength]);
-
- mHal->sendPropEvent(std::move(unsubscribedValue));
- cb->getReceivedEvents();
- cb->waitForExpectedEvents(0);
-
- auto subscribedValue = mObjectPool->obtain(VehiclePropertyType::INT32);
- subscribedValue->prop = toInt(kVehicleProp[abs(vehicleProp2) % kVehiclePropArrayLength]);
- subscribedValue->value.int32Values[0] = INT32_MAX;
-
- cb->reset();
- VehiclePropValue actualValue(*subscribedValue.get());
- mHal->sendPropEvent(std::move(subscribedValue));
- cb->waitForExpectedEvents(1);
- mManager->unsubscribe(cb, prop1);
-
- sp<MockedVehicleCallback> cb2 = new MockedVehicleCallback();
-
- hidl_vec<SubscribeOptions> options2 = {
- SubscribeOptions{
- .propId = toInt(kVehicleProp[abs(vehicleProp3) % kVehiclePropArrayLength]),
- .flags = SubscribeFlags::EVENTS_FROM_CAR},
- };
-
- mManager->subscribe(cb2, options2);
-
- mHal->sendHalError(StatusCode::TRY_AGAIN,
- toInt(kVehicleProp[abs(vehicleProp3) % kVehiclePropArrayLength]),
- /*areaId=*/0);
+ });
+ invokeSubscribeAPI();
}
void VehicleHalManagerFuzzer::invokeSetAndGetValues() {
- uint32_t vehicleProp1 =
- mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kVehiclePropArrayLength - 1);
- uint32_t vehicleProp2 =
- mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kVehiclePropArrayLength - 1);
- uint32_t vehicleProp3 =
- mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kVehiclePropArrayLength - 1);
-
- invokeGet(kCustomComplexProperty, 0);
- invokeGet(toInt(kVehicleProp[vehicleProp2]), 0);
- invokeGet(toInt(kVehicleProp[vehicleProp1]), 0);
-
- auto expectedValue = mObjectPool->obtainInt32(mFuzzedDataProvider->ConsumeIntegral<int32_t>());
- mObjectPool->obtainInt64(mFuzzedDataProvider->ConsumeIntegral<int64_t>());
- mObjectPool->obtainFloat(mFuzzedDataProvider->ConsumeFloatingPoint<float>());
- mObjectPool->obtainBoolean(mFuzzedDataProvider->ConsumeBool());
- expectedValue->prop = toInt(kVehicleProp[vehicleProp2]);
- expectedValue->areaId = 0;
-
- mManager->set(*expectedValue.get());
- invokeGet(toInt(kVehicleProp[vehicleProp2]), 0);
- expectedValue->prop = toInt(kVehicleProp[vehicleProp3]);
- mManager->set(*expectedValue.get());
- expectedValue->prop = toInt(VehicleProperty::INVALID);
- mManager->set(*expectedValue.get());
+ auto invokeSetAndGetAPI = mFuzzedDataProvider->PickValueInArray<const std::function<void()>>({
+ [&]() {
+ invokeGet(mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
+ mFuzzedDataProvider->ConsumeIntegral<int32_t>());
+ },
+ [&]() { mObjectPool->obtainInt64(mFuzzedDataProvider->ConsumeIntegral<int64_t>()); },
+ [&]() { mObjectPool->obtainFloat(mFuzzedDataProvider->ConsumeFloatingPoint<float>()); },
+ [&]() { mObjectPool->obtainBoolean(mFuzzedDataProvider->ConsumeBool()); },
+ [&]() {
+ int32_t vehicleProp2 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+ auto expectedValue =
+ mObjectPool->obtainInt32(mFuzzedDataProvider->ConsumeIntegral<int32_t>());
+ expectedValue->prop = vehicleProp2;
+ expectedValue->areaId = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+ mManager->set(*expectedValue.get());
+ },
+ });
+ invokeSetAndGetAPI();
}
void VehicleHalManagerFuzzer::invokeObd2SensorStore() {
- uint32_t diagnosticIntIndex =
- mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kIntSensorArrayLength - 1);
- int32_t diagnosticIntValue = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
- uint32_t diagnosticFloatIndex =
- mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kFloatSensorArrayLength - 1);
- float diagnosticFloatValue = mFuzzedDataProvider->ConsumeFloatingPoint<float>();
+ size_t diagnosticInt = mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ size_t diagnosticFloat =
+ mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
std::unique_ptr<Obd2SensorStore> sensorStore(
- new Obd2SensorStore(kIntSensorArrayLength, kFloatSensorArrayLength));
- if (sensorStore) {
- sensorStore->setIntegerSensor(kDiagnosticIntIndex[diagnosticIntIndex], diagnosticIntValue);
- sensorStore->setFloatSensor(kDiagnosticFloatIndex[diagnosticFloatIndex],
- diagnosticFloatValue);
- sensorStore->getIntegerSensors();
- sensorStore->getFloatSensors();
- sensorStore->getSensorsBitmask();
- static std::vector<std::string> sampleDtcs = {"P0070",
- "P0102"
- "P0123"};
- for (auto&& dtc : sampleDtcs) {
- auto freezeFrame = createVehiclePropValue(VehiclePropertyType::MIXED, 0);
- sensorStore->fillPropValue(dtc, freezeFrame.get());
- freezeFrame->prop = static_cast<int>(VehicleProperty::OBD2_FREEZE_FRAME);
- }
+ new Obd2SensorStore(diagnosticInt, diagnosticFloat));
+
+ if (!sensorStore.get()) {
+ return;
}
+
+ auto invokeObd2SensorStoreAPI =
+ mFuzzedDataProvider->PickValueInArray<const std::function<void()>>({
+ [&]() {
+ int32_t diagnosticIntValue =
+ mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+ int32_t diagnosticIntIndex =
+ mFuzzedDataProvider->ConsumeIntegralInRange<int32_t>(
+ kMinSize,
+ toInt(DiagnosticIntegerSensorIndex::LAST_SYSTEM_INDEX) +
+ diagnosticInt);
+ sensorStore->setIntegerSensor(
+ static_cast<DiagnosticIntegerSensorIndex>(diagnosticIntIndex),
+ diagnosticIntValue);
+ },
+ [&]() {
+ float diagnosticFloatValue =
+ mFuzzedDataProvider->ConsumeFloatingPoint<float>();
+ int32_t diagnosticFloatIndex =
+ mFuzzedDataProvider->ConsumeIntegralInRange<int32_t>(
+ kMinSize,
+ toInt(DiagnosticFloatSensorIndex::LAST_SYSTEM_INDEX) +
+ diagnosticFloat);
+ sensorStore->setFloatSensor(
+ static_cast<DiagnosticFloatSensorIndex>(diagnosticFloatIndex),
+ diagnosticFloatValue);
+ },
+ [&]() { sensorStore->getIntegerSensors(); },
+ [&]() { sensorStore->getFloatSensors(); },
+ [&]() { sensorStore->getSensorsBitmask(); },
+ [&]() {
+ for (auto&& dtc : kSampleDtcs) {
+ VehiclePropertyType type = static_cast<VehiclePropertyType>(
+ mFuzzedDataProvider->ConsumeIntegral<int32_t>());
+ auto freezeFrame = createVehiclePropValue(
+ type, mFuzzedDataProvider->ConsumeIntegralInRange<int32_t>(
+ kMinSize, kMaxSize));
+ if (!freezeFrame.get()) {
+ return;
+ }
+ freezeFrame->prop = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+ sensorStore->fillPropValue(dtc, freezeFrame.get());
+ }
+ },
+ });
+ invokeObd2SensorStoreAPI();
}
void VehicleHalManagerFuzzer::invokeVmsUtils() {
- bool availabilityMsgType = mFuzzedDataProvider->ConsumeBool();
- bool subscriptionMsgType = mFuzzedDataProvider->ConsumeBool();
+ std::unique_ptr<VehiclePropValue> message;
int32_t intValue = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+ VmsLayer layer(mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
+ mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
+ mFuzzedDataProvider->ConsumeIntegral<int32_t>());
+ VmsOffers offers = {
+ intValue,
+ {VmsLayerOffering(VmsLayer(mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
+ mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
+ mFuzzedDataProvider->ConsumeIntegral<int32_t>()))}};
+ const VmsLayerAndPublisher layer_and_publisher(
+ VmsLayer(mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
+ mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
+ mFuzzedDataProvider->ConsumeIntegral<int32_t>()),
+ intValue);
- VmsLayer layer(1, 0, 2);
- auto message = createSubscribeMessage(layer);
+ switch (mFuzzedDataProvider->ConsumeIntegralInRange<int32_t>(kMinSize, kMaxCaseMessage)) {
+ case 0: {
+ message = createSubscribeMessage(layer);
+ break;
+ }
+ case 1: {
+ message = createUnsubscribeMessage(layer);
+ break;
+ }
+ case 2: {
+ message = createSubscriptionsRequest();
+ break;
+ }
+ case 3: {
+ message = createOfferingMessage(offers);
+ break;
+ }
+ case 4: {
+ message = createAvailabilityRequest();
+ break;
+ }
+ case 5: {
+ std::string pub_bytes;
+ if (mFuzzedDataProvider->ConsumeBool()) {
+ pub_bytes = "pub_id";
+ } else {
+ pub_bytes = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxFileSize);
+ }
+ message = createPublisherIdRequest(pub_bytes);
+ break;
+ }
+ case 6: {
+ std::string bytes = "placeholder";
+ if (mFuzzedDataProvider->ConsumeBool()) {
+ bytes = "placeholder";
+ } else {
+ bytes = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxFileSize);
+ }
+ message = createDataMessageWithLayerPublisherInfo(layer_and_publisher, bytes);
+ break;
+ }
+ case 7: {
+ message = createBaseVmsMessage(
+ mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+ break;
+ }
+ case 8: {
+ message = createStartSessionMessage(intValue, intValue + 1);
+ break;
+ }
+ }
+
isValidVmsMessage(*message);
- message = createUnsubscribeMessage(layer);
-
- VmsOffers offers = {intValue, {VmsLayerOffering(VmsLayer(1, 0, 2))}};
- message = createOfferingMessage(offers);
- std::vector<VmsLayer> dependencies = {VmsLayer(2, 0, 2), VmsLayer(3, 0, 3)};
- std::vector<VmsLayerOffering> offering = {VmsLayerOffering(layer, dependencies)};
- offers = {intValue, offering};
- message = createOfferingMessage(offers);
-
- message = createAvailabilityRequest();
- message = createSubscriptionsRequest();
-
- std::string bytes = "placeholder";
- const VmsLayerAndPublisher layer_and_publisher(VmsLayer(2, 0, 1), intValue);
- message = createDataMessageWithLayerPublisherInfo(layer_and_publisher, bytes);
- parseData(*message);
- createSubscribeToPublisherMessage(layer_and_publisher);
- createUnsubscribeToPublisherMessage(layer_and_publisher);
-
- std::string pub_bytes = "pub_id";
- message = createPublisherIdRequest(pub_bytes);
- message = createBaseVmsMessage(2);
message->value.int32Values =
- hidl_vec<int32_t>{toInt(VmsMessageType::PUBLISHER_ID_RESPONSE), intValue};
- parsePublisherIdResponse(*message);
+ hidl_vec<int32_t>{mFuzzedDataProvider->ConsumeIntegral<int32_t>(), intValue};
- message->value.int32Values =
- hidl_vec<int32_t>{toInt(kSubscriptionMessageType[subscriptionMsgType]), intValue};
- getSequenceNumberForSubscriptionsState(*message);
-
- message->value.int32Values = hidl_vec<int32_t>{toInt(kSubscriptionMessageType[0]), intValue};
- isSequenceNumberNewer(*message, intValue + 1);
- invokeGetSubscribedLayers(kSubscriptionMessageType[subscriptionMsgType]);
-
- message->value.int32Values =
- hidl_vec<int32_t>{toInt(kAvailabilityMessageType[availabilityMsgType]), 0};
- hasServiceNewlyStarted(*message);
- message = createStartSessionMessage(intValue, intValue + 1);
- parseMessageType(*message);
-
- message->value.int32Values =
- hidl_vec<int32_t>{toInt(kAvailabilityMessageType[availabilityMsgType]), intValue};
- isAvailabilitySequenceNumberNewer(*message, intValue + 1);
-
- message->value.int32Values =
- hidl_vec<int32_t>{toInt(kAvailabilityMessageType[availabilityMsgType]), intValue};
- getSequenceNumberForAvailabilityState(*message);
- message = createBaseVmsMessage(3);
- int new_service_id;
- message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), 0, -1};
- parseStartSessionMessage(*message, -1, 0, &new_service_id);
+ auto invokeVmsUtilsAPI = mFuzzedDataProvider->PickValueInArray<const std::function<void()>>({
+ [&]() { parseData(*message); },
+ [&]() { createSubscribeToPublisherMessage(layer_and_publisher); },
+ [&]() { createUnsubscribeToPublisherMessage(layer_and_publisher); },
+ [&]() { parsePublisherIdResponse(*message); },
+ [&]() { getSequenceNumberForSubscriptionsState(*message); },
+ [&]() { isSequenceNumberNewer(*message, intValue + 1); },
+ [&]() {
+ invokeGetSubscribedLayers(
+ (VmsMessageType)mFuzzedDataProvider->ConsumeIntegral<int32_t>());
+ },
+ [&]() { hasServiceNewlyStarted(*message); },
+ [&]() { parseMessageType(*message); },
+ [&]() { isAvailabilitySequenceNumberNewer(*message, intValue + 1); },
+ [&]() { getSequenceNumberForAvailabilityState(*message); },
+ [&]() {
+ int32_t new_service_id;
+ parseStartSessionMessage(*message, -1, 0, &new_service_id);
+ },
+ });
+ invokeVmsUtilsAPI();
}
void VehicleHalManagerFuzzer::invokeGet(int32_t property, int32_t areaId) {
@@ -367,27 +468,31 @@
mActualStatusCode = refStatus;
}
-void VehicleHalManagerFuzzer::invokeGetSubscribedLayers(VmsMessageType type) {
- VmsOffers offers = {123,
- {VmsLayerOffering(VmsLayer(1, 0, 1), {VmsLayer(4, 1, 1)}),
- VmsLayerOffering(VmsLayer(2, 0, 1))}};
- auto message = createBaseVmsMessage(16);
- message->value.int32Values = hidl_vec<int32_t>{toInt(type),
- 1234, // sequence number
- 2, // number of layers
- 1, // number of associated layers
- 1, // layer 1
- 0, 1,
- 4, // layer 2
- 1, 1,
- 2, // associated layer
- 0, 1,
- 2, // number of publisher IDs
- 111, // publisher IDs
- 123};
- isValidVmsMessage(*message);
- getSubscribedLayers(*message, offers);
- getAvailableLayers(*message);
+void VehicleHalManagerFuzzer::invokeGetSubscribedLayers(VmsMessageType /*type*/) {
+ int32_t intValue = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+ VmsOffers offers = {
+ intValue,
+ {VmsLayerOffering(VmsLayer(mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
+ mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
+ mFuzzedDataProvider->ConsumeIntegral<int32_t>()))}};
+ auto message = createBaseVmsMessage(
+ mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxFileSize));
+ std::vector<int32_t> v;
+ size_t size = mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ for (size_t i = 0; i < size; i++) {
+ v.push_back(mFuzzedDataProvider->ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize));
+ }
+
+ message->value.int32Values = hidl_vec<int32_t>(v);
+ if (!isValidVmsMessage(*message)) {
+ return;
+ }
+
+ if (mFuzzedDataProvider->ConsumeBool()) {
+ getSubscribedLayers(*message, offers);
+ } else {
+ getAvailableLayers(*message);
+ }
}
void VehicleHalManagerFuzzer::invokeVehiclePropStore() {
@@ -398,33 +503,49 @@
.prop = vehicleProp,
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::STATIC,
- .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
+ .areaConfigs = {VehicleAreaConfig{
+ .areaId = (mFuzzedDataProvider->ConsumeIntegral<int32_t>())}},
};
- store->registerProperty(config);
VehiclePropValue propValue{};
propValue.prop = vehicleProp;
- propValue.areaId = 0;
- store->writeValue(propValue, shouldWriteStatus);
- store->readAllValues();
- store->getAllConfigs();
- store->getConfigOrNull(vehicleProp);
- store->readValuesForProperty(vehicleProp);
- store->readValueOrNull(propValue);
- store->readValueOrNull(propValue.prop, propValue.areaId, 0);
- store->removeValuesForProperty(vehicleProp);
- store->removeValue(propValue);
- store->getConfigOrDie(vehicleProp);
+ propValue.areaId = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+
+ auto invokeVehiclePropStoreAPI =
+ mFuzzedDataProvider->PickValueInArray<const std::function<void()>>({
+ [&]() { store->registerProperty(config); },
+ [&]() { store->writeValue(propValue, shouldWriteStatus); },
+ [&]() { store->readAllValues(); },
+ [&]() { store->getAllConfigs(); },
+ [&]() { store->getConfigOrNull(vehicleProp); },
+ [&]() { store->readValuesForProperty(vehicleProp); },
+ [&]() { store->readValueOrNull(propValue); },
+ [&]() {
+ store->readValueOrNull(propValue.prop, propValue.areaId,
+ mFuzzedDataProvider->ConsumeIntegralInRange<int64_t>(
+ kMinSize, kMaxFileSize));
+ },
+ [&]() { store->removeValuesForProperty(vehicleProp); },
+ [&]() { store->removeValue(propValue); },
+ [&]() {
+ if (store->getConfigOrNull(vehicleProp)) {
+ store->getConfigOrDie(vehicleProp);
+ }
+ },
+ });
+ invokeVehiclePropStoreAPI();
}
void VehicleHalManagerFuzzer::invokeWatchDogClient() {
- auto service = new VehicleHalManager(mHal.get());
sp<Looper> looper(Looper::prepare(/*opts=*/mFuzzedDataProvider->ConsumeBool()));
- if (auto watchdogClient = ndk::SharedRefBase::make<WatchdogClient>(looper, service);
+ if (auto watchdogClient = ndk::SharedRefBase::make<WatchdogClient>(looper, mManager.get());
watchdogClient->initialize()) {
- watchdogClient->checkIfAlive(-1, TimeoutLength::TIMEOUT_NORMAL);
+ if (mFuzzedDataProvider->ConsumeBool()) {
+ watchdogClient->checkIfAlive(
+ mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
+ (TimeoutLength)mFuzzedDataProvider->ConsumeIntegral<int32_t>());
+ }
watchdogClient->prepareProcessTermination();
}
- delete service;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
diff --git a/automotive/vehicle/2.0/default/tests/fuzzer/VehicleManager_fuzzer.h b/automotive/vehicle/2.0/default/tests/fuzzer/VehicleManager_fuzzer.h
index e9335d3..26ac11e 100644
--- a/automotive/vehicle/2.0/default/tests/fuzzer/VehicleManager_fuzzer.h
+++ b/automotive/vehicle/2.0/default/tests/fuzzer/VehicleManager_fuzzer.h
@@ -98,6 +98,13 @@
}
void process(const uint8_t* data, size_t size);
+ template <typename T>
+ void fillParameter(size_t size, std::vector<T>& data) {
+ for (size_t i = 0; i < size; ++i) {
+ data.push_back(mFuzzedDataProvider->ConsumeIntegral<T>());
+ }
+ }
+
private:
FuzzedDataProvider* mFuzzedDataProvider = nullptr;
VehiclePropValue mActualValue = VehiclePropValue{};
@@ -108,6 +115,7 @@
std::unique_ptr<VehicleHalManager> mManager;
void invokeDebug();
+ void initValue();
void invokePropConfigs();
void invokeSubscribe();
void invokeSetAndGetValues();
diff --git a/automotive/vehicle/Android.bp b/automotive/vehicle/Android.bp
index 3549519..e614937 100644
--- a/automotive/vehicle/Android.bp
+++ b/automotive/vehicle/Android.bp
@@ -25,3 +25,11 @@
"android.hardware.automotive.vehicle.property-V3-ndk",
],
}
+
+rust_defaults {
+ name: "VehicleHalInterfaceRustDefaults",
+ rustlibs: [
+ "android.hardware.automotive.vehicle-V3-rust",
+ "android.hardware.automotive.vehicle.property-V3-rust",
+ ],
+}
diff --git a/automotive/vehicle/OWNERS b/automotive/vehicle/OWNERS
index d6969e5..9a6b65d 100644
--- a/automotive/vehicle/OWNERS
+++ b/automotive/vehicle/OWNERS
@@ -1,2 +1,9 @@
ericjeong@google.com
shanyu@google.com
+
+# GRPC VHAL
+per-file aidl/impl/grpc/** = chenhaosjtuacm@google.com, egranata@google.com
+
+# Property definition
+per-file aidl_property/** = tylertrephan@google.com
+per-file aidl/generated_lib/** = tylertrephan@google.com
diff --git a/automotive/vehicle/aidl/Android.bp b/automotive/vehicle/aidl/Android.bp
index 3be0f28..5ca1fc8 100644
--- a/automotive/vehicle/aidl/Android.bp
+++ b/automotive/vehicle/aidl/Android.bp
@@ -41,6 +41,9 @@
"com.android.car.framework",
],
},
+ rust: {
+ enabled: true,
+ },
},
versions_with_info: [
{
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl
index 69f6190..14469b5 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl
@@ -45,8 +45,8 @@
*
* This value indicates the resolution at which continuous property updates should be sent to
* the platform. For example, if resolution is 0.01, the subscribed property value should be
- * rounded to two decimal places. If the incoming resolution value is not an integer multiple of
- * 10, VHAL should return a StatusCode::INVALID_ARG.
+ * rounded to two decimal places. If the incoming resolution value is not an integer power of
+ * 10 (i.e. 10^-2, 10^-1, 10^2, etc.), VHAL should return a StatusCode::INVALID_ARG.
*/
float resolution = 0.0f;
diff --git a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp b/automotive/vehicle/aidl/emu_metadata/Android.bp
similarity index 66%
copy from health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
copy to automotive/vehicle/aidl/emu_metadata/Android.bp
index aba6cc3..64f895f 100644
--- a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
+++ b/automotive/vehicle/aidl/emu_metadata/Android.bp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -13,12 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "include/StorageHealthDefault.h"
-void get_storage_info(std::vector<struct StorageInfo>&) {
- // Use defaults.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
}
-void get_disk_stats(std::vector<struct DiskStats>&) {
- // Use defaults
+filegroup {
+ name: "android.hardware.automotive.vehicle-types-meta",
+ srcs: [
+ "android.hardware.automotive.vehicle-types-meta.json",
+ ],
}
diff --git a/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json b/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json
index e312a3a..df0f51c 100644
--- a/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json
+++ b/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json
@@ -1,3460 +1,2929 @@
[
- {
- "name": "VehicleApPowerStateReqIndex",
- "values": [
- {
- "name": "STATE",
- "value": 0
- },
- {
- "name": "ADDITIONAL",
- "value": 1
- }
- ]
- },
- {
- "name": "EvChargeState",
- "values": [
- {
- "name": "UNKNOWN",
- "value": 0
- },
- {
- "name": "CHARGING",
- "value": 1
- },
- {
- "name": "FULLY_CHARGED",
- "value": 2
- },
- {
- "name": "NOT_CHARGING",
- "value": 3
- },
- {
- "name": "ERROR",
- "value": 4
- }
- ]
- },
- {
- "name": "TrailerState",
- "values": [
- {
- "name": "UNKNOWN",
- "value": 0
- },
- {
- "name": "NOT_PRESENT",
- "value": 1
- },
- {
- "name": "PRESENT",
- "value": 2
- },
- {
- "name": "ERROR",
- "value": 3
- }
- ]
- },
- {
- "name": "ProcessTerminationReason",
- "values": [
- {
- "name": "NOT_RESPONDING",
- "value": 1
- },
- {
- "name": "IO_OVERUSE",
- "value": 2
- },
- {
- "name": "MEMORY_OVERUSE",
- "value": 3
- }
- ]
- },
- {
- "name": "VehicleApPowerStateConfigFlag",
- "values": [
- {
- "name": "ENABLE_DEEP_SLEEP_FLAG",
- "value": 1
- },
- {
- "name": "CONFIG_SUPPORT_TIMER_POWER_ON_FLAG",
- "value": 2
- },
- {
- "name": "ENABLE_HIBERNATION_FLAG",
- "value": 3
- }
- ]
- },
- {
- "name": "Obd2FuelType",
- "values": [
- {
- "name": "NOT_AVAILABLE",
- "value": 0
- },
- {
- "name": "GASOLINE",
- "value": 1
- },
- {
- "name": "METHANOL",
- "value": 2
- },
- {
- "name": "ETHANOL",
- "value": 3
- },
- {
- "name": "DIESEL",
- "value": 4
- },
- {
- "name": "LPG",
- "value": 5
- },
- {
- "name": "CNG",
- "value": 6
- },
- {
- "name": "PROPANE",
- "value": 7
- },
- {
- "name": "ELECTRIC",
- "value": 8
- },
- {
- "name": "BIFUEL_RUNNING_GASOLINE",
- "value": 9
- },
- {
- "name": "BIFUEL_RUNNING_METHANOL",
- "value": 10
- },
- {
- "name": "BIFUEL_RUNNING_ETHANOL",
- "value": 11
- },
- {
- "name": "BIFUEL_RUNNING_LPG",
- "value": 12
- },
- {
- "name": "BIFUEL_RUNNING_CNG",
- "value": 13
- },
- {
- "name": "BIFUEL_RUNNING_PROPANE",
- "value": 14
- },
- {
- "name": "BIFUEL_RUNNING_ELECTRIC",
- "value": 15
- },
- {
- "name": "BIFUEL_RUNNING_ELECTRIC_AND_COMBUSTION",
- "value": 16
- },
- {
- "name": "HYBRID_GASOLINE",
- "value": 17
- },
- {
- "name": "HYBRID_ETHANOL",
- "value": 18
- },
- {
- "name": "HYBRID_DIESEL",
- "value": 19
- },
- {
- "name": "HYBRID_ELECTRIC",
- "value": 20
- },
- {
- "name": "HYBRID_RUNNING_ELECTRIC_AND_COMBUSTION",
- "value": 21
- },
- {
- "name": "HYBRID_REGENERATIVE",
- "value": 22
- },
- {
- "name": "BIFUEL_RUNNING_DIESEL",
- "value": 23
- }
- ]
- },
- {
- "name": "VmsSubscriptionsStateIntegerValuesIndex",
- "values": [
- {
- "name": "MESSAGE_TYPE",
- "value": 0
- },
- {
- "name": "SEQUENCE_NUMBER",
- "value": 1
- },
- {
- "name": "NUMBER_OF_LAYERS",
- "value": 2
- },
- {
- "name": "NUMBER_OF_ASSOCIATED_LAYERS",
- "value": 3
- },
- {
- "name": "SUBSCRIPTIONS_START",
- "value": 4
- }
- ]
- },
- {
- "name": "VehicleArea",
- "values": [
- {
- "name": "GLOBAL",
- "value": 16777216
- },
- {
- "name": "WINDOW",
- "value": 50331648
- },
- {
- "name": "MIRROR",
- "value": 67108864
- },
- {
- "name": "SEAT",
- "value": 83886080
- },
- {
- "name": "DOOR",
- "value": 100663296
- },
- {
- "name": "WHEEL",
- "value": 117440512
- },
- {
- "name": "MASK",
- "value": 251658240
- }
- ]
- },
- {
- "name": "VehicleAreaWindow",
- "values": [
- {
- "name": "FRONT_WINDSHIELD",
- "value": 1
- },
- {
- "name": "REAR_WINDSHIELD",
- "value": 2
- },
- {
- "name": "ROW_1_LEFT",
- "value": 16
- },
- {
- "name": "ROW_1_RIGHT",
- "value": 64
- },
- {
- "name": "ROW_2_LEFT",
- "value": 256
- },
- {
- "name": "ROW_2_RIGHT",
- "value": 1024
- },
- {
- "name": "ROW_3_LEFT",
- "value": 4096
- },
- {
- "name": "ROW_3_RIGHT",
- "value": 16384
- },
- {
- "name": "ROOF_TOP_1",
- "value": 65536
- },
- {
- "name": "ROOF_TOP_2",
- "value": 131072
- }
- ]
- },
- {
- "name": "ElectronicTollCollectionCardStatus",
- "values": [
- {
- "name": "UNKNOWN",
- "value": 0
- },
- {
- "name": "ELECTRONIC_TOLL_COLLECTION_CARD_VALID",
- "value": 1
- },
- {
- "name": "ELECTRONIC_TOLL_COLLECTION_CARD_INVALID",
- "value": 2
- },
- {
- "name": "ELECTRONIC_TOLL_COLLECTION_CARD_NOT_INSERTED",
- "value": 3
- }
- ]
- },
- {
- "name": "VehiclePropertyType",
- "values": [
- {
- "name": "STRING",
- "value": 1048576
- },
- {
- "name": "BOOLEAN",
- "value": 2097152
- },
- {
- "name": "INT32",
- "value": 4194304
- },
- {
- "name": "INT32_VEC",
- "value": 4259840
- },
- {
- "name": "INT64",
- "value": 5242880
- },
- {
- "name": "INT64_VEC",
- "value": 5308416
- },
- {
- "name": "FLOAT",
- "value": 6291456
- },
- {
- "name": "FLOAT_VEC",
- "value": 6356992
- },
- {
- "name": "BYTES",
- "value": 7340032
- },
- {
- "name": "MIXED",
- "value": 14680064
- },
- {
- "name": "MASK",
- "value": 16711680
- }
- ]
- },
- {
- "name": "StatusCode",
- "values": [
- {
- "name": "OK",
- "value": 0
- },
- {
- "name": "TRY_AGAIN",
- "value": 1
- },
- {
- "name": "INVALID_ARG",
- "value": 2
- },
- {
- "name": "NOT_AVAILABLE",
- "value": 3
- },
- {
- "name": "ACCESS_DENIED",
- "value": 4
- },
- {
- "name": "INTERNAL_ERROR",
- "value": 5
- }
- ]
- },
- {
- "name": "CreateUserStatus",
- "values": [
- {
- "name": "SUCCESS",
- "value": 1
- },
- {
- "name": "FAILURE",
- "value": 2
- }
- ]
- },
- {
- "name": "ElectronicTollCollectionCardType",
- "values": [
- {
- "name": "UNKNOWN",
- "value": 0
- },
- {
- "name": "JP_ELECTRONIC_TOLL_COLLECTION_CARD",
- "value": 1
- },
- {
- "name": "JP_ELECTRONIC_TOLL_COLLECTION_CARD_V2",
- "value": 2
- }
- ]
- },
- {
- "name": "VehicleAreaMirror",
- "values": [
- {
- "name": "DRIVER_LEFT",
- "value": 1
- },
- {
- "name": "DRIVER_RIGHT",
- "value": 2
- },
- {
- "name": "DRIVER_CENTER",
- "value": 4
- }
- ]
- },
- {
- "name": "InitialUserInfoResponseAction",
- "values": [
- {
- "name": "DEFAULT",
- "value": 0
- },
- {
- "name": "SWITCH",
- "value": 1
- },
- {
- "name": "CREATE",
- "value": 2
- }
- ]
- },
- {
- "name": "VehicleHvacFanDirection",
- "values": [
- {
- "name": "UNKNOWN",
- "value": 0
- },
- {
- "name": "FACE",
- "value": 1
- },
- {
- "name": "FLOOR",
- "value": 2
- },
- {
- "name": "FACE_AND_FLOOR",
- "value": 3
- },
- {
- "name": "DEFROST",
- "value": 4
- },
- {
- "name": "DEFROST_AND_FLOOR",
- "value": 6
- }
- ]
- },
- {
- "name": "Obd2SecondaryAirStatus",
- "values": [
- {
- "name": "UPSTREAM",
- "value": 1
- },
- {
- "name": "DOWNSTREAM_OF_CATALYCIC_CONVERTER",
- "value": 2
- },
- {
- "name": "FROM_OUTSIDE_OR_OFF",
- "value": 4
- },
- {
- "name": "PUMP_ON_FOR_DIAGNOSTICS",
- "value": 8
- }
- ]
- },
- {
- "name": "VmsStartSessionMessageIntegerValuesIndex",
- "values": [
- {
- "name": "MESSAGE_TYPE",
- "value": 0
- },
- {
- "name": "SERVICE_ID",
- "value": 1
- },
- {
- "name": "CLIENT_ID",
- "value": 2
- }
- ]
- },
- {
- "name": "VehicleOilLevel",
- "values": [
- {
- "name": "CRITICALLY_LOW",
- "value": 0
- },
- {
- "name": "LOW",
- "value": 1
- },
- {
- "name": "NORMAL",
- "value": 2
- },
- {
- "name": "HIGH",
- "value": 3
- },
- {
- "name": "ERROR",
- "value": 4
- }
- ]
- },
- {
- "name": "VehicleUnit",
- "values": [
- {
- "name": "SHOULD_NOT_USE",
- "value": 0
- },
- {
- "name": "METER_PER_SEC",
- "value": 1
- },
- {
- "name": "RPM",
- "value": 2
- },
- {
- "name": "HERTZ",
- "value": 3
- },
- {
- "name": "PERCENTILE",
- "value": 16
- },
- {
- "name": "MILLIMETER",
- "value": 32
- },
- {
- "name": "METER",
- "value": 33
- },
- {
- "name": "KILOMETER",
- "value": 35
- },
- {
- "name": "MILE",
- "value": 36
- },
- {
- "name": "CELSIUS",
- "value": 48
- },
- {
- "name": "FAHRENHEIT",
- "value": 49
- },
- {
- "name": "KELVIN",
- "value": 50
- },
- {
- "name": "MILLILITER",
- "value": 64
- },
- {
- "name": "LITER",
- "value": 65
- },
- {
- "name": "GALLON",
- "value": 66
- },
- {
- "name": "US_GALLON",
- "value": 66
- },
- {
- "name": "IMPERIAL_GALLON",
- "value": 67
- },
- {
- "name": "NANO_SECS",
- "value": 80
- },
- {
- "name": "SECS",
- "value": 83
- },
- {
- "name": "YEAR",
- "value": 89
- },
- {
- "name": "WATT_HOUR",
- "value": 96
- },
- {
- "name": "MILLIAMPERE",
- "value": 97
- },
- {
- "name": "MILLIVOLT",
- "value": 98
- },
- {
- "name": "MILLIWATTS",
- "value": 99
- },
- {
- "name": "AMPERE_HOURS",
- "value": 100
- },
- {
- "name": "KILOWATT_HOUR",
- "value": 101
- },
- {
- "name": "AMPERE",
- "value": 102
- },
- {
- "name": "KILOPASCAL",
- "value": 112
- },
- {
- "name": "PSI",
- "value": 113
- },
- {
- "name": "BAR",
- "value": 114
- },
- {
- "name": "DEGREES",
- "value": 128
- },
- {
- "name": "MILES_PER_HOUR",
- "value": 144
- },
- {
- "name": "KILOMETERS_PER_HOUR",
- "value": 145
- }
- ]
- },
- {
- "name": "VehicleAreaWheel",
- "values": [
- {
- "name": "UNKNOWN",
- "value": 0
- },
- {
- "name": "LEFT_FRONT",
- "value": 1
- },
- {
- "name": "RIGHT_FRONT",
- "value": 2
- },
- {
- "name": "LEFT_REAR",
- "value": 4
- },
- {
- "name": "RIGHT_REAR",
- "value": 8
- }
- ]
- },
- {
- "name": "EvsServiceState",
- "values": [
- {
- "name": "OFF",
- "value": 0
- },
- {
- "name": "ON",
- "value": 1
- }
- ]
- },
- {
- "name": "EvsServiceRequestIndex",
- "values": [
- {
- "name": "TYPE",
- "value": 0
- },
- {
- "name": "STATE",
- "value": 1
- }
- ]
- },
- {
- "name": "VehicleSeatOccupancyState",
- "values": [
- {
- "name": "UNKNOWN",
- "value": 0
- },
- {
- "name": "VACANT",
- "value": 1
- },
- {
- "name": "OCCUPIED",
- "value": 2
- }
- ]
- },
- {
- "name": "VehicleProperty",
- "values": [
- {
- "name": "Undefined property.",
- "value": 0
- },
- {
- "name": "VIN of vehicle",
- "value": 286261504,
- "change_mode": "VehiclePropertyChangeMode:STATIC",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "Manufacturer of vehicle",
- "value": 286261505,
- "change_mode": "VehiclePropertyChangeMode:STATIC",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "Model of vehicle",
- "value": 286261506,
- "change_mode": "VehiclePropertyChangeMode:STATIC",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "Model year of vehicle.",
- "value": 289407235,
- "change_mode": "VehiclePropertyChangeMode:STATIC",
- "access": "VehiclePropertyAccess:READ",
- "unit": "VehicleUnit:YEAR"
- },
- {
- "name": "Fuel capacity of the vehicle in milliliters",
- "value": 291504388,
- "change_mode": "VehiclePropertyChangeMode:STATIC",
- "access": "VehiclePropertyAccess:READ",
- "unit": "VehicleUnit:MILLILITER"
- },
- {
- "name": "List of fuels the vehicle may use",
- "value": 289472773,
- "change_mode": "VehiclePropertyChangeMode:STATIC",
- "access": "VehiclePropertyAccess:READ",
- "data_enum": "FuelType"
- },
- {
- "name": "INFO_EV_BATTERY_CAPACITY",
- "value": 291504390,
- "change_mode": "VehiclePropertyChangeMode:STATIC",
- "access": "VehiclePropertyAccess:READ",
- "unit": "VehicleUnit:WH"
- },
- {
- "name": "List of connectors this EV may use",
- "value": 289472775,
- "change_mode": "VehiclePropertyChangeMode:STATIC",
- "data_enum": "EvConnectorType",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "Fuel door location",
- "value": 289407240,
- "change_mode": "VehiclePropertyChangeMode:STATIC",
- "data_enum": "PortLocationType",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "EV port location",
- "value": 289407241,
- "change_mode": "VehiclePropertyChangeMode:STATIC",
- "access": "VehiclePropertyAccess:READ",
- "data_enum": "PortLocationType"
- },
- {
- "name": "INFO_DRIVER_SEAT",
- "value": 356516106,
- "change_mode": "VehiclePropertyChangeMode:STATIC",
- "data_enum": "VehicleAreaSeat",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "Exterior dimensions of vehicle.",
- "value": 289472779,
- "change_mode": "VehiclePropertyChangeMode:STATIC",
- "access": "VehiclePropertyAccess:READ",
- "unit": "VehicleUnit:MILLIMETER"
- },
- {
- "name": "Multiple EV port locations",
- "value": 289472780,
- "change_mode": "VehiclePropertyChangeMode:STATIC",
- "access": "VehiclePropertyAccess:READ",
- "data_enum": "PortLocationType"
- },
- {
- "name": "Current odometer value of the vehicle",
- "value": 291504644,
- "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
- "access": "VehiclePropertyAccess:READ",
- "unit": "VehicleUnit:KILOMETER"
- },
- {
- "name": "Speed of the vehicle",
- "value": 291504647,
- "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
- "access": "VehiclePropertyAccess:READ",
- "unit": "VehicleUnit:METER_PER_SEC"
- },
- {
- "name": "Speed of the vehicle for displays",
- "value": 291504648,
- "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
- "access": "VehiclePropertyAccess:READ",
- "unit": "VehicleUnit:METER_PER_SEC"
- },
- {
- "name": "Front bicycle model steering angle for vehicle",
- "value": 291504649,
- "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
- "access": "VehiclePropertyAccess:READ",
- "unit": "VehicleUnit:DEGREES"
- },
- {
- "name": "Rear bicycle model steering angle for vehicle",
- "value": 291504656,
- "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
- "access": "VehiclePropertyAccess:READ",
- "unit": "VehicleUnit:DEGREES"
- },
- {
- "name": "Temperature of engine coolant",
- "value": 291504897,
- "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
- "access": "VehiclePropertyAccess:READ",
- "unit": "VehicleUnit:CELSIUS"
- },
- {
- "name": "Engine oil level",
- "value": 289407747,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ",
- "data_enum": "VehicleOilLevel"
- },
- {
- "name": "Temperature of engine oil",
- "value": 291504900,
- "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
- "access": "VehiclePropertyAccess:READ",
- "unit": "VehicleUnit:CELSIUS"
- },
- {
- "name": "Engine rpm",
- "value": 291504901,
- "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
- "access": "VehiclePropertyAccess:READ",
- "unit": "VehicleUnit:RPM"
- },
- {
- "name": "Reports wheel ticks",
- "value": 290521862,
- "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "FUEL_LEVEL",
- "value": 291504903,
- "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
- "access": "VehiclePropertyAccess:READ",
- "unit": "VehicleUnit:MILLILITER"
- },
- {
- "name": "Fuel door open",
- "value": 287310600,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "EV_BATTERY_LEVEL",
- "value": 291504905,
- "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
- "access": "VehiclePropertyAccess:READ",
- "unit": "VehicleUnit:WH"
- },
- {
- "name": "EV charge port open",
- "value": 287310602,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "EV charge port connected",
- "value": 287310603,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "EV instantaneous charge rate in milliwatts",
- "value": 291504908,
- "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
- "access": "VehiclePropertyAccess:READ",
- "unit": "VehicleUnit:MW"
- },
- {
- "name": "Range remaining",
- "value": 291504904,
- "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
- "access": "VehiclePropertyAccess:READ_WRITE",
- "unit": "VehicleUnit:METER"
- },
- {
- "name": "Tire pressure",
- "value": 392168201,
- "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
- "access": "VehiclePropertyAccess:READ",
- "unit": "VehicleUnit:KILOPASCAL"
- },
- {
- "name": "Critically low tire pressure",
- "value": 392168202,
- "change_mode": "VehiclePropertyChangeMode:STATIC",
- "access": "VehiclePropertyAccess:READ",
- "unit": "VehicleUnit:KILOPASCAL"
- },
- {
- "name": "Currently selected gear",
- "value": 289408000,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ",
- "data_enum": "VehicleGear"
- },
- {
- "name": "CURRENT_GEAR",
- "value": 289408001,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ",
- "data_enum": "VehicleGear"
- },
- {
- "name": "Parking brake state.",
- "value": 287310850,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "PARKING_BRAKE_AUTO_APPLY",
- "value": 287310851,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "Warning for fuel low level.",
- "value": 287310853,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "Night mode",
- "value": 287310855,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "State of the vehicles turn signals",
- "value": 289408008,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ",
- "data_enum": "VehicleTurnSignal"
- },
- {
- "name": "Represents ignition state",
- "value": 289408009,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ",
- "data_enum": "VehicleIgnitionState"
- },
- {
- "name": "ABS is active",
- "value": 287310858,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "Traction Control is active",
- "value": 287310859,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "HVAC_FAN_SPEED",
- "value": 356517120
- },
- {
- "name": "Fan direction setting",
- "value": 356517121,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE",
- "data_enum": "VehicleHvacFanDirection"
- },
- {
- "name": "HVAC current temperature.",
- "value": 358614274,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ",
- "unit": "VehicleUnit:CELSIUS"
- },
- {
- "name": "HVAC_TEMPERATURE_SET",
- "value": 358614275,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE",
- "unit": "VehicleUnit:CELSIUS"
- },
- {
- "name": "HVAC_DEFROSTER",
- "value": 320865540,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "HVAC_AC_ON",
- "value": 354419973,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE",
- "config_flags": "Supported"
- },
- {
- "name": "HVAC_MAX_AC_ON",
- "value": 354419974,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "HVAC_MAX_DEFROST_ON",
- "value": 354419975,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "HVAC_RECIRC_ON",
- "value": 354419976,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Enable temperature coupling between areas.",
- "value": 354419977,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "HVAC_AUTO_ON",
- "value": 354419978,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "HVAC_SEAT_TEMPERATURE",
- "value": 356517131,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Side Mirror Heat",
- "value": 339739916,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "HVAC_STEERING_WHEEL_HEAT",
- "value": 289408269,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Temperature units for display",
- "value": 289408270,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE",
- "data_enum": "VehicleUnit"
- },
- {
- "name": "Actual fan speed",
- "value": 356517135,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "HVAC_POWER_ON",
- "value": 354419984,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Fan Positions Available",
- "value": 356582673,
- "change_mode": "VehiclePropertyChangeMode:STATIC",
- "access": "VehiclePropertyAccess:READ",
- "data_enum": "VehicleHvacFanDirection"
- },
- {
- "name": "HVAC_AUTO_RECIRC_ON",
- "value": 354419986,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Seat ventilation",
- "value": 356517139,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "HVAC_ELECTRIC_DEFROSTER_ON",
- "value": 320865556,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Suggested values for setting HVAC temperature.",
- "value": 291570965,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Distance units for display",
- "value": 289408512,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE",
- "data_enum": "VehicleUnit"
- },
- {
- "name": "Fuel volume units for display",
- "value": 289408513,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE",
- "data_enum": "VehicleUnit"
- },
- {
- "name": "Tire pressure units for display",
- "value": 289408514,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE",
- "data_enum": "VehicleUnit"
- },
- {
- "name": "EV battery units for display",
- "value": 289408515,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE",
- "data_enum": "VehicleUnit"
- },
- {
- "name": "Fuel consumption units for display",
- "value": 287311364,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Speed units for display",
- "value": 289408517,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "ANDROID_EPOCH_TIME",
- "value": 290457094,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:WRITE_ONLY",
- "unit": "VehicleUnit:MILLI_SECS"
- },
- {
- "name": "External encryption binding seed.",
- "value": 292554247,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Outside temperature",
- "value": 291505923,
- "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
- "access": "VehiclePropertyAccess:READ",
- "unit": "VehicleUnit:CELSIUS"
- },
- {
- "name": "Property to control power state of application processor",
- "value": 289475072,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "Property to report power state of application processor",
- "value": 289475073,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "AP_POWER_BOOTUP_REASON",
- "value": 289409538,
- "change_mode": "VehiclePropertyChangeMode:STATIC",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "DISPLAY_BRIGHTNESS",
- "value": 289409539,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "HW_KEY_INPUT",
- "value": 289475088,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ",
- "config_flags": ""
- },
- {
- "name": "HW_ROTARY_INPUT",
- "value": 289475104,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "data_enum": "RotaryInputType",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "Defines a custom OEM partner input event.",
- "value": 289475120,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "data_enum": "CustomInputType",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "DOOR_POS",
- "value": 373295872,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Door move",
- "value": 373295873,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Door lock",
- "value": 371198722,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Mirror Z Position",
- "value": 339741504,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Mirror Z Move",
- "value": 339741505,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Mirror Y Position",
- "value": 339741506,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Mirror Y Move",
- "value": 339741507,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Mirror Lock",
- "value": 287312708,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Mirror Fold",
- "value": 287312709,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Seat memory select",
- "value": 356518784,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:WRITE"
- },
- {
- "name": "Seat memory set",
- "value": 356518785,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:WRITE"
- },
- {
- "name": "Seatbelt buckled",
- "value": 354421634,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Seatbelt height position",
- "value": 356518787,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Seatbelt height move",
- "value": 356518788,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "SEAT_FORE_AFT_POS",
- "value": 356518789,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "SEAT_FORE_AFT_MOVE",
- "value": 356518790,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Seat backrest angle 1 position",
- "value": 356518791,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Seat backrest angle 1 move",
- "value": 356518792,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Seat backrest angle 2 position",
- "value": 356518793,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Seat backrest angle 2 move",
- "value": 356518794,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Seat height position",
- "value": 356518795,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Seat height move",
- "value": 356518796,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Seat depth position",
- "value": 356518797,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Seat depth move",
- "value": 356518798,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Seat tilt position",
- "value": 356518799,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Seat tilt move",
- "value": 356518800,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "SEAT_LUMBAR_FORE_AFT_POS",
- "value": 356518801,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "SEAT_LUMBAR_FORE_AFT_MOVE",
- "value": 356518802,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Lumbar side support position",
- "value": 356518803,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Lumbar side support move",
- "value": 356518804,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Headrest height position",
- "value": 289409941,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Headrest height move",
- "value": 356518806,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Headrest angle position",
- "value": 356518807,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Headrest angle move",
- "value": 356518808,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "SEAT_HEADREST_FORE_AFT_POS",
- "value": 356518809,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "SEAT_HEADREST_FORE_AFT_MOVE",
- "value": 356518810,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Seat Occupancy",
- "value": 356518832,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ",
- "data_enum": "VehicleSeatOccupancyState"
- },
- {
- "name": "Window Position",
- "value": 322964416,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Window Move",
- "value": 322964417,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Window Lock",
- "value": 320867268,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "VEHICLE_MAP_SERVICE",
- "value": 299895808,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "OBD2 Live Sensor Data",
- "value": 299896064,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "OBD2 Freeze Frame Sensor Data",
- "value": 299896065,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "OBD2 Freeze Frame Information",
- "value": 299896066,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "OBD2 Freeze Frame Clear",
- "value": 299896067,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:WRITE"
- },
- {
- "name": "Headlights State",
- "value": 289410560,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ",
- "data_enum": "VehicleLightState"
- },
- {
- "name": "High beam lights state",
- "value": 289410561,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ",
- "data_enum": "VehicleLightState"
- },
- {
- "name": "Fog light state",
- "value": 289410562,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ",
- "data_enum": "VehicleLightState"
- },
- {
- "name": "Hazard light status",
- "value": 289410563,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ",
- "data_enum": "VehicleLightState"
- },
- {
- "name": "Headlight switch",
- "value": 289410576,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE",
- "data_enum": "VehicleLightSwitch"
- },
- {
- "name": "High beam light switch",
- "value": 289410577,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE",
- "data_enum": "VehicleLightSwitch"
- },
- {
- "name": "Fog light switch",
- "value": 289410578,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE",
- "data_enum": "VehicleLightSwitch"
- },
- {
- "name": "Hazard light switch",
- "value": 289410579,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE",
- "data_enum": "VehicleLightSwitch"
- },
- {
- "name": "Cabin lights",
- "value": 289410817,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ",
- "data_enum": "VehicleLightState"
- },
- {
- "name": "Cabin lights switch",
- "value": 289410818,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE",
- "data_enum": "VehicleLightSwitch"
- },
- {
- "name": "Reading lights",
- "value": 356519683,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ",
- "data_enum": "VehicleLightState"
- },
- {
- "name": "Reading lights switch",
- "value": 356519684,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE",
- "data_enum": "VehicleLightSwitch"
- },
- {
- "name": "Support customize permissions for vendor properties",
- "value": 287313669,
- "change_mode": "VehiclePropertyChangeMode:STATIC",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "Allow disabling optional featurs from vhal.",
- "value": 286265094,
- "change_mode": "VehiclePropertyChangeMode:STATIC",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "Defines the initial Android user to be used during initialization.",
- "value": 299896583,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Defines a request to switch the foreground Android user.",
- "value": 299896584,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Called by the Android System after an Android user was created.",
- "value": 299896585,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Called by the Android System after an Android user was removed.",
- "value": 299896586,
- "change_mode": "VehiclePropertyChangeMode:STATIC",
- "access": "VehiclePropertyAccess:WRITE"
- },
- {
- "name": "USER_IDENTIFICATION_ASSOCIATION",
- "value": 299896587,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "EVS_SERVICE_REQUEST",
- "value": 289476368,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "Defines a request to apply power policy.",
- "value": 286265121,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "POWER_POLICY_GROUP_REQ",
- "value": 286265122,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "Notifies the current power policy to VHAL layer.",
- "value": 286265123,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "WATCHDOG_ALIVE",
- "value": 290459441,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:WRITE"
- },
- {
- "name": "Defines a process terminated by car watchdog and the reason of termination.",
- "value": 299896626,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:WRITE"
- },
- {
- "name": "Defines an event that VHAL signals to car watchdog as a heartbeat.",
- "value": 290459443,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "Starts the ClusterUI in cluster display.",
- "value": 289410868,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "Changes the state of the cluster display.",
- "value": 289476405,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ"
- },
- {
- "name": "Reports the current display state and ClusterUI state.",
- "value": 299896630,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:WRITE"
- },
- {
- "name": "Requests to change the cluster display state to show some ClusterUI.",
- "value": 289410871,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:WRITE"
- },
- {
- "name": "Informs the current navigation state.",
- "value": 292556600,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:WRITE"
- },
- {
- "name": "Electronic Toll Collection card type.",
- "value": 289410873,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ",
- "data_enum": "ElectronicTollCollectionCardType"
- },
- {
- "name": "Electronic Toll Collection card status.",
- "value": 289410874,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ",
- "data_enum": "ElectronicTollCollectionCardStatus"
- },
- {
- "name": "Front fog lights state",
- "value": 289410875,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ",
- "data_enum": "VehicleLightState"
- },
- {
- "name": "Front fog lights switch",
- "value": 289410876,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE",
- "data_enum": "VehicleLightSwitch"
- },
- {
- "name": "Rear fog lights state",
- "value": 289410877,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ",
- "data_enum": "VehicleLightState"
- },
- {
- "name": "Rear fog lights switch",
- "value": 289410878,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE",
- "data_enum": "VehicleLightSwitch"
- },
- {
- "name": "Indicates the maximum current draw threshold for charging set by the user",
- "value": 291508031,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE",
- "unit": "VehicleUnit:AMPERE"
- },
- {
- "name": "Indicates the maximum charge percent threshold set by the user",
- "value": 291508032,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Charging state of the car",
- "value": 289410881,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ",
- "data_enum": "EvChargeState"
- },
- {
- "name": "Start or stop charging the EV battery",
- "value": 287313730,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ_WRITE"
- },
- {
- "name": "Estimated charge time remaining in seconds",
- "value": 289410883,
- "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
- "access": "VehiclePropertyAccess:READ",
- "unit": "VehicleUnit:SECS"
- },
- {
- "name": "EV_REGENERATIVE_BRAKING_STATE",
- "value": 289410884,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ",
- "data_enum": "EvRegenerativeBrakingState"
- },
- {
- "name": "Indicates if there is a trailer present or not.",
- "value": 289410885,
- "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
- "access": "VehiclePropertyAccess:READ",
- "data_enum": "TrailerState"
- },
- {
- "name": "VEHICLE_CURB_WEIGHT",
- "value": 289410886,
- "change_mode": "VehiclePropertyChangeMode:STATIC",
- "access": "VehiclePropertyAccess:READ",
- "unit": "VehicleUnit:KILOGRAM"
- }
- ]
- },
- {
- "name": "EvsServiceType",
- "values": [
- {
- "name": "REARVIEW",
- "value": 0
- },
- {
- "name": "SURROUNDVIEW",
- "value": 1
- }
- ]
- },
- {
- "name": "VehiclePropertyChangeMode",
- "values": [
- {
- "name": "STATIC",
- "value": 0
- },
- {
- "name": "ON_CHANGE",
- "value": 1
- },
- {
- "name": "CONTINUOUS",
- "value": 2
- }
- ]
- },
- {
- "name": "Obd2CompressionIgnitionMonitors",
- "values": []
- },
- {
- "name": "VehicleLightState",
- "values": [
- {
- "name": "OFF",
- "value": 0
- },
- {
- "name": "ON",
- "value": 1
- },
- {
- "name": "DAYTIME_RUNNING",
- "value": 2
- }
- ]
- },
- {
- "name": "SwitchUserMessageType",
- "values": [
- {
- "name": "UNKNOWN",
- "value": 0
- },
- {
- "name": "LEGACY_ANDROID_SWITCH",
- "value": 1
- },
- {
- "name": "ANDROID_SWITCH",
- "value": 2
- },
- {
- "name": "VEHICLE_RESPONSE",
- "value": 3
- },
- {
- "name": "VEHICLE_REQUEST",
- "value": 4
- },
- {
- "name": "ANDROID_POST_SWITCH",
- "value": 5
- }
- ]
- },
- {
- "name": "PortLocationType",
- "values": [
- {
- "name": "UNKNOWN",
- "value": 0
- },
- {
- "name": "FRONT_LEFT",
- "value": 1
- },
- {
- "name": "FRONT_RIGHT",
- "value": 2
- },
- {
- "name": "REAR_RIGHT",
- "value": 3
- },
- {
- "name": "REAR_LEFT",
- "value": 4
- },
- {
- "name": "FRONT",
- "value": 5
- },
- {
- "name": "REAR",
- "value": 6
- }
- ]
- },
- {
- "name": "VehiclePropertyStatus",
- "values": [
- {
- "name": "AVAILABLE",
- "value": 0
- },
- {
- "name": "UNAVAILABLE",
- "value": 1
- },
- {
- "name": "ERROR",
- "value": 2
- }
- ]
- },
- {
- "name": "VehicleDisplay",
- "values": [
- {
- "name": "MAIN",
- "value": 0
- },
- {
- "name": "INSTRUMENT_CLUSTER",
- "value": 1
- }
- ]
- },
- {
- "name": "SwitchUserStatus",
- "values": [
- {
- "name": "SUCCESS",
- "value": 1
- },
- {
- "name": "FAILURE",
- "value": 2
- }
- ]
- },
- {
- "name": "InitialUserInfoRequestType",
- "values": [
- {
- "name": "UNKNOWN",
- "value": 0
- },
- {
- "name": "FIRST_BOOT",
- "value": 1
- },
- {
- "name": "FIRST_BOOT_AFTER_OTA",
- "value": 2
- },
- {
- "name": "COLD_BOOT",
- "value": 3
- },
- {
- "name": "RESUME",
- "value": 4
- }
- ]
- },
- {
- "name": "UserIdentificationAssociationSetValue",
- "values": [
- {
- "name": "INVALID",
- "value": 0
- },
- {
- "name": "ASSOCIATE_CURRENT_USER",
- "value": 1
- },
- {
- "name": "DISASSOCIATE_CURRENT_USER",
- "value": 2
- },
- {
- "name": "DISASSOCIATE_ALL_USERS",
- "value": 3
- }
- ]
- },
- {
- "name": "VehicleAreaDoor",
- "values": [
- {
- "name": "ROW_1_LEFT",
- "value": 1
- },
- {
- "name": "ROW_1_RIGHT",
- "value": 4
- },
- {
- "name": "ROW_2_LEFT",
- "value": 16
- },
- {
- "name": "ROW_2_RIGHT",
- "value": 64
- },
- {
- "name": "ROW_3_LEFT",
- "value": 256
- },
- {
- "name": "ROW_3_RIGHT",
- "value": 1024
- },
- {
- "name": "HOOD",
- "value": 268435456
- },
- {
- "name": "REAR",
- "value": 536870912
- }
- ]
- },
- {
- "name": "VehicleLightSwitch",
- "values": [
- {
- "name": "OFF",
- "value": 0
- },
- {
- "name": "ON",
- "value": 1
- },
- {
- "name": "DAYTIME_RUNNING",
- "value": 2
- },
- {
- "name": "AUTOMATIC",
- "value": 256
- }
- ]
- },
- {
- "name": "VehicleGear",
- "values": [
- {
- "name": "GEAR_UNKNOWN",
- "value": 0
- },
- {
- "name": "GEAR_NEUTRAL",
- "value": 1
- },
- {
- "name": "GEAR_REVERSE",
- "value": 2
- },
- {
- "name": "GEAR_PARK",
- "value": 4
- },
- {
- "name": "GEAR_DRIVE",
- "value": 8
- },
- {
- "name": "GEAR_1",
- "value": 16
- },
- {
- "name": "GEAR_2",
- "value": 32
- },
- {
- "name": "GEAR_3",
- "value": 64
- },
- {
- "name": "GEAR_4",
- "value": 128
- },
- {
- "name": "GEAR_5",
- "value": 256
- },
- {
- "name": "GEAR_6",
- "value": 512
- },
- {
- "name": "GEAR_7",
- "value": 1024
- },
- {
- "name": "GEAR_8",
- "value": 2048
- },
- {
- "name": "GEAR_9",
- "value": 4096
- }
- ]
- },
- {
- "name": "Obd2IgnitionMonitorKind",
- "values": [
- {
- "name": "SPARK",
- "value": 0
- },
- {
- "name": "COMPRESSION",
- "value": 1
- }
- ]
- },
- {
- "name": "CustomInputType",
- "values": [
- {
- "name": "CUSTOM_EVENT_F1",
- "value": 1001
- },
- {
- "name": "CUSTOM_EVENT_F2",
- "value": 1002
- },
- {
- "name": "CUSTOM_EVENT_F3",
- "value": 1003
- },
- {
- "name": "CUSTOM_EVENT_F4",
- "value": 1004
- },
- {
- "name": "CUSTOM_EVENT_F5",
- "value": 1005
- },
- {
- "name": "CUSTOM_EVENT_F6",
- "value": 1006
- },
- {
- "name": "CUSTOM_EVENT_F7",
- "value": 1007
- },
- {
- "name": "CUSTOM_EVENT_F8",
- "value": 1008
- },
- {
- "name": "CUSTOM_EVENT_F9",
- "value": 1009
- },
- {
- "name": "CUSTOM_EVENT_F10",
- "value": 1010
- }
- ]
- },
- {
- "name": "VehicleApPowerStateReport",
- "values": [
- {
- "name": "WAIT_FOR_VHAL",
- "value": 1
- },
- {
- "name": "DEEP_SLEEP_ENTRY",
- "value": 2
- },
- {
- "name": "DEEP_SLEEP_EXIT",
- "value": 3
- },
- {
- "name": "SHUTDOWN_POSTPONE",
- "value": 4
- },
- {
- "name": "SHUTDOWN_START",
- "value": 5
- },
- {
- "name": "ON",
- "value": 6
- },
- {
- "name": "SHUTDOWN_PREPARE",
- "value": 7
- },
- {
- "name": "SHUTDOWN_CANCELLED",
- "value": 8
- },
- {
- "name": "HIBERNATION_ENTRY",
- "value": 9
- },
- {
- "name": "HIBERNATION_EXIT",
- "value": 10
- }
- ]
- },
- {
- "name": "VmsMessageWithLayerIntegerValuesIndex",
- "values": [
- {
- "name": "MESSAGE_TYPE",
- "value": 0
- },
- {
- "name": "LAYER_TYPE",
- "value": 1
- },
- {
- "name": "LAYER_SUBTYPE",
- "value": 2
- },
- {
- "name": "LAYER_VERSION",
- "value": 3
- }
- ]
- },
- {
- "name": "EvRegenerativeBrakingState",
- "values": [
- {
- "name": "UNKNOWN",
- "value": 0
- },
- {
- "name": "DISABLED",
- "value": 1
- },
- {
- "name": "PARTIALLY_ENABLED",
- "value": 2
- },
- {
- "name": "FULLY_ENABLED",
- "value": 3
- }
- ]
- },
- {
- "name": "VehiclePropertyGroup",
- "values": [
- {
- "name": "SYSTEM",
- "value": 268435456
- },
- {
- "name": "VENDOR",
- "value": 536870912
- },
- {
- "name": "MASK",
- "value": 4026531840
- }
- ]
- },
- {
- "name": "VehicleIgnitionState",
- "values": [
- {
- "name": "UNDEFINED",
- "value": 0
- },
- {
- "name": "LOCK",
- "value": 1
- },
- {
- "name": "OFF",
- "value": 2
- },
- {
- "name": "ACC",
- "value": 3
- },
- {
- "name": "ON",
- "value": 4
- },
- {
- "name": "START",
- "value": 5
- }
- ]
- },
- {
- "name": "VehicleHwKeyInputAction",
- "values": [
- {
- "name": "ACTION_DOWN",
- "value": 0
- },
- {
- "name": "ACTION_UP",
- "value": 1
- }
- ]
- },
- {
- "name": "DiagnosticIntegerSensorIndex",
- "values": [
- {
- "name": "FUEL_SYSTEM_STATUS",
- "value": 0
- },
- {
- "name": "MALFUNCTION_INDICATOR_LIGHT_ON",
- "value": 1
- },
- {
- "name": "IGNITION_MONITORS_SUPPORTED",
- "value": 2
- },
- {
- "name": "IGNITION_SPECIFIC_MONITORS",
- "value": 3
- },
- {
- "name": "INTAKE_AIR_TEMPERATURE",
- "value": 4
- },
- {
- "name": "COMMANDED_SECONDARY_AIR_STATUS",
- "value": 5
- },
- {
- "name": "NUM_OXYGEN_SENSORS_PRESENT",
- "value": 6
- },
- {
- "name": "RUNTIME_SINCE_ENGINE_START",
- "value": 7
- },
- {
- "name": "DISTANCE_TRAVELED_WITH_MALFUNCTION_INDICATOR_LIGHT_ON",
- "value": 8
- },
- {
- "name": "WARMUPS_SINCE_CODES_CLEARED",
- "value": 9
- },
- {
- "name": "DISTANCE_TRAVELED_SINCE_CODES_CLEARED",
- "value": 10
- },
- {
- "name": "ABSOLUTE_BAROMETRIC_PRESSURE",
- "value": 11
- },
- {
- "name": "CONTROL_MODULE_VOLTAGE",
- "value": 12
- },
- {
- "name": "AMBIENT_AIR_TEMPERATURE",
- "value": 13
- },
- {
- "name": "TIME_WITH_MALFUNCTION_LIGHT_ON",
- "value": 14
- },
- {
- "name": "TIME_SINCE_TROUBLE_CODES_CLEARED",
- "value": 15
- },
- {
- "name": "MAX_FUEL_AIR_EQUIVALENCE_RATIO",
- "value": 16
- },
- {
- "name": "MAX_OXYGEN_SENSOR_VOLTAGE",
- "value": 17
- },
- {
- "name": "MAX_OXYGEN_SENSOR_CURRENT",
- "value": 18
- },
- {
- "name": "MAX_INTAKE_MANIFOLD_ABSOLUTE_PRESSURE",
- "value": 19
- },
- {
- "name": "MAX_AIR_FLOW_RATE_FROM_MASS_AIR_FLOW_SENSOR",
- "value": 20
- },
- {
- "name": "FUEL_TYPE",
- "value": 21
- },
- {
- "name": "FUEL_RAIL_ABSOLUTE_PRESSURE",
- "value": 22
- },
- {
- "name": "ENGINE_OIL_TEMPERATURE",
- "value": 23
- },
- {
- "name": "DRIVER_DEMAND_PERCENT_TORQUE",
- "value": 24
- },
- {
- "name": "ENGINE_ACTUAL_PERCENT_TORQUE",
- "value": 25
- },
- {
- "name": "ENGINE_REFERENCE_PERCENT_TORQUE",
- "value": 26
- },
- {
- "name": "ENGINE_PERCENT_TORQUE_DATA_IDLE",
- "value": 27
- },
- {
- "name": "ENGINE_PERCENT_TORQUE_DATA_POINT1",
- "value": 28
- },
- {
- "name": "ENGINE_PERCENT_TORQUE_DATA_POINT2",
- "value": 29
- },
- {
- "name": "ENGINE_PERCENT_TORQUE_DATA_POINT3",
- "value": 30
- },
- {
- "name": "ENGINE_PERCENT_TORQUE_DATA_POINT4",
- "value": 31
- }
- ]
- },
- {
- "name": "UserIdentificationAssociationValue",
- "values": [
- {
- "name": "UNKNOWN",
- "value": 1
- },
- {
- "name": "ASSOCIATED_CURRENT_USER",
- "value": 2
- },
- {
- "name": "ASSOCIATED_ANOTHER_USER",
- "value": 3
- },
- {
- "name": "NOT_ASSOCIATED_ANY_USER",
- "value": 4
- }
- ]
- },
- {
- "name": "VmsBaseMessageIntegerValuesIndex",
- "values": [
- {
- "name": "MESSAGE_TYPE",
- "value": 0
- }
- ]
- },
- {
- "name": "DiagnosticFloatSensorIndex",
- "values": [
- {
- "name": "CALCULATED_ENGINE_LOAD",
- "value": 0
- },
- {
- "name": "ENGINE_COOLANT_TEMPERATURE",
- "value": 1
- },
- {
- "name": "SHORT_TERM_FUEL_TRIM_BANK1",
- "value": 2
- },
- {
- "name": "LONG_TERM_FUEL_TRIM_BANK1",
- "value": 3
- },
- {
- "name": "SHORT_TERM_FUEL_TRIM_BANK2",
- "value": 4
- },
- {
- "name": "LONG_TERM_FUEL_TRIM_BANK2",
- "value": 5
- },
- {
- "name": "FUEL_PRESSURE",
- "value": 6
- },
- {
- "name": "INTAKE_MANIFOLD_ABSOLUTE_PRESSURE",
- "value": 7
- },
- {
- "name": "ENGINE_RPM",
- "value": 8
- },
- {
- "name": "VEHICLE_SPEED",
- "value": 9
- },
- {
- "name": "TIMING_ADVANCE",
- "value": 10
- },
- {
- "name": "MAF_AIR_FLOW_RATE",
- "value": 11
- },
- {
- "name": "THROTTLE_POSITION",
- "value": 12
- },
- {
- "name": "OXYGEN_SENSOR1_VOLTAGE",
- "value": 13
- },
- {
- "name": "OXYGEN_SENSOR1_SHORT_TERM_FUEL_TRIM",
- "value": 14
- },
- {
- "name": "OXYGEN_SENSOR1_FUEL_AIR_EQUIVALENCE_RATIO",
- "value": 15
- },
- {
- "name": "OXYGEN_SENSOR2_VOLTAGE",
- "value": 16
- },
- {
- "name": "OXYGEN_SENSOR2_SHORT_TERM_FUEL_TRIM",
- "value": 17
- },
- {
- "name": "OXYGEN_SENSOR2_FUEL_AIR_EQUIVALENCE_RATIO",
- "value": 18
- },
- {
- "name": "OXYGEN_SENSOR3_VOLTAGE",
- "value": 19
- },
- {
- "name": "OXYGEN_SENSOR3_SHORT_TERM_FUEL_TRIM",
- "value": 20
- },
- {
- "name": "OXYGEN_SENSOR3_FUEL_AIR_EQUIVALENCE_RATIO",
- "value": 21
- },
- {
- "name": "OXYGEN_SENSOR4_VOLTAGE",
- "value": 22
- },
- {
- "name": "OXYGEN_SENSOR4_SHORT_TERM_FUEL_TRIM",
- "value": 23
- },
- {
- "name": "OXYGEN_SENSOR4_FUEL_AIR_EQUIVALENCE_RATIO",
- "value": 24
- },
- {
- "name": "OXYGEN_SENSOR5_VOLTAGE",
- "value": 25
- },
- {
- "name": "OXYGEN_SENSOR5_SHORT_TERM_FUEL_TRIM",
- "value": 26
- },
- {
- "name": "OXYGEN_SENSOR5_FUEL_AIR_EQUIVALENCE_RATIO",
- "value": 27
- },
- {
- "name": "OXYGEN_SENSOR6_VOLTAGE",
- "value": 28
- },
- {
- "name": "OXYGEN_SENSOR6_SHORT_TERM_FUEL_TRIM",
- "value": 29
- },
- {
- "name": "OXYGEN_SENSOR6_FUEL_AIR_EQUIVALENCE_RATIO",
- "value": 30
- },
- {
- "name": "OXYGEN_SENSOR7_VOLTAGE",
- "value": 31
- },
- {
- "name": "OXYGEN_SENSOR7_SHORT_TERM_FUEL_TRIM",
- "value": 32
- },
- {
- "name": "OXYGEN_SENSOR7_FUEL_AIR_EQUIVALENCE_RATIO",
- "value": 33
- },
- {
- "name": "OXYGEN_SENSOR8_VOLTAGE",
- "value": 34
- },
- {
- "name": "OXYGEN_SENSOR8_SHORT_TERM_FUEL_TRIM",
- "value": 35
- },
- {
- "name": "OXYGEN_SENSOR8_FUEL_AIR_EQUIVALENCE_RATIO",
- "value": 36
- },
- {
- "name": "FUEL_RAIL_PRESSURE",
- "value": 37
- },
- {
- "name": "FUEL_RAIL_GAUGE_PRESSURE",
- "value": 38
- },
- {
- "name": "COMMANDED_EXHAUST_GAS_RECIRCULATION",
- "value": 39
- },
- {
- "name": "EXHAUST_GAS_RECIRCULATION_ERROR",
- "value": 40
- },
- {
- "name": "COMMANDED_EVAPORATIVE_PURGE",
- "value": 41
- },
- {
- "name": "FUEL_TANK_LEVEL_INPUT",
- "value": 42
- },
- {
- "name": "EVAPORATION_SYSTEM_VAPOR_PRESSURE",
- "value": 43
- },
- {
- "name": "CATALYST_TEMPERATURE_BANK1_SENSOR1",
- "value": 44
- },
- {
- "name": "CATALYST_TEMPERATURE_BANK2_SENSOR1",
- "value": 45
- },
- {
- "name": "CATALYST_TEMPERATURE_BANK1_SENSOR2",
- "value": 46
- },
- {
- "name": "CATALYST_TEMPERATURE_BANK2_SENSOR2",
- "value": 47
- },
- {
- "name": "ABSOLUTE_LOAD_VALUE",
- "value": 48
- },
- {
- "name": "FUEL_AIR_COMMANDED_EQUIVALENCE_RATIO",
- "value": 49
- },
- {
- "name": "RELATIVE_THROTTLE_POSITION",
- "value": 50
- },
- {
- "name": "ABSOLUTE_THROTTLE_POSITION_B",
- "value": 51
- },
- {
- "name": "ABSOLUTE_THROTTLE_POSITION_C",
- "value": 52
- },
- {
- "name": "ACCELERATOR_PEDAL_POSITION_D",
- "value": 53
- },
- {
- "name": "ACCELERATOR_PEDAL_POSITION_E",
- "value": 54
- },
- {
- "name": "ACCELERATOR_PEDAL_POSITION_F",
- "value": 55
- },
- {
- "name": "COMMANDED_THROTTLE_ACTUATOR",
- "value": 56
- },
- {
- "name": "ETHANOL_FUEL_PERCENTAGE",
- "value": 57
- },
- {
- "name": "ABSOLUTE_EVAPORATION_SYSTEM_VAPOR_PRESSURE",
- "value": 58
- },
- {
- "name": "SHORT_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK1",
- "value": 59
- },
- {
- "name": "SHORT_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK2",
- "value": 60
- },
- {
- "name": "SHORT_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK3",
- "value": 61
- },
- {
- "name": "SHORT_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK4",
- "value": 62
- },
- {
- "name": "LONG_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK1",
- "value": 63
- },
- {
- "name": "LONG_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK2",
- "value": 64
- },
- {
- "name": "LONG_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK3",
- "value": 65
- },
- {
- "name": "LONG_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK4",
- "value": 66
- },
- {
- "name": "RELATIVE_ACCELERATOR_PEDAL_POSITION",
- "value": 67
- },
- {
- "name": "HYBRID_BATTERY_PACK_REMAINING_LIFE",
- "value": 68
- },
- {
- "name": "FUEL_INJECTION_TIMING",
- "value": 69
- },
- {
- "name": "ENGINE_FUEL_RATE",
- "value": 70
- }
- ]
- },
- {
- "name": "VmsMessageWithLayerAndPublisherIdIntegerValuesIndex",
- "values": [
- {
- "name": "MESSAGE_TYPE",
- "value": 0
- },
- {
- "name": "LAYER_TYPE",
- "value": 1
- },
- {
- "name": "LAYER_SUBTYPE",
- "value": 2
- },
- {
- "name": "LAYER_VERSION",
- "value": 3
- },
- {
- "name": "PUBLISHER_ID",
- "value": 4
- }
- ]
- },
- {
- "name": "FuelType",
- "values": [
- {
- "name": "FUEL_TYPE_UNKNOWN",
- "value": 0
- },
- {
- "name": "FUEL_TYPE_UNLEADED",
- "value": 1
- },
- {
- "name": "FUEL_TYPE_LEADED",
- "value": 2
- },
- {
- "name": "FUEL_TYPE_DIESEL_1",
- "value": 3
- },
- {
- "name": "FUEL_TYPE_DIESEL_2",
- "value": 4
- },
- {
- "name": "FUEL_TYPE_BIODIESEL",
- "value": 5
- },
- {
- "name": "FUEL_TYPE_E85",
- "value": 6
- },
- {
- "name": "FUEL_TYPE_LPG",
- "value": 7
- },
- {
- "name": "FUEL_TYPE_CNG",
- "value": 8
- },
- {
- "name": "FUEL_TYPE_LNG",
- "value": 9
- },
- {
- "name": "FUEL_TYPE_ELECTRIC",
- "value": 10
- },
- {
- "name": "FUEL_TYPE_HYDROGEN",
- "value": 11
- },
- {
- "name": "FUEL_TYPE_OTHER",
- "value": 12
- }
- ]
- },
- {
- "name": "VehicleApPowerStateReq",
- "values": [
- {
- "name": "ON",
- "value": 0
- },
- {
- "name": "SHUTDOWN_PREPARE",
- "value": 1
- },
- {
- "name": "CANCEL_SHUTDOWN",
- "value": 2
- },
- {
- "name": "FINISHED",
- "value": 3
- }
- ]
- },
- {
- "name": "VmsMessageType",
- "values": [
- {
- "name": "SUBSCRIBE",
- "value": 1
- },
- {
- "name": "SUBSCRIBE_TO_PUBLISHER",
- "value": 2
- },
- {
- "name": "UNSUBSCRIBE",
- "value": 3
- },
- {
- "name": "UNSUBSCRIBE_TO_PUBLISHER",
- "value": 4
- },
- {
- "name": "OFFERING",
- "value": 5
- },
- {
- "name": "AVAILABILITY_REQUEST",
- "value": 6
- },
- {
- "name": "SUBSCRIPTIONS_REQUEST",
- "value": 7
- },
- {
- "name": "AVAILABILITY_RESPONSE",
- "value": 8
- },
- {
- "name": "AVAILABILITY_CHANGE",
- "value": 9
- },
- {
- "name": "SUBSCRIPTIONS_RESPONSE",
- "value": 10
- },
- {
- "name": "SUBSCRIPTIONS_CHANGE",
- "value": 11
- },
- {
- "name": "DATA",
- "value": 12
- },
- {
- "name": "PUBLISHER_ID_REQUEST",
- "value": 13
- },
- {
- "name": "PUBLISHER_ID_RESPONSE",
- "value": 14
- },
- {
- "name": "PUBLISHER_INFORMATION_REQUEST",
- "value": 15
- },
- {
- "name": "PUBLISHER_INFORMATION_RESPONSE",
- "value": 16
- },
- {
- "name": "START_SESSION",
- "value": 17
- }
- ]
- },
- {
- "name": "Obd2CommonIgnitionMonitors",
- "values": []
- },
- {
- "name": "UserIdentificationAssociationType",
- "values": [
- {
- "name": "INVALID",
- "value": 0
- },
- {
- "name": "KEY_FOB",
- "value": 1
- },
- {
- "name": "CUSTOM_1",
- "value": 101
- },
- {
- "name": "CUSTOM_2",
- "value": 102
- },
- {
- "name": "CUSTOM_3",
- "value": 103
- },
- {
- "name": "CUSTOM_4",
- "value": 104
- }
- ]
- },
- {
- "name": "EvConnectorType",
- "values": [
- {
- "name": "UNKNOWN",
- "value": 0
- },
- {
- "name": "IEC_TYPE_1_AC",
- "value": 1
- },
- {
- "name": "IEC_TYPE_2_AC",
- "value": 2
- },
- {
- "name": "IEC_TYPE_3_AC",
- "value": 3
- },
- {
- "name": "IEC_TYPE_4_DC",
- "value": 4
- },
- {
- "name": "IEC_TYPE_1_CCS_DC",
- "value": 5
- },
- {
- "name": "IEC_TYPE_2_CCS_DC",
- "value": 6
- },
- {
- "name": "TESLA_ROADSTER",
- "value": 7
- },
- {
- "name": "TESLA_HPWC",
- "value": 8
- },
- {
- "name": "TESLA_SUPERCHARGER",
- "value": 9
- },
- {
- "name": "GBT_AC",
- "value": 10
- },
- {
- "name": "GBT_DC",
- "value": 11
- },
- {
- "name": "OTHER",
- "value": 101
- }
- ]
- },
- {
- "name": "VehicleApPowerStateShutdownParam",
- "values": [
- {
- "name": "SHUTDOWN_IMMEDIATELY",
- "value": 1
- },
- {
- "name": "CAN_SLEEP",
- "value": 2
- },
- {
- "name": "SHUTDOWN_ONLY",
- "value": 3
- },
- {
- "name": "SLEEP_IMMEDIATELY",
- "value": 4
- },
- {
- "name": "HIBERNATE_IMMEDIATELY",
- "value": 5
- },
- {
- "name": "CAN_HIBERNATE",
- "value": 6
- }
- ]
- },
- {
- "name": "VmsOfferingMessageIntegerValuesIndex",
- "values": [
- {
- "name": "MESSAGE_TYPE",
- "value": 0
- },
- {
- "name": "PUBLISHER_ID",
- "value": 1
- },
- {
- "name": "NUMBER_OF_OFFERS",
- "value": 2
- },
- {
- "name": "OFFERING_START",
- "value": 3
- }
- ]
- },
- {
- "name": "VehicleAreaSeat",
- "values": [
- {
- "name": "ROW_1_LEFT",
- "value": 1
- },
- {
- "name": "ROW_1_CENTER",
- "value": 2
- },
- {
- "name": "ROW_1_RIGHT",
- "value": 4
- },
- {
- "name": "ROW_2_LEFT",
- "value": 16
- },
- {
- "name": "ROW_2_CENTER",
- "value": 32
- },
- {
- "name": "ROW_2_RIGHT",
- "value": 64
- },
- {
- "name": "ROW_3_LEFT",
- "value": 256
- },
- {
- "name": "ROW_3_CENTER",
- "value": 512
- },
- {
- "name": "ROW_3_RIGHT",
- "value": 1024
- }
- ]
- },
- {
- "name": "VehicleVendorPermission",
- "values": [
- {
- "name": "PERMISSION_DEFAULT",
- "value": 0
- },
- {
- "name": "PERMISSION_SET_VENDOR_CATEGORY_WINDOW",
- "value": 1
- },
- {
- "name": "PERMISSION_GET_VENDOR_CATEGORY_WINDOW",
- "value": 2
- },
- {
- "name": "PERMISSION_SET_VENDOR_CATEGORY_DOOR",
- "value": 3
- },
- {
- "name": "PERMISSION_GET_VENDOR_CATEGORY_DOOR",
- "value": 4
- },
- {
- "name": "PERMISSION_SET_VENDOR_CATEGORY_SEAT",
- "value": 5
- },
- {
- "name": "PERMISSION_GET_VENDOR_CATEGORY_SEAT",
- "value": 6
- },
- {
- "name": "PERMISSION_SET_VENDOR_CATEGORY_MIRROR",
- "value": 7
- },
- {
- "name": "PERMISSION_GET_VENDOR_CATEGORY_MIRROR",
- "value": 8
- },
- {
- "name": "PERMISSION_SET_VENDOR_CATEGORY_INFO",
- "value": 9
- },
- {
- "name": "PERMISSION_GET_VENDOR_CATEGORY_INFO",
- "value": 10
- },
- {
- "name": "PERMISSION_SET_VENDOR_CATEGORY_ENGINE",
- "value": 11
- },
- {
- "name": "PERMISSION_GET_VENDOR_CATEGORY_ENGINE",
- "value": 12
- },
- {
- "name": "PERMISSION_SET_VENDOR_CATEGORY_HVAC",
- "value": 13
- },
- {
- "name": "PERMISSION_GET_VENDOR_CATEGORY_HVAC",
- "value": 14
- },
- {
- "name": "PERMISSION_SET_VENDOR_CATEGORY_LIGHT",
- "value": 15
- },
- {
- "name": "PERMISSION_GET_VENDOR_CATEGORY_LIGHT",
- "value": 16
- },
- {
- "name": "PERMISSION_SET_VENDOR_CATEGORY_1",
- "value": 65536
- },
- {
- "name": "PERMISSION_GET_VENDOR_CATEGORY_1",
- "value": 69632
- },
- {
- "name": "PERMISSION_SET_VENDOR_CATEGORY_2",
- "value": 131072
- },
- {
- "name": "PERMISSION_GET_VENDOR_CATEGORY_2",
- "value": 135168
- },
- {
- "name": "PERMISSION_SET_VENDOR_CATEGORY_3",
- "value": 196608
- },
- {
- "name": "PERMISSION_GET_VENDOR_CATEGORY_3",
- "value": 200704
- },
- {
- "name": "PERMISSION_SET_VENDOR_CATEGORY_4",
- "value": 262144
- },
- {
- "name": "PERMISSION_GET_VENDOR_CATEGORY_4",
- "value": 266240
- },
- {
- "name": "PERMISSION_SET_VENDOR_CATEGORY_5",
- "value": 327680
- },
- {
- "name": "PERMISSION_GET_VENDOR_CATEGORY_5",
- "value": 331776
- },
- {
- "name": "PERMISSION_SET_VENDOR_CATEGORY_6",
- "value": 393216
- },
- {
- "name": "PERMISSION_GET_VENDOR_CATEGORY_6",
- "value": 397312
- },
- {
- "name": "PERMISSION_SET_VENDOR_CATEGORY_7",
- "value": 458752
- },
- {
- "name": "PERMISSION_GET_VENDOR_CATEGORY_7",
- "value": 462848
- },
- {
- "name": "PERMISSION_SET_VENDOR_CATEGORY_8",
- "value": 524288
- },
- {
- "name": "PERMISSION_GET_VENDOR_CATEGORY_8",
- "value": 528384
- },
- {
- "name": "PERMISSION_SET_VENDOR_CATEGORY_9",
- "value": 589824
- },
- {
- "name": "PERMISSION_GET_VENDOR_CATEGORY_9",
- "value": 593920
- },
- {
- "name": "PERMISSION_SET_VENDOR_CATEGORY_10",
- "value": 655360
- },
- {
- "name": "PERMISSION_GET_VENDOR_CATEGORY_10",
- "value": 659456
- },
- {
- "name": "PERMISSION_NOT_ACCESSIBLE",
- "value": 4026531840
- }
- ]
- },
- {
- "name": "VehiclePropertyAccess",
- "values": [
- {
- "name": "NONE",
- "value": 0
- },
- {
- "name": "READ",
- "value": 1
- },
- {
- "name": "WRITE",
- "value": 2
- },
- {
- "name": "READ_WRITE",
- "value": 3
- }
- ]
- },
- {
- "name": "VmsAvailabilityStateIntegerValuesIndex",
- "values": [
- {
- "name": "MESSAGE_TYPE",
- "value": 0
- },
- {
- "name": "SEQUENCE_NUMBER",
- "value": 1
- },
- {
- "name": "NUMBER_OF_ASSOCIATED_LAYERS",
- "value": 2
- },
- {
- "name": "LAYERS_START",
- "value": 3
- }
- ]
- },
- {
- "name": "Obd2SparkIgnitionMonitors",
- "values": []
- },
- {
- "name": "VehicleTurnSignal",
- "values": [
- {
- "name": "NONE",
- "value": 0
- },
- {
- "name": "RIGHT",
- "value": 1
- },
- {
- "name": "LEFT",
- "value": 2
- }
- ]
- },
- {
- "name": "VmsPublisherInformationIntegerValuesIndex",
- "values": [
- {
- "name": "MESSAGE_TYPE",
- "value": 0
- },
- {
- "name": "PUBLISHER_ID",
- "value": 1
- }
- ]
- },
- {
- "name": "RotaryInputType",
- "values": [
- {
- "name": "ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION",
- "value": 0
- },
- {
- "name": "ROTARY_INPUT_TYPE_AUDIO_VOLUME",
- "value": 1
- }
- ]
- },
- {
- "name": "Obd2FuelSystemStatus",
- "values": [
- {
- "name": "OPEN_INSUFFICIENT_ENGINE_TEMPERATURE",
- "value": 1
- },
- {
- "name": "CLOSED_LOOP",
- "value": 2
- },
- {
- "name": "OPEN_ENGINE_LOAD_OR_DECELERATION",
- "value": 4
- },
- {
- "name": "OPEN_SYSTEM_FAILURE",
- "value": 8
- },
- {
- "name": "CLOSED_LOOP_BUT_FEEDBACK_FAULT",
- "value": 16
- }
- ]
- }
+ {
+ "name": "VehicleProperty",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "VIN of vehicle",
+ "value": 286261504
+ },
+ {
+ "name": "Manufacturer of vehicle",
+ "value": 286261505
+ },
+ {
+ "name": "Model of vehicle",
+ "value": 286261506
+ },
+ {
+ "name": "INFO_MODEL_YEAR",
+ "value": 289407235
+ },
+ {
+ "name": "INFO_FUEL_CAPACITY",
+ "value": 291504388
+ },
+ {
+ "name": "INFO_FUEL_TYPE",
+ "value": 289472773,
+ "data_enums": [
+ "FuelType"
+ ],
+ "data_enum": "FuelType"
+ },
+ {
+ "name": "INFO_EV_BATTERY_CAPACITY",
+ "value": 291504390
+ },
+ {
+ "name": "INFO_EV_CONNECTOR_TYPE",
+ "value": 289472775,
+ "data_enums": [
+ "EvConnectorType"
+ ],
+ "data_enum": "EvConnectorType"
+ },
+ {
+ "name": "Fuel door location",
+ "value": 289407240,
+ "data_enums": [
+ "PortLocationType"
+ ],
+ "data_enum": "PortLocationType"
+ },
+ {
+ "name": "EV port location",
+ "value": 289407241,
+ "data_enums": [
+ "PortLocationType"
+ ],
+ "data_enum": "PortLocationType"
+ },
+ {
+ "name": "INFO_DRIVER_SEAT",
+ "value": 356516106,
+ "data_enums": [
+ "VehicleAreaSeat"
+ ],
+ "data_enum": "VehicleAreaSeat"
+ },
+ {
+ "name": "INFO_EXTERIOR_DIMENSIONS",
+ "value": 289472779
+ },
+ {
+ "name": "Multiple EV port locations",
+ "value": 289472780,
+ "data_enums": [
+ "PortLocationType"
+ ],
+ "data_enum": "PortLocationType"
+ },
+ {
+ "name": "PERF_ODOMETER",
+ "value": 291504644
+ },
+ {
+ "name": "Speed of the vehicle",
+ "value": 291504647
+ },
+ {
+ "name": "PERF_VEHICLE_SPEED_DISPLAY",
+ "value": 291504648
+ },
+ {
+ "name": "PERF_STEERING_ANGLE",
+ "value": 291504649
+ },
+ {
+ "name": "PERF_REAR_STEERING_ANGLE",
+ "value": 291504656
+ },
+ {
+ "name": "Temperature of engine coolant",
+ "value": 291504897
+ },
+ {
+ "name": "Engine oil level",
+ "value": 289407747,
+ "data_enums": [
+ "VehicleOilLevel"
+ ],
+ "data_enum": "VehicleOilLevel"
+ },
+ {
+ "name": "Temperature of engine oil",
+ "value": 291504900
+ },
+ {
+ "name": "Engine rpm",
+ "value": 291504901
+ },
+ {
+ "name": "Reports wheel ticks",
+ "value": 290521862
+ },
+ {
+ "name": "FUEL_LEVEL",
+ "value": 291504903
+ },
+ {
+ "name": "Fuel door open",
+ "value": 287310600
+ },
+ {
+ "name": "EV_BATTERY_LEVEL",
+ "value": 291504905
+ },
+ {
+ "name": "EV_CURRENT_BATTERY_CAPACITY",
+ "value": 291504909
+ },
+ {
+ "name": "EV charge port open",
+ "value": 287310602
+ },
+ {
+ "name": "EV charge port connected",
+ "value": 287310603
+ },
+ {
+ "name": "EV_BATTERY_INSTANTANEOUS_CHARGE_RATE",
+ "value": 291504908
+ },
+ {
+ "name": "Range remaining",
+ "value": 291504904
+ },
+ {
+ "name": "EV battery average temperature",
+ "value": 291504910
+ },
+ {
+ "name": "Tire pressure",
+ "value": 392168201
+ },
+ {
+ "name": "Critically low tire pressure",
+ "value": 392168202
+ },
+ {
+ "name": "ENGINE_IDLE_AUTO_STOP_ENABLED",
+ "value": 287310624
+ },
+ {
+ "name": "Impact detected.",
+ "value": 289407792,
+ "data_enums": [
+ "ImpactSensorLocation"
+ ],
+ "data_enum": "ImpactSensorLocation"
+ },
+ {
+ "name": "Currently selected gear",
+ "value": 289408000,
+ "data_enums": [
+ "VehicleGear"
+ ],
+ "data_enum": "VehicleGear"
+ },
+ {
+ "name": "CURRENT_GEAR",
+ "value": 289408001,
+ "data_enums": [
+ "VehicleGear"
+ ],
+ "data_enum": "VehicleGear"
+ },
+ {
+ "name": "Parking brake state.",
+ "value": 287310850
+ },
+ {
+ "name": "Auto-apply parking brake.",
+ "value": 287310851
+ },
+ {
+ "name": "EV_BRAKE_REGENERATION_LEVEL",
+ "value": 289408012
+ },
+ {
+ "name": "Warning for fuel low level.",
+ "value": 287310853
+ },
+ {
+ "name": "Night mode",
+ "value": 287310855
+ },
+ {
+ "name": "TURN_SIGNAL_STATE",
+ "value": 289408008,
+ "data_enums": [
+ "VehicleTurnSignal"
+ ],
+ "data_enum": "VehicleTurnSignal"
+ },
+ {
+ "name": "Represents ignition state",
+ "value": 289408009,
+ "data_enums": [
+ "VehicleIgnitionState"
+ ],
+ "data_enum": "VehicleIgnitionState"
+ },
+ {
+ "name": "ABS is active",
+ "value": 287310858
+ },
+ {
+ "name": "Traction Control is active",
+ "value": 287310859
+ },
+ {
+ "name": "EV_STOPPING_MODE",
+ "value": 289408013,
+ "data_enums": [
+ "EvStoppingMode"
+ ],
+ "data_enum": "EvStoppingMode"
+ },
+ {
+ "name": "ELECTRONIC_STABILITY_CONTROL_ENABLED",
+ "value": 287310862
+ },
+ {
+ "name": "ELECTRONIC_STABILITY_CONTROL_STATE",
+ "value": 289408015,
+ "data_enums": [
+ "ElectronicStabilityControlState",
+ "ErrorState"
+ ],
+ "data_enum": "ElectronicStabilityControlState"
+ },
+ {
+ "name": "Fan speed setting",
+ "value": 356517120
+ },
+ {
+ "name": "Fan direction setting",
+ "value": 356517121,
+ "data_enums": [
+ "VehicleHvacFanDirection"
+ ],
+ "data_enum": "VehicleHvacFanDirection"
+ },
+ {
+ "name": "HVAC current temperature.",
+ "value": 358614274
+ },
+ {
+ "name": "HVAC, target temperature set.",
+ "value": 358614275
+ },
+ {
+ "name": "HVAC_DEFROSTER",
+ "value": 320865540
+ },
+ {
+ "name": "HVAC_AC_ON",
+ "value": 354419973
+ },
+ {
+ "name": "On\/off max AC",
+ "value": 354419974
+ },
+ {
+ "name": "On\/off max defrost",
+ "value": 354419975
+ },
+ {
+ "name": "Recirculation on\/off",
+ "value": 354419976
+ },
+ {
+ "name": "HVAC_DUAL_ON",
+ "value": 354419977
+ },
+ {
+ "name": "HVAC_AUTO_ON",
+ "value": 354419978
+ },
+ {
+ "name": "Seat heating\/cooling",
+ "value": 356517131
+ },
+ {
+ "name": "Side Mirror Heat",
+ "value": 339739916
+ },
+ {
+ "name": "Steering Wheel Heating\/Cooling",
+ "value": 289408269
+ },
+ {
+ "name": "Temperature units for display",
+ "value": 289408270,
+ "data_enums": [
+ "VehicleUnit"
+ ],
+ "data_enum": "VehicleUnit"
+ },
+ {
+ "name": "Actual fan speed",
+ "value": 356517135
+ },
+ {
+ "name": "HVAC_POWER_ON",
+ "value": 354419984
+ },
+ {
+ "name": "Fan Positions Available",
+ "value": 356582673,
+ "data_enums": [
+ "VehicleHvacFanDirection"
+ ],
+ "data_enum": "VehicleHvacFanDirection"
+ },
+ {
+ "name": "Automatic recirculation on\/off",
+ "value": 354419986
+ },
+ {
+ "name": "Seat ventilation",
+ "value": 356517139
+ },
+ {
+ "name": "Electric defrosters' status",
+ "value": 320865556
+ },
+ {
+ "name": "HVAC_TEMPERATURE_VALUE_SUGGESTION",
+ "value": 291570965
+ },
+ {
+ "name": "Distance units for display",
+ "value": 289408512,
+ "data_enums": [
+ "VehicleUnit"
+ ],
+ "data_enum": "VehicleUnit"
+ },
+ {
+ "name": "Fuel volume units for display",
+ "value": 289408513,
+ "data_enums": [
+ "VehicleUnit"
+ ],
+ "data_enum": "VehicleUnit"
+ },
+ {
+ "name": "TIRE_PRESSURE_DISPLAY_UNITS",
+ "value": 289408514,
+ "data_enums": [
+ "VehicleUnit"
+ ],
+ "data_enum": "VehicleUnit"
+ },
+ {
+ "name": "EV battery units for display",
+ "value": 289408515,
+ "data_enums": [
+ "VehicleUnit"
+ ],
+ "data_enum": "VehicleUnit"
+ },
+ {
+ "name": "FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME",
+ "value": 287311364
+ },
+ {
+ "name": "Speed units for display",
+ "value": 289408517
+ },
+ {
+ "name": "EXTERNAL_CAR_TIME",
+ "value": 290457096
+ },
+ {
+ "name": "ANDROID_EPOCH_TIME",
+ "value": 290457094
+ },
+ {
+ "name": "STORAGE_ENCRYPTION_BINDING_SEED",
+ "value": 292554247
+ },
+ {
+ "name": "Outside temperature",
+ "value": 291505923
+ },
+ {
+ "name": "AP_POWER_STATE_REQ",
+ "value": 289475072
+ },
+ {
+ "name": "AP_POWER_STATE_REPORT",
+ "value": 289475073
+ },
+ {
+ "name": "AP_POWER_BOOTUP_REASON",
+ "value": 289409538
+ },
+ {
+ "name": "DISPLAY_BRIGHTNESS",
+ "value": 289409539
+ },
+ {
+ "name": "PER_DISPLAY_BRIGHTNESS",
+ "value": 289475076
+ },
+ {
+ "name": "Valet mode enabled",
+ "value": 287312389
+ },
+ {
+ "name": "Head up display (HUD) enabled",
+ "value": 354421254
+ },
+ {
+ "name": "HW_KEY_INPUT",
+ "value": 289475088
+ },
+ {
+ "name": "HW_KEY_INPUT_V2",
+ "value": 367004177
+ },
+ {
+ "name": "HW_MOTION_INPUT",
+ "value": 367004178
+ },
+ {
+ "name": "HW_ROTARY_INPUT",
+ "value": 289475104,
+ "data_enums": [
+ "RotaryInputType"
+ ],
+ "data_enum": "RotaryInputType"
+ },
+ {
+ "name": "HW_CUSTOM_INPUT",
+ "value": 289475120,
+ "data_enums": [
+ "CustomInputType"
+ ],
+ "data_enum": "CustomInputType"
+ },
+ {
+ "name": "Door position",
+ "value": 373295872
+ },
+ {
+ "name": "Door move",
+ "value": 373295873
+ },
+ {
+ "name": "Door lock",
+ "value": 371198722
+ },
+ {
+ "name": "DOOR_CHILD_LOCK_ENABLED",
+ "value": 371198723
+ },
+ {
+ "name": "Mirror Z Position",
+ "value": 339741504
+ },
+ {
+ "name": "Mirror Z Move",
+ "value": 339741505
+ },
+ {
+ "name": "Mirror Y Position",
+ "value": 339741506
+ },
+ {
+ "name": "Mirror Y Move",
+ "value": 339741507
+ },
+ {
+ "name": "Mirror Lock",
+ "value": 287312708
+ },
+ {
+ "name": "Mirror Fold",
+ "value": 287312709
+ },
+ {
+ "name": "MIRROR_AUTO_FOLD_ENABLED",
+ "value": 337644358
+ },
+ {
+ "name": "MIRROR_AUTO_TILT_ENABLED",
+ "value": 337644359
+ },
+ {
+ "name": "Seat memory select",
+ "value": 356518784
+ },
+ {
+ "name": "Seat memory set",
+ "value": 356518785
+ },
+ {
+ "name": "Seatbelt buckled",
+ "value": 354421634
+ },
+ {
+ "name": "Seatbelt height position",
+ "value": 356518787
+ },
+ {
+ "name": "Seatbelt height move",
+ "value": 356518788
+ },
+ {
+ "name": "Seat fore\/aft position",
+ "value": 356518789
+ },
+ {
+ "name": "Seat fore\/aft move",
+ "value": 356518790
+ },
+ {
+ "name": "Seat backrest angle 1 position",
+ "value": 356518791
+ },
+ {
+ "name": "Seat backrest angle 1 move",
+ "value": 356518792
+ },
+ {
+ "name": "Seat backrest angle 2 position",
+ "value": 356518793
+ },
+ {
+ "name": "Seat backrest angle 2 move",
+ "value": 356518794
+ },
+ {
+ "name": "Seat height position",
+ "value": 356518795
+ },
+ {
+ "name": "Seat height move",
+ "value": 356518796
+ },
+ {
+ "name": "Seat depth position",
+ "value": 356518797
+ },
+ {
+ "name": "Seat depth move",
+ "value": 356518798
+ },
+ {
+ "name": "Seat tilt position",
+ "value": 356518799
+ },
+ {
+ "name": "Seat tilt move",
+ "value": 356518800
+ },
+ {
+ "name": "Lumber fore\/aft position",
+ "value": 356518801
+ },
+ {
+ "name": "Lumbar fore\/aft move",
+ "value": 356518802
+ },
+ {
+ "name": "Lumbar side support position",
+ "value": 356518803
+ },
+ {
+ "name": "Lumbar side support move",
+ "value": 356518804
+ },
+ {
+ "name": "SEAT_HEADREST_HEIGHT_POS",
+ "value": 289409941
+ },
+ {
+ "name": "Headrest height position",
+ "value": 356518820
+ },
+ {
+ "name": "Headrest height move",
+ "value": 356518806
+ },
+ {
+ "name": "Headrest angle position",
+ "value": 356518807
+ },
+ {
+ "name": "Headrest angle move",
+ "value": 356518808
+ },
+ {
+ "name": "Headrest fore\/aft position",
+ "value": 356518809
+ },
+ {
+ "name": "Headrest fore\/aft move",
+ "value": 356518810
+ },
+ {
+ "name": "SEAT_FOOTWELL_LIGHTS_STATE",
+ "value": 356518811,
+ "data_enums": [
+ "VehicleLightState"
+ ],
+ "data_enum": "VehicleLightState"
+ },
+ {
+ "name": "SEAT_FOOTWELL_LIGHTS_SWITCH",
+ "value": 356518812,
+ "data_enums": [
+ "VehicleLightSwitch"
+ ],
+ "data_enum": "VehicleLightSwitch"
+ },
+ {
+ "name": "SEAT_EASY_ACCESS_ENABLED",
+ "value": 354421661
+ },
+ {
+ "name": "SEAT_AIRBAG_ENABLED",
+ "value": 354421662
+ },
+ {
+ "name": "Seat airbags deployed",
+ "value": 356518821,
+ "data_enums": [
+ "VehicleAirbagLocation"
+ ],
+ "data_enum": "VehicleAirbagLocation"
+ },
+ {
+ "name": "SEAT_CUSHION_SIDE_SUPPORT_POS",
+ "value": 356518815
+ },
+ {
+ "name": "SEAT_CUSHION_SIDE_SUPPORT_MOVE",
+ "value": 356518816
+ },
+ {
+ "name": "SEAT_LUMBAR_VERTICAL_POS",
+ "value": 356518817
+ },
+ {
+ "name": "SEAT_LUMBAR_VERTICAL_MOVE",
+ "value": 356518818
+ },
+ {
+ "name": "SEAT_WALK_IN_POS",
+ "value": 356518819
+ },
+ {
+ "name": "SEAT_BELT_PRETENSIONER_DEPLOYED",
+ "value": 354421670
+ },
+ {
+ "name": "Seat Occupancy",
+ "value": 356518832,
+ "data_enums": [
+ "VehicleSeatOccupancyState"
+ ],
+ "data_enum": "VehicleSeatOccupancyState"
+ },
+ {
+ "name": "Window Position",
+ "value": 322964416
+ },
+ {
+ "name": "Window Move",
+ "value": 322964417
+ },
+ {
+ "name": "Window Lock",
+ "value": 320867268
+ },
+ {
+ "name": "WINDSHIELD_WIPERS_PERIOD",
+ "value": 322964421
+ },
+ {
+ "name": "Windshield wipers state.",
+ "value": 322964422,
+ "data_enums": [
+ "WindshieldWipersState"
+ ],
+ "data_enum": "WindshieldWipersState"
+ },
+ {
+ "name": "Windshield wipers switch.",
+ "value": 322964423,
+ "data_enums": [
+ "WindshieldWipersSwitch"
+ ],
+ "data_enum": "WindshieldWipersSwitch"
+ },
+ {
+ "name": "Steering wheel depth position",
+ "value": 289410016
+ },
+ {
+ "name": "Steering wheel depth movement",
+ "value": 289410017
+ },
+ {
+ "name": "Steering wheel height position",
+ "value": 289410018
+ },
+ {
+ "name": "Steering wheel height movement",
+ "value": 289410019
+ },
+ {
+ "name": "STEERING_WHEEL_THEFT_LOCK_ENABLED",
+ "value": 287312868
+ },
+ {
+ "name": "Steering wheel locked",
+ "value": 287312869
+ },
+ {
+ "name": "STEERING_WHEEL_EASY_ACCESS_ENABLED",
+ "value": 287312870
+ },
+ {
+ "name": "GLOVE_BOX_DOOR_POS",
+ "value": 356518896
+ },
+ {
+ "name": "Lock or unlock the glove box.",
+ "value": 354421745
+ },
+ {
+ "name": "VEHICLE_MAP_SERVICE",
+ "value": 299895808
+ },
+ {
+ "name": "LOCATION_CHARACTERIZATION",
+ "value": 289410064
+ },
+ {
+ "name": "ULTRASONICS_SENSOR_POSITION",
+ "value": 406916128
+ },
+ {
+ "name": "ULTRASONICS_SENSOR_ORIENTATION",
+ "value": 409013281
+ },
+ {
+ "name": "ULTRASONICS_SENSOR_FIELD_OF_VIEW",
+ "value": 406916130
+ },
+ {
+ "name": "ULTRASONICS_SENSOR_DETECTION_RANGE",
+ "value": 406916131
+ },
+ {
+ "name": "ULTRASONICS_SENSOR_SUPPORTED_RANGES",
+ "value": 406916132
+ },
+ {
+ "name": "ULTRASONICS_SENSOR_MEASURED_DISTANCE",
+ "value": 406916133
+ },
+ {
+ "name": "OBD2 Live Sensor Data",
+ "value": 299896064
+ },
+ {
+ "name": "OBD2 Freeze Frame Sensor Data",
+ "value": 299896065
+ },
+ {
+ "name": "OBD2 Freeze Frame Information",
+ "value": 299896066
+ },
+ {
+ "name": "OBD2 Freeze Frame Clear",
+ "value": 299896067
+ },
+ {
+ "name": "Headlights State",
+ "value": 289410560,
+ "data_enums": [
+ "VehicleLightState"
+ ],
+ "data_enum": "VehicleLightState"
+ },
+ {
+ "name": "High beam lights state",
+ "value": 289410561,
+ "data_enums": [
+ "VehicleLightState"
+ ],
+ "data_enum": "VehicleLightState"
+ },
+ {
+ "name": "Fog light state",
+ "value": 289410562,
+ "data_enums": [
+ "VehicleLightState"
+ ],
+ "data_enum": "VehicleLightState"
+ },
+ {
+ "name": "Hazard light status",
+ "value": 289410563,
+ "data_enums": [
+ "VehicleLightState"
+ ],
+ "data_enum": "VehicleLightState"
+ },
+ {
+ "name": "Headlight switch",
+ "value": 289410576,
+ "data_enums": [
+ "VehicleLightSwitch"
+ ],
+ "data_enum": "VehicleLightSwitch"
+ },
+ {
+ "name": "High beam light switch",
+ "value": 289410577,
+ "data_enums": [
+ "VehicleLightSwitch"
+ ],
+ "data_enum": "VehicleLightSwitch"
+ },
+ {
+ "name": "Fog light switch",
+ "value": 289410578,
+ "data_enums": [
+ "VehicleLightSwitch"
+ ],
+ "data_enum": "VehicleLightSwitch"
+ },
+ {
+ "name": "Hazard light switch",
+ "value": 289410579,
+ "data_enums": [
+ "VehicleLightSwitch"
+ ],
+ "data_enum": "VehicleLightSwitch"
+ },
+ {
+ "name": "Cabin lights",
+ "value": 289410817,
+ "data_enums": [
+ "VehicleLightState"
+ ],
+ "data_enum": "VehicleLightState"
+ },
+ {
+ "name": "Cabin lights switch",
+ "value": 289410818,
+ "data_enums": [
+ "VehicleLightSwitch"
+ ],
+ "data_enum": "VehicleLightSwitch"
+ },
+ {
+ "name": "Reading lights",
+ "value": 356519683,
+ "data_enums": [
+ "VehicleLightState"
+ ],
+ "data_enum": "VehicleLightState"
+ },
+ {
+ "name": "Reading lights switch",
+ "value": 356519684,
+ "data_enums": [
+ "VehicleLightSwitch"
+ ],
+ "data_enum": "VehicleLightSwitch"
+ },
+ {
+ "name": "Steering wheel lights state",
+ "value": 289410828,
+ "data_enums": [
+ "VehicleLightState"
+ ],
+ "data_enum": "VehicleLightState"
+ },
+ {
+ "name": "Steering wheel lights switch",
+ "value": 289410829,
+ "data_enums": [
+ "VehicleLightSwitch"
+ ],
+ "data_enum": "VehicleLightSwitch"
+ },
+ {
+ "name": "SUPPORT_CUSTOMIZE_VENDOR_PERMISSION",
+ "value": 287313669
+ },
+ {
+ "name": "DISABLED_OPTIONAL_FEATURES",
+ "value": 286265094
+ },
+ {
+ "name": "INITIAL_USER_INFO",
+ "value": 299896583
+ },
+ {
+ "name": "SWITCH_USER",
+ "value": 299896584
+ },
+ {
+ "name": "CREATE_USER",
+ "value": 299896585
+ },
+ {
+ "name": "REMOVE_USER",
+ "value": 299896586
+ },
+ {
+ "name": "USER_IDENTIFICATION_ASSOCIATION",
+ "value": 299896587
+ },
+ {
+ "name": "Enable\/request an EVS service.",
+ "value": 289476368
+ },
+ {
+ "name": "POWER_POLICY_REQ",
+ "value": 286265121
+ },
+ {
+ "name": "POWER_POLICY_GROUP_REQ",
+ "value": 286265122
+ },
+ {
+ "name": "CURRENT_POWER_POLICY",
+ "value": 286265123
+ },
+ {
+ "name": "WATCHDOG_ALIVE",
+ "value": 290459441
+ },
+ {
+ "name": "WATCHDOG_TERMINATED_PROCESS",
+ "value": 299896626
+ },
+ {
+ "name": "VHAL_HEARTBEAT",
+ "value": 290459443
+ },
+ {
+ "name": "CLUSTER_SWITCH_UI",
+ "value": 289410868
+ },
+ {
+ "name": "CLUSTER_DISPLAY_STATE",
+ "value": 289476405
+ },
+ {
+ "name": "CLUSTER_REPORT_STATE",
+ "value": 299896630
+ },
+ {
+ "name": "CLUSTER_REQUEST_DISPLAY",
+ "value": 289410871
+ },
+ {
+ "name": "CLUSTER_NAVIGATION_STATE",
+ "value": 292556600
+ },
+ {
+ "name": "ELECTRONIC_TOLL_COLLECTION_CARD_TYPE",
+ "value": 289410873,
+ "data_enums": [
+ "ElectronicTollCollectionCardType"
+ ],
+ "data_enum": "ElectronicTollCollectionCardType"
+ },
+ {
+ "name": "ELECTRONIC_TOLL_COLLECTION_CARD_STATUS",
+ "value": 289410874,
+ "data_enums": [
+ "ElectronicTollCollectionCardStatus"
+ ],
+ "data_enum": "ElectronicTollCollectionCardStatus"
+ },
+ {
+ "name": "Front fog lights state",
+ "value": 289410875,
+ "data_enums": [
+ "VehicleLightState"
+ ],
+ "data_enum": "VehicleLightState"
+ },
+ {
+ "name": "Front fog lights switch",
+ "value": 289410876,
+ "data_enums": [
+ "VehicleLightSwitch"
+ ],
+ "data_enum": "VehicleLightSwitch"
+ },
+ {
+ "name": "Rear fog lights state",
+ "value": 289410877,
+ "data_enums": [
+ "VehicleLightState"
+ ],
+ "data_enum": "VehicleLightState"
+ },
+ {
+ "name": "Rear fog lights switch",
+ "value": 289410878,
+ "data_enums": [
+ "VehicleLightSwitch"
+ ],
+ "data_enum": "VehicleLightSwitch"
+ },
+ {
+ "name": "EV_CHARGE_CURRENT_DRAW_LIMIT",
+ "value": 291508031
+ },
+ {
+ "name": "EV_CHARGE_PERCENT_LIMIT",
+ "value": 291508032
+ },
+ {
+ "name": "Charging state of the car",
+ "value": 289410881,
+ "data_enums": [
+ "EvChargeState"
+ ],
+ "data_enum": "EvChargeState"
+ },
+ {
+ "name": "EV_CHARGE_SWITCH",
+ "value": 287313730
+ },
+ {
+ "name": "EV_CHARGE_TIME_REMAINING",
+ "value": 289410883
+ },
+ {
+ "name": "EV_REGENERATIVE_BRAKING_STATE",
+ "value": 289410884,
+ "data_enums": [
+ "EvRegenerativeBrakingState"
+ ],
+ "data_enum": "EvRegenerativeBrakingState"
+ },
+ {
+ "name": "TRAILER_PRESENT",
+ "value": 289410885,
+ "data_enums": [
+ "TrailerState"
+ ],
+ "data_enum": "TrailerState"
+ },
+ {
+ "name": "Vehicle’s curb weight",
+ "value": 289410886
+ },
+ {
+ "name": "GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT",
+ "value": 289410887,
+ "data_enums": [
+ "GsrComplianceRequirementType"
+ ],
+ "data_enum": "GsrComplianceRequirementType"
+ },
+ {
+ "name": "SUPPORTED_PROPERTY_IDS",
+ "value": 289476424
+ },
+ {
+ "name": "SHUTDOWN_REQUEST",
+ "value": 289410889,
+ "data_enums": [
+ "VehicleApPowerStateShutdownParam"
+ ],
+ "data_enum": "VehicleApPowerStateShutdownParam"
+ },
+ {
+ "name": "VEHICLE_IN_USE",
+ "value": 287313738
+ },
+ {
+ "name": "CLUSTER_HEARTBEAT",
+ "value": 299896651
+ },
+ {
+ "name": "VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL",
+ "value": 289410892,
+ "data_enums": [
+ "VehicleAutonomousState"
+ ],
+ "data_enum": "VehicleAutonomousState"
+ },
+ {
+ "name": "CAMERA_SERVICE_CURRENT_STATE",
+ "value": 289476429,
+ "data_enums": [
+ "CameraServiceState"
+ ],
+ "data_enum": "CameraServiceState"
+ },
+ {
+ "name": "AUTOMATIC_EMERGENCY_BRAKING_ENABLED",
+ "value": 287313920
+ },
+ {
+ "name": "AUTOMATIC_EMERGENCY_BRAKING_STATE",
+ "value": 289411073,
+ "data_enums": [
+ "AutomaticEmergencyBrakingState",
+ "ErrorState"
+ ],
+ "data_enum": "AutomaticEmergencyBrakingState"
+ },
+ {
+ "name": "FORWARD_COLLISION_WARNING_ENABLED",
+ "value": 287313922
+ },
+ {
+ "name": "FORWARD_COLLISION_WARNING_STATE",
+ "value": 289411075,
+ "data_enums": [
+ "ForwardCollisionWarningState",
+ "ErrorState"
+ ],
+ "data_enum": "ForwardCollisionWarningState"
+ },
+ {
+ "name": "BLIND_SPOT_WARNING_ENABLED",
+ "value": 287313924
+ },
+ {
+ "name": "BLIND_SPOT_WARNING_STATE",
+ "value": 339742725,
+ "data_enums": [
+ "BlindSpotWarningState",
+ "ErrorState"
+ ],
+ "data_enum": "BlindSpotWarningState"
+ },
+ {
+ "name": "LANE_DEPARTURE_WARNING_ENABLED",
+ "value": 287313926
+ },
+ {
+ "name": "LANE_DEPARTURE_WARNING_STATE",
+ "value": 289411079,
+ "data_enums": [
+ "LaneDepartureWarningState",
+ "ErrorState"
+ ],
+ "data_enum": "LaneDepartureWarningState"
+ },
+ {
+ "name": "LANE_KEEP_ASSIST_ENABLED",
+ "value": 287313928
+ },
+ {
+ "name": "Lane Keep Assist (LKA) state.",
+ "value": 289411081,
+ "data_enums": [
+ "LaneKeepAssistState",
+ "ErrorState"
+ ],
+ "data_enum": "LaneKeepAssistState"
+ },
+ {
+ "name": "LANE_CENTERING_ASSIST_ENABLED",
+ "value": 287313930
+ },
+ {
+ "name": "LANE_CENTERING_ASSIST_COMMAND",
+ "value": 289411083,
+ "data_enums": [
+ "LaneCenteringAssistCommand"
+ ],
+ "data_enum": "LaneCenteringAssistCommand"
+ },
+ {
+ "name": "LANE_CENTERING_ASSIST_STATE",
+ "value": 289411084,
+ "data_enums": [
+ "LaneCenteringAssistState",
+ "ErrorState"
+ ],
+ "data_enum": "LaneCenteringAssistState"
+ },
+ {
+ "name": "EMERGENCY_LANE_KEEP_ASSIST_ENABLED",
+ "value": 287313933
+ },
+ {
+ "name": "EMERGENCY_LANE_KEEP_ASSIST_STATE",
+ "value": 289411086,
+ "data_enums": [
+ "EmergencyLaneKeepAssistState",
+ "ErrorState"
+ ],
+ "data_enum": "EmergencyLaneKeepAssistState"
+ },
+ {
+ "name": "CRUISE_CONTROL_ENABLED",
+ "value": 287313935
+ },
+ {
+ "name": "CRUISE_CONTROL_TYPE",
+ "value": 289411088,
+ "data_enums": [
+ "CruiseControlType",
+ "ErrorState"
+ ],
+ "data_enum": "CruiseControlType"
+ },
+ {
+ "name": "CRUISE_CONTROL_STATE",
+ "value": 289411089,
+ "data_enums": [
+ "CruiseControlState",
+ "ErrorState"
+ ],
+ "data_enum": "CruiseControlState"
+ },
+ {
+ "name": "CRUISE_CONTROL_COMMAND",
+ "value": 289411090,
+ "data_enums": [
+ "CruiseControlCommand"
+ ],
+ "data_enum": "CruiseControlCommand"
+ },
+ {
+ "name": "CRUISE_CONTROL_TARGET_SPEED",
+ "value": 291508243
+ },
+ {
+ "name": "ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP",
+ "value": 289411092
+ },
+ {
+ "name": "ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE",
+ "value": 289411093
+ },
+ {
+ "name": "HANDS_ON_DETECTION_ENABLED",
+ "value": 287313942
+ },
+ {
+ "name": "HANDS_ON_DETECTION_DRIVER_STATE",
+ "value": 289411095,
+ "data_enums": [
+ "HandsOnDetectionDriverState",
+ "ErrorState"
+ ],
+ "data_enum": "HandsOnDetectionDriverState"
+ },
+ {
+ "name": "HANDS_ON_DETECTION_WARNING",
+ "value": 289411096,
+ "data_enums": [
+ "HandsOnDetectionWarning",
+ "ErrorState"
+ ],
+ "data_enum": "HandsOnDetectionWarning"
+ },
+ {
+ "name": "DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED",
+ "value": 287313945
+ },
+ {
+ "name": "DRIVER_DROWSINESS_ATTENTION_STATE",
+ "value": 289411098,
+ "data_enums": [
+ "DriverDrowsinessAttentionState",
+ "ErrorState"
+ ],
+ "data_enum": "DriverDrowsinessAttentionState"
+ },
+ {
+ "name": "DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED",
+ "value": 287313947
+ },
+ {
+ "name": "DRIVER_DROWSINESS_ATTENTION_WARNING",
+ "value": 289411100,
+ "data_enums": [
+ "DriverDrowsinessAttentionWarning",
+ "ErrorState"
+ ],
+ "data_enum": "DriverDrowsinessAttentionWarning"
+ },
+ {
+ "name": "DRIVER_DISTRACTION_SYSTEM_ENABLED",
+ "value": 287313949
+ },
+ {
+ "name": "Driver distraction state.",
+ "value": 289411102,
+ "data_enums": [
+ "DriverDistractionState",
+ "ErrorState"
+ ],
+ "data_enum": "DriverDistractionState"
+ },
+ {
+ "name": "DRIVER_DISTRACTION_WARNING_ENABLED",
+ "value": 287313951
+ },
+ {
+ "name": "Driver distraction warning.",
+ "value": 289411104,
+ "data_enums": [
+ "DriverDistractionWarning",
+ "ErrorState"
+ ],
+ "data_enum": "DriverDistractionWarning"
+ },
+ {
+ "name": "LOW_SPEED_COLLISION_WARNING_ENABLED",
+ "value": 287313953
+ },
+ {
+ "name": "LOW_SPEED_COLLISION_WARNING_STATE",
+ "value": 289411106,
+ "data_enums": [
+ "LowSpeedCollisionWarningState",
+ "ErrorState"
+ ],
+ "data_enum": "LowSpeedCollisionWarningState"
+ },
+ {
+ "name": "CROSS_TRAFFIC_MONITORING_ENABLED",
+ "value": 287313955
+ },
+ {
+ "name": "CROSS_TRAFFIC_MONITORING_WARNING_STATE",
+ "value": 289411108,
+ "data_enums": [
+ "CrossTrafficMonitoringWarningState",
+ "ErrorState"
+ ],
+ "data_enum": "CrossTrafficMonitoringWarningState"
+ },
+ {
+ "name": "LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED",
+ "value": 287313957
+ },
+ {
+ "name": "LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE",
+ "value": 289411110,
+ "data_enums": [
+ "LowSpeedAutomaticEmergencyBrakingState",
+ "ErrorState"
+ ],
+ "data_enum": "LowSpeedAutomaticEmergencyBrakingState"
+ }
+ ]
+ },
+ {
+ "name": "LaneDepartureWarningState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 0
+ },
+ {
+ "name": "NO_WARNING",
+ "value": 1
+ },
+ {
+ "name": "WARNING_LEFT",
+ "value": 2
+ },
+ {
+ "name": "WARNING_RIGHT",
+ "value": 3
+ }
+ ]
+ },
+ {
+ "name": "HandsOnDetectionWarning",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 0
+ },
+ {
+ "name": "NO_WARNING",
+ "value": 1
+ },
+ {
+ "name": "WARNING",
+ "value": 2
+ }
+ ]
+ },
+ {
+ "name": "DriverDistractionState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 0
+ },
+ {
+ "name": "NOT_DISTRACTED",
+ "value": 1
+ },
+ {
+ "name": "DISTRACTED",
+ "value": 2
+ }
+ ]
+ },
+ {
+ "name": "VehicleTurnSignal",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "NONE",
+ "value": 0
+ },
+ {
+ "name": "RIGHT",
+ "value": 1
+ },
+ {
+ "name": "LEFT",
+ "value": 2
+ }
+ ]
+ },
+ {
+ "name": "RotaryInputType",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION",
+ "value": 0
+ },
+ {
+ "name": "ROTARY_INPUT_TYPE_AUDIO_VOLUME",
+ "value": 1
+ }
+ ]
+ },
+ {
+ "name": "EvStoppingMode",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 0
+ },
+ {
+ "name": "CREEP",
+ "value": 1
+ },
+ {
+ "name": "ROLL",
+ "value": 2
+ },
+ {
+ "name": "HOLD",
+ "value": 3
+ }
+ ]
+ },
+ {
+ "name": "VehicleLightState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OFF",
+ "value": 0
+ },
+ {
+ "name": "ON",
+ "value": 1
+ },
+ {
+ "name": "DAYTIME_RUNNING",
+ "value": 2
+ }
+ ]
+ },
+ {
+ "name": "FuelType",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "FUEL_TYPE_UNKNOWN",
+ "value": 0
+ },
+ {
+ "name": "FUEL_TYPE_UNLEADED",
+ "value": 1
+ },
+ {
+ "name": "FUEL_TYPE_LEADED",
+ "value": 2
+ },
+ {
+ "name": "FUEL_TYPE_DIESEL_1",
+ "value": 3
+ },
+ {
+ "name": "FUEL_TYPE_DIESEL_2",
+ "value": 4
+ },
+ {
+ "name": "FUEL_TYPE_BIODIESEL",
+ "value": 5
+ },
+ {
+ "name": "FUEL_TYPE_E85",
+ "value": 6
+ },
+ {
+ "name": "FUEL_TYPE_LPG",
+ "value": 7
+ },
+ {
+ "name": "FUEL_TYPE_CNG",
+ "value": 8
+ },
+ {
+ "name": "FUEL_TYPE_LNG",
+ "value": 9
+ },
+ {
+ "name": "FUEL_TYPE_ELECTRIC",
+ "value": 10
+ },
+ {
+ "name": "FUEL_TYPE_HYDROGEN",
+ "value": 11
+ },
+ {
+ "name": "FUEL_TYPE_OTHER",
+ "value": 12
+ }
+ ]
+ },
+ {
+ "name": "VehicleIgnitionState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "UNDEFINED",
+ "value": 0
+ },
+ {
+ "name": "LOCK",
+ "value": 1
+ },
+ {
+ "name": "OFF",
+ "value": 2
+ },
+ {
+ "name": "ACC",
+ "value": 3
+ },
+ {
+ "name": "ON",
+ "value": 4
+ },
+ {
+ "name": "START",
+ "value": 5
+ }
+ ]
+ },
+ {
+ "name": "EvConnectorType",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "UNKNOWN",
+ "value": 0
+ },
+ {
+ "name": "IEC_TYPE_1_AC",
+ "value": 1
+ },
+ {
+ "name": "IEC_TYPE_2_AC",
+ "value": 2
+ },
+ {
+ "name": "IEC_TYPE_3_AC",
+ "value": 3
+ },
+ {
+ "name": "IEC_TYPE_4_DC",
+ "value": 4
+ },
+ {
+ "name": "IEC_TYPE_1_CCS_DC",
+ "value": 5
+ },
+ {
+ "name": "IEC_TYPE_2_CCS_DC",
+ "value": 6
+ },
+ {
+ "name": "TESLA_ROADSTER",
+ "value": 7
+ },
+ {
+ "name": "TESLA_HPWC",
+ "value": 8
+ },
+ {
+ "name": "TESLA_SUPERCHARGER",
+ "value": 9
+ },
+ {
+ "name": "GBT_AC",
+ "value": 10
+ },
+ {
+ "name": "GBT_DC",
+ "value": 11
+ },
+ {
+ "name": "OTHER",
+ "value": 101
+ }
+ ]
+ },
+ {
+ "name": "TrailerState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "UNKNOWN",
+ "value": 0
+ },
+ {
+ "name": "NOT_PRESENT",
+ "value": 1
+ },
+ {
+ "name": "PRESENT",
+ "value": 2
+ },
+ {
+ "name": "ERROR",
+ "value": 3
+ }
+ ]
+ },
+ {
+ "name": "DriverDrowsinessAttentionState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 0
+ },
+ {
+ "name": "KSS_RATING_1_EXTREMELY_ALERT",
+ "value": 1
+ },
+ {
+ "name": "KSS_RATING_2_VERY_ALERT",
+ "value": 2
+ },
+ {
+ "name": "KSS_RATING_3_ALERT",
+ "value": 3
+ },
+ {
+ "name": "KSS_RATING_4_RATHER_ALERT",
+ "value": 4
+ },
+ {
+ "name": "KSS_RATING_5_NEITHER_ALERT_NOR_SLEEPY",
+ "value": 5
+ },
+ {
+ "name": "KSS_RATING_6_SOME_SLEEPINESS",
+ "value": 6
+ },
+ {
+ "name": "KSS_RATING_7_SLEEPY_NO_EFFORT",
+ "value": 7
+ },
+ {
+ "name": "KSS_RATING_8_SLEEPY_SOME_EFFORT",
+ "value": 8
+ },
+ {
+ "name": "KSS_RATING_9_VERY_SLEEPY",
+ "value": 9
+ }
+ ]
+ },
+ {
+ "name": "DriverDistractionWarning",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 0
+ },
+ {
+ "name": "NO_WARNING",
+ "value": 1
+ },
+ {
+ "name": "WARNING",
+ "value": 2
+ }
+ ]
+ },
+ {
+ "name": "VehicleAreaSeat",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "UNKNOWN",
+ "value": 0
+ },
+ {
+ "name": "ROW_1_LEFT",
+ "value": 1
+ },
+ {
+ "name": "ROW_1_CENTER",
+ "value": 2
+ },
+ {
+ "name": "ROW_1_RIGHT",
+ "value": 4
+ },
+ {
+ "name": "ROW_2_LEFT",
+ "value": 16
+ },
+ {
+ "name": "ROW_2_CENTER",
+ "value": 32
+ },
+ {
+ "name": "ROW_2_RIGHT",
+ "value": 64
+ },
+ {
+ "name": "ROW_3_LEFT",
+ "value": 256
+ },
+ {
+ "name": "ROW_3_CENTER",
+ "value": 512
+ },
+ {
+ "name": "ROW_3_RIGHT",
+ "value": 1024
+ }
+ ]
+ },
+ {
+ "name": "VehicleLightSwitch",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OFF",
+ "value": 0
+ },
+ {
+ "name": "ON",
+ "value": 1
+ },
+ {
+ "name": "DAYTIME_RUNNING",
+ "value": 2
+ },
+ {
+ "name": "AUTOMATIC",
+ "value": 256
+ }
+ ]
+ },
+ {
+ "name": "WindshieldWipersSwitch",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 0
+ },
+ {
+ "name": "OFF",
+ "value": 1
+ },
+ {
+ "name": "MIST",
+ "value": 2
+ },
+ {
+ "name": "INTERMITTENT_LEVEL_1",
+ "value": 3
+ },
+ {
+ "name": "INTERMITTENT_LEVEL_2",
+ "value": 4
+ },
+ {
+ "name": "INTERMITTENT_LEVEL_3",
+ "value": 5
+ },
+ {
+ "name": "INTERMITTENT_LEVEL_4",
+ "value": 6
+ },
+ {
+ "name": "INTERMITTENT_LEVEL_5",
+ "value": 7
+ },
+ {
+ "name": "CONTINUOUS_LEVEL_1",
+ "value": 8
+ },
+ {
+ "name": "CONTINUOUS_LEVEL_2",
+ "value": 9
+ },
+ {
+ "name": "CONTINUOUS_LEVEL_3",
+ "value": 10
+ },
+ {
+ "name": "CONTINUOUS_LEVEL_4",
+ "value": 11
+ },
+ {
+ "name": "CONTINUOUS_LEVEL_5",
+ "value": 12
+ },
+ {
+ "name": "AUTO",
+ "value": 13
+ },
+ {
+ "name": "SERVICE",
+ "value": 14
+ }
+ ]
+ },
+ {
+ "name": "CrossTrafficMonitoringWarningState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 0
+ },
+ {
+ "name": "NO_WARNING",
+ "value": 1
+ },
+ {
+ "name": "WARNING_FRONT_LEFT",
+ "value": 2
+ },
+ {
+ "name": "WARNING_FRONT_RIGHT",
+ "value": 3
+ },
+ {
+ "name": "WARNING_FRONT_BOTH",
+ "value": 4
+ },
+ {
+ "name": "WARNING_REAR_LEFT",
+ "value": 5
+ },
+ {
+ "name": "WARNING_REAR_RIGHT",
+ "value": 6
+ },
+ {
+ "name": "WARNING_REAR_BOTH",
+ "value": 7
+ }
+ ]
+ },
+ {
+ "name": "LaneCenteringAssistCommand",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "ACTIVATE",
+ "value": 1
+ },
+ {
+ "name": "DEACTIVATE",
+ "value": 2
+ }
+ ]
+ },
+ {
+ "name": "VehicleSeatOccupancyState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "UNKNOWN",
+ "value": 0
+ },
+ {
+ "name": "VACANT",
+ "value": 1
+ },
+ {
+ "name": "OCCUPIED",
+ "value": 2
+ }
+ ]
+ },
+ {
+ "name": "ErrorState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER_ERROR_STATE",
+ "value": -1
+ },
+ {
+ "name": "NOT_AVAILABLE_DISABLED",
+ "value": -2
+ },
+ {
+ "name": "NOT_AVAILABLE_SPEED_LOW",
+ "value": -3
+ },
+ {
+ "name": "NOT_AVAILABLE_SPEED_HIGH",
+ "value": -4
+ },
+ {
+ "name": "NOT_AVAILABLE_POOR_VISIBILITY",
+ "value": -5
+ },
+ {
+ "name": "NOT_AVAILABLE_SAFETY",
+ "value": -6
+ }
+ ]
+ },
+ {
+ "name": "BlindSpotWarningState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 0
+ },
+ {
+ "name": "NO_WARNING",
+ "value": 1
+ },
+ {
+ "name": "WARNING",
+ "value": 2
+ }
+ ]
+ },
+ {
+ "name": "WindshieldWipersState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 0
+ },
+ {
+ "name": "OFF",
+ "value": 1
+ },
+ {
+ "name": "ON",
+ "value": 2
+ },
+ {
+ "name": "SERVICE",
+ "value": 3
+ }
+ ]
+ },
+ {
+ "name": "VehicleAirbagLocation",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 1
+ },
+ {
+ "name": "FRONT",
+ "value": 2
+ },
+ {
+ "name": "KNEE",
+ "value": 4
+ },
+ {
+ "name": "LEFT_SIDE",
+ "value": 8
+ },
+ {
+ "name": "RIGHT_SIDE",
+ "value": 16
+ },
+ {
+ "name": "CURTAIN",
+ "value": 32
+ }
+ ]
+ },
+ {
+ "name": "DriverDrowsinessAttentionWarning",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 0
+ },
+ {
+ "name": "NO_WARNING",
+ "value": 1
+ },
+ {
+ "name": "WARNING",
+ "value": 2
+ }
+ ]
+ },
+ {
+ "name": "VehicleOilLevel",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "CRITICALLY_LOW",
+ "value": 0
+ },
+ {
+ "name": "LOW",
+ "value": 1
+ },
+ {
+ "name": "NORMAL",
+ "value": 2
+ },
+ {
+ "name": "HIGH",
+ "value": 3
+ },
+ {
+ "name": "ERROR",
+ "value": 4
+ }
+ ]
+ },
+ {
+ "name": "ForwardCollisionWarningState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 0
+ },
+ {
+ "name": "NO_WARNING",
+ "value": 1
+ },
+ {
+ "name": "WARNING",
+ "value": 2
+ }
+ ]
+ },
+ {
+ "name": "VehicleUnit",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "SHOULD_NOT_USE",
+ "value": 0
+ },
+ {
+ "name": "METER_PER_SEC",
+ "value": 1
+ },
+ {
+ "name": "RPM",
+ "value": 2
+ },
+ {
+ "name": "HERTZ",
+ "value": 3
+ },
+ {
+ "name": "PERCENTILE",
+ "value": 16
+ },
+ {
+ "name": "MILLIMETER",
+ "value": 32
+ },
+ {
+ "name": "METER",
+ "value": 33
+ },
+ {
+ "name": "KILOMETER",
+ "value": 35
+ },
+ {
+ "name": "MILE",
+ "value": 36
+ },
+ {
+ "name": "CELSIUS",
+ "value": 48
+ },
+ {
+ "name": "FAHRENHEIT",
+ "value": 49
+ },
+ {
+ "name": "KELVIN",
+ "value": 50
+ },
+ {
+ "name": "MILLILITER",
+ "value": 64
+ },
+ {
+ "name": "LITER",
+ "value": 65
+ },
+ {
+ "name": "GALLON",
+ "value": 66
+ },
+ {
+ "name": "US_GALLON",
+ "value": 66
+ },
+ {
+ "name": "IMPERIAL_GALLON",
+ "value": 67
+ },
+ {
+ "name": "NANO_SECS",
+ "value": 80
+ },
+ {
+ "name": "MILLI_SECS",
+ "value": 81
+ },
+ {
+ "name": "SECS",
+ "value": 83
+ },
+ {
+ "name": "YEAR",
+ "value": 89
+ },
+ {
+ "name": "WATT_HOUR",
+ "value": 96
+ },
+ {
+ "name": "MILLIAMPERE",
+ "value": 97
+ },
+ {
+ "name": "MILLIVOLT",
+ "value": 98
+ },
+ {
+ "name": "MILLIWATTS",
+ "value": 99
+ },
+ {
+ "name": "AMPERE_HOURS",
+ "value": 100
+ },
+ {
+ "name": "KILOWATT_HOUR",
+ "value": 101
+ },
+ {
+ "name": "AMPERE",
+ "value": 102
+ },
+ {
+ "name": "KILOPASCAL",
+ "value": 112
+ },
+ {
+ "name": "PSI",
+ "value": 113
+ },
+ {
+ "name": "BAR",
+ "value": 114
+ },
+ {
+ "name": "DEGREES",
+ "value": 128
+ },
+ {
+ "name": "MILES_PER_HOUR",
+ "value": 144
+ },
+ {
+ "name": "KILOMETERS_PER_HOUR",
+ "value": 145
+ }
+ ]
+ },
+ {
+ "name": "VehicleHvacFanDirection",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "UNKNOWN",
+ "value": 0
+ },
+ {
+ "name": "FACE",
+ "value": 1
+ },
+ {
+ "name": "FLOOR",
+ "value": 2
+ },
+ {
+ "name": "FACE_AND_FLOOR",
+ "value": 3
+ },
+ {
+ "name": "DEFROST",
+ "value": 4
+ },
+ {
+ "name": "DEFROST_AND_FLOOR",
+ "value": 6
+ }
+ ]
+ },
+ {
+ "name": "LowSpeedCollisionWarningState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 0
+ },
+ {
+ "name": "NO_WARNING",
+ "value": 1
+ },
+ {
+ "name": "WARNING",
+ "value": 2
+ }
+ ]
+ },
+ {
+ "name": "CruiseControlCommand",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "ACTIVATE",
+ "value": 1
+ },
+ {
+ "name": "SUSPEND",
+ "value": 2
+ },
+ {
+ "name": "INCREASE_TARGET_SPEED",
+ "value": 3
+ },
+ {
+ "name": "DECREASE_TARGET_SPEED",
+ "value": 4
+ },
+ {
+ "name": "INCREASE_TARGET_TIME_GAP",
+ "value": 5
+ },
+ {
+ "name": "DECREASE_TARGET_TIME_GAP",
+ "value": 6
+ }
+ ]
+ },
+ {
+ "name": "ElectronicStabilityControlState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 0
+ },
+ {
+ "name": "ENABLED",
+ "value": 1
+ },
+ {
+ "name": "ACTIVATED",
+ "value": 2
+ }
+ ]
+ },
+ {
+ "name": "EvRegenerativeBrakingState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "UNKNOWN",
+ "value": 0
+ },
+ {
+ "name": "DISABLED",
+ "value": 1
+ },
+ {
+ "name": "PARTIALLY_ENABLED",
+ "value": 2
+ },
+ {
+ "name": "FULLY_ENABLED",
+ "value": 3
+ }
+ ]
+ },
+ {
+ "name": "LowSpeedAutomaticEmergencyBrakingState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 0
+ },
+ {
+ "name": "ENABLED",
+ "value": 1
+ },
+ {
+ "name": "ACTIVATED",
+ "value": 2
+ },
+ {
+ "name": "USER_OVERRIDE",
+ "value": 3
+ }
+ ]
+ },
+ {
+ "name": "LaneCenteringAssistState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 0
+ },
+ {
+ "name": "ENABLED",
+ "value": 1
+ },
+ {
+ "name": "ACTIVATION_REQUESTED",
+ "value": 2
+ },
+ {
+ "name": "ACTIVATED",
+ "value": 3
+ },
+ {
+ "name": "USER_OVERRIDE",
+ "value": 4
+ },
+ {
+ "name": "FORCED_DEACTIVATION_WARNING",
+ "value": 5
+ }
+ ]
+ },
+ {
+ "name": "VehicleGear",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "GEAR_UNKNOWN",
+ "value": 0
+ },
+ {
+ "name": "GEAR_NEUTRAL",
+ "value": 1
+ },
+ {
+ "name": "GEAR_REVERSE",
+ "value": 2
+ },
+ {
+ "name": "GEAR_PARK",
+ "value": 4
+ },
+ {
+ "name": "GEAR_DRIVE",
+ "value": 8
+ },
+ {
+ "name": "GEAR_1",
+ "value": 16
+ },
+ {
+ "name": "GEAR_2",
+ "value": 32
+ },
+ {
+ "name": "GEAR_3",
+ "value": 64
+ },
+ {
+ "name": "GEAR_4",
+ "value": 128
+ },
+ {
+ "name": "GEAR_5",
+ "value": 256
+ },
+ {
+ "name": "GEAR_6",
+ "value": 512
+ },
+ {
+ "name": "GEAR_7",
+ "value": 1024
+ },
+ {
+ "name": "GEAR_8",
+ "value": 2048
+ },
+ {
+ "name": "GEAR_9",
+ "value": 4096
+ }
+ ]
+ },
+ {
+ "name": "ElectronicTollCollectionCardType",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "UNKNOWN",
+ "value": 0
+ },
+ {
+ "name": "JP_ELECTRONIC_TOLL_COLLECTION_CARD",
+ "value": 1
+ },
+ {
+ "name": "JP_ELECTRONIC_TOLL_COLLECTION_CARD_V2",
+ "value": 2
+ }
+ ]
+ },
+ {
+ "name": "VehicleApPowerStateShutdownParam",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "SHUTDOWN_IMMEDIATELY",
+ "value": 1
+ },
+ {
+ "name": "CAN_SLEEP",
+ "value": 2
+ },
+ {
+ "name": "SHUTDOWN_ONLY",
+ "value": 3
+ },
+ {
+ "name": "SLEEP_IMMEDIATELY",
+ "value": 4
+ },
+ {
+ "name": "HIBERNATE_IMMEDIATELY",
+ "value": 5
+ },
+ {
+ "name": "CAN_HIBERNATE",
+ "value": 6
+ },
+ {
+ "name": "EMERGENCY_SHUTDOWN",
+ "value": 7
+ }
+ ]
+ },
+ {
+ "name": "AutomaticEmergencyBrakingState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 0
+ },
+ {
+ "name": "ENABLED",
+ "value": 1
+ },
+ {
+ "name": "ACTIVATED",
+ "value": 2
+ },
+ {
+ "name": "USER_OVERRIDE",
+ "value": 3
+ }
+ ]
+ },
+ {
+ "name": "ImpactSensorLocation",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 1
+ },
+ {
+ "name": "FRONT",
+ "value": 2
+ },
+ {
+ "name": "FRONT_LEFT_DOOR_SIDE",
+ "value": 4
+ },
+ {
+ "name": "FRONT_RIGHT_DOOR_SIDE",
+ "value": 8
+ },
+ {
+ "name": "REAR_LEFT_DOOR_SIDE",
+ "value": 16
+ },
+ {
+ "name": "REAR_RIGHT_DOOR_SIDE",
+ "value": 32
+ },
+ {
+ "name": "REAR",
+ "value": 64
+ }
+ ]
+ },
+ {
+ "name": "CruiseControlType",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 0
+ },
+ {
+ "name": "STANDARD",
+ "value": 1
+ },
+ {
+ "name": "ADAPTIVE",
+ "value": 2
+ },
+ {
+ "name": "PREDICTIVE",
+ "value": 3
+ }
+ ]
+ },
+ {
+ "name": "LaneKeepAssistState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 0
+ },
+ {
+ "name": "ENABLED",
+ "value": 1
+ },
+ {
+ "name": "ACTIVATED_STEER_LEFT",
+ "value": 2
+ },
+ {
+ "name": "ACTIVATED_STEER_RIGHT",
+ "value": 3
+ },
+ {
+ "name": "USER_OVERRIDE",
+ "value": 4
+ }
+ ]
+ },
+ {
+ "name": "CustomInputType",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "CUSTOM_EVENT_F1",
+ "value": 1001
+ },
+ {
+ "name": "CUSTOM_EVENT_F2",
+ "value": 1002
+ },
+ {
+ "name": "CUSTOM_EVENT_F3",
+ "value": 1003
+ },
+ {
+ "name": "CUSTOM_EVENT_F4",
+ "value": 1004
+ },
+ {
+ "name": "CUSTOM_EVENT_F5",
+ "value": 1005
+ },
+ {
+ "name": "CUSTOM_EVENT_F6",
+ "value": 1006
+ },
+ {
+ "name": "CUSTOM_EVENT_F7",
+ "value": 1007
+ },
+ {
+ "name": "CUSTOM_EVENT_F8",
+ "value": 1008
+ },
+ {
+ "name": "CUSTOM_EVENT_F9",
+ "value": 1009
+ },
+ {
+ "name": "CUSTOM_EVENT_F10",
+ "value": 1010
+ }
+ ]
+ },
+ {
+ "name": "ElectronicTollCollectionCardStatus",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "UNKNOWN",
+ "value": 0
+ },
+ {
+ "name": "ELECTRONIC_TOLL_COLLECTION_CARD_VALID",
+ "value": 1
+ },
+ {
+ "name": "ELECTRONIC_TOLL_COLLECTION_CARD_INVALID",
+ "value": 2
+ },
+ {
+ "name": "ELECTRONIC_TOLL_COLLECTION_CARD_NOT_INSERTED",
+ "value": 3
+ }
+ ]
+ },
+ {
+ "name": "HandsOnDetectionDriverState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 0
+ },
+ {
+ "name": "HANDS_ON",
+ "value": 1
+ },
+ {
+ "name": "HANDS_OFF",
+ "value": 2
+ }
+ ]
+ },
+ {
+ "name": "EmergencyLaneKeepAssistState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 0
+ },
+ {
+ "name": "ENABLED",
+ "value": 1
+ },
+ {
+ "name": "WARNING_LEFT",
+ "value": 2
+ },
+ {
+ "name": "WARNING_RIGHT",
+ "value": 3
+ },
+ {
+ "name": "ACTIVATED_STEER_LEFT",
+ "value": 4
+ },
+ {
+ "name": "ACTIVATED_STEER_RIGHT",
+ "value": 5
+ },
+ {
+ "name": "USER_OVERRIDE",
+ "value": 6
+ }
+ ]
+ },
+ {
+ "name": "VehicleAutonomousState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "LEVEL_0",
+ "value": 0
+ },
+ {
+ "name": "LEVEL_1",
+ "value": 1
+ },
+ {
+ "name": "LEVEL_2",
+ "value": 2
+ },
+ {
+ "name": "LEVEL_3",
+ "value": 3
+ },
+ {
+ "name": "LEVEL_4",
+ "value": 4
+ },
+ {
+ "name": "LEVEL_5",
+ "value": 5
+ }
+ ]
+ },
+ {
+ "name": "EvChargeState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "UNKNOWN",
+ "value": 0
+ },
+ {
+ "name": "CHARGING",
+ "value": 1
+ },
+ {
+ "name": "FULLY_CHARGED",
+ "value": 2
+ },
+ {
+ "name": "NOT_CHARGING",
+ "value": 3
+ },
+ {
+ "name": "ERROR",
+ "value": 4
+ }
+ ]
+ },
+ {
+ "name": "CameraServiceState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "UNAVAILABLE",
+ "value": 0
+ },
+ {
+ "name": "INACTIVE",
+ "value": 1
+ },
+ {
+ "name": "REQUESTED",
+ "value": 2
+ },
+ {
+ "name": "ACTIVE",
+ "value": 3
+ }
+ ]
+ },
+ {
+ "name": "GsrComplianceRequirementType",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "GSR_COMPLIANCE_NOT_REQUIRED",
+ "value": 0
+ },
+ {
+ "name": "GSR_COMPLIANCE_REQUIRED_V1",
+ "value": 1
+ }
+ ]
+ },
+ {
+ "name": "PortLocationType",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "UNKNOWN",
+ "value": 0
+ },
+ {
+ "name": "FRONT_LEFT",
+ "value": 1
+ },
+ {
+ "name": "FRONT_RIGHT",
+ "value": 2
+ },
+ {
+ "name": "REAR_RIGHT",
+ "value": 3
+ },
+ {
+ "name": "REAR_LEFT",
+ "value": 4
+ },
+ {
+ "name": "FRONT",
+ "value": 5
+ },
+ {
+ "name": "REAR",
+ "value": 6
+ }
+ ]
+ },
+ {
+ "name": "CruiseControlState",
+ "package": "android.hardware.automotive.vehicle",
+ "values": [
+ {
+ "name": "OTHER",
+ "value": 0
+ },
+ {
+ "name": "ENABLED",
+ "value": 1
+ },
+ {
+ "name": "ACTIVATED",
+ "value": 2
+ },
+ {
+ "name": "USER_OVERRIDE",
+ "value": 3
+ },
+ {
+ "name": "SUSPENDED",
+ "value": 4
+ },
+ {
+ "name": "FORCED_DEACTIVATION_WARNING",
+ "value": 5
+ }
+ ]
+ }
]
\ No newline at end of file
diff --git a/automotive/vehicle/aidl/emu_metadata/generate_emulator_metadata.py b/automotive/vehicle/aidl/emu_metadata/generate_emulator_metadata.py
deleted file mode 100755
index b2eb172..0000000
--- a/automotive/vehicle/aidl/emu_metadata/generate_emulator_metadata.py
+++ /dev/null
@@ -1,97 +0,0 @@
-#!/usr/bin/python3
-
-#
-# Script for generation of VHAL properties metadata .json from AIDL interface
-#
-# This metadata is used to display human property names, names of enum
-# data types for their values, change and access modes and other information,
-# available from AIDL block comments, but not at runtime.
-#
-# Usage example:
-# ./emu_metadata/generate_emulator_metadata.py android/hardware/automotive/vehicle $OUT/android.hardware.automotive.vehicle-types-meta.json
-# (Note, that the resulting file has to match a '*types-meta.json' pattern to be parsed by the emulator).
-#
-
-import json
-import os
-import re
-import sys
-
-from pathlib import Path
-
-RE_ENUM = re.compile(r"\s*enum\s+(\w*) {\n(.*)}", re.MULTILINE | re.DOTALL)
-RE_COMMENT = re.compile(r"(?:(?:\/\*\*)((?:.|\n)*?)(?:\*\/))?(?:\n|^)\s*(\w*)(?:\s+=\s*)?((?:[a-zA-Z0-9]|\s|\+|)*),", re.DOTALL)
-RE_BLOCK_COMMENT_TITLE = re.compile("^(?:\s|\*)*((?:\w|\s|\.)*)\n(?:\s|\*)*(?:\n|$)")
-RE_BLOCK_COMMENT_ANNOTATION = re.compile("^(?:\s|\*)*@(\w*)\s+((?:\w|:)*)", re.MULTILINE)
-RE_HEX_NUMBER = re.compile("([0-9A-Fa-fxX]+)")
-
-
-class JEnum:
- def __init__(self, name):
- self.name = name
- self.values = []
-
-
-class Converter:
- # Only addition is supported for now, but that covers all existing properties except
- # OBD diagnostics, which use bitwise shifts
- def calculateValue(self, expression, default_value):
- numbers = RE_HEX_NUMBER.findall(expression)
- if len(numbers) == 0:
- return default_value
- result = 0
- base = 10
- if numbers[0].lower().startswith("0x"):
- base = 16
- for number in numbers:
- result += int(number, base)
- return result
-
- def parseBlockComment(self, value, blockComment):
- titles = RE_BLOCK_COMMENT_TITLE.findall(blockComment)
- for title in titles:
- value['name'] = title
- break
- annots_res = RE_BLOCK_COMMENT_ANNOTATION.findall(blockComment)
- for annot in annots_res:
- value[annot[0]] = annot[1]
-
- def parseEnumContents(self, enum: JEnum, enumValue):
- matches = RE_COMMENT.findall(enumValue)
- defaultValue = 0
- for match in matches:
- value = dict()
- value['name'] = match[1]
- value['value'] = self.calculateValue(match[2], defaultValue)
- defaultValue = value['value'] + 1
- if enum.name == "VehicleProperty":
- block_comment = match[0]
- self.parseBlockComment(value, block_comment)
- enum.values.append(value)
-
- def convert(self, input):
- text = Path(input).read_text()
- matches = RE_ENUM.findall(text)
- jenums = []
- for match in matches:
- enum = JEnum(match[0])
- self.parseEnumContents(enum, match[1])
- jenums.append(enum)
- return jenums
-
-def main():
- if (len(sys.argv) != 3):
- print("Usage: ", sys.argv[0], " INPUT_PATH OUTPUT")
- sys.exit(1)
- aidl_path = sys.argv[1]
- out_path = sys.argv[2]
- result = []
- for file in os.listdir(aidl_path):
- result.extend(Converter().convert(os.path.join(aidl_path, file)))
- json_result = json.dumps(result, default=vars, indent=2)
- with open(out_path, 'w') as f:
- f.write(json_result)
-
-
-if __name__ == "__main__":
- main()
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
index c4e2c64..51a3025 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
@@ -22,8 +22,7 @@
// clang-format off
-#ifndef android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
-#define android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
+#pragma once
#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyAccess.h>
@@ -68,9 +67,11 @@
{VehicleProperty::EV_CHARGE_PORT_CONNECTED, VehiclePropertyAccess::READ},
{VehicleProperty::EV_BATTERY_INSTANTANEOUS_CHARGE_RATE, VehiclePropertyAccess::READ},
{VehicleProperty::RANGE_REMAINING, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::EV_BATTERY_AVERAGE_TEMPERATURE, VehiclePropertyAccess::READ},
{VehicleProperty::TIRE_PRESSURE, VehiclePropertyAccess::READ},
{VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE, VehiclePropertyAccess::READ},
{VehicleProperty::ENGINE_IDLE_AUTO_STOP_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::IMPACT_DETECTED, VehiclePropertyAccess::READ},
{VehicleProperty::GEAR_SELECTION, VehiclePropertyAccess::READ},
{VehicleProperty::CURRENT_GEAR, VehiclePropertyAccess::READ},
{VehicleProperty::PARKING_BRAKE_ON, VehiclePropertyAccess::READ},
@@ -83,6 +84,8 @@
{VehicleProperty::ABS_ACTIVE, VehiclePropertyAccess::READ},
{VehicleProperty::TRACTION_CONTROL_ACTIVE, VehiclePropertyAccess::READ},
{VehicleProperty::EV_STOPPING_MODE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_STATE, VehiclePropertyAccess::READ},
{VehicleProperty::HVAC_FAN_SPEED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::HVAC_FAN_DIRECTION, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::HVAC_TEMPERATURE_CURRENT, VehiclePropertyAccess::READ},
@@ -120,6 +123,8 @@
{VehicleProperty::AP_POWER_BOOTUP_REASON, VehiclePropertyAccess::READ},
{VehicleProperty::DISPLAY_BRIGHTNESS, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::PER_DISPLAY_BRIGHTNESS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::VALET_MODE_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HEAD_UP_DISPLAY_ENABLED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::HW_KEY_INPUT, VehiclePropertyAccess::READ},
{VehicleProperty::HW_KEY_INPUT_V2, VehiclePropertyAccess::READ},
{VehicleProperty::HW_MOTION_INPUT, VehiclePropertyAccess::READ},
@@ -169,11 +174,13 @@
{VehicleProperty::SEAT_FOOTWELL_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::SEAT_EASY_ACCESS_ENABLED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::SEAT_AIRBAG_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_AIRBAGS_DEPLOYED, VehiclePropertyAccess::READ},
{VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::SEAT_LUMBAR_VERTICAL_POS, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::SEAT_LUMBAR_VERTICAL_MOVE, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::SEAT_WALK_IN_POS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_BELT_PRETENSIONER_DEPLOYED, VehiclePropertyAccess::READ},
{VehicleProperty::SEAT_OCCUPANCY, VehiclePropertyAccess::READ},
{VehicleProperty::WINDOW_POS, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::WINDOW_MOVE, VehiclePropertyAccess::READ_WRITE},
@@ -192,6 +199,12 @@
{VehicleProperty::GLOVE_BOX_LOCKED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::VEHICLE_MAP_SERVICE, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::LOCATION_CHARACTERIZATION, VehiclePropertyAccess::READ},
+ {VehicleProperty::ULTRASONICS_SENSOR_POSITION, VehiclePropertyAccess::READ},
+ {VehicleProperty::ULTRASONICS_SENSOR_ORIENTATION, VehiclePropertyAccess::READ},
+ {VehicleProperty::ULTRASONICS_SENSOR_FIELD_OF_VIEW, VehiclePropertyAccess::READ},
+ {VehicleProperty::ULTRASONICS_SENSOR_DETECTION_RANGE, VehiclePropertyAccess::READ},
+ {VehicleProperty::ULTRASONICS_SENSOR_SUPPORTED_RANGES, VehiclePropertyAccess::READ},
+ {VehicleProperty::ULTRASONICS_SENSOR_MEASURED_DISTANCE, VehiclePropertyAccess::READ},
{VehicleProperty::OBD2_LIVE_FRAME, VehiclePropertyAccess::READ},
{VehicleProperty::OBD2_FREEZE_FRAME, VehiclePropertyAccess::READ},
{VehicleProperty::OBD2_FREEZE_FRAME_INFO, VehiclePropertyAccess::READ},
@@ -248,6 +261,8 @@
{VehicleProperty::SHUTDOWN_REQUEST, VehiclePropertyAccess::WRITE},
{VehicleProperty::VEHICLE_IN_USE, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::CLUSTER_HEARTBEAT, VehiclePropertyAccess::WRITE},
+ {VehicleProperty::VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, VehiclePropertyAccess::READ},
+ {VehicleProperty::CAMERA_SERVICE_CURRENT_STATE, VehiclePropertyAccess::WRITE},
{VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess::READ},
{VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
@@ -273,6 +288,20 @@
{VehicleProperty::HANDS_ON_DETECTION_ENABLED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE, VehiclePropertyAccess::READ},
{VehicleProperty::HANDS_ON_DETECTION_WARNING, VehiclePropertyAccess::READ},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING, VehiclePropertyAccess::READ},
+ {VehicleProperty::DRIVER_DISTRACTION_SYSTEM_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::DRIVER_DISTRACTION_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::DRIVER_DISTRACTION_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::DRIVER_DISTRACTION_WARNING, VehiclePropertyAccess::READ},
+ {VehicleProperty::LOW_SPEED_COLLISION_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::CROSS_TRAFFIC_MONITORING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess::READ},
};
} // namespace vehicle
@@ -280,5 +309,3 @@
} // namespace hardware
} // namespace android
} // aidl
-
-#endif // android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
index bd6c705..60e9a72 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
@@ -22,8 +22,7 @@
// clang-format off
-#ifndef android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
-#define android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
+#pragma once
#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.h>
@@ -68,9 +67,11 @@
{VehicleProperty::EV_CHARGE_PORT_CONNECTED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::EV_BATTERY_INSTANTANEOUS_CHARGE_RATE, VehiclePropertyChangeMode::CONTINUOUS},
{VehicleProperty::RANGE_REMAINING, VehiclePropertyChangeMode::CONTINUOUS},
+ {VehicleProperty::EV_BATTERY_AVERAGE_TEMPERATURE, VehiclePropertyChangeMode::CONTINUOUS},
{VehicleProperty::TIRE_PRESSURE, VehiclePropertyChangeMode::CONTINUOUS},
{VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE, VehiclePropertyChangeMode::STATIC},
{VehicleProperty::ENGINE_IDLE_AUTO_STOP_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::IMPACT_DETECTED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::GEAR_SELECTION, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::CURRENT_GEAR, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::PARKING_BRAKE_ON, VehiclePropertyChangeMode::ON_CHANGE},
@@ -83,6 +84,8 @@
{VehicleProperty::ABS_ACTIVE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::TRACTION_CONTROL_ACTIVE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::EV_STOPPING_MODE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_STATE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HVAC_FAN_SPEED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HVAC_FAN_DIRECTION, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HVAC_TEMPERATURE_CURRENT, VehiclePropertyChangeMode::ON_CHANGE},
@@ -120,6 +123,8 @@
{VehicleProperty::AP_POWER_BOOTUP_REASON, VehiclePropertyChangeMode::STATIC},
{VehicleProperty::DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::PER_DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::VALET_MODE_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HEAD_UP_DISPLAY_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HW_KEY_INPUT, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HW_KEY_INPUT_V2, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HW_MOTION_INPUT, VehiclePropertyChangeMode::ON_CHANGE},
@@ -169,11 +174,13 @@
{VehicleProperty::SEAT_FOOTWELL_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::SEAT_EASY_ACCESS_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::SEAT_AIRBAG_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_AIRBAGS_DEPLOYED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::SEAT_LUMBAR_VERTICAL_POS, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::SEAT_LUMBAR_VERTICAL_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::SEAT_WALK_IN_POS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_BELT_PRETENSIONER_DEPLOYED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::SEAT_OCCUPANCY, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::WINDOW_POS, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::WINDOW_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
@@ -192,6 +199,12 @@
{VehicleProperty::GLOVE_BOX_LOCKED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::VEHICLE_MAP_SERVICE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::LOCATION_CHARACTERIZATION, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::ULTRASONICS_SENSOR_POSITION, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::ULTRASONICS_SENSOR_ORIENTATION, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::ULTRASONICS_SENSOR_FIELD_OF_VIEW, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::ULTRASONICS_SENSOR_DETECTION_RANGE, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::ULTRASONICS_SENSOR_SUPPORTED_RANGES, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::ULTRASONICS_SENSOR_MEASURED_DISTANCE, VehiclePropertyChangeMode::CONTINUOUS},
{VehicleProperty::OBD2_LIVE_FRAME, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::OBD2_FREEZE_FRAME, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::OBD2_FREEZE_FRAME_INFO, VehiclePropertyChangeMode::ON_CHANGE},
@@ -248,6 +261,8 @@
{VehicleProperty::SHUTDOWN_REQUEST, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::VEHICLE_IN_USE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::CLUSTER_HEARTBEAT, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::CAMERA_SERVICE_CURRENT_STATE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
@@ -273,6 +288,20 @@
{VehicleProperty::HANDS_ON_DETECTION_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HANDS_ON_DETECTION_WARNING, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DRIVER_DISTRACTION_SYSTEM_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DRIVER_DISTRACTION_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DRIVER_DISTRACTION_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DRIVER_DISTRACTION_WARNING, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::LOW_SPEED_COLLISION_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::CROSS_TRAFFIC_MONITORING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
};
} // namespace vehicle
@@ -280,5 +309,3 @@
} // namespace hardware
} // namespace android
} // aidl
-
-#endif // android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/VersionForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/VersionForVehicleProperty.h
new file mode 100644
index 0000000..1c1035d
--- /dev/null
+++ b/automotive/vehicle/aidl/generated_lib/cpp/VersionForVehicleProperty.h
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * DO NOT EDIT MANUALLY!!!
+ *
+ * Generated by tools/generate_annotation_enums.py.
+ */
+
+// clang-format off
+
+#pragma once
+
+#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
+
+#include <unordered_map>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+std::unordered_map<VehicleProperty, int32_t> VersionForVehicleProperty = {
+ {VehicleProperty::INFO_VIN, 2},
+ {VehicleProperty::INFO_MAKE, 2},
+ {VehicleProperty::INFO_MODEL, 2},
+ {VehicleProperty::INFO_MODEL_YEAR, 2},
+ {VehicleProperty::INFO_FUEL_CAPACITY, 2},
+ {VehicleProperty::INFO_FUEL_TYPE, 2},
+ {VehicleProperty::INFO_EV_BATTERY_CAPACITY, 2},
+ {VehicleProperty::INFO_EV_CONNECTOR_TYPE, 2},
+ {VehicleProperty::INFO_FUEL_DOOR_LOCATION, 2},
+ {VehicleProperty::INFO_EV_PORT_LOCATION, 2},
+ {VehicleProperty::INFO_DRIVER_SEAT, 2},
+ {VehicleProperty::INFO_EXTERIOR_DIMENSIONS, 2},
+ {VehicleProperty::INFO_MULTI_EV_PORT_LOCATIONS, 2},
+ {VehicleProperty::PERF_ODOMETER, 2},
+ {VehicleProperty::PERF_VEHICLE_SPEED, 2},
+ {VehicleProperty::PERF_VEHICLE_SPEED_DISPLAY, 2},
+ {VehicleProperty::PERF_STEERING_ANGLE, 2},
+ {VehicleProperty::PERF_REAR_STEERING_ANGLE, 2},
+ {VehicleProperty::ENGINE_COOLANT_TEMP, 2},
+ {VehicleProperty::ENGINE_OIL_LEVEL, 2},
+ {VehicleProperty::ENGINE_OIL_TEMP, 2},
+ {VehicleProperty::ENGINE_RPM, 2},
+ {VehicleProperty::WHEEL_TICK, 2},
+ {VehicleProperty::FUEL_LEVEL, 2},
+ {VehicleProperty::FUEL_DOOR_OPEN, 2},
+ {VehicleProperty::EV_BATTERY_LEVEL, 2},
+ {VehicleProperty::EV_CURRENT_BATTERY_CAPACITY, 2},
+ {VehicleProperty::EV_CHARGE_PORT_OPEN, 2},
+ {VehicleProperty::EV_CHARGE_PORT_CONNECTED, 2},
+ {VehicleProperty::EV_BATTERY_INSTANTANEOUS_CHARGE_RATE, 2},
+ {VehicleProperty::RANGE_REMAINING, 2},
+ {VehicleProperty::EV_BATTERY_AVERAGE_TEMPERATURE, 3},
+ {VehicleProperty::TIRE_PRESSURE, 2},
+ {VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE, 2},
+ {VehicleProperty::ENGINE_IDLE_AUTO_STOP_ENABLED, 2},
+ {VehicleProperty::IMPACT_DETECTED, 3},
+ {VehicleProperty::GEAR_SELECTION, 2},
+ {VehicleProperty::CURRENT_GEAR, 2},
+ {VehicleProperty::PARKING_BRAKE_ON, 2},
+ {VehicleProperty::PARKING_BRAKE_AUTO_APPLY, 2},
+ {VehicleProperty::EV_BRAKE_REGENERATION_LEVEL, 2},
+ {VehicleProperty::FUEL_LEVEL_LOW, 2},
+ {VehicleProperty::NIGHT_MODE, 2},
+ {VehicleProperty::TURN_SIGNAL_STATE, 2},
+ {VehicleProperty::IGNITION_STATE, 2},
+ {VehicleProperty::ABS_ACTIVE, 2},
+ {VehicleProperty::TRACTION_CONTROL_ACTIVE, 2},
+ {VehicleProperty::EV_STOPPING_MODE, 2},
+ {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_ENABLED, 3},
+ {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_STATE, 2},
+ {VehicleProperty::HVAC_FAN_SPEED, 2},
+ {VehicleProperty::HVAC_FAN_DIRECTION, 2},
+ {VehicleProperty::HVAC_TEMPERATURE_CURRENT, 2},
+ {VehicleProperty::HVAC_TEMPERATURE_SET, 2},
+ {VehicleProperty::HVAC_DEFROSTER, 2},
+ {VehicleProperty::HVAC_AC_ON, 2},
+ {VehicleProperty::HVAC_MAX_AC_ON, 2},
+ {VehicleProperty::HVAC_MAX_DEFROST_ON, 2},
+ {VehicleProperty::HVAC_RECIRC_ON, 2},
+ {VehicleProperty::HVAC_DUAL_ON, 2},
+ {VehicleProperty::HVAC_AUTO_ON, 2},
+ {VehicleProperty::HVAC_SEAT_TEMPERATURE, 2},
+ {VehicleProperty::HVAC_SIDE_MIRROR_HEAT, 2},
+ {VehicleProperty::HVAC_STEERING_WHEEL_HEAT, 2},
+ {VehicleProperty::HVAC_TEMPERATURE_DISPLAY_UNITS, 2},
+ {VehicleProperty::HVAC_ACTUAL_FAN_SPEED_RPM, 2},
+ {VehicleProperty::HVAC_POWER_ON, 2},
+ {VehicleProperty::HVAC_FAN_DIRECTION_AVAILABLE, 2},
+ {VehicleProperty::HVAC_AUTO_RECIRC_ON, 2},
+ {VehicleProperty::HVAC_SEAT_VENTILATION, 2},
+ {VehicleProperty::HVAC_ELECTRIC_DEFROSTER_ON, 2},
+ {VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION, 2},
+ {VehicleProperty::DISTANCE_DISPLAY_UNITS, 2},
+ {VehicleProperty::FUEL_VOLUME_DISPLAY_UNITS, 2},
+ {VehicleProperty::TIRE_PRESSURE_DISPLAY_UNITS, 2},
+ {VehicleProperty::EV_BATTERY_DISPLAY_UNITS, 2},
+ {VehicleProperty::FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME, 2},
+ {VehicleProperty::VEHICLE_SPEED_DISPLAY_UNITS, 2},
+ {VehicleProperty::EXTERNAL_CAR_TIME, 2},
+ {VehicleProperty::ANDROID_EPOCH_TIME, 2},
+ {VehicleProperty::STORAGE_ENCRYPTION_BINDING_SEED, 2},
+ {VehicleProperty::ENV_OUTSIDE_TEMPERATURE, 2},
+ {VehicleProperty::AP_POWER_STATE_REQ, 2},
+ {VehicleProperty::AP_POWER_STATE_REPORT, 2},
+ {VehicleProperty::AP_POWER_BOOTUP_REASON, 2},
+ {VehicleProperty::DISPLAY_BRIGHTNESS, 2},
+ {VehicleProperty::PER_DISPLAY_BRIGHTNESS, 2},
+ {VehicleProperty::VALET_MODE_ENABLED, 3},
+ {VehicleProperty::HEAD_UP_DISPLAY_ENABLED, 3},
+ {VehicleProperty::HW_KEY_INPUT, 2},
+ {VehicleProperty::HW_KEY_INPUT_V2, 2},
+ {VehicleProperty::HW_MOTION_INPUT, 2},
+ {VehicleProperty::HW_ROTARY_INPUT, 2},
+ {VehicleProperty::HW_CUSTOM_INPUT, 2},
+ {VehicleProperty::DOOR_POS, 2},
+ {VehicleProperty::DOOR_MOVE, 2},
+ {VehicleProperty::DOOR_LOCK, 2},
+ {VehicleProperty::DOOR_CHILD_LOCK_ENABLED, 2},
+ {VehicleProperty::MIRROR_Z_POS, 2},
+ {VehicleProperty::MIRROR_Z_MOVE, 2},
+ {VehicleProperty::MIRROR_Y_POS, 2},
+ {VehicleProperty::MIRROR_Y_MOVE, 2},
+ {VehicleProperty::MIRROR_LOCK, 2},
+ {VehicleProperty::MIRROR_FOLD, 2},
+ {VehicleProperty::MIRROR_AUTO_FOLD_ENABLED, 2},
+ {VehicleProperty::MIRROR_AUTO_TILT_ENABLED, 2},
+ {VehicleProperty::SEAT_MEMORY_SELECT, 2},
+ {VehicleProperty::SEAT_MEMORY_SET, 2},
+ {VehicleProperty::SEAT_BELT_BUCKLED, 2},
+ {VehicleProperty::SEAT_BELT_HEIGHT_POS, 2},
+ {VehicleProperty::SEAT_BELT_HEIGHT_MOVE, 2},
+ {VehicleProperty::SEAT_FORE_AFT_POS, 2},
+ {VehicleProperty::SEAT_FORE_AFT_MOVE, 2},
+ {VehicleProperty::SEAT_BACKREST_ANGLE_1_POS, 2},
+ {VehicleProperty::SEAT_BACKREST_ANGLE_1_MOVE, 2},
+ {VehicleProperty::SEAT_BACKREST_ANGLE_2_POS, 2},
+ {VehicleProperty::SEAT_BACKREST_ANGLE_2_MOVE, 2},
+ {VehicleProperty::SEAT_HEIGHT_POS, 2},
+ {VehicleProperty::SEAT_HEIGHT_MOVE, 2},
+ {VehicleProperty::SEAT_DEPTH_POS, 2},
+ {VehicleProperty::SEAT_DEPTH_MOVE, 2},
+ {VehicleProperty::SEAT_TILT_POS, 2},
+ {VehicleProperty::SEAT_TILT_MOVE, 2},
+ {VehicleProperty::SEAT_LUMBAR_FORE_AFT_POS, 2},
+ {VehicleProperty::SEAT_LUMBAR_FORE_AFT_MOVE, 2},
+ {VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_POS, 2},
+ {VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_MOVE, 2},
+ {VehicleProperty::SEAT_HEADREST_HEIGHT_POS, 2},
+ {VehicleProperty::SEAT_HEADREST_HEIGHT_POS_V2, 2},
+ {VehicleProperty::SEAT_HEADREST_HEIGHT_MOVE, 2},
+ {VehicleProperty::SEAT_HEADREST_ANGLE_POS, 2},
+ {VehicleProperty::SEAT_HEADREST_ANGLE_MOVE, 2},
+ {VehicleProperty::SEAT_HEADREST_FORE_AFT_POS, 2},
+ {VehicleProperty::SEAT_HEADREST_FORE_AFT_MOVE, 2},
+ {VehicleProperty::SEAT_FOOTWELL_LIGHTS_STATE, 2},
+ {VehicleProperty::SEAT_FOOTWELL_LIGHTS_SWITCH, 2},
+ {VehicleProperty::SEAT_EASY_ACCESS_ENABLED, 2},
+ {VehicleProperty::SEAT_AIRBAG_ENABLED, 3},
+ {VehicleProperty::SEAT_AIRBAGS_DEPLOYED, 2},
+ {VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_POS, 2},
+ {VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE, 2},
+ {VehicleProperty::SEAT_LUMBAR_VERTICAL_POS, 2},
+ {VehicleProperty::SEAT_LUMBAR_VERTICAL_MOVE, 2},
+ {VehicleProperty::SEAT_WALK_IN_POS, 2},
+ {VehicleProperty::SEAT_BELT_PRETENSIONER_DEPLOYED, 3},
+ {VehicleProperty::SEAT_OCCUPANCY, 2},
+ {VehicleProperty::WINDOW_POS, 2},
+ {VehicleProperty::WINDOW_MOVE, 2},
+ {VehicleProperty::WINDOW_LOCK, 2},
+ {VehicleProperty::WINDSHIELD_WIPERS_PERIOD, 2},
+ {VehicleProperty::WINDSHIELD_WIPERS_STATE, 2},
+ {VehicleProperty::WINDSHIELD_WIPERS_SWITCH, 2},
+ {VehicleProperty::STEERING_WHEEL_DEPTH_POS, 2},
+ {VehicleProperty::STEERING_WHEEL_DEPTH_MOVE, 2},
+ {VehicleProperty::STEERING_WHEEL_HEIGHT_POS, 2},
+ {VehicleProperty::STEERING_WHEEL_HEIGHT_MOVE, 2},
+ {VehicleProperty::STEERING_WHEEL_THEFT_LOCK_ENABLED, 2},
+ {VehicleProperty::STEERING_WHEEL_LOCKED, 2},
+ {VehicleProperty::STEERING_WHEEL_EASY_ACCESS_ENABLED, 2},
+ {VehicleProperty::GLOVE_BOX_DOOR_POS, 2},
+ {VehicleProperty::GLOVE_BOX_LOCKED, 2},
+ {VehicleProperty::VEHICLE_MAP_SERVICE, 2},
+ {VehicleProperty::LOCATION_CHARACTERIZATION, 2},
+ {VehicleProperty::ULTRASONICS_SENSOR_POSITION, 3},
+ {VehicleProperty::ULTRASONICS_SENSOR_ORIENTATION, 3},
+ {VehicleProperty::ULTRASONICS_SENSOR_FIELD_OF_VIEW, 3},
+ {VehicleProperty::ULTRASONICS_SENSOR_DETECTION_RANGE, 3},
+ {VehicleProperty::ULTRASONICS_SENSOR_SUPPORTED_RANGES, 3},
+ {VehicleProperty::ULTRASONICS_SENSOR_MEASURED_DISTANCE, 3},
+ {VehicleProperty::OBD2_LIVE_FRAME, 2},
+ {VehicleProperty::OBD2_FREEZE_FRAME, 2},
+ {VehicleProperty::OBD2_FREEZE_FRAME_INFO, 2},
+ {VehicleProperty::OBD2_FREEZE_FRAME_CLEAR, 2},
+ {VehicleProperty::HEADLIGHTS_STATE, 2},
+ {VehicleProperty::HIGH_BEAM_LIGHTS_STATE, 2},
+ {VehicleProperty::FOG_LIGHTS_STATE, 2},
+ {VehicleProperty::HAZARD_LIGHTS_STATE, 2},
+ {VehicleProperty::HEADLIGHTS_SWITCH, 2},
+ {VehicleProperty::HIGH_BEAM_LIGHTS_SWITCH, 2},
+ {VehicleProperty::FOG_LIGHTS_SWITCH, 2},
+ {VehicleProperty::HAZARD_LIGHTS_SWITCH, 2},
+ {VehicleProperty::CABIN_LIGHTS_STATE, 2},
+ {VehicleProperty::CABIN_LIGHTS_SWITCH, 2},
+ {VehicleProperty::READING_LIGHTS_STATE, 2},
+ {VehicleProperty::READING_LIGHTS_SWITCH, 2},
+ {VehicleProperty::STEERING_WHEEL_LIGHTS_STATE, 2},
+ {VehicleProperty::STEERING_WHEEL_LIGHTS_SWITCH, 2},
+ {VehicleProperty::SUPPORT_CUSTOMIZE_VENDOR_PERMISSION, 2},
+ {VehicleProperty::DISABLED_OPTIONAL_FEATURES, 2},
+ {VehicleProperty::INITIAL_USER_INFO, 2},
+ {VehicleProperty::SWITCH_USER, 2},
+ {VehicleProperty::CREATE_USER, 2},
+ {VehicleProperty::REMOVE_USER, 2},
+ {VehicleProperty::USER_IDENTIFICATION_ASSOCIATION, 2},
+ {VehicleProperty::EVS_SERVICE_REQUEST, 2},
+ {VehicleProperty::POWER_POLICY_REQ, 2},
+ {VehicleProperty::POWER_POLICY_GROUP_REQ, 2},
+ {VehicleProperty::CURRENT_POWER_POLICY, 2},
+ {VehicleProperty::WATCHDOG_ALIVE, 2},
+ {VehicleProperty::WATCHDOG_TERMINATED_PROCESS, 2},
+ {VehicleProperty::VHAL_HEARTBEAT, 2},
+ {VehicleProperty::CLUSTER_SWITCH_UI, 2},
+ {VehicleProperty::CLUSTER_DISPLAY_STATE, 2},
+ {VehicleProperty::CLUSTER_REPORT_STATE, 2},
+ {VehicleProperty::CLUSTER_REQUEST_DISPLAY, 2},
+ {VehicleProperty::CLUSTER_NAVIGATION_STATE, 2},
+ {VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_TYPE, 2},
+ {VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_STATUS, 2},
+ {VehicleProperty::FRONT_FOG_LIGHTS_STATE, 2},
+ {VehicleProperty::FRONT_FOG_LIGHTS_SWITCH, 2},
+ {VehicleProperty::REAR_FOG_LIGHTS_STATE, 2},
+ {VehicleProperty::REAR_FOG_LIGHTS_SWITCH, 2},
+ {VehicleProperty::EV_CHARGE_CURRENT_DRAW_LIMIT, 2},
+ {VehicleProperty::EV_CHARGE_PERCENT_LIMIT, 2},
+ {VehicleProperty::EV_CHARGE_STATE, 2},
+ {VehicleProperty::EV_CHARGE_SWITCH, 2},
+ {VehicleProperty::EV_CHARGE_TIME_REMAINING, 2},
+ {VehicleProperty::EV_REGENERATIVE_BRAKING_STATE, 2},
+ {VehicleProperty::TRAILER_PRESENT, 2},
+ {VehicleProperty::VEHICLE_CURB_WEIGHT, 2},
+ {VehicleProperty::GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT, 2},
+ {VehicleProperty::SUPPORTED_PROPERTY_IDS, 2},
+ {VehicleProperty::SHUTDOWN_REQUEST, 2},
+ {VehicleProperty::VEHICLE_IN_USE, 2},
+ {VehicleProperty::CLUSTER_HEARTBEAT, 3},
+ {VehicleProperty::VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, 3},
+ {VehicleProperty::CAMERA_SERVICE_CURRENT_STATE, 3},
+ {VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED, 2},
+ {VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE, 2},
+ {VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED, 2},
+ {VehicleProperty::FORWARD_COLLISION_WARNING_STATE, 2},
+ {VehicleProperty::BLIND_SPOT_WARNING_ENABLED, 2},
+ {VehicleProperty::BLIND_SPOT_WARNING_STATE, 2},
+ {VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED, 2},
+ {VehicleProperty::LANE_DEPARTURE_WARNING_STATE, 2},
+ {VehicleProperty::LANE_KEEP_ASSIST_ENABLED, 2},
+ {VehicleProperty::LANE_KEEP_ASSIST_STATE, 2},
+ {VehicleProperty::LANE_CENTERING_ASSIST_ENABLED, 2},
+ {VehicleProperty::LANE_CENTERING_ASSIST_COMMAND, 2},
+ {VehicleProperty::LANE_CENTERING_ASSIST_STATE, 2},
+ {VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED, 2},
+ {VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_STATE, 2},
+ {VehicleProperty::CRUISE_CONTROL_ENABLED, 2},
+ {VehicleProperty::CRUISE_CONTROL_TYPE, 2},
+ {VehicleProperty::CRUISE_CONTROL_STATE, 2},
+ {VehicleProperty::CRUISE_CONTROL_COMMAND, 2},
+ {VehicleProperty::CRUISE_CONTROL_TARGET_SPEED, 2},
+ {VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP, 2},
+ {VehicleProperty::ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE, 2},
+ {VehicleProperty::HANDS_ON_DETECTION_ENABLED, 2},
+ {VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE, 2},
+ {VehicleProperty::HANDS_ON_DETECTION_WARNING, 2},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED, 3},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_STATE, 3},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED, 3},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING, 3},
+ {VehicleProperty::DRIVER_DISTRACTION_SYSTEM_ENABLED, 3},
+ {VehicleProperty::DRIVER_DISTRACTION_STATE, 3},
+ {VehicleProperty::DRIVER_DISTRACTION_WARNING_ENABLED, 2},
+ {VehicleProperty::DRIVER_DISTRACTION_WARNING, 3},
+ {VehicleProperty::LOW_SPEED_COLLISION_WARNING_ENABLED, 3},
+ {VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE, 3},
+ {VehicleProperty::CROSS_TRAFFIC_MONITORING_ENABLED, 3},
+ {VehicleProperty::CROSS_TRAFFIC_MONITORING_WARNING_STATE, 3},
+ {VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, 3},
+ {VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, 3},
+};
+
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+} // aidl
diff --git a/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
index 6e66632..afb6cab 100644
--- a/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
@@ -60,9 +60,11 @@
Map.entry(VehicleProperty.EV_CHARGE_PORT_CONNECTED, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.EV_BATTERY_INSTANTANEOUS_CHARGE_RATE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.RANGE_REMAINING, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.EV_BATTERY_AVERAGE_TEMPERATURE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.TIRE_PRESSURE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.CRITICALLY_LOW_TIRE_PRESSURE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.ENGINE_IDLE_AUTO_STOP_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.IMPACT_DETECTED, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.GEAR_SELECTION, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.CURRENT_GEAR, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.PARKING_BRAKE_ON, VehiclePropertyAccess.READ),
@@ -75,6 +77,8 @@
Map.entry(VehicleProperty.ABS_ACTIVE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.TRACTION_CONTROL_ACTIVE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.EV_STOPPING_MODE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.ELECTRONIC_STABILITY_CONTROL_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.ELECTRONIC_STABILITY_CONTROL_STATE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.HVAC_FAN_SPEED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.HVAC_FAN_DIRECTION, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.HVAC_TEMPERATURE_CURRENT, VehiclePropertyAccess.READ),
@@ -112,6 +116,8 @@
Map.entry(VehicleProperty.AP_POWER_BOOTUP_REASON, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.DISPLAY_BRIGHTNESS, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.PER_DISPLAY_BRIGHTNESS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.VALET_MODE_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.HEAD_UP_DISPLAY_ENABLED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.HW_KEY_INPUT, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.HW_KEY_INPUT_V2, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.HW_MOTION_INPUT, VehiclePropertyAccess.READ),
@@ -161,11 +167,13 @@
Map.entry(VehicleProperty.SEAT_FOOTWELL_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.SEAT_EASY_ACCESS_ENABLED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.SEAT_AIRBAG_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_AIRBAGS_DEPLOYED, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.SEAT_CUSHION_SIDE_SUPPORT_MOVE, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.SEAT_LUMBAR_VERTICAL_POS, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.SEAT_LUMBAR_VERTICAL_MOVE, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.SEAT_WALK_IN_POS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_BELT_PRETENSIONER_DEPLOYED, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.SEAT_OCCUPANCY, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.WINDOW_POS, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.WINDOW_MOVE, VehiclePropertyAccess.READ_WRITE),
@@ -184,6 +192,12 @@
Map.entry(VehicleProperty.GLOVE_BOX_LOCKED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.VEHICLE_MAP_SERVICE, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.LOCATION_CHARACTERIZATION, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_POSITION, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_ORIENTATION, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_FIELD_OF_VIEW, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_DETECTION_RANGE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_SUPPORTED_RANGES, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_MEASURED_DISTANCE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.OBD2_LIVE_FRAME, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.OBD2_FREEZE_FRAME, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.OBD2_FREEZE_FRAME_INFO, VehiclePropertyAccess.READ),
@@ -240,6 +254,8 @@
Map.entry(VehicleProperty.SHUTDOWN_REQUEST, VehiclePropertyAccess.WRITE),
Map.entry(VehicleProperty.VEHICLE_IN_USE, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.CLUSTER_HEARTBEAT, VehiclePropertyAccess.WRITE),
+ Map.entry(VehicleProperty.VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.CAMERA_SERVICE_CURRENT_STATE, VehiclePropertyAccess.WRITE),
Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
@@ -264,7 +280,21 @@
Map.entry(VehicleProperty.ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.HANDS_ON_DETECTION_ENABLED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.HANDS_ON_DETECTION_DRIVER_STATE, VehiclePropertyAccess.READ),
- Map.entry(VehicleProperty.HANDS_ON_DETECTION_WARNING, VehiclePropertyAccess.READ)
+ Map.entry(VehicleProperty.HANDS_ON_DETECTION_WARNING, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_WARNING, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_SYSTEM_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_WARNING, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess.READ)
);
}
diff --git a/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
index 522c82f..12aff40 100644
--- a/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
@@ -60,9 +60,11 @@
Map.entry(VehicleProperty.EV_CHARGE_PORT_CONNECTED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.EV_BATTERY_INSTANTANEOUS_CHARGE_RATE, VehiclePropertyChangeMode.CONTINUOUS),
Map.entry(VehicleProperty.RANGE_REMAINING, VehiclePropertyChangeMode.CONTINUOUS),
+ Map.entry(VehicleProperty.EV_BATTERY_AVERAGE_TEMPERATURE, VehiclePropertyChangeMode.CONTINUOUS),
Map.entry(VehicleProperty.TIRE_PRESSURE, VehiclePropertyChangeMode.CONTINUOUS),
Map.entry(VehicleProperty.CRITICALLY_LOW_TIRE_PRESSURE, VehiclePropertyChangeMode.STATIC),
Map.entry(VehicleProperty.ENGINE_IDLE_AUTO_STOP_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.IMPACT_DETECTED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.GEAR_SELECTION, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.CURRENT_GEAR, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.PARKING_BRAKE_ON, VehiclePropertyChangeMode.ON_CHANGE),
@@ -75,6 +77,8 @@
Map.entry(VehicleProperty.ABS_ACTIVE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.TRACTION_CONTROL_ACTIVE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.EV_STOPPING_MODE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.ELECTRONIC_STABILITY_CONTROL_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.ELECTRONIC_STABILITY_CONTROL_STATE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.HVAC_FAN_SPEED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.HVAC_FAN_DIRECTION, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.HVAC_TEMPERATURE_CURRENT, VehiclePropertyChangeMode.ON_CHANGE),
@@ -112,6 +116,8 @@
Map.entry(VehicleProperty.AP_POWER_BOOTUP_REASON, VehiclePropertyChangeMode.STATIC),
Map.entry(VehicleProperty.DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.PER_DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.VALET_MODE_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HEAD_UP_DISPLAY_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.HW_KEY_INPUT, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.HW_KEY_INPUT_V2, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.HW_MOTION_INPUT, VehiclePropertyChangeMode.ON_CHANGE),
@@ -161,11 +167,13 @@
Map.entry(VehicleProperty.SEAT_FOOTWELL_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.SEAT_EASY_ACCESS_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.SEAT_AIRBAG_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_AIRBAGS_DEPLOYED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.SEAT_CUSHION_SIDE_SUPPORT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.SEAT_LUMBAR_VERTICAL_POS, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.SEAT_LUMBAR_VERTICAL_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.SEAT_WALK_IN_POS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_BELT_PRETENSIONER_DEPLOYED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.SEAT_OCCUPANCY, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.WINDOW_POS, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.WINDOW_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
@@ -184,6 +192,12 @@
Map.entry(VehicleProperty.GLOVE_BOX_LOCKED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.VEHICLE_MAP_SERVICE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.LOCATION_CHARACTERIZATION, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_POSITION, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_ORIENTATION, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_FIELD_OF_VIEW, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_DETECTION_RANGE, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_SUPPORTED_RANGES, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_MEASURED_DISTANCE, VehiclePropertyChangeMode.CONTINUOUS),
Map.entry(VehicleProperty.OBD2_LIVE_FRAME, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.OBD2_FREEZE_FRAME, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.OBD2_FREEZE_FRAME_INFO, VehiclePropertyChangeMode.ON_CHANGE),
@@ -240,6 +254,8 @@
Map.entry(VehicleProperty.SHUTDOWN_REQUEST, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.VEHICLE_IN_USE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.CLUSTER_HEARTBEAT, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.CAMERA_SERVICE_CURRENT_STATE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
@@ -264,7 +280,21 @@
Map.entry(VehicleProperty.ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE, VehiclePropertyChangeMode.CONTINUOUS),
Map.entry(VehicleProperty.HANDS_ON_DETECTION_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.HANDS_ON_DETECTION_DRIVER_STATE, VehiclePropertyChangeMode.ON_CHANGE),
- Map.entry(VehicleProperty.HANDS_ON_DETECTION_WARNING, VehiclePropertyChangeMode.ON_CHANGE)
+ Map.entry(VehicleProperty.HANDS_ON_DETECTION_WARNING, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_WARNING, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_SYSTEM_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_WARNING, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyChangeMode.ON_CHANGE)
);
}
diff --git a/automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java
index 144d0e1..0f86bfa 100644
--- a/automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java
@@ -37,11 +37,13 @@
Map.entry(VehicleProperty.INFO_DRIVER_SEAT, List.of(VehicleAreaSeat.class)),
Map.entry(VehicleProperty.INFO_MULTI_EV_PORT_LOCATIONS, List.of(PortLocationType.class)),
Map.entry(VehicleProperty.ENGINE_OIL_LEVEL, List.of(VehicleOilLevel.class)),
+ Map.entry(VehicleProperty.IMPACT_DETECTED, List.of(ImpactSensorLocation.class)),
Map.entry(VehicleProperty.GEAR_SELECTION, List.of(VehicleGear.class)),
Map.entry(VehicleProperty.CURRENT_GEAR, List.of(VehicleGear.class)),
Map.entry(VehicleProperty.TURN_SIGNAL_STATE, List.of(VehicleTurnSignal.class)),
Map.entry(VehicleProperty.IGNITION_STATE, List.of(VehicleIgnitionState.class)),
Map.entry(VehicleProperty.EV_STOPPING_MODE, List.of(EvStoppingMode.class)),
+ Map.entry(VehicleProperty.ELECTRONIC_STABILITY_CONTROL_STATE, List.of(ElectronicStabilityControlState.class, ErrorState.class)),
Map.entry(VehicleProperty.HVAC_FAN_DIRECTION, List.of(VehicleHvacFanDirection.class)),
Map.entry(VehicleProperty.HVAC_TEMPERATURE_DISPLAY_UNITS, List.of(VehicleUnit.class)),
Map.entry(VehicleProperty.HVAC_FAN_DIRECTION_AVAILABLE, List.of(VehicleHvacFanDirection.class)),
@@ -53,6 +55,7 @@
Map.entry(VehicleProperty.HW_CUSTOM_INPUT, List.of(CustomInputType.class)),
Map.entry(VehicleProperty.SEAT_FOOTWELL_LIGHTS_STATE, List.of(VehicleLightState.class)),
Map.entry(VehicleProperty.SEAT_FOOTWELL_LIGHTS_SWITCH, List.of(VehicleLightSwitch.class)),
+ Map.entry(VehicleProperty.SEAT_AIRBAGS_DEPLOYED, List.of(VehicleAirbagLocation.class)),
Map.entry(VehicleProperty.SEAT_OCCUPANCY, List.of(VehicleSeatOccupancyState.class)),
Map.entry(VehicleProperty.WINDSHIELD_WIPERS_STATE, List.of(WindshieldWipersState.class)),
Map.entry(VehicleProperty.WINDSHIELD_WIPERS_SWITCH, List.of(WindshieldWipersSwitch.class)),
@@ -81,6 +84,8 @@
Map.entry(VehicleProperty.TRAILER_PRESENT, List.of(TrailerState.class)),
Map.entry(VehicleProperty.GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT, List.of(GsrComplianceRequirementType.class)),
Map.entry(VehicleProperty.SHUTDOWN_REQUEST, List.of(VehicleApPowerStateShutdownParam.class)),
+ Map.entry(VehicleProperty.VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, List.of(VehicleAutonomousState.class)),
+ Map.entry(VehicleProperty.CAMERA_SERVICE_CURRENT_STATE, List.of(CameraServiceState.class)),
Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_STATE, List.of(AutomaticEmergencyBrakingState.class, ErrorState.class)),
Map.entry(VehicleProperty.FORWARD_COLLISION_WARNING_STATE, List.of(ForwardCollisionWarningState.class, ErrorState.class)),
Map.entry(VehicleProperty.BLIND_SPOT_WARNING_STATE, List.of(BlindSpotWarningState.class, ErrorState.class)),
@@ -93,7 +98,14 @@
Map.entry(VehicleProperty.CRUISE_CONTROL_STATE, List.of(CruiseControlState.class, ErrorState.class)),
Map.entry(VehicleProperty.CRUISE_CONTROL_COMMAND, List.of(CruiseControlCommand.class)),
Map.entry(VehicleProperty.HANDS_ON_DETECTION_DRIVER_STATE, List.of(HandsOnDetectionDriverState.class, ErrorState.class)),
- Map.entry(VehicleProperty.HANDS_ON_DETECTION_WARNING, List.of(HandsOnDetectionWarning.class, ErrorState.class))
+ Map.entry(VehicleProperty.HANDS_ON_DETECTION_WARNING, List.of(HandsOnDetectionWarning.class, ErrorState.class)),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_STATE, List.of(DriverDrowsinessAttentionState.class, ErrorState.class)),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_WARNING, List.of(DriverDrowsinessAttentionWarning.class, ErrorState.class)),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_STATE, List.of(DriverDistractionState.class, ErrorState.class)),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_WARNING, List.of(DriverDistractionWarning.class, ErrorState.class)),
+ Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_STATE, List.of(LowSpeedCollisionWarningState.class, ErrorState.class)),
+ Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_WARNING_STATE, List.of(CrossTrafficMonitoringWarningState.class, ErrorState.class)),
+ Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, List.of(LowSpeedAutomaticEmergencyBrakingState.class, ErrorState.class))
);
}
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/JsonConfigLoader.h b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/JsonConfigLoader.h
index f3bdbd2..82e5860 100644
--- a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/JsonConfigLoader.h
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/JsonConfigLoader.h
@@ -130,12 +130,9 @@
std::vector<T>* outPtr, std::vector<std::string>* errors);
// Parses a JSON field to VehiclePropertyAccess or VehiclePropertyChangeMode.
template <class T>
- void parseAccessChangeMode(
- const Json::Value& parentJsonNode, const std::string& fieldName, int propId,
- const std::string& propStr,
- const std::unordered_map<aidl::android::hardware::automotive::vehicle::VehicleProperty,
- T>& defaultMap,
- T* outPtr, std::vector<std::string>* errors);
+ void parseAccessChangeMode(const Json::Value& parentJsonNode, const std::string& fieldName,
+ const std::string& propStr, const T* defaultAccessChangeModePtr,
+ T* outPtr, std::vector<std::string>* errors);
// Parses a JSON field to RawPropValues.
//
@@ -145,8 +142,10 @@
std::vector<std::string>* errors);
// Prase a JSON field as an array of area configs.
- void parseAreas(const Json::Value& parentJsonNode, const std::string& fieldName,
- ConfigDeclaration* outPtr, std::vector<std::string>* errors);
+ void parseAreas(
+ const Json::Value& parentJsonNode, const std::string& fieldName,
+ ConfigDeclaration* outPtr, std::vector<std::string>* errors,
+ aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess defaultAccess);
};
} // namespace jsonconfigloader_impl
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
index 82dc8a6..2a7ac96 100644
--- a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
@@ -37,10 +37,17 @@
using ::aidl::android::hardware::automotive::vehicle::AccessForVehicleProperty;
using ::aidl::android::hardware::automotive::vehicle::AutomaticEmergencyBrakingState;
using ::aidl::android::hardware::automotive::vehicle::BlindSpotWarningState;
+using ::aidl::android::hardware::automotive::vehicle::CameraServiceState;
using ::aidl::android::hardware::automotive::vehicle::ChangeModeForVehicleProperty;
+using ::aidl::android::hardware::automotive::vehicle::CrossTrafficMonitoringWarningState;
using ::aidl::android::hardware::automotive::vehicle::CruiseControlCommand;
using ::aidl::android::hardware::automotive::vehicle::CruiseControlState;
using ::aidl::android::hardware::automotive::vehicle::CruiseControlType;
+using ::aidl::android::hardware::automotive::vehicle::DriverDistractionState;
+using ::aidl::android::hardware::automotive::vehicle::DriverDistractionWarning;
+using ::aidl::android::hardware::automotive::vehicle::DriverDrowsinessAttentionState;
+using ::aidl::android::hardware::automotive::vehicle::DriverDrowsinessAttentionWarning;
+using ::aidl::android::hardware::automotive::vehicle::ElectronicStabilityControlState;
using ::aidl::android::hardware::automotive::vehicle::EmergencyLaneKeepAssistState;
using ::aidl::android::hardware::automotive::vehicle::ErrorState;
using ::aidl::android::hardware::automotive::vehicle::EvConnectorType;
@@ -51,17 +58,22 @@
using ::aidl::android::hardware::automotive::vehicle::GsrComplianceRequirementType;
using ::aidl::android::hardware::automotive::vehicle::HandsOnDetectionDriverState;
using ::aidl::android::hardware::automotive::vehicle::HandsOnDetectionWarning;
+using ::aidl::android::hardware::automotive::vehicle::ImpactSensorLocation;
using ::aidl::android::hardware::automotive::vehicle::LaneCenteringAssistCommand;
using ::aidl::android::hardware::automotive::vehicle::LaneCenteringAssistState;
using ::aidl::android::hardware::automotive::vehicle::LaneDepartureWarningState;
using ::aidl::android::hardware::automotive::vehicle::LaneKeepAssistState;
using ::aidl::android::hardware::automotive::vehicle::LocationCharacterization;
+using ::aidl::android::hardware::automotive::vehicle::LowSpeedAutomaticEmergencyBrakingState;
+using ::aidl::android::hardware::automotive::vehicle::LowSpeedCollisionWarningState;
using ::aidl::android::hardware::automotive::vehicle::RawPropValues;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAirbagLocation;
using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReport;
using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq;
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaMirror;
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaWindow;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAutonomousState;
using ::aidl::android::hardware::automotive::vehicle::VehicleGear;
using ::aidl::android::hardware::automotive::vehicle::VehicleHvacFanDirection;
using ::aidl::android::hardware::automotive::vehicle::VehicleIgnitionState;
@@ -240,8 +252,16 @@
std::make_unique<ConstantParser<WindshieldWipersState>>();
mConstantParsersByType["WindshieldWipersSwitch"] =
std::make_unique<ConstantParser<WindshieldWipersSwitch>>();
+ mConstantParsersByType["VehicleAutonomousState"] =
+ std::make_unique<ConstantParser<VehicleAutonomousState>>();
+ mConstantParsersByType["VehicleAirbagLocation"] =
+ std::make_unique<ConstantParser<VehicleAirbagLocation>>();
+ mConstantParsersByType["ImpactSensorLocation"] =
+ std::make_unique<ConstantParser<ImpactSensorLocation>>();
mConstantParsersByType["EmergencyLaneKeepAssistState"] =
std::make_unique<ConstantParser<EmergencyLaneKeepAssistState>>();
+ mConstantParsersByType["CameraServiceState"] =
+ std::make_unique<ConstantParser<CameraServiceState>>();
mConstantParsersByType["CruiseControlType"] =
std::make_unique<ConstantParser<CruiseControlType>>();
mConstantParsersByType["CruiseControlState"] =
@@ -252,6 +272,14 @@
std::make_unique<ConstantParser<HandsOnDetectionDriverState>>();
mConstantParsersByType["HandsOnDetectionWarning"] =
std::make_unique<ConstantParser<HandsOnDetectionWarning>>();
+ mConstantParsersByType["DriverDrowsinessAttentionState"] =
+ std::make_unique<ConstantParser<DriverDrowsinessAttentionState>>();
+ mConstantParsersByType["DriverDrowsinessAttentionWarning"] =
+ std::make_unique<ConstantParser<DriverDrowsinessAttentionWarning>>();
+ mConstantParsersByType["DriverDistractionState"] =
+ std::make_unique<ConstantParser<DriverDistractionState>>();
+ mConstantParsersByType["DriverDistractionWarning"] =
+ std::make_unique<ConstantParser<DriverDistractionWarning>>();
mConstantParsersByType["ErrorState"] = std::make_unique<ConstantParser<ErrorState>>();
mConstantParsersByType["AutomaticEmergencyBrakingState"] =
std::make_unique<ConstantParser<AutomaticEmergencyBrakingState>>();
@@ -267,6 +295,14 @@
std::make_unique<ConstantParser<LaneCenteringAssistCommand>>();
mConstantParsersByType["LaneCenteringAssistState"] =
std::make_unique<ConstantParser<LaneCenteringAssistState>>();
+ mConstantParsersByType["LowSpeedCollisionWarningState"] =
+ std::make_unique<ConstantParser<LowSpeedCollisionWarningState>>();
+ mConstantParsersByType["ElectronicStabilityControlState"] =
+ std::make_unique<ConstantParser<ElectronicStabilityControlState>>();
+ mConstantParsersByType["CrossTrafficMonitoringWarningState"] =
+ std::make_unique<ConstantParser<CrossTrafficMonitoringWarningState>>();
+ mConstantParsersByType["LowSpeedAutomaticEmergencyBrakingState"] =
+ std::make_unique<ConstantParser<LowSpeedAutomaticEmergencyBrakingState>>();
mConstantParsersByType["Constants"] = std::make_unique<LocalVariableParser>();
#ifdef ENABLE_VEHICLE_HAL_TEST_PROPERTIES
mConstantParsersByType["TestVendorProperty"] =
@@ -454,10 +490,11 @@
}
template <class T>
-void JsonConfigParser::parseAccessChangeMode(
- const Json::Value& parentJsonNode, const std::string& fieldName, int propId,
- const std::string& propStr, const std::unordered_map<VehicleProperty, T>& defaultMap,
- T* outPtr, std::vector<std::string>* errors) {
+void JsonConfigParser::parseAccessChangeMode(const Json::Value& parentJsonNode,
+ const std::string& fieldName,
+ const std::string& propStr,
+ const T* defaultAccessChangeModeValuePtr, T* outPtr,
+ std::vector<std::string>* errors) {
if (!parentJsonNode.isObject()) {
errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
return;
@@ -471,12 +508,11 @@
*outPtr = static_cast<T>(result.value());
return;
}
- auto it = defaultMap.find(static_cast<VehicleProperty>(propId));
- if (it == defaultMap.end()) {
+ if (defaultAccessChangeModeValuePtr == NULL) {
errors->push_back("No " + fieldName + " specified for property: " + propStr);
return;
}
- *outPtr = it->second;
+ *outPtr = *defaultAccessChangeModeValuePtr;
return;
}
@@ -505,7 +541,8 @@
}
void JsonConfigParser::parseAreas(const Json::Value& parentJsonNode, const std::string& fieldName,
- ConfigDeclaration* config, std::vector<std::string>* errors) {
+ ConfigDeclaration* config, std::vector<std::string>* errors,
+ VehiclePropertyAccess defaultAccess) {
if (!parentJsonNode.isObject()) {
errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
return;
@@ -513,6 +550,7 @@
if (!parentJsonNode.isMember(fieldName)) {
return;
}
+ std::string propStr = parentJsonNode["property"].toStyledString();
const Json::Value& jsonValue = parentJsonNode[fieldName];
if (!jsonValue.isArray()) {
@@ -528,6 +566,8 @@
}
VehicleAreaConfig areaConfig = {};
areaConfig.areaId = areaId;
+ parseAccessChangeMode(jsonAreaConfig, "access", propStr, &defaultAccess, &areaConfig.access,
+ errors);
tryParseJsonValueToVariable(jsonAreaConfig, "minInt32Value", /*optional=*/true,
&areaConfig.minInt32Value, errors);
tryParseJsonValueToVariable(jsonAreaConfig, "maxInt32Value", /*optional=*/true,
@@ -575,12 +615,21 @@
configDecl.config.prop = propId;
std::string propStr = propJsonValue["property"].toStyledString();
+ VehiclePropertyAccess* defaultAccessMode = NULL;
+ auto itAccess = AccessForVehicleProperty.find(static_cast<VehicleProperty>(propId));
+ if (itAccess != AccessForVehicleProperty.end()) {
+ defaultAccessMode = &itAccess->second;
+ }
+ VehiclePropertyChangeMode* defaultChangeMode = NULL;
+ auto itChangeMode = ChangeModeForVehicleProperty.find(static_cast<VehicleProperty>(propId));
+ if (itChangeMode != ChangeModeForVehicleProperty.end()) {
+ defaultChangeMode = &itChangeMode->second;
+ }
+ VehiclePropertyAccess access = VehiclePropertyAccess::NONE;
+ parseAccessChangeMode(propJsonValue, "access", propStr, defaultAccessMode, &access, errors);
- parseAccessChangeMode(propJsonValue, "access", propId, propStr, AccessForVehicleProperty,
- &configDecl.config.access, errors);
-
- parseAccessChangeMode(propJsonValue, "changeMode", propId, propStr,
- ChangeModeForVehicleProperty, &configDecl.config.changeMode, errors);
+ parseAccessChangeMode(propJsonValue, "changeMode", propStr, defaultChangeMode,
+ &configDecl.config.changeMode, errors);
tryParseJsonValueToVariable(propJsonValue, "configString", /*optional=*/true,
&configDecl.config.configString, errors);
@@ -596,21 +645,23 @@
tryParseJsonValueToVariable(propJsonValue, "maxSampleRate", /*optional=*/true,
&configDecl.config.maxSampleRate, errors);
- parseAreas(propJsonValue, "areas", &configDecl, errors);
-
- if (errors->size() != initialErrorCount) {
- return std::nullopt;
- }
+ parseAreas(propJsonValue, "areas", &configDecl, errors, access);
// If there is no area config, by default we allow variable update rate, so we have to add
// a global area config.
if (configDecl.config.areaConfigs.size() == 0) {
VehicleAreaConfig areaConfig = {
.areaId = 0,
+ .access = access,
.supportVariableUpdateRate = true,
};
configDecl.config.areaConfigs.push_back(std::move(areaConfig));
}
+
+ if (errors->size() != initialErrorCount) {
+ return std::nullopt;
+ }
+
return configDecl;
}
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/JsonConfigLoaderUnitTest.cpp b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/JsonConfigLoaderUnitTest.cpp
index 9882653..a13d3df 100644
--- a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/JsonConfigLoaderUnitTest.cpp
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/JsonConfigLoaderUnitTest.cpp
@@ -286,7 +286,8 @@
ASSERT_EQ(configs.size(), 1u);
const VehiclePropConfig& propConfig = configs.begin()->second.config;
- ASSERT_EQ(propConfig.access, VehiclePropertyAccess::READ);
+ ASSERT_EQ(propConfig.access, VehiclePropertyAccess::NONE);
+ ASSERT_EQ(propConfig.areaConfigs[0].access, VehiclePropertyAccess::READ);
ASSERT_EQ(propConfig.changeMode, VehiclePropertyChangeMode::STATIC);
}
@@ -307,7 +308,8 @@
ASSERT_EQ(configs.size(), 1u);
const VehiclePropConfig& propConfig = configs.begin()->second.config;
- ASSERT_EQ(propConfig.access, VehiclePropertyAccess::WRITE);
+ ASSERT_EQ(propConfig.access, VehiclePropertyAccess::NONE);
+ ASSERT_EQ(propConfig.areaConfigs[0].access, VehiclePropertyAccess::WRITE);
ASSERT_EQ(propConfig.changeMode, VehiclePropertyChangeMode::STATIC);
}
@@ -328,7 +330,8 @@
ASSERT_EQ(configs.size(), 1u);
const VehiclePropConfig& propConfig = configs.begin()->second.config;
- ASSERT_EQ(propConfig.access, VehiclePropertyAccess::READ);
+ ASSERT_EQ(propConfig.access, VehiclePropertyAccess::NONE);
+ ASSERT_EQ(propConfig.areaConfigs[0].access, VehiclePropertyAccess::READ);
ASSERT_EQ(propConfig.changeMode, VehiclePropertyChangeMode::ON_CHANGE);
}
@@ -350,7 +353,8 @@
ASSERT_EQ(configs.size(), 1u);
const VehiclePropConfig& propConfig = configs.begin()->second.config;
- ASSERT_EQ(propConfig.access, VehiclePropertyAccess::WRITE);
+ ASSERT_EQ(propConfig.access, VehiclePropertyAccess::NONE);
+ ASSERT_EQ(propConfig.areaConfigs[0].access, VehiclePropertyAccess::WRITE);
ASSERT_EQ(propConfig.changeMode, VehiclePropertyChangeMode::ON_CHANGE);
}
@@ -550,10 +554,12 @@
ASSERT_EQ(configs.size(), 1u);
const VehiclePropConfig& config = configs.begin()->second.config;
+ ASSERT_EQ(config.access, VehiclePropertyAccess::NONE);
ASSERT_EQ(config.areaConfigs.size(), 1u);
const VehicleAreaConfig& areaConfig = config.areaConfigs[0];
ASSERT_EQ(areaConfig.minInt32Value, 1);
ASSERT_EQ(areaConfig.maxInt32Value, 7);
+ ASSERT_EQ(areaConfig.access, VehiclePropertyAccess::READ);
ASSERT_EQ(areaConfig.areaId, HVAC_ALL);
}
@@ -635,9 +641,11 @@
ASSERT_EQ(configs.size(), 1u);
const VehiclePropConfig& config = configs.begin()->second.config;
+ ASSERT_EQ(config.access, VehiclePropertyAccess::NONE);
ASSERT_EQ(config.areaConfigs.size(), 1u);
const VehicleAreaConfig& areaConfig = config.areaConfigs[0];
+ ASSERT_EQ(areaConfig.access, VehiclePropertyAccess::READ);
ASSERT_EQ(areaConfig.areaId, 0);
ASSERT_FALSE(areaConfig.supportedEnumValues);
}
@@ -662,9 +670,11 @@
ASSERT_EQ(configs.size(), 1u);
const VehiclePropConfig& config = configs.begin()->second.config;
+ ASSERT_EQ(config.access, VehiclePropertyAccess::NONE);
ASSERT_EQ(config.areaConfigs.size(), 1u);
const VehicleAreaConfig& areaConfig = config.areaConfigs[0];
+ ASSERT_EQ(areaConfig.access, VehiclePropertyAccess::READ);
ASSERT_EQ(areaConfig.areaId, 0);
ASSERT_TRUE(areaConfig.supportedEnumValues);
ASSERT_EQ(areaConfig.supportedEnumValues.value().size(), 2u);
@@ -692,13 +702,107 @@
ASSERT_EQ(configs.size(), 1u);
const VehiclePropConfig& config = configs.begin()->second.config;
+ ASSERT_EQ(config.access, VehiclePropertyAccess::NONE);
ASSERT_EQ(config.areaConfigs.size(), 1u);
const VehicleAreaConfig& areaConfig = config.areaConfigs[0];
+ ASSERT_EQ(areaConfig.access, VehiclePropertyAccess::READ);
ASSERT_EQ(areaConfig.areaId, 0);
ASSERT_FALSE(areaConfig.supportedEnumValues);
}
+TEST_F(JsonConfigLoaderUnitTest, testAccess_areaOverrideGlobalDefault) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::CABIN_LIGHTS_SWITCH",
+ "areas": [{
+ "access": "VehiclePropertyAccess::READ",
+ "areaId": 0
+ }]
+ }]
+ }
+ )");
+
+ auto result = mLoader.loadPropConfig(iss);
+ ASSERT_TRUE(result.ok());
+
+ auto configs = result.value();
+ ASSERT_EQ(configs.size(), 1u);
+
+ const VehiclePropConfig& config = configs.begin()->second.config;
+ ASSERT_EQ(config.access, VehiclePropertyAccess::NONE);
+ ASSERT_EQ(config.areaConfigs.size(), 1u);
+
+ const VehicleAreaConfig& areaConfig = config.areaConfigs[0];
+ ASSERT_EQ(areaConfig.access, VehiclePropertyAccess::READ);
+ ASSERT_EQ(areaConfig.areaId, 0);
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testAccess_globalOverrideDefault) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::CABIN_LIGHTS_SWITCH",
+ "areas": [{
+ "areaId": 0
+ }],
+ "access": "VehiclePropertyAccess::READ"
+ }]
+ }
+ )");
+
+ auto result = mLoader.loadPropConfig(iss);
+ ASSERT_TRUE(result.ok());
+
+ auto configs = result.value();
+ ASSERT_EQ(configs.size(), 1u);
+
+ const VehiclePropConfig& config = configs.begin()->second.config;
+ ASSERT_EQ(config.access, VehiclePropertyAccess::NONE);
+ ASSERT_EQ(config.areaConfigs.size(), 1u);
+
+ const VehicleAreaConfig& areaConfig = config.areaConfigs[0];
+ ASSERT_EQ(areaConfig.access, VehiclePropertyAccess::READ);
+ ASSERT_EQ(areaConfig.areaId, 0);
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testAccess_areaOverrideGlobal) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::CABIN_LIGHTS_SWITCH",
+ "areas": [{
+ "access": "VehiclePropertyAccess::WRITE",
+ "areaId": 0
+ },
+ {
+ "areaId": 1
+ }],
+ "access": "VehiclePropertyAccess::READ",
+ }]
+ }
+ )");
+
+ auto result = mLoader.loadPropConfig(iss);
+ ASSERT_TRUE(result.ok());
+
+ auto configs = result.value();
+ ASSERT_EQ(configs.size(), 1u);
+
+ const VehiclePropConfig& config = configs.begin()->second.config;
+ ASSERT_EQ(config.access, VehiclePropertyAccess::NONE);
+ ASSERT_EQ(config.areaConfigs.size(), 2u);
+
+ const VehicleAreaConfig& areaConfig1 = config.areaConfigs[0];
+ ASSERT_EQ(areaConfig1.access, VehiclePropertyAccess::WRITE);
+ ASSERT_EQ(areaConfig1.areaId, 0);
+
+ const VehicleAreaConfig& areaConfig2 = config.areaConfigs[1];
+ ASSERT_EQ(areaConfig2.access, VehiclePropertyAccess::READ);
+ ASSERT_EQ(areaConfig2.areaId, 1);
+}
+
} // namespace vehicle
} // namespace automotive
} // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
index d3bb60c..b7911eb 100644
--- a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
+++ b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
@@ -1328,6 +1328,75 @@
]
},
{
+ "property": "VehicleProperty::SEAT_AIRBAGS_DEPLOYED",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "supportedEnumValues": [
+ "VehicleAirbagLocation::FRONT",
+ "VehicleAirbagLocation::KNEE",
+ "VehicleAirbagLocation::LEFT_SIDE",
+ "VehicleAirbagLocation::RIGHT_SIDE",
+ "VehicleAirbagLocation::CURTAIN"
+ ]
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "supportedEnumValues": [
+ "VehicleAirbagLocation::FRONT",
+ "VehicleAirbagLocation::KNEE",
+ "VehicleAirbagLocation::LEFT_SIDE",
+ "VehicleAirbagLocation::RIGHT_SIDE",
+ "VehicleAirbagLocation::CURTAIN"
+ ]
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "supportedEnumValues": [
+ "VehicleAirbagLocation::FRONT",
+ "VehicleAirbagLocation::CURTAIN"
+ ]
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "supportedEnumValues": [
+ "VehicleAirbagLocation::FRONT",
+ "VehicleAirbagLocation::CURTAIN"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_BELT_PRETENSIONER_DEPLOYED",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT"
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT"
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT"
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT"
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER"
+ }
+ ]
+ },
+ {
"property": "VehicleProperty::SEAT_OCCUPANCY",
"defaultValue": {
"int32Values": [
@@ -1560,6 +1629,16 @@
"minSampleRate": 1.0
},
{
+ "property": "VehicleProperty::EV_BATTERY_AVERAGE_TEMPERATURE",
+ "defaultValue": {
+ "floatValues": [
+ 25.0
+ ]
+ },
+ "maxSampleRate": 2.0,
+ "minSampleRate": 1.0
+ },
+ {
"property": "VehicleProperty::TIRE_PRESSURE",
"defaultValue": {
"floatValues": [
@@ -2368,9 +2447,9 @@
160,
280,
5,
- 600,
- 840,
- 10
+ 608,
+ 824,
+ 9
]
},
{
@@ -2380,7 +2459,7 @@
66.19999694824219,
"VehicleUnit::FAHRENHEIT",
19.0,
- 66.0
+ 66.2
]
}
},
@@ -2503,6 +2582,27 @@
}
},
{
+ "property": "VehicleProperty::IMPACT_DETECTED",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ImpactSensorLocation::FRONT",
+ "ImpactSensorLocation::FRONT_LEFT_DOOR_SIDE",
+ "ImpactSensorLocation::FRONT_RIGHT_DOOR_SIDE",
+ "ImpactSensorLocation::REAR_LEFT_DOOR_SIDE",
+ "ImpactSensorLocation::REAR_RIGHT_DOOR_SIDE",
+ "ImpactSensorLocation::REAR"
+ ]
+ }
+ ]
+ },
+ {
"property": "VehicleProperty::DOOR_LOCK",
"areas": [
{
@@ -3111,6 +3211,27 @@
]
},
{
+ "property": "VehicleProperty::VALET_MODE_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::HEAD_UP_DISPLAY_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT"
+ }
+ ]
+ },
+ {
"property": "VehicleProperty::OBD2_LIVE_FRAME",
"configArray": [
0,
@@ -3335,6 +3456,839 @@
}
},
{
+ "property": "VehicleProperty::ULTRASONICS_SENSOR_POSITION",
+ "comment":
+ "Default values for 12 individual ultrasonic sensors installed on the vehicle. Six sensors on the front bumper. Six sensors on the back bumper.",
+ "areas": [
+ {
+ "defaultValue": {
+ "int32Values": [
+ -1000,
+ 3900,
+ 0
+ ]
+ },
+ "areaId": 1,
+ "comment": "Rough numbers representing front left most sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ -600,
+ 4000,
+ 0
+ ]
+ },
+ "areaId": 2,
+ "comment": "Rough numbers representing front 2nd to the left sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ -200,
+ 4000,
+ 0
+ ]
+ },
+ "areaId": 4,
+ "comment": "Rough numbers representing front 3rd to the left sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 200,
+ 4000,
+ 0
+ ]
+ },
+ "areaId": 8,
+ "comment": "Rough numbers representing front 3rd to the right sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 600,
+ 4000,
+ 0
+ ]
+ },
+ "areaId": 16,
+ "comment": "Rough numbers representing front 2nd to the right sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 1000,
+ 3900,
+ 0
+ ]
+ },
+ "areaId": 32,
+ "comment": "Rough numbers representing front right most sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ -1000,
+ -900,
+ 0
+ ]
+ },
+ "areaId": 64,
+ "comment": "Rough numbers representing back left most sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ -600,
+ -1000,
+ 0
+ ]
+ },
+ "areaId": 128,
+ "comment": "Rough numbers representing back 2nd to the left sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ -200,
+ -1000,
+ 0
+ ]
+ },
+ "areaId": 256,
+ "comment": "Rough numbers representing back 3rd to the left sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 200,
+ -1000,
+ 0
+ ]
+ },
+ "areaId": 512,
+ "comment": "Rough numbers representing back 3rd to the right sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 600,
+ -1000,
+ 0
+ ]
+ },
+ "areaId": 1024,
+ "comment": "Rough numbers representing back 2nd to the right sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 1000,
+ -900,
+ 0
+ ]
+ },
+ "areaId": 2048,
+ "comment": "Rough numbers representing back right most sensor."
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::ULTRASONICS_SENSOR_ORIENTATION",
+ "comment":
+ "Default values for 12 individual ultrasonic sensors installed on the vehicle. Six sensors on the front bumper. Six sensors on the back bumper.",
+ "areas": [
+ {
+ "defaultValue": {
+ "floatValues": [
+ 0.924,
+ 0,
+ 0,
+ 0.383
+ ]
+ },
+ "areaId": 1,
+ "comment":
+ "Rough quaternion values [w, x, y, z] representing front left most sensor rotated 45 degrees counter-clockwise."
+ },
+ {
+ "defaultValue": {
+ "floatValues": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ },
+ "areaId": 2,
+ "comment":
+ "Rough quaternion values [w, x, y, z] representing front 2nd to the left sensor rotated 0 degrees"
+ },
+ {
+ "defaultValue": {
+ "floatValues": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ },
+ "areaId": 4,
+ "comment":
+ "Rough quaternion values [w, x, y, z] representing front 3rd to the left sensor rotated 0 degrees"
+ },
+ {
+ "defaultValue": {
+ "floatValues": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ },
+ "areaId": 8,
+ "comment":
+ "Rough quaternion values [w, x, y, z] representing front 3rd to the right sensor rotated 0 degrees"
+ },
+ {
+ "defaultValue": {
+ "floatValues": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ },
+ "areaId": 16,
+ "comment":
+ "Rough quaternion values [w, x, y, z] representing front 2nd to the right sensor rotated 0 degrees"
+ },
+ {
+ "defaultValue": {
+ "floatValues": [
+ 0.924,
+ 0,
+ 0,
+ -0.383
+ ]
+ },
+ "areaId": 32,
+ "comment":
+ "Rough quaternion values [w, x, y, z] representing front right most sensor rotated 45 degrees clockwise."
+ },
+ {
+ "defaultValue": {
+ "floatValues": [
+ 60,
+ 61,
+ 62,
+ 63
+ ]
+ },
+ "areaId": 64,
+ "comment":
+ "Rough quaternion values [w, x, y, z] representing back left most sensor rotated 45 degrees counter-clockwise."
+ },
+ {
+ "defaultValue": {
+ "floatValues": [
+ 70,
+ 71,
+ 72,
+ 73
+ ]
+ },
+ "areaId": 128,
+ "comment":
+ "Rough quaternion values [w, x, y, z] representing back 2nd to the left sensor rotated 0 degrees"
+ },
+ {
+ "defaultValue": {
+ "floatValues": [
+ 81,
+ 82,
+ 83,
+ 84
+ ]
+ },
+ "areaId": 256,
+ "comment":
+ "Rough quaternion values [w, x, y, z] representing back 3rd to the right sensor rotated 0 degrees"
+ },
+ {
+ "defaultValue": {
+ "floatValues": [
+ 90,
+ 91,
+ 92,
+ 93
+ ]
+ },
+ "areaId": 512,
+ "comment":
+ "Rough quaternion values [w, x, y, z] representing back 3rd to the right sensor rotated 0 degrees"
+ },
+ {
+ "defaultValue": {
+ "floatValues": [
+ 100,
+ 101,
+ 102,
+ 103
+ ]
+ },
+ "areaId": 1024,
+ "comment":
+ "Rough quaternion values [w, x, y, z] representing back 2nd to the right sensor rotated 0 degrees"
+ },
+ {
+ "defaultValue": {
+ "floatValues": [
+ 110,
+ 111,
+ 112,
+ 113
+ ]
+ },
+ "areaId": 2048,
+ "comment":
+ "Rough quaternion values [w, x, y, z] representing back right most sensor rotated 45 degrees clockwise."
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::ULTRASONICS_SENSOR_FIELD_OF_VIEW",
+ "comment":
+ "Default values for 12 individual ultrasonic sensors installed on the vehicle. Six sensors on the front bumper. Six sensors on the back bumper.",
+ "areas": [
+ {
+ "defaultValue": {
+ "int32Values": [
+ 85,
+ 45
+ ]
+ },
+ "areaId": 1,
+ "comment": "Rough values representing front left most sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 75,
+ 45
+ ]
+ },
+ "areaId": 2,
+ "comment": "Rough values representing front 2nd to the left sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 75,
+ 45
+ ]
+ },
+ "areaId": 4,
+ "comment": "Rough values representing front 3rd to the left sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 75,
+ 45
+ ]
+ },
+ "areaId": 8,
+ "comment": "Rough values representing front 3rd to the right sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 75,
+ 45
+ ]
+ },
+ "areaId": 16,
+ "comment": "Rough values representing front 2nd to the right sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 85,
+ 45
+ ]
+ },
+ "areaId": 32,
+ "comment": "Rough values representing front right most sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 85,
+ 45
+ ]
+ },
+ "areaId": 64,
+ "comment": "Rough values representing back left most sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 75,
+ 45
+ ]
+ },
+ "areaId": 128,
+ "comment": "Rough values representing back 2nd to the left sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 75,
+ 45
+ ]
+ },
+ "areaId": 256,
+ "comment": "Rough values representing back 3rd to the left sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 75,
+ 45
+ ]
+ },
+ "areaId": 512,
+ "comment": "Rough values representing back 3rd to the right sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 75,
+ 45
+ ]
+ },
+ "areaId": 1024,
+ "comment": "Rough values representing back 2nd to the right sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 85,
+ 45
+ ]
+ },
+ "areaId": 2048,
+ "comment": "Rough values representing back right most sensor."
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::ULTRASONICS_SENSOR_DETECTION_RANGE",
+ "areas": [
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 4000
+ ]
+ },
+ "areaId": 1,
+ "comment": "Rough values representing front left most sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 3000
+ ]
+ },
+ "areaId": 2,
+ "comment": "Rough values representing front 2nd to the left sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 3000
+ ]
+ },
+ "areaId": 4,
+ "comment": "Rough values representing front 3rd to the left sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 3000
+ ]
+ },
+ "areaId": 8,
+ "comment": "Rough values representing front 3rd to the right sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 3000
+ ]
+ },
+ "areaId": 16,
+ "comment": "Rough values representing front 2nd to the right sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 4000
+ ]
+ },
+ "areaId": 32,
+ "comment": "Rough values representing front right most sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 4000
+ ]
+ },
+ "areaId": 64,
+ "comment": "Rough values representing back left most sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 3000
+ ]
+ },
+ "areaId": 128,
+ "comment": "Rough values representing back 2nd to the left sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 3000
+ ]
+ },
+ "areaId": 256,
+ "comment": "Rough values representing back 3rd to the left sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 3000
+ ]
+ },
+ "areaId": 512,
+ "comment": "Rough values representing back 3rd to the right sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 3000
+ ]
+ },
+ "areaId": 1024,
+ "comment": "Rough values representing back 2nd to the right sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 4000
+ ]
+ },
+ "areaId": 2048,
+ "comment": "Rough values representing back right most sensor."
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::ULTRASONICS_SENSOR_SUPPORTED_RANGES",
+ "areas": [
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 999,
+ 1000,
+ 1999,
+ 2000,
+ 4000
+ ]
+ },
+ "areaId": 1,
+ "comment": "Rough values representing front left most sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 999,
+ 1000,
+ 1999,
+ 2000,
+ 3000
+ ]
+ },
+ "areaId": 2,
+ "comment": "Rough values representing front 2nd to the left sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 999,
+ 1000,
+ 1999,
+ 2000,
+ 3000
+ ]
+ },
+ "areaId": 4,
+ "comment": "Rough values representing front 3rd to the left sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 999,
+ 1000,
+ 1999,
+ 2000,
+ 3000
+ ]
+ },
+ "areaId": 8,
+ "comment": "Rough values representing front 3rd to the right sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 999,
+ 1000,
+ 1999,
+ 2000,
+ 3000
+ ]
+ },
+ "areaId": 16,
+ "comment": "Rough values representing front 2nd to the right sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 999,
+ 1000,
+ 1999,
+ 2000,
+ 4000
+ ]
+ },
+ "areaId": 32,
+ "comment": "Rough values representing front right most sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 999,
+ 1000,
+ 1999,
+ 2000,
+ 4000
+ ]
+ },
+ "areaId": 64,
+ "comment": "Rough values representing back left most sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 999,
+ 1000,
+ 1999,
+ 2000,
+ 3000
+ ]
+ },
+ "areaId": 128,
+ "comment": "Rough values representing back 2nd to the left sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 999,
+ 1000,
+ 3000
+ ]
+ },
+ "areaId": 256,
+ "comment": "Rough values representing back 3rd to the left sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 999,
+ 1000,
+ 3000
+ ]
+ },
+ "areaId": 512,
+ "comment": "Rough values representing back 3rd to the right sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 999,
+ 1000,
+ 1999,
+ 2000,
+ 3000
+ ]
+ },
+ "areaId": 1024,
+ "comment": "Rough values representing back 2nd to the right sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 150,
+ 999,
+ 1000,
+ 1999,
+ 2000,
+ 4000
+ ]
+ },
+ "areaId": 2048,
+ "comment": "Rough values representing back right most sensor."
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::ULTRASONICS_SENSOR_MEASURED_DISTANCE",
+ "areas": [
+ {
+ "defaultValue": {
+ "int32Values": [
+ 2000,
+ 10
+ ]
+ },
+ "areaId": 1,
+ "comment": "Rough values representing front left most sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": []
+ },
+ "areaId": 2,
+ "comment":
+ "Rough values representing front 2nd to the left sensor. Nothing detected."
+ },
+ {
+ "defaultValue": {
+ "int32Values": []
+ },
+ "areaId": 4,
+ "comment":
+ "Rough values representing front 3rd to the left sensor. Nothing detected."
+ },
+ {
+ "defaultValue": {
+ "int32Values": []
+ },
+ "areaId": 8,
+ "comment":
+ "Rough values representing front 3rd to the right sensor. Nothing detected."
+ },
+ {
+ "defaultValue": {
+ "int32Values": []
+ },
+ "areaId": 16,
+ "comment":
+ "Rough values representing front 2nd to the right sensor. Nothing detected."
+ },
+ {
+ "defaultValue": {
+ "int32Values": []
+ },
+ "areaId": 32,
+ "comment":
+ "Rough values representing front right most sensor. Nothing detected."
+ },
+ {
+ "defaultValue": {
+ "int32Values": []
+ },
+ "areaId": 64,
+ "comment": "Rough values representing back left most sensor. Nothing detected."
+ },
+ {
+ "defaultValue": {
+ "int32Values": []
+ },
+ "areaId": 128,
+ "comment":
+ "Rough values representing back 2nd to the left sensor. Nothing detected."
+ },
+ {
+ "defaultValue": {
+ "int32Values": []
+ },
+ "areaId": 256,
+ "comment":
+ "Rough values representing back 3rd to the left sensor. Nothing detected."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 1000
+ ]
+ },
+ "areaId": 512,
+ "comment":
+ "Rough values representing back 3rd to the right sensor. Nothing detected."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 2000,
+ 50
+ ]
+ },
+ "areaId": 1024,
+ "comment": "Rough values representing back 2nd to the right sensor."
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 2000
+ ]
+ },
+ "areaId": 2048,
+ "comment":
+ "Rough values representing back right most sensor. No distance error."
+ }
+ ],
+ "maxSampleRate": 10.0,
+ "minSampleRate": 1.0
+ },
+ {
"property": "VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_TYPE",
"defaultValue": {
"int32Values": [
@@ -3546,6 +4500,117 @@
]
},
{
+ "property": "VehicleProperty::DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::DRIVER_DROWSINESS_ATTENTION_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "DriverDrowsinessAttentionState::KSS_RATING_3_ALERT"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "DriverDrowsinessAttentionState::KSS_RATING_1_EXTREMELY_ALERT",
+ "DriverDrowsinessAttentionState::KSS_RATING_2_VERY_ALERT",
+ "DriverDrowsinessAttentionState::KSS_RATING_3_ALERT",
+ "DriverDrowsinessAttentionState::KSS_RATING_4_RATHER_ALERT",
+ "DriverDrowsinessAttentionState::KSS_RATING_5_NEITHER_ALERT_NOR_SLEEPY",
+ "DriverDrowsinessAttentionState::KSS_RATING_6_SOME_SLEEPINESS",
+ "DriverDrowsinessAttentionState::KSS_RATING_7_SLEEPY_NO_EFFORT",
+ "DriverDrowsinessAttentionState::KSS_RATING_8_SLEEPY_SOME_EFFORT",
+ "DriverDrowsinessAttentionState::KSS_RATING_9_VERY_SLEEPY"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING",
+ "defaultValue": {
+ "int32Values": [
+ "DriverDrowsinessAttentionWarning::NO_WARNING"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "DriverDrowsinessAttentionWarning::NO_WARNING",
+ "DriverDrowsinessAttentionWarning::WARNING"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::DRIVER_DISTRACTION_SYSTEM_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::DRIVER_DISTRACTION_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "DriverDistractionState::NOT_DISTRACTED"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "DriverDistractionState::NOT_DISTRACTED",
+ "DriverDistractionState::DISTRACTED"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::DRIVER_DISTRACTION_WARNING_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::DRIVER_DISTRACTION_WARNING",
+ "defaultValue": {
+ "int32Values": [
+ "DriverDistractionWarning::NO_WARNING"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "DriverDistractionWarning::NO_WARNING",
+ "DriverDistractionWarning::WARNING"
+ ]
+ }
+ ]
+ },
+ {
"property": "VehicleProperty::INITIAL_USER_INFO"
},
{
@@ -3675,6 +4740,14 @@
}
},
{
+ "property": "VehicleProperty::VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL",
+ "defaultValue": {
+ "int32Values": [
+ "VehicleAutonomousState::LEVEL_0"
+ ]
+ }
+ },
+ {
"property": "VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED",
"defaultValue": {
"int32Values": [
@@ -3872,6 +4945,143 @@
]
}
]
+ },
+ {
+ "property": "VehicleProperty::LOW_SPEED_COLLISION_WARNING_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "LowSpeedCollisionWarningState::NO_WARNING"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_SAFETY",
+ "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
+ "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "LowSpeedCollisionWarningState::NO_WARNING",
+ "LowSpeedCollisionWarningState::WARNING"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::ELECTRONIC_STABILITY_CONTROL_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::ELECTRONIC_STABILITY_CONTROL_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "ElectronicStabilityControlState::ENABLED"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_SAFETY",
+ "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+ "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "ElectronicStabilityControlState::ENABLED",
+ "ElectronicStabilityControlState::ACTIVATED"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::CROSS_TRAFFIC_MONITORING_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::CROSS_TRAFFIC_MONITORING_WARNING_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "CrossTrafficMonitoringWarningState::NO_WARNING"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_SAFETY",
+ "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
+ "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "CrossTrafficMonitoringWarningState::NO_WARNING",
+ "CrossTrafficMonitoringWarningState::WARNING_FRONT_LEFT",
+ "CrossTrafficMonitoringWarningState::WARNING_FRONT_RIGHT",
+ "CrossTrafficMonitoringWarningState::WARNING_FRONT_BOTH",
+ "CrossTrafficMonitoringWarningState::WARNING_REAR_LEFT",
+ "CrossTrafficMonitoringWarningState::WARNING_REAR_RIGHT",
+ "CrossTrafficMonitoringWarningState::WARNING_REAR_BOTH"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "LowSpeedAutomaticEmergencyBrakingState::ENABLED"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_SAFETY",
+ "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
+ "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "LowSpeedAutomaticEmergencyBrakingState::ENABLED",
+ "LowSpeedAutomaticEmergencyBrakingState::ACTIVATED",
+ "LowSpeedAutomaticEmergencyBrakingState::USER_OVERRIDE"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::CAMERA_SERVICE_CURRENT_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "CameraServiceState::UNAVAILABLE",
+ "CameraServiceState::UNAVAILABLE",
+ "CameraServiceState::UNAVAILABLE",
+ "CameraServiceState::UNAVAILABLE",
+ "CameraServiceState::UNAVAILABLE",
+ "CameraServiceState::UNAVAILABLE",
+ "CameraServiceState::UNAVAILABLE",
+ "CameraServiceState::UNAVAILABLE"
+ ]
+ }
}
]
}
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
index 26fdee6..1153217 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
@@ -142,6 +142,16 @@
void handleRequestsOnce();
};
+ struct RefreshInfo {
+ VehiclePropertyStore::EventMode eventMode;
+ int64_t intervalInNanos;
+ };
+
+ struct ActionForInterval {
+ std::unordered_set<PropIdAreaId, PropIdAreaIdHash> propIdAreaIdsToRefresh;
+ std::shared_ptr<RecurrentTimer::Callback> recurrentAction;
+ };
+
const std::unique_ptr<obd2frame::FakeObd2Frame> mFakeObd2Frame;
const std::unique_ptr<FakeUserHal> mFakeUserHal;
// RecurrentTimer is thread-safe.
@@ -154,8 +164,9 @@
std::unique_ptr<const PropertySetErrorCallback> mOnPropertySetErrorCallback;
std::mutex mLock;
- std::unordered_map<PropIdAreaId, std::shared_ptr<RecurrentTimer::Callback>, PropIdAreaIdHash>
- mRecurrentActions GUARDED_BY(mLock);
+ std::unordered_map<PropIdAreaId, RefreshInfo, PropIdAreaIdHash> mRefreshInfoByPropIdAreaId
+ GUARDED_BY(mLock);
+ std::unordered_map<int64_t, ActionForInterval> mActionByIntervalInNanos GUARDED_BY(mLock);
std::unordered_map<PropIdAreaId, VehiclePropValuePool::RecyclableType, PropIdAreaIdHash>
mSavedProps GUARDED_BY(mLock);
std::unordered_set<PropIdAreaId, PropIdAreaIdHash> mSubOnChangePropIdAreaIds GUARDED_BY(mLock);
@@ -183,6 +194,10 @@
void onValueChangeCallback(
const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value)
EXCLUDES(mLock);
+ // The callback that would be called when multiple vehicle property value changes happen.
+ void onValuesChangeCallback(
+ std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue> values)
+ EXCLUDES(mLock);
// Load the config files in format '*.json' from the directory and parse the config files
// into a map from property ID to ConfigDeclarations.
void loadPropConfigsFromDir(const std::string& dirPath,
@@ -241,6 +256,7 @@
std::string dumpSaveProperty(const std::vector<std::string>& options);
std::string dumpRestoreProperty(const std::vector<std::string>& options);
std::string dumpInjectEvent(const std::vector<std::string>& options);
+ std::string dumpSubscriptions();
template <typename T>
android::base::Result<T> safelyParseInt(int index, const std::string& s) {
@@ -276,6 +292,11 @@
const aidl::android::hardware::automotive::vehicle::VehiclePropConfig&
vehiclePropConfig) REQUIRES(mLock);
+ void registerRefreshLocked(PropIdAreaId propIdAreaId, VehiclePropertyStore::EventMode eventMode,
+ float sampleRateHz) REQUIRES(mLock);
+ void unregisterRefreshLocked(PropIdAreaId propIdAreaId) REQUIRES(mLock);
+ void refreshTimestampForInterval(int64_t intervalInNanos) EXCLUDES(mLock);
+
static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwInputKeyProp(
aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction action,
int32_t keyCode, int32_t targetDisplay);
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
index cc4fae1..bcc765c 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -51,8 +51,14 @@
namespace {
+#define PROP_ID_TO_CSTR(A) (propIdToString(A).c_str())
+
using ::aidl::android::hardware::automotive::vehicle::CruiseControlCommand;
using ::aidl::android::hardware::automotive::vehicle::CruiseControlType;
+using ::aidl::android::hardware::automotive::vehicle::DriverDistractionState;
+using ::aidl::android::hardware::automotive::vehicle::DriverDistractionWarning;
+using ::aidl::android::hardware::automotive::vehicle::DriverDrowsinessAttentionState;
+using ::aidl::android::hardware::automotive::vehicle::DriverDrowsinessAttentionWarning;
using ::aidl::android::hardware::automotive::vehicle::ErrorState;
using ::aidl::android::hardware::automotive::vehicle::GetValueRequest;
using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
@@ -192,6 +198,63 @@
toInt(VehicleProperty::HANDS_ON_DETECTION_WARNING),
},
},
+ // Driver Drowsiness and Attention
+ {
+ toInt(VehicleProperty::DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED),
+ {
+ toInt(VehicleProperty::DRIVER_DROWSINESS_ATTENTION_STATE),
+ },
+ },
+ // Driver Drowsiness and Attention Warning
+ {
+ toInt(VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED),
+ {
+ toInt(VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING),
+ },
+ },
+ // Driver Distraction
+ {
+ toInt(VehicleProperty::DRIVER_DISTRACTION_SYSTEM_ENABLED),
+ {
+ toInt(VehicleProperty::DRIVER_DISTRACTION_STATE),
+ toInt(VehicleProperty::DRIVER_DISTRACTION_WARNING),
+ },
+ },
+ // Driver Distraction Warning
+ {
+ toInt(VehicleProperty::DRIVER_DISTRACTION_WARNING_ENABLED),
+ {
+ toInt(VehicleProperty::DRIVER_DISTRACTION_WARNING),
+ },
+ },
+ // LSCW
+ {
+ toInt(VehicleProperty::LOW_SPEED_COLLISION_WARNING_ENABLED),
+ {
+ toInt(VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE),
+ },
+ },
+ // ESC
+ {
+ toInt(VehicleProperty::ELECTRONIC_STABILITY_CONTROL_ENABLED),
+ {
+ toInt(VehicleProperty::ELECTRONIC_STABILITY_CONTROL_STATE),
+ },
+ },
+ // CTMW
+ {
+ toInt(VehicleProperty::CROSS_TRAFFIC_MONITORING_ENABLED),
+ {
+ toInt(VehicleProperty::CROSS_TRAFFIC_MONITORING_WARNING_STATE),
+ },
+ },
+ // LSAEB
+ {
+ toInt(VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED),
+ {
+ toInt(VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE),
+ },
+ },
};
} // namespace
@@ -304,17 +367,18 @@
}
// OBD2_LIVE_FRAME and OBD2_FREEZE_FRAME must be configured in default configs.
- auto maybeObd2LiveFrame = mServerSidePropStore->getConfig(OBD2_LIVE_FRAME);
+ auto maybeObd2LiveFrame = mServerSidePropStore->getPropConfig(OBD2_LIVE_FRAME);
if (maybeObd2LiveFrame.has_value()) {
- mFakeObd2Frame->initObd2LiveFrame(*maybeObd2LiveFrame.value());
+ mFakeObd2Frame->initObd2LiveFrame(maybeObd2LiveFrame.value());
}
- auto maybeObd2FreezeFrame = mServerSidePropStore->getConfig(OBD2_FREEZE_FRAME);
+ auto maybeObd2FreezeFrame = mServerSidePropStore->getPropConfig(OBD2_FREEZE_FRAME);
if (maybeObd2FreezeFrame.has_value()) {
- mFakeObd2Frame->initObd2FreezeFrame(*maybeObd2FreezeFrame.value());
+ mFakeObd2Frame->initObd2FreezeFrame(maybeObd2FreezeFrame.value());
}
- mServerSidePropStore->setOnValueChangeCallback(
- [this](const VehiclePropValue& value) { return onValueChangeCallback(value); });
+ mServerSidePropStore->setOnValuesChangeCallback([this](std::vector<VehiclePropValue> values) {
+ return onValuesChangeCallback(std::move(values));
+ });
}
std::vector<VehiclePropConfig> FakeVehicleHardware::getAllPropertyConfigs() const {
@@ -434,7 +498,7 @@
int increment) {
requestedTemp = std::max(requestedTemp, minTemp);
requestedTemp = std::min(requestedTemp, maxTemp);
- int numIncrements = (requestedTemp - minTemp) / increment;
+ int numIncrements = std::round((requestedTemp - minTemp) / static_cast<float>(increment));
return numIncrements;
}
@@ -472,7 +536,7 @@
VhalResult<void> FakeVehicleHardware::setHvacTemperatureValueSuggestion(
const VehiclePropValue& hvacTemperatureValueSuggestion) {
auto hvacTemperatureSetConfigResult =
- mServerSidePropStore->getConfig(toInt(VehicleProperty::HVAC_TEMPERATURE_SET));
+ mServerSidePropStore->getPropConfig(toInt(VehicleProperty::HVAC_TEMPERATURE_SET));
if (!hvacTemperatureSetConfigResult.ok()) {
return StatusError(getErrorCode(hvacTemperatureSetConfigResult)) << StringPrintf(
@@ -499,7 +563,7 @@
}
auto updatedValue = mValuePool->obtain(hvacTemperatureValueSuggestion);
- const auto& hvacTemperatureSetConfigArray = hvacTemperatureSetConfigResult.value()->configArray;
+ const auto& hvacTemperatureSetConfigArray = hvacTemperatureSetConfigResult.value().configArray;
auto& hvacTemperatureValueSuggestionInput = updatedValue->value.floatValues;
updateHvacTemperatureValueSuggestionInput(hvacTemperatureSetConfigArray,
@@ -663,7 +727,7 @@
FakeVehicleHardware::ValueResultType FakeVehicleHardware::getUserHalProp(
const VehiclePropValue& value) const {
auto propId = value.prop;
- ALOGI("get(): getting value for prop %d from User HAL", propId);
+ ALOGI("get(): getting value for prop %s from User HAL", PROP_ID_TO_CSTR(propId));
auto result = mFakeUserHal->onGetProperty(value);
if (!result.ok()) {
@@ -822,14 +886,14 @@
void FakeVehicleHardware::sendAdasPropertiesState(int32_t propertyId, int32_t state) {
auto& adasDependentPropIds = mAdasEnabledPropToAdasPropWithErrorState.find(propertyId)->second;
for (auto dependentPropId : adasDependentPropIds) {
- auto dependentPropConfigResult = mServerSidePropStore->getConfig(dependentPropId);
+ auto dependentPropConfigResult = mServerSidePropStore->getPropConfig(dependentPropId);
if (!dependentPropConfigResult.ok()) {
ALOGW("Failed to get config for ADAS property 0x%x, error: %s", dependentPropId,
getErrorMsg(dependentPropConfigResult).c_str());
continue;
}
auto& dependentPropConfig = dependentPropConfigResult.value();
- for (auto& areaConfig : dependentPropConfig->areaConfigs) {
+ for (auto& areaConfig : dependentPropConfig.areaConfigs) {
int32_t hardcoded_state = state;
// TODO: restore old/initial values here instead of hardcoded value (b/295542701)
if (state == 1 && dependentPropId == toInt(VehicleProperty::CRUISE_CONTROL_TYPE)) {
@@ -1026,7 +1090,7 @@
const std::vector<SetValueRequest>& requests) {
for (auto& request : requests) {
if (FAKE_VEHICLEHARDWARE_DEBUG) {
- ALOGD("Set value for property ID: %d", request.value.prop);
+ ALOGD("Set value for property ID: %s", PROP_ID_TO_CSTR(request.value.prop));
}
// In a real VHAL implementation, you could either send the setValue request to vehicle bus
@@ -1047,9 +1111,9 @@
auto setSpecialValueResult = maybeSetSpecialValue(value, &isSpecialValue);
if (isSpecialValue) {
if (!setSpecialValueResult.ok()) {
- return StatusError(getErrorCode(setSpecialValueResult))
- << StringPrintf("failed to set special value for property ID: %d, error: %s",
- value.prop, getErrorMsg(setSpecialValueResult).c_str());
+ return StatusError(getErrorCode(setSpecialValueResult)) << StringPrintf(
+ "failed to set special value for property ID: %s, error: %s",
+ PROP_ID_TO_CSTR(value.prop), getErrorMsg(setSpecialValueResult).c_str());
}
return {};
}
@@ -1088,7 +1152,7 @@
const std::vector<GetValueRequest>& requests) const {
for (auto& request : requests) {
if (FAKE_VEHICLEHARDWARE_DEBUG) {
- ALOGD("getValues(%d)", request.prop.prop);
+ ALOGD("getValues(%s)", PROP_ID_TO_CSTR(request.prop.prop));
}
// In a real VHAL implementation, you could either send the getValue request to vehicle bus
@@ -1127,8 +1191,8 @@
if (isSpecialValue) {
if (!result.ok()) {
return StatusError(getErrorCode(result))
- << StringPrintf("failed to get special value: %d, error: %s", value.prop,
- getErrorMsg(result).c_str());
+ << StringPrintf("failed to get special value: %s, error: %s",
+ PROP_ID_TO_CSTR(value.prop), getErrorMsg(result).c_str());
} else {
return result;
}
@@ -1187,6 +1251,8 @@
mAddExtraTestVendorConfigs = false;
result.refreshPropertyConfigs = true;
result.buffer = "successfully restored vendor configs";
+ } else if (EqualsIgnoreCase(option, "--dumpSub")) {
+ result.buffer = dumpSubscriptions();
} else {
result.buffer = StringPrintf("Invalid option: %s\n", option.c_str());
}
@@ -1318,7 +1384,8 @@
if (mGeneratorHub->unregisterGenerator(propId)) {
return "Linear event generator stopped successfully";
}
- return StringPrintf("No linear event generator found for property: %d", propId);
+ return StringPrintf("No linear event generator found for property: %s",
+ PROP_ID_TO_CSTR(propId));
} else if (command == "--startjson") {
// --genfakedata --startjson --path path repetition
// or
@@ -1588,6 +1655,26 @@
mServerSidePropStore->writeValue(mValuePool->obtain(value));
}
+std::string FakeVehicleHardware::dumpSubscriptions() {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ std::string result = "Subscriptions: \n";
+ for (const auto& [interval, actionForInterval] : mActionByIntervalInNanos) {
+ for (const auto& propIdAreaId : actionForInterval.propIdAreaIdsToRefresh) {
+ const auto& refreshInfo = mRefreshInfoByPropIdAreaId[propIdAreaId];
+ bool vur = (refreshInfo.eventMode == VehiclePropertyStore::EventMode::ON_VALUE_CHANGE);
+ float sampleRateHz = 1'000'000'000. / refreshInfo.intervalInNanos;
+ result += StringPrintf("Continuous{property: %s, areaId: %d, rate: %lf hz, vur: %b}\n",
+ PROP_ID_TO_CSTR(propIdAreaId.propId), propIdAreaId.areaId,
+ sampleRateHz, vur);
+ }
+ }
+ for (const auto& propIdAreaId : mSubOnChangePropIdAreaIds) {
+ result += StringPrintf("OnChange{property: %s, areaId: %d}\n",
+ PROP_ID_TO_CSTR(propIdAreaId.propId), propIdAreaId.areaId);
+ }
+ return result;
+}
+
std::string FakeVehicleHardware::dumpHelp() {
return "Usage: \n\n"
"[no args]: dumps (id and value) all supported properties \n"
@@ -1655,8 +1742,9 @@
result = mServerSidePropStore->readValue(value);
}
if (!result.ok()) {
- return StringPrintf("failed to read property value: %d, error: %s, code: %d\n", propId,
- getErrorMsg(result).c_str(), getIntErrorCode(result));
+ return StringPrintf("failed to read property value: %s, error: %s, code: %d\n",
+ PROP_ID_TO_CSTR(propId), getErrorMsg(result).c_str(),
+ getIntErrorCode(result));
} else {
return result.value()->toString() + "\n";
@@ -1671,7 +1759,7 @@
int rowNumber = 1;
std::string msg = StringPrintf("listing %zu properties\n", configs.size());
for (const auto& config : configs) {
- msg += StringPrintf("%d: %d\n", rowNumber++, config.prop);
+ msg += StringPrintf("%d: %s\n", rowNumber++, PROP_ID_TO_CSTR(config.prop));
}
return msg;
}
@@ -1702,12 +1790,12 @@
continue;
}
int32_t prop = propResult.value();
- auto result = mServerSidePropStore->getConfig(prop);
+ auto result = mServerSidePropStore->getPropConfig(prop);
if (!result.ok()) {
- msg += StringPrintf("No property %d\n", prop);
+ msg += StringPrintf("No property %s\n", PROP_ID_TO_CSTR(prop));
continue;
}
- msg += dumpOnePropertyByConfig(rowNumber++, *result.value());
+ msg += dumpOnePropertyByConfig(rowNumber++, result.value());
}
return msg;
}
@@ -1890,8 +1978,9 @@
}
if (!result.ok()) {
- return StringPrintf("failed to read property value: %d, error: %s, code: %d\n", prop.prop,
- getErrorMsg(result).c_str(), getIntErrorCode(result));
+ return StringPrintf("failed to read property value: %s, error: %s, code: %d\n",
+ PROP_ID_TO_CSTR(prop.prop), getErrorMsg(result).c_str(),
+ getIntErrorCode(result));
}
return StringPrintf("Get property result: %s\n", result.value()->toString().c_str());
}
@@ -1984,7 +2073,7 @@
eventFromVehicleBus(prop);
- return StringPrintf("Event for property: %d injected", prop.prop);
+ return StringPrintf("Event for property: %s injected", PROP_ID_TO_CSTR(prop.prop));
}
StatusCode FakeVehicleHardware::checkHealth() {
@@ -2014,7 +2103,7 @@
StatusCode FakeVehicleHardware::subscribe(SubscribeOptions options) {
int32_t propId = options.propId;
- auto configResult = mServerSidePropStore->getConfig(propId);
+ auto configResult = mServerSidePropStore->getPropConfig(propId);
if (!configResult.ok()) {
ALOGE("subscribe: property: %" PRId32 " is not supported", propId);
return StatusCode::INVALID_ARG;
@@ -2024,7 +2113,7 @@
for (int areaId : options.areaIds) {
if (StatusCode status = subscribePropIdAreaIdLocked(propId, areaId, options.sampleRate,
options.enableVariableUpdateRate,
- *configResult.value());
+ configResult.value());
status != StatusCode::OK) {
return status;
}
@@ -2047,6 +2136,81 @@
return false;
}
+void FakeVehicleHardware::refreshTimestampForInterval(int64_t intervalInNanos) {
+ std::unordered_map<PropIdAreaId, VehiclePropertyStore::EventMode, PropIdAreaIdHash>
+ eventModeByPropIdAreaId;
+
+ {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+
+ if (mActionByIntervalInNanos.find(intervalInNanos) == mActionByIntervalInNanos.end()) {
+ ALOGE("No actions scheduled for the interval: %" PRId64 ", ignore the refresh request",
+ intervalInNanos);
+ return;
+ }
+
+ ActionForInterval actionForInterval = mActionByIntervalInNanos[intervalInNanos];
+
+ // Make a copy so that we don't hold the lock while trying to refresh the timestamp.
+ // Refreshing the timestamp will inovke onValueChangeCallback which also requires lock, so
+ // we must not hold lock.
+ for (const PropIdAreaId& propIdAreaId : actionForInterval.propIdAreaIdsToRefresh) {
+ const RefreshInfo& refreshInfo = mRefreshInfoByPropIdAreaId[propIdAreaId];
+ eventModeByPropIdAreaId[propIdAreaId] = refreshInfo.eventMode;
+ }
+ }
+
+ mServerSidePropStore->refreshTimestamps(eventModeByPropIdAreaId);
+}
+
+void FakeVehicleHardware::registerRefreshLocked(PropIdAreaId propIdAreaId,
+ VehiclePropertyStore::EventMode eventMode,
+ float sampleRateHz) {
+ if (mRefreshInfoByPropIdAreaId.find(propIdAreaId) != mRefreshInfoByPropIdAreaId.end()) {
+ unregisterRefreshLocked(propIdAreaId);
+ }
+
+ int64_t intervalInNanos = static_cast<int64_t>(1'000'000'000. / sampleRateHz);
+ RefreshInfo refreshInfo = {
+ .eventMode = eventMode,
+ .intervalInNanos = intervalInNanos,
+ };
+ mRefreshInfoByPropIdAreaId[propIdAreaId] = refreshInfo;
+
+ if (mActionByIntervalInNanos.find(intervalInNanos) != mActionByIntervalInNanos.end()) {
+ // If we have already registered for this interval, then add the action info to the
+ // actions list.
+ mActionByIntervalInNanos[intervalInNanos].propIdAreaIdsToRefresh.insert(propIdAreaId);
+ return;
+ }
+
+ // This is the first action for the interval, register a timer callback for that interval.
+ auto action = std::make_shared<RecurrentTimer::Callback>(
+ [this, intervalInNanos] { refreshTimestampForInterval(intervalInNanos); });
+ mActionByIntervalInNanos[intervalInNanos] = ActionForInterval{
+ .propIdAreaIdsToRefresh = {propIdAreaId},
+ .recurrentAction = action,
+ };
+ mRecurrentTimer->registerTimerCallback(intervalInNanos, action);
+}
+
+void FakeVehicleHardware::unregisterRefreshLocked(PropIdAreaId propIdAreaId) {
+ if (mRefreshInfoByPropIdAreaId.find(propIdAreaId) == mRefreshInfoByPropIdAreaId.end()) {
+ ALOGW("PropId: %" PRId32 ", areaId: %" PRId32 " was not registered for refresh, ignore",
+ propIdAreaId.propId, propIdAreaId.areaId);
+ return;
+ }
+
+ int64_t intervalInNanos = mRefreshInfoByPropIdAreaId[propIdAreaId].intervalInNanos;
+ auto& actionForInterval = mActionByIntervalInNanos[intervalInNanos];
+ actionForInterval.propIdAreaIdsToRefresh.erase(propIdAreaId);
+ if (actionForInterval.propIdAreaIdsToRefresh.empty()) {
+ mRecurrentTimer->unregisterTimerCallback(actionForInterval.recurrentAction);
+ mActionByIntervalInNanos.erase(intervalInNanos);
+ }
+ mRefreshInfoByPropIdAreaId.erase(propIdAreaId);
+}
+
StatusCode FakeVehicleHardware::subscribePropIdAreaIdLocked(
int32_t propId, int32_t areaId, float sampleRateHz, bool enableVariableUpdateRate,
const VehiclePropConfig& vehiclePropConfig) {
@@ -2064,13 +2228,8 @@
case VehiclePropertyChangeMode::CONTINUOUS:
if (sampleRateHz == 0.f) {
ALOGE("Must not use sample rate 0 for a continuous property");
- return StatusCode::INTERNAL_ERROR;
+ return StatusCode::INVALID_ARG;
}
- if (mRecurrentActions.find(propIdAreaId) != mRecurrentActions.end()) {
- mRecurrentTimer->unregisterTimerCallback(mRecurrentActions[propIdAreaId]);
- }
- int64_t intervalInNanos = static_cast<int64_t>(1'000'000'000. / sampleRateHz);
-
// For continuous properties, we must generate a new onPropertyChange event
// periodically according to the sample rate.
auto eventMode = VehiclePropertyStore::EventMode::ALWAYS;
@@ -2078,27 +2237,8 @@
enableVariableUpdateRate) {
eventMode = VehiclePropertyStore::EventMode::ON_VALUE_CHANGE;
}
- auto action = std::make_shared<RecurrentTimer::Callback>([this, propId, areaId,
- eventMode] {
- // Refresh the property value. In real implementation, this should poll the latest
- // value from vehicle bus. Here, we are just refreshing the existing value with a
- // new timestamp.
- auto result = getValue(VehiclePropValue{
- .areaId = areaId,
- .prop = propId,
- .value = {},
- });
- if (!result.ok()) {
- // Failed to read current value, skip refreshing.
- return;
- }
- mServerSidePropStore->writeValue(std::move(result.value()),
- /*updateStatus=*/true, eventMode,
- /*useCurrentTimestamp=*/true);
- });
- mRecurrentTimer->registerTimerCallback(intervalInNanos, action);
- mRecurrentActions[propIdAreaId] = action;
+ registerRefreshLocked(propIdAreaId, eventMode, sampleRateHz);
return StatusCode::OK;
}
}
@@ -2109,39 +2249,47 @@
.propId = propId,
.areaId = areaId,
};
- if (mRecurrentActions.find(propIdAreaId) != mRecurrentActions.end()) {
- mRecurrentTimer->unregisterTimerCallback(mRecurrentActions[propIdAreaId]);
- mRecurrentActions.erase(propIdAreaId);
+ if (mRefreshInfoByPropIdAreaId.find(propIdAreaId) != mRefreshInfoByPropIdAreaId.end()) {
+ unregisterRefreshLocked(propIdAreaId);
}
mSubOnChangePropIdAreaIds.erase(propIdAreaId);
return StatusCode::OK;
}
void FakeVehicleHardware::onValueChangeCallback(const VehiclePropValue& value) {
- if (mOnPropertyChangeCallback == nullptr) {
- return;
- }
+ ATRACE_CALL();
+ onValuesChangeCallback({value});
+}
- PropIdAreaId propIdAreaId{
- .propId = value.prop,
- .areaId = value.areaId,
- };
+void FakeVehicleHardware::onValuesChangeCallback(std::vector<VehiclePropValue> values) {
+ ATRACE_CALL();
+ std::vector<VehiclePropValue> subscribedUpdatedValues;
{
std::scoped_lock<std::mutex> lockGuard(mLock);
- if (mRecurrentActions.find(propIdAreaId) == mRecurrentActions.end() &&
- mSubOnChangePropIdAreaIds.find(propIdAreaId) == mSubOnChangePropIdAreaIds.end()) {
- if (FAKE_VEHICLEHARDWARE_DEBUG) {
- ALOGD("The updated property value: %s is not subscribed, ignore",
- value.toString().c_str());
- }
+ if (mOnPropertyChangeCallback == nullptr) {
return;
}
+
+ for (const auto& value : values) {
+ PropIdAreaId propIdAreaId{
+ .propId = value.prop,
+ .areaId = value.areaId,
+ };
+ if (mRefreshInfoByPropIdAreaId.find(propIdAreaId) == mRefreshInfoByPropIdAreaId.end() &&
+ mSubOnChangePropIdAreaIds.find(propIdAreaId) == mSubOnChangePropIdAreaIds.end()) {
+ if (FAKE_VEHICLEHARDWARE_DEBUG) {
+ ALOGD("The updated property value: %s is not subscribed, ignore",
+ value.toString().c_str());
+ }
+ continue;
+ }
+
+ subscribedUpdatedValues.push_back(value);
+ }
}
- std::vector<VehiclePropValue> updatedValues;
- updatedValues.push_back(value);
- (*mOnPropertyChangeCallback)(std::move(updatedValues));
+ (*mOnPropertyChangeCallback)(std::move(subscribedUpdatedValues));
}
void FakeVehicleHardware::loadPropConfigsFromDir(
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
index 3b6f717..90643aa 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
@@ -1593,6 +1593,116 @@
},
},
SetSpecialValueTestCase{
+ .name = "set_low_speed_collision_warning_enabled_false",
+ .valuesToSet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ LOW_SPEED_COLLISION_WARNING_ENABLED),
+ .value.int32Values = {0},
+ },
+ },
+ .expectedValuesToGet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ LOW_SPEED_COLLISION_WARNING_ENABLED),
+ .value.int32Values = {0},
+ },
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ LOW_SPEED_COLLISION_WARNING_STATE),
+ .value.int32Values = {toInt(
+ ErrorState::NOT_AVAILABLE_DISABLED)},
+ },
+ },
+ },
+ SetSpecialValueTestCase{
+ .name = "set_low_speed_collision_warning_enabled_true",
+ .valuesToSet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ LOW_SPEED_COLLISION_WARNING_ENABLED),
+ .value.int32Values = {1},
+ },
+ },
+ .expectedValuesToGet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ LOW_SPEED_COLLISION_WARNING_ENABLED),
+ .value.int32Values = {1},
+ },
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ LOW_SPEED_COLLISION_WARNING_STATE),
+ .value.int32Values = {1},
+ },
+ },
+ },
+ SetSpecialValueTestCase{
+ .name = "set_electronic_stability_control_enabled_false",
+ .valuesToSet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ ELECTRONIC_STABILITY_CONTROL_ENABLED),
+ .value.int32Values = {0},
+ },
+ },
+ .expectedValuesToGet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ ELECTRONIC_STABILITY_CONTROL_ENABLED),
+ .value.int32Values = {0},
+ },
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ ELECTRONIC_STABILITY_CONTROL_STATE),
+ .value.int32Values = {toInt(
+ ErrorState::NOT_AVAILABLE_DISABLED)},
+ },
+ },
+ },
+ SetSpecialValueTestCase{
+ .name = "set_electronic_stability_control_enabled_true",
+ .valuesToSet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ ELECTRONIC_STABILITY_CONTROL_ENABLED),
+ .value.int32Values = {1},
+ },
+ },
+ .expectedValuesToGet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ ELECTRONIC_STABILITY_CONTROL_ENABLED),
+ .value.int32Values = {1},
+ },
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ ELECTRONIC_STABILITY_CONTROL_STATE),
+ .value.int32Values = {1},
+ },
+ },
+ },
+ SetSpecialValueTestCase{
.name = "set_shutdown_request",
.valuesToSet =
{
@@ -2149,6 +2259,20 @@
toInt(VehicleProperty::HANDS_ON_DETECTION_WARNING),
},
},
+ // LSCW
+ {
+ toInt(VehicleProperty::LOW_SPEED_COLLISION_WARNING_ENABLED),
+ {
+ toInt(VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE),
+ },
+ },
+ // ESC
+ {
+ toInt(VehicleProperty::ELECTRONIC_STABILITY_CONTROL_ENABLED),
+ {
+ toInt(VehicleProperty::ELECTRONIC_STABILITY_CONTROL_STATE),
+ },
+ },
};
// First subscribe to all the properties that we will change.
@@ -2493,8 +2617,8 @@
DumpResult result = getHardware()->dump(options);
ASSERT_FALSE(result.callerShouldDumpState);
ASSERT_NE(result.buffer, "");
- ASSERT_THAT(result.buffer, ContainsRegex(StringPrintf("1:.*prop: %s.*\nNo property %d\n",
- prop1.c_str(), INVALID_PROP_ID)));
+ ASSERT_THAT(result.buffer, ContainsRegex(StringPrintf("1:.*prop: %s.*\nNo property INVALID\n",
+ prop1.c_str())));
}
TEST_F(FakeVehicleHardwareTest, testDumpSpecificPropertiesNoArg) {
@@ -2577,8 +2701,7 @@
{"--inject-event", propIdStr, "-i", "1234", "-t", std::to_string(timestamp)});
ASSERT_FALSE(result.callerShouldDumpState);
- ASSERT_THAT(result.buffer,
- ContainsRegex(StringPrintf("Event for property: %d injected", prop)));
+ ASSERT_THAT(result.buffer, ContainsRegex("Event for property: ENGINE_OIL_LEVEL injected"));
ASSERT_TRUE(waitForChangedProperties(prop, 0, /*count=*/1, milliseconds(1000)))
<< "No changed event received for injected event from vehicle bus";
auto events = getChangedProperties();
@@ -3320,6 +3443,14 @@
<< "must not receive on change events if the propId, areaId is unsubscribed";
}
+TEST_F(FakeVehicleHardwareTest, testSubscribeContinuous_rate0_mustReturnInvalidArg) {
+ int32_t propSpeed = toInt(VehicleProperty::PERF_VEHICLE_SPEED);
+ int32_t areaId = 0;
+ auto status = getHardware()->subscribe(newSubscribeOptions(propSpeed, areaId, 0));
+
+ ASSERT_EQ(status, StatusCode::INVALID_ARG);
+}
+
TEST_F(FakeVehicleHardwareTest, testSetHvacTemperatureValueSuggestion) {
float CELSIUS = static_cast<float>(toInt(VehicleUnit::CELSIUS));
float FAHRENHEIT = static_cast<float>(toInt(VehicleUnit::FAHRENHEIT));
diff --git a/automotive/vehicle/aidl/impl/grpc/Android.bp b/automotive/vehicle/aidl/impl/grpc/Android.bp
index 06c9600..e5106f8 100644
--- a/automotive/vehicle/aidl/impl/grpc/Android.bp
+++ b/automotive/vehicle/aidl/impl/grpc/Android.bp
@@ -22,9 +22,11 @@
"aprotoc",
"protoc-gen-grpc-cpp-plugin",
],
- cmd: "$(location aprotoc) -I$$(dirname $(in)) -Ihardware/interfaces/automotive/vehicle/aidl/impl/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)",
+ cmd: "$(location aprotoc) -I$$(dirname $(location proto/VehicleServer.proto)) -Ihardware/interfaces/automotive/vehicle/aidl/impl/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(location proto/VehicleServer.proto) --grpc_out=$(genDir) --cpp_out=$(genDir)",
srcs: [
"proto/VehicleServer.proto",
+ ":libprotobuf-internal-protos",
+ ":VehicleHalProtoFiles",
],
out: [
"VehicleServer.pb.h",
@@ -39,9 +41,11 @@
"aprotoc",
"protoc-gen-grpc-cpp-plugin",
],
- cmd: "$(location aprotoc) -I$$(dirname $(in)) -Ihardware/interfaces/automotive/vehicle/aidl/impl/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)",
+ cmd: "$(location aprotoc) -I$$(dirname $(location proto/VehicleServer.proto)) -Ihardware/interfaces/automotive/vehicle/aidl/impl/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(location proto/VehicleServer.proto) --grpc_out=$(genDir) --cpp_out=$(genDir)",
srcs: [
"proto/VehicleServer.proto",
+ ":libprotobuf-internal-protos",
+ ":VehicleHalProtoFiles",
],
out: [
"VehicleServer.pb.cc",
diff --git a/automotive/vehicle/aidl/impl/grpc/OWNERS b/automotive/vehicle/aidl/impl/grpc/OWNERS
deleted file mode 100644
index 7a96f23..0000000
--- a/automotive/vehicle/aidl/impl/grpc/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-shanyu@google.com
-chenhaosjtuacm@google.com
-egranata@google.com
diff --git a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp
index 491aa10..1ea0df4 100644
--- a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp
+++ b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp
@@ -67,6 +67,7 @@
for (auto& areaConfig : in.areaConfigs) {
auto* protoACfg = out->add_area_configs();
protoACfg->set_area_id(areaConfig.areaId);
+ protoACfg->set_access(static_cast<proto::VehiclePropertyAccess>(toInt(areaConfig.access)));
protoACfg->set_min_int64_value(areaConfig.minInt64Value);
protoACfg->set_max_int64_value(areaConfig.maxInt64Value);
protoACfg->set_min_float_value(areaConfig.minFloatValue);
@@ -95,6 +96,7 @@
auto cast_to_acfg = [](const proto::VehicleAreaConfig& protoAcfg) {
auto vehicleAreaConfig = aidl_vehicle::VehicleAreaConfig{
.areaId = protoAcfg.area_id(),
+ .access = static_cast<aidl_vehicle::VehiclePropertyAccess>(protoAcfg.access()),
.minInt32Value = protoAcfg.min_int32_value(),
.maxInt32Value = protoAcfg.max_int32_value(),
.minInt64Value = protoAcfg.min_int64_value(),
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehicleAreaConfig.proto b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehicleAreaConfig.proto
index 8093658..7ea8540 100644
--- a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehicleAreaConfig.proto
+++ b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehicleAreaConfig.proto
@@ -18,6 +18,8 @@
package android.hardware.automotive.vehicle.proto;
+import "android/hardware/automotive/vehicle/VehiclePropertyAccess.proto";
+
/* Must be in sync with VehicleAreaConfig.aidl. */
message VehicleAreaConfig {
/* Area id is ignored for VehiclePropertyGroup:GLOBAL properties. */
@@ -43,6 +45,6 @@
* assumed all @data_enum values are supported unless specified through another mechanism.
*/
repeated int64 supported_enum_values = 8;
- int32 access = 9;
+ VehiclePropertyAccess access = 9;
bool support_variable_update_rate = 10;
};
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h b/automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h
index cd2b727..712359a 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h
@@ -19,6 +19,8 @@
#include <android-base/thread_annotations.h>
+#include <utils/Looper.h>
+#include <atomic>
#include <memory>
#include <mutex>
#include <queue>
@@ -31,6 +33,9 @@
namespace automotive {
namespace vehicle {
+// Forward declaration
+class RecurrentMessageHandler;
+
// A thread-safe recurrent timer.
class RecurrentTimer final {
public:
@@ -43,49 +48,44 @@
// Registers a recurrent callback for a given interval.
// Registering the same callback twice will override the interval provided before.
- void registerTimerCallback(int64_t intervalInNano, std::shared_ptr<Callback> callback);
+ void registerTimerCallback(int64_t intervalInNanos, std::shared_ptr<Callback> callback);
// Unregisters a previously registered recurrent callback.
void unregisterTimerCallback(std::shared_ptr<Callback> callback);
private:
- // friend class for unit testing.
+ friend class RecurrentMessageHandler;
+
+ // For unit test
friend class RecurrentTimerTest;
struct CallbackInfo {
std::shared_ptr<Callback> callback;
- int64_t interval;
- int64_t nextTime;
- // A flag to indicate whether this CallbackInfo is already outdated and should be ignored.
- // The reason we need this flag is because we cannot easily remove an element from a heap.
- bool outdated = false;
-
- static bool cmp(const std::unique_ptr<CallbackInfo>& lhs,
- const std::unique_ptr<CallbackInfo>& rhs);
+ int64_t intervalInNanos;
+ int64_t nextTimeInNanos;
};
+ android::sp<Looper> mLooper;
+ android::sp<RecurrentMessageHandler> mHandler;
+
+ std::atomic<bool> mStopRequested = false;
+ std::atomic<int> mCallbackId = 0;
std::mutex mLock;
std::thread mThread;
- std::condition_variable mCond;
- bool mStopRequested GUARDED_BY(mLock) = false;
- // A map to map each callback to its current active CallbackInfo in the mCallbackQueue.
- std::unordered_map<std::shared_ptr<Callback>, CallbackInfo*> mCallbacks GUARDED_BY(mLock);
- // A min-heap sorted by nextTime. Note that because we cannot remove arbitrary element from the
- // heap, a single Callback can have multiple entries in this queue, all but one should be valid.
- // The rest should be mark as outdated. The valid one is one stored in mCallbacks.
- std::vector<std::unique_ptr<CallbackInfo>> mCallbackQueue GUARDED_BY(mLock);
+ std::unordered_map<std::shared_ptr<Callback>, int> mIdByCallback GUARDED_BY(mLock);
+ std::unordered_map<int, std::unique_ptr<CallbackInfo>> mCallbackInfoById GUARDED_BY(mLock);
- void loop();
+ void handleMessage(const android::Message& message) EXCLUDES(mLock);
+ int getCallbackIdLocked(std::shared_ptr<Callback> callback) REQUIRES(mLock);
+};
- // Mark the callbackInfo as outdated and should be ignored when popped from the heap.
- void markOutdatedLocked(CallbackInfo* callback) REQUIRES(mLock);
- // Remove all outdated callbackInfos from the top of the heap. This function must be called
- // each time we might introduce outdated elements to the top. We must make sure the heap is
- // always valid from the top.
- void removeInvalidCallbackLocked() REQUIRES(mLock);
- // Gets the next calblack to run (must be valid) from the heap, update its nextTime and put
- // it back to the heap.
- std::shared_ptr<Callback> getNextCallbackLocked(int64_t now) REQUIRES(mLock);
+class RecurrentMessageHandler final : public android::MessageHandler {
+ public:
+ RecurrentMessageHandler(RecurrentTimer* timer) { mTimer = timer; }
+ void handleMessage(const android::Message& message) override;
+
+ private:
+ RecurrentTimer* mTimer;
};
} // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
index e6d657d..1cd0d16 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
@@ -19,11 +19,18 @@
#include <aidl/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.h>
#include <aidl/android/hardware/automotive/vehicle/BlindSpotWarningState.h>
+#include <aidl/android/hardware/automotive/vehicle/CameraServiceState.h>
+#include <aidl/android/hardware/automotive/vehicle/CrossTrafficMonitoringWarningState.h>
#include <aidl/android/hardware/automotive/vehicle/CruiseControlCommand.h>
#include <aidl/android/hardware/automotive/vehicle/CruiseControlState.h>
#include <aidl/android/hardware/automotive/vehicle/CruiseControlType.h>
#include <aidl/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.h>
#include <aidl/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.h>
+#include <aidl/android/hardware/automotive/vehicle/DriverDistractionState.h>
+#include <aidl/android/hardware/automotive/vehicle/DriverDistractionWarning.h>
+#include <aidl/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.h>
+#include <aidl/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.h>
+#include <aidl/android/hardware/automotive/vehicle/ElectronicStabilityControlState.h>
#include <aidl/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.h>
#include <aidl/android/hardware/automotive/vehicle/ErrorState.h>
#include <aidl/android/hardware/automotive/vehicle/EvConnectorType.h>
@@ -38,11 +45,14 @@
#include <aidl/android/hardware/automotive/vehicle/GsrComplianceRequirementType.h>
#include <aidl/android/hardware/automotive/vehicle/HandsOnDetectionDriverState.h>
#include <aidl/android/hardware/automotive/vehicle/HandsOnDetectionWarning.h>
+#include <aidl/android/hardware/automotive/vehicle/ImpactSensorLocation.h>
#include <aidl/android/hardware/automotive/vehicle/LaneCenteringAssistCommand.h>
#include <aidl/android/hardware/automotive/vehicle/LaneCenteringAssistState.h>
#include <aidl/android/hardware/automotive/vehicle/LaneDepartureWarningState.h>
#include <aidl/android/hardware/automotive/vehicle/LaneKeepAssistState.h>
#include <aidl/android/hardware/automotive/vehicle/LocationCharacterization.h>
+#include <aidl/android/hardware/automotive/vehicle/LowSpeedAutomaticEmergencyBrakingState.h>
+#include <aidl/android/hardware/automotive/vehicle/LowSpeedCollisionWarningState.h>
#include <aidl/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.h>
#include <aidl/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.h>
#include <aidl/android/hardware/automotive/vehicle/Obd2FuelType.h>
@@ -55,6 +65,7 @@
#include <aidl/android/hardware/automotive/vehicle/SetValueResults.h>
#include <aidl/android/hardware/automotive/vehicle/StatusCode.h>
#include <aidl/android/hardware/automotive/vehicle/SubscribeOptions.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleAirbagLocation.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReport.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleArea.h>
@@ -63,6 +74,7 @@
#include <aidl/android/hardware/automotive/vehicle/VehicleAreaSeat.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleAreaWheel.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleAreaWindow.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleAutonomousState.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleGear.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleHvacFanDirection.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleIgnitionState.h>
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleObjectPool.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleObjectPool.h
index 6e812d1..501ce40 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleObjectPool.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehicleObjectPool.h
@@ -235,7 +235,7 @@
bool isDisposable(aidl::android::hardware::automotive::vehicle::VehiclePropertyType type,
size_t vectorSize) const {
- return vectorSize > mMaxRecyclableVectorSize || isComplexType(type);
+ return vectorSize == 0 || vectorSize > mMaxRecyclableVectorSize || isComplexType(type);
}
RecyclableType obtainDisposable(
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h b/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h
index 2812c3b..d9599ed 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h
@@ -48,21 +48,21 @@
enum class EventMode : uint8_t {
/**
- * Only invoke OnValueChangeCallback if the new property value (ignoring timestamp) is
- * different than the existing value.
+ * Only invoke OnValueChangeCallback or OnValuesChangeCallback if the new property value
+ * (ignoring timestamp) is different than the existing value.
*
* This should be used for regular cases.
*/
ON_VALUE_CHANGE,
/**
- * Always invoke OnValueChangeCallback.
+ * Always invoke OnValueChangeCallback or OnValuesChangeCallback.
*
* This should be used for the special properties that are used for delivering event, e.g.
* HW_KEY_INPUT.
*/
ALWAYS,
/**
- * Never invoke OnValueChangeCallback.
+ * Never invoke OnValueChangeCallback or OnValuesChangeCalblack.
*
* This should be used for continuous property subscription when the sample rate for the
* subscription is smaller than the refresh rate for the property. E.g., the vehicle speed
@@ -82,6 +82,10 @@
using OnValueChangeCallback = std::function<void(
const aidl::android::hardware::automotive::vehicle::VehiclePropValue&)>;
+ // Callback when one or more property values have been updated or new values added.
+ using OnValuesChangeCallback = std::function<void(
+ std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>)>;
+
// Function that used to calculate unique token for given VehiclePropValue.
using TokenFunction = std::function<int64_t(
const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value)>;
@@ -99,13 +103,24 @@
// 'status' would be initialized to {@code VehiclePropertyStatus::AVAILABLE}, if this is to
// override an existing value, the status for the existing value would be used for the
// overridden value.
- // 'EventMode' controls whether the 'OnValueChangeCallback' will be called for this operation.
+ // 'EventMode' controls whether the 'OnValueChangeCallback' or 'OnValuesChangeCallback' will be
+ // called for this operation.
// If 'useCurrentTimestamp' is true, the property value will be set to the current timestamp.
VhalResult<void> writeValue(VehiclePropValuePool::RecyclableType propValue,
bool updateStatus = false,
EventMode mode = EventMode::ON_VALUE_CHANGE,
bool useCurrentTimestamp = false) EXCLUDES(mLock);
+ // Refresh the timestamp for the stored property value for [propId, areaId]. If eventMode is
+ // always, generates the property update event, otherwise, only update the stored timestamp
+ // without generating event. This operation is atomic with other writeValue operations.
+ void refreshTimestamp(int32_t propId, int32_t areaId, EventMode eventMode) EXCLUDES(mLock);
+
+ // Refresh the timestamp for multiple [propId, areaId]s.
+ void refreshTimestamps(
+ std::unordered_map<PropIdAreaId, EventMode, PropIdAreaIdHash> eventModeByPropIdAreaId)
+ EXCLUDES(mLock);
+
// Remove a given property value from the property store. The 'propValue' would be used to
// generate the key for the value to remove.
void removeValue(
@@ -138,14 +153,27 @@
std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropConfig> getAllConfigs()
const EXCLUDES(mLock);
- // Get the property config for the requested property.
+ // Deprecated, use getPropConfig instead. This is unsafe to use if registerProperty overwrites
+ // an existing config.
android::base::Result<const aidl::android::hardware::automotive::vehicle::VehiclePropConfig*,
VhalError>
getConfig(int32_t propId) const EXCLUDES(mLock);
+ // Get the property config for the requested property.
+ android::base::Result<aidl::android::hardware::automotive::vehicle::VehiclePropConfig,
+ VhalError>
+ getPropConfig(int32_t propId) const EXCLUDES(mLock);
+
// Set a callback that would be called when a property value has been updated.
void setOnValueChangeCallback(const OnValueChangeCallback& callback) EXCLUDES(mLock);
+ // Set a callback that would be called when one or more property values have been updated.
+ // For backward compatibility, this is optional. If this is not set, then multiple property
+ // updates will be delivered through multiple OnValueChangeCallback instead.
+ // It is recommended to set this and batch the property update events for better performance.
+ // If this is set, then OnValueChangeCallback will not be used.
+ void setOnValuesChangeCallback(const OnValuesChangeCallback& callback) EXCLUDES(mLock);
+
inline std::shared_ptr<VehiclePropValuePool> getValuePool() { return mValuePool; }
private:
@@ -173,6 +201,7 @@
mutable std::mutex mLock;
std::unordered_map<int32_t, Record> mRecordsByPropId GUARDED_BY(mLock);
OnValueChangeCallback mOnValueChangeCallback GUARDED_BY(mLock);
+ OnValuesChangeCallback mOnValuesChangeCallback GUARDED_BY(mLock);
const Record* getRecordLocked(int32_t propId) const;
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h
index 546421e..523cac5 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h
@@ -124,7 +124,6 @@
break; // Valid, but nothing to do.
default:
ALOGE("createVehiclePropValue: unknown type: %d", toInt(type));
- val.reset(nullptr);
}
return val;
}
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp b/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp
index c6d3687..8dec695 100644
--- a/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp
@@ -17,6 +17,7 @@
#include "RecurrentTimer.h"
#include <utils/Log.h>
+#include <utils/Looper.h>
#include <utils/SystemClock.h>
#include <inttypes.h>
@@ -27,153 +28,119 @@
namespace automotive {
namespace vehicle {
+namespace {
+
using ::android::base::ScopedLockAssertion;
+constexpr int INVALID_ID = -1;
+
+} // namespace
+
RecurrentTimer::RecurrentTimer() {
- mThread = std::thread(&RecurrentTimer::loop, this);
+ mHandler = sp<RecurrentMessageHandler>::make(this);
+ mLooper = sp<Looper>::make(/*allowNonCallbacks=*/false);
+ mThread = std::thread([this] {
+ Looper::setForThread(mLooper);
+
+ while (!mStopRequested) {
+ mLooper->pollOnce(/*timeoutMillis=*/-1);
+ }
+ });
}
RecurrentTimer::~RecurrentTimer() {
- {
- std::scoped_lock<std::mutex> lockGuard(mLock);
- mStopRequested = true;
- }
- mCond.notify_one();
+ mStopRequested = true;
+ mLooper->removeMessages(mHandler);
+ mLooper->wake();
if (mThread.joinable()) {
mThread.join();
}
}
-void RecurrentTimer::registerTimerCallback(int64_t intervalInNano,
+int RecurrentTimer::getCallbackIdLocked(std::shared_ptr<RecurrentTimer::Callback> callback) {
+ const auto& it = mIdByCallback.find(callback);
+ if (it != mIdByCallback.end()) {
+ return it->second;
+ }
+ return INVALID_ID;
+}
+
+void RecurrentTimer::registerTimerCallback(int64_t intervalInNanos,
std::shared_ptr<RecurrentTimer::Callback> callback) {
{
std::scoped_lock<std::mutex> lockGuard(mLock);
+ int callbackId = getCallbackIdLocked(callback);
+
+ if (callbackId == INVALID_ID) {
+ callbackId = mCallbackId++;
+ mIdByCallback.insert({callback, callbackId});
+ } else {
+ ALOGI("Replacing an existing timer callback with a new interval, current: %" PRId64
+ " ns, new: %" PRId64 " ns",
+ mCallbackInfoById[callbackId]->intervalInNanos, intervalInNanos);
+ mLooper->removeMessages(mHandler, callbackId);
+ }
+
// Aligns the nextTime to multiply of interval.
- int64_t nextTime = ceil(uptimeNanos() / intervalInNano) * intervalInNano;
+ int64_t nextTimeInNanos = ceil(uptimeNanos() / intervalInNanos) * intervalInNanos;
std::unique_ptr<CallbackInfo> info = std::make_unique<CallbackInfo>();
info->callback = callback;
- info->interval = intervalInNano;
- info->nextTime = nextTime;
+ info->intervalInNanos = intervalInNanos;
+ info->nextTimeInNanos = nextTimeInNanos;
+ mCallbackInfoById.insert({callbackId, std::move(info)});
- auto it = mCallbacks.find(callback);
- if (it != mCallbacks.end()) {
- ALOGI("Replacing an existing timer callback with a new interval, current: %" PRId64
- " ns, new: %" PRId64 " ns",
- it->second->interval, intervalInNano);
- markOutdatedLocked(it->second);
- }
- mCallbacks[callback] = info.get();
- mCallbackQueue.push_back(std::move(info));
- // Insert the last element into the heap.
- std::push_heap(mCallbackQueue.begin(), mCallbackQueue.end(), CallbackInfo::cmp);
+ mLooper->sendMessageAtTime(nextTimeInNanos, mHandler, Message(callbackId));
}
- mCond.notify_one();
}
void RecurrentTimer::unregisterTimerCallback(std::shared_ptr<RecurrentTimer::Callback> callback) {
{
std::scoped_lock<std::mutex> lockGuard(mLock);
- auto it = mCallbacks.find(callback);
- if (it == mCallbacks.end()) {
+ int callbackId = getCallbackIdLocked(callback);
+
+ if (callbackId == INVALID_ID) {
ALOGE("No event found to unregister");
return;
}
- markOutdatedLocked(it->second);
- mCallbacks.erase(it);
- }
-
- mCond.notify_one();
-}
-
-void RecurrentTimer::markOutdatedLocked(RecurrentTimer::CallbackInfo* info) {
- info->outdated = true;
- info->callback = nullptr;
- // Make sure the first element is always valid.
- removeInvalidCallbackLocked();
-}
-
-void RecurrentTimer::removeInvalidCallbackLocked() {
- while (mCallbackQueue.size() != 0 && mCallbackQueue[0]->outdated) {
- std::pop_heap(mCallbackQueue.begin(), mCallbackQueue.end(), CallbackInfo::cmp);
- mCallbackQueue.pop_back();
+ mLooper->removeMessages(mHandler, callbackId);
+ mCallbackInfoById.erase(callbackId);
+ mIdByCallback.erase(callback);
}
}
-std::shared_ptr<RecurrentTimer::Callback> RecurrentTimer::getNextCallbackLocked(int64_t now) {
- std::pop_heap(mCallbackQueue.begin(), mCallbackQueue.end(), CallbackInfo::cmp);
- auto& callbackInfo = mCallbackQueue[mCallbackQueue.size() - 1];
- auto nextCallback = callbackInfo->callback;
- // intervalCount is the number of interval we have to advance until we pass now.
- size_t intervalCount = (now - callbackInfo->nextTime) / callbackInfo->interval + 1;
- callbackInfo->nextTime += intervalCount * callbackInfo->interval;
- std::push_heap(mCallbackQueue.begin(), mCallbackQueue.end(), CallbackInfo::cmp);
+void RecurrentTimer::handleMessage(const Message& message) {
+ std::shared_ptr<RecurrentTimer::Callback> callback;
+ {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
- // Make sure the first element is always valid.
- removeInvalidCallbackLocked();
+ int callbackId = message.what;
- return nextCallback;
-}
-
-void RecurrentTimer::loop() {
- std::vector<std::shared_ptr<Callback>> callbacksToRun;
- while (true) {
- {
- std::unique_lock<std::mutex> uniqueLock(mLock);
- ScopedLockAssertion lockAssertion(mLock);
- // Wait until the timer exits or we have at least one recurrent callback.
- mCond.wait(uniqueLock, [this] {
- ScopedLockAssertion lockAssertion(mLock);
- return mStopRequested || mCallbackQueue.size() != 0;
- });
-
- int64_t interval;
- if (mStopRequested) {
- return;
- }
- // The first element is the nearest next event.
- int64_t nextTime = mCallbackQueue[0]->nextTime;
- int64_t now = uptimeNanos();
-
- if (nextTime > now) {
- interval = nextTime - now;
- } else {
- interval = 0;
- }
-
- // Wait for the next event or the timer exits.
- if (mCond.wait_for(uniqueLock, std::chrono::nanoseconds(interval), [this] {
- ScopedLockAssertion lockAssertion(mLock);
- return mStopRequested;
- })) {
- return;
- }
-
- now = uptimeNanos();
- callbacksToRun.clear();
- while (mCallbackQueue.size() > 0) {
- int64_t nextTime = mCallbackQueue[0]->nextTime;
- if (nextTime > now) {
- break;
- }
-
- callbacksToRun.push_back(getNextCallbackLocked(now));
- }
+ auto it = mCallbackInfoById.find(callbackId);
+ if (it == mCallbackInfoById.end()) {
+ ALOGW("The event for callback ID: %d is outdated, ignore", callbackId);
+ return;
}
- // Do not execute the callback while holding the lock.
- for (size_t i = 0; i < callbacksToRun.size(); i++) {
- (*callbacksToRun[i])();
- }
+ CallbackInfo* callbackInfo = it->second.get();
+ callback = callbackInfo->callback;
+ int64_t nowNanos = uptimeNanos();
+ // intervalCount is the number of interval we have to advance until we pass now.
+ size_t intervalCount =
+ (nowNanos - callbackInfo->nextTimeInNanos) / callbackInfo->intervalInNanos + 1;
+ callbackInfo->nextTimeInNanos += intervalCount * callbackInfo->intervalInNanos;
+
+ mLooper->sendMessageAtTime(callbackInfo->nextTimeInNanos, mHandler, Message(callbackId));
}
+
+ (*callback)();
}
-bool RecurrentTimer::CallbackInfo::cmp(const std::unique_ptr<RecurrentTimer::CallbackInfo>& lhs,
- const std::unique_ptr<RecurrentTimer::CallbackInfo>& rhs) {
- return lhs->nextTime > rhs->nextTime;
+void RecurrentMessageHandler::handleMessage(const Message& message) {
+ mTimer->handleMessage(message);
}
} // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/VehicleObjectPool.cpp b/automotive/vehicle/aidl/impl/utils/common/src/VehicleObjectPool.cpp
index 2480a73..7e02767 100644
--- a/automotive/vehicle/aidl/impl/utils/common/src/VehicleObjectPool.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/src/VehicleObjectPool.cpp
@@ -55,13 +55,6 @@
int propId = src.prop;
VehiclePropertyType type = getPropType(propId);
size_t vectorSize = getVehicleRawValueVectorSize(src.value, type);
- if (vectorSize == 0 && !isComplexType(type)) {
- ALOGW("empty vehicle prop value, contains no content");
- ALOGW("empty vehicle prop value, contains no content, prop: %d", propId);
- // Return any empty VehiclePropValue.
- return RecyclableType{new VehiclePropValue{}, mDisposableDeleter};
- }
-
auto dest = obtain(type, vectorSize);
dest->prop = propId;
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp b/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
index b879850..6a2a695 100644
--- a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
@@ -113,6 +113,9 @@
bool valueUpdated = true;
VehiclePropValue updatedValue;
OnValueChangeCallback onValueChangeCallback = nullptr;
+ OnValuesChangeCallback onValuesChangeCallback = nullptr;
+ int32_t propId;
+ int32_t areaId;
{
std::scoped_lock<std::mutex> g(mLock);
@@ -122,7 +125,8 @@
propValue->timestamp = elapsedRealtimeNano();
}
- int32_t propId = propValue->prop;
+ propId = propValue->prop;
+ areaId = propValue->areaId;
VehiclePropertyStore::Record* record = getRecordLocked(propId);
if (record == nullptr) {
@@ -163,19 +167,99 @@
return {};
}
updatedValue = *(record->values[recId]);
- if (mOnValueChangeCallback == nullptr) {
- return {};
- }
+
+ onValuesChangeCallback = mOnValuesChangeCallback;
onValueChangeCallback = mOnValueChangeCallback;
}
+ if (onValuesChangeCallback == nullptr && onValueChangeCallback == nullptr) {
+ ALOGW("No callback registered, ignoring property update for propId: %" PRId32
+ ", area ID: %" PRId32,
+ propId, areaId);
+ return {};
+ }
+
// Invoke the callback outside the lock to prevent dead-lock.
if (eventMode == EventMode::ALWAYS || valueUpdated) {
- onValueChangeCallback(updatedValue);
+ if (onValuesChangeCallback != nullptr) {
+ onValuesChangeCallback({updatedValue});
+ } else {
+ onValueChangeCallback(updatedValue);
+ }
}
return {};
}
+void VehiclePropertyStore::refreshTimestamp(int32_t propId, int32_t areaId, EventMode eventMode) {
+ std::unordered_map<PropIdAreaId, EventMode, PropIdAreaIdHash> eventModeByPropIdAreaId;
+ PropIdAreaId propIdAreaId = {
+ .propId = propId,
+ .areaId = areaId,
+ };
+ eventModeByPropIdAreaId[propIdAreaId] = eventMode;
+ refreshTimestamps(eventModeByPropIdAreaId);
+}
+
+void VehiclePropertyStore::refreshTimestamps(
+ std::unordered_map<PropIdAreaId, EventMode, PropIdAreaIdHash> eventModeByPropIdAreaId) {
+ std::vector<VehiclePropValue> updatedValues;
+ OnValuesChangeCallback onValuesChangeCallback = nullptr;
+ OnValueChangeCallback onValueChangeCallback = nullptr;
+ {
+ std::scoped_lock<std::mutex> g(mLock);
+
+ onValuesChangeCallback = mOnValuesChangeCallback;
+ onValueChangeCallback = mOnValueChangeCallback;
+
+ for (const auto& [propIdAreaId, eventMode] : eventModeByPropIdAreaId) {
+ int32_t propId = propIdAreaId.propId;
+ int32_t areaId = propIdAreaId.areaId;
+ VehiclePropertyStore::Record* record = getRecordLocked(propId);
+ if (record == nullptr) {
+ continue;
+ }
+
+ VehiclePropValue propValue = {
+ .areaId = areaId,
+ .prop = propId,
+ .value = {},
+ };
+
+ VehiclePropertyStore::RecordId recId = getRecordIdLocked(propValue, *record);
+ if (auto it = record->values.find(recId); it != record->values.end()) {
+ it->second->timestamp = elapsedRealtimeNano();
+ if (eventMode == EventMode::ALWAYS) {
+ updatedValues.push_back(*(it->second));
+ }
+ } else {
+ continue;
+ }
+ }
+ }
+
+ // Invoke the callback outside the lock to prevent dead-lock.
+ if (updatedValues.empty()) {
+ return;
+ }
+ if (!onValuesChangeCallback && !onValueChangeCallback) {
+ // If no callback is set, then we don't have to do anything.
+ for (const auto& updateValue : updatedValues) {
+ ALOGW("No callback registered, ignoring property update for propId: %" PRId32
+ ", area ID: %" PRId32,
+ updateValue.prop, updateValue.areaId);
+ }
+ return;
+ }
+ if (onValuesChangeCallback != nullptr) {
+ onValuesChangeCallback(updatedValues);
+ } else {
+ // Fallback to use multiple onValueChangeCallback
+ for (const auto& updateValue : updatedValues) {
+ onValueChangeCallback(updateValue);
+ }
+ }
+}
+
void VehiclePropertyStore::removeValue(const VehiclePropValue& propValue) {
std::scoped_lock<std::mutex> g(mLock);
@@ -282,6 +366,17 @@
return &record->propConfig;
}
+VhalResult<VehiclePropConfig> VehiclePropertyStore::getPropConfig(int32_t propId) const {
+ std::scoped_lock<std::mutex> g(mLock);
+
+ const VehiclePropertyStore::Record* record = getRecordLocked(propId);
+ if (record == nullptr) {
+ return StatusError(StatusCode::INVALID_ARG) << "property: " << propId << " not registered";
+ }
+
+ return record->propConfig;
+}
+
void VehiclePropertyStore::setOnValueChangeCallback(
const VehiclePropertyStore::OnValueChangeCallback& callback) {
std::scoped_lock<std::mutex> g(mLock);
@@ -289,6 +384,13 @@
mOnValueChangeCallback = callback;
}
+void VehiclePropertyStore::setOnValuesChangeCallback(
+ const VehiclePropertyStore::OnValuesChangeCallback& callback) {
+ std::scoped_lock<std::mutex> g(mLock);
+
+ mOnValuesChangeCallback = callback;
+}
+
} // namespace vehicle
} // namespace automotive
} // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp b/automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp
index 62046f3..e8ac2a5 100644
--- a/automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp
@@ -60,9 +60,14 @@
mCallbacks.clear();
}
- size_t countTimerCallbackQueue(RecurrentTimer* timer) {
+ size_t countCallbackInfoById(RecurrentTimer* timer) {
std::scoped_lock<std::mutex> lockGuard(timer->mLock);
- return timer->mCallbackQueue.size();
+ return timer->mCallbackInfoById.size();
+ }
+
+ size_t countIdByCallback(RecurrentTimer* timer) {
+ std::scoped_lock<std::mutex> lockGuard(timer->mLock);
+ return timer->mIdByCallback.size();
}
private:
@@ -109,6 +114,9 @@
<< "Not enough callbacks called before timeout";
timer.unregisterTimerCallback(action);
+
+ ASSERT_EQ(countCallbackInfoById(&timer), 0u);
+ ASSERT_EQ(countIdByCallback(&timer), 0u);
}
TEST_F(RecurrentTimerTest, testDestroyTimerWithCallback) {
@@ -198,8 +206,8 @@
timer.unregisterTimerCallback(action);
- // Make sure there is no item in the callback queue.
- ASSERT_EQ(countTimerCallbackQueue(&timer), static_cast<size_t>(0));
+ ASSERT_EQ(countCallbackInfoById(&timer), 0u);
+ ASSERT_EQ(countIdByCallback(&timer), 0u);
}
TEST_F(RecurrentTimerTest, testRegisterCallbackMultipleTimesNoDeadLock) {
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/VehicleObjectPoolTest.cpp b/automotive/vehicle/aidl/impl/utils/common/test/VehicleObjectPoolTest.cpp
index a62532c..6226e89 100644
--- a/automotive/vehicle/aidl/impl/utils/common/test/VehicleObjectPoolTest.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/test/VehicleObjectPoolTest.cpp
@@ -267,6 +267,20 @@
ASSERT_EQ(*gotValue, prop);
}
+TEST_F(VehicleObjectPoolTest, testObtainCopyInt32ValuesEmptyArray) {
+ VehiclePropValue prop{
+ // INT32_VEC property.
+ .prop = toInt(VehicleProperty::INFO_FUEL_TYPE),
+ .areaId = 2,
+ .timestamp = 3,
+ .value = {.int32Values = {}},
+ };
+ auto gotValue = mValuePool->obtain(prop);
+
+ ASSERT_NE(gotValue, nullptr);
+ ASSERT_EQ(*gotValue, prop);
+}
+
TEST_F(VehicleObjectPoolTest, testObtainCopyInt64Values) {
VehiclePropValue prop{
// INT64_VEC property.
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp b/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
index 625652e..6646b7e 100644
--- a/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
@@ -20,6 +20,7 @@
#include <VehicleUtils.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
+#include <utils/SystemClock.h>
namespace android {
namespace hardware {
@@ -101,16 +102,16 @@
ASSERT_EQ(configs.size(), static_cast<size_t>(2));
}
-TEST_F(VehiclePropertyStoreTest, testGetConfig) {
- VhalResult<const VehiclePropConfig*> result =
- mStore->getConfig(toInt(VehicleProperty::INFO_FUEL_CAPACITY));
+TEST_F(VehiclePropertyStoreTest, testGetPropConfig) {
+ VhalResult<VehiclePropConfig> result =
+ mStore->getPropConfig(toInt(VehicleProperty::INFO_FUEL_CAPACITY));
ASSERT_RESULT_OK(result);
- ASSERT_EQ(*(result.value()), mConfigFuelCapacity);
+ ASSERT_EQ(result.value(), mConfigFuelCapacity);
}
-TEST_F(VehiclePropertyStoreTest, testGetConfigWithInvalidPropId) {
- VhalResult<const VehiclePropConfig*> result = mStore->getConfig(INVALID_PROP_ID);
+TEST_F(VehiclePropertyStoreTest, testGetPropConfigWithInvalidPropId) {
+ VhalResult<VehiclePropConfig> result = mStore->getPropConfig(INVALID_PROP_ID);
EXPECT_FALSE(result.ok()) << "expect error when getting a config for an invalid property ID";
EXPECT_EQ(result.error().code(), StatusCode::INVALID_ARG);
@@ -527,6 +528,133 @@
ASSERT_EQ(configs.size(), static_cast<size_t>(2));
}
+TEST_F(VehiclePropertyStoreTest, testOnValuesChangeCallback) {
+ std::vector<VehiclePropValue> updatedValues;
+ VehiclePropValue fuelCapacity = {
+ .prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
+ .value = {.floatValues = {1.0}},
+ };
+ ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity)));
+
+ mStore->setOnValuesChangeCallback(
+ [&updatedValues](std::vector<VehiclePropValue> values) { updatedValues = values; });
+
+ fuelCapacity.value.floatValues[0] = 2.0;
+ fuelCapacity.timestamp = 1;
+
+ ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity)));
+
+ ASSERT_THAT(updatedValues, ElementsAre(fuelCapacity));
+}
+
+TEST_F(VehiclePropertyStoreTest, testRefreshTimestamp) {
+ std::vector<VehiclePropValue> updatedValues;
+ mStore->setOnValuesChangeCallback(
+ [&updatedValues](std::vector<VehiclePropValue> values) { updatedValues = values; });
+
+ int64_t now = elapsedRealtimeNano();
+ int propId = toInt(VehicleProperty::TIRE_PRESSURE);
+ int areaId = WHEEL_FRONT_LEFT;
+ VehiclePropValue tirePressure = {
+ .prop = propId,
+ .areaId = areaId,
+ .value = {.floatValues = {1.0}},
+ };
+ ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(tirePressure)));
+ updatedValues.clear();
+
+ mStore->refreshTimestamp(propId, areaId, VehiclePropertyStore::EventMode::ALWAYS);
+
+ ASSERT_EQ(updatedValues.size(), 1u);
+ ASSERT_EQ(updatedValues[0].prop, propId);
+ ASSERT_EQ(updatedValues[0].areaId, areaId);
+ ASSERT_EQ(updatedValues[0].value.floatValues[0], 1.0);
+ int64_t timestamp = updatedValues[0].timestamp;
+ ASSERT_GE(timestamp, now);
+
+ auto result = mStore->readValue(tirePressure);
+
+ ASSERT_RESULT_OK(result);
+ ASSERT_EQ((result.value())->timestamp, timestamp);
+}
+
+TEST_F(VehiclePropertyStoreTest, testRefreshTimestamp_eventModeOnValueChange) {
+ std::vector<VehiclePropValue> updatedValues;
+ mStore->setOnValuesChangeCallback(
+ [&updatedValues](std::vector<VehiclePropValue> values) { updatedValues = values; });
+
+ int64_t now = elapsedRealtimeNano();
+ int propId = toInt(VehicleProperty::TIRE_PRESSURE);
+ int areaId = WHEEL_FRONT_LEFT;
+ VehiclePropValue tirePressure = {
+ .prop = propId,
+ .areaId = areaId,
+ .value = {.floatValues = {1.0}},
+ };
+ ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(tirePressure)));
+ updatedValues.clear();
+
+ mStore->refreshTimestamp(propId, areaId, VehiclePropertyStore::EventMode::ON_VALUE_CHANGE);
+
+ ASSERT_EQ(updatedValues.size(), 0u)
+ << "Must generate no property update events if only the timestamp is refreshed";
+
+ auto result = mStore->readValue(tirePressure);
+
+ ASSERT_RESULT_OK(result);
+ ASSERT_GE((result.value())->timestamp, now)
+ << "Even though event mode is on value change, the store timestamp must be updated";
+}
+
+TEST_F(VehiclePropertyStoreTest, testRefreshTimestamps) {
+ std::vector<VehiclePropValue> updatedValues;
+ mStore->setOnValuesChangeCallback(
+ [&updatedValues](std::vector<VehiclePropValue> values) { updatedValues = values; });
+
+ int64_t now = elapsedRealtimeNano();
+ int propId1 = toInt(VehicleProperty::INFO_FUEL_CAPACITY);
+ int areaId1 = 0;
+ VehiclePropValue fuelCapacity = {
+ .prop = propId1,
+ .areaId = areaId1,
+ .value = {.floatValues = {1.0}},
+ };
+ ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity)));
+
+ int propId2 = toInt(VehicleProperty::TIRE_PRESSURE);
+ int areaId2 = WHEEL_FRONT_LEFT;
+ VehiclePropValue tirePressure = {
+ .prop = propId2,
+ .areaId = areaId2,
+ .value = {.floatValues = {2.0}},
+ };
+ ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(tirePressure)));
+ updatedValues.clear();
+
+ std::unordered_map<PropIdAreaId, VehiclePropertyStore::EventMode, PropIdAreaIdHash>
+ eventModeByPropIdAreaId;
+ eventModeByPropIdAreaId[PropIdAreaId{
+ .propId = propId1,
+ .areaId = areaId1,
+ }] = VehiclePropertyStore::EventMode::ALWAYS;
+ eventModeByPropIdAreaId[PropIdAreaId{
+ .propId = propId2,
+ .areaId = areaId2,
+ }] = VehiclePropertyStore::EventMode::ALWAYS;
+
+ mStore->refreshTimestamps(eventModeByPropIdAreaId);
+
+ ASSERT_EQ(updatedValues.size(), 2u);
+ ASSERT_EQ(updatedValues[0].prop, propId1);
+ ASSERT_EQ(updatedValues[0].areaId, areaId1);
+ ASSERT_EQ(updatedValues[0].value.floatValues[0], 1.0);
+ ASSERT_GE(updatedValues[0].timestamp, now);
+ ASSERT_EQ(updatedValues[1].prop, propId2);
+ ASSERT_EQ(updatedValues[1].areaId, areaId2);
+ ASSERT_EQ(updatedValues[1].value.floatValues[0], 2.0);
+ ASSERT_GE(updatedValues[1].timestamp, now);
+}
+
} // namespace vehicle
} // namespace automotive
} // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/vhal/Android.bp b/automotive/vehicle/aidl/impl/vhal/Android.bp
index c29345f..aa30f80 100644
--- a/automotive/vehicle/aidl/impl/vhal/Android.bp
+++ b/automotive/vehicle/aidl/impl/vhal/Android.bp
@@ -55,12 +55,17 @@
"src/ConnectedClient.cpp",
"src/DefaultVehicleHal.cpp",
"src/SubscriptionManager.cpp",
+ // A target to check whether the file
+ // android.hardware.automotive.vehicle-types-meta.json needs update.
+ // The output is just an empty cpp file and not actually used.
+ ":check_generated_enum_metadata_json",
],
static_libs: [
"VehicleHalUtils",
],
header_libs: [
"IVehicleHardware",
+ "IVehicleGeneratedHeaders",
],
shared_libs: [
"libbinder_ndk",
diff --git a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
index f7a71b4..250b30c 100644
--- a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
+++ b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
@@ -49,6 +49,9 @@
explicit DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware);
+ // Test-only
+ DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware, int32_t testInterfaceVersion);
+
~DefaultVehicleHal();
ndk::ScopedAStatus getAllPropConfigs(
@@ -153,6 +156,8 @@
mPropertyChangeEventsBatchingConsumer;
// Only set once during initialization.
std::chrono::nanoseconds mEventBatchingWindow;
+ // Only used for testing.
+ int32_t mTestInterfaceVersion = 0;
std::mutex mLock;
std::unordered_map<const AIBinder*, std::unique_ptr<OnBinderDiedContext>> mOnBinderDiedContexts
@@ -227,6 +232,8 @@
std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&&
batchedEvents);
+ int32_t getVhalInterfaceVersion();
+
// Puts the property change events into a queue so that they can handled in batch.
static void batchPropertyChangeEvent(
const std::weak_ptr<ConcurrentQueue<
diff --git a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
index 847f3b8..cc5edcc 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
@@ -22,6 +22,7 @@
#include <LargeParcelableBase.h>
#include <VehicleHalTypes.h>
#include <VehicleUtils.h>
+#include <VersionForVehicleProperty.h>
#include <android-base/result.h>
#include <android-base/stringprintf.h>
@@ -61,6 +62,7 @@
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyChangeMode;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
+using ::aidl::android::hardware::automotive::vehicle::VersionForVehicleProperty;
using ::android::automotive::car_binder_lib::LargeParcelableBase;
using ::android::base::Error;
using ::android::base::expected;
@@ -94,8 +96,13 @@
} // namespace
DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> vehicleHardware)
+ : DefaultVehicleHal(std::move(vehicleHardware), /* testInterfaceVersion= */ 0){};
+
+DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> vehicleHardware,
+ int32_t testInterfaceVersion)
: mVehicleHardware(std::move(vehicleHardware)),
- mPendingRequestPool(std::make_shared<PendingRequestPool>(TIMEOUT_IN_NANO)) {
+ mPendingRequestPool(std::make_shared<PendingRequestPool>(TIMEOUT_IN_NANO)),
+ mTestInterfaceVersion(testInterfaceVersion) {
if (!getAllPropConfigsFromHardware()) {
return;
}
@@ -194,6 +201,7 @@
void DefaultVehicleHal::onPropertyChangeEvent(
const std::weak_ptr<SubscriptionManager>& subscriptionManager,
std::vector<VehiclePropValue>&& updatedValues) {
+ ATRACE_CALL();
auto manager = subscriptionManager.lock();
if (manager == nullptr) {
ALOGW("the SubscriptionManager is destroyed, DefaultVehicleHal is ending");
@@ -311,13 +319,46 @@
mPendingRequestPool = std::make_unique<PendingRequestPool>(timeoutInNano);
}
+int32_t DefaultVehicleHal::getVhalInterfaceVersion() {
+ if (mTestInterfaceVersion != 0) {
+ return mTestInterfaceVersion;
+ }
+ int32_t myVersion = 0;
+ getInterfaceVersion(&myVersion);
+ return myVersion;
+}
+
bool DefaultVehicleHal::getAllPropConfigsFromHardware() {
auto configs = mVehicleHardware->getAllPropertyConfigs();
+ std::vector<VehiclePropConfig> filteredConfigs;
+ int32_t myVersion = getVhalInterfaceVersion();
for (auto& config : configs) {
+ if (!isSystemProp(config.prop)) {
+ filteredConfigs.push_back(std::move(config));
+ continue;
+ }
+ VehicleProperty property = static_cast<VehicleProperty>(config.prop);
+ std::string propertyName = aidl::android::hardware::automotive::vehicle::toString(property);
+ auto it = VersionForVehicleProperty.find(property);
+ if (it == VersionForVehicleProperty.end()) {
+ ALOGE("The property: %s is not a supported system property, ignore",
+ propertyName.c_str());
+ continue;
+ }
+ int requiredVersion = it->second;
+ if (myVersion < requiredVersion) {
+ ALOGE("The property: %s is not supported for current client VHAL version, "
+ "require %d, current version: %d, ignore",
+ propertyName.c_str(), requiredVersion, myVersion);
+ continue;
+ }
+ filteredConfigs.push_back(std::move(config));
+ }
+ for (auto& config : filteredConfigs) {
mConfigsByPropId[config.prop] = config;
}
VehiclePropConfigs vehiclePropConfigs;
- vehiclePropConfigs.payloads = std::move(configs);
+ vehiclePropConfigs.payloads = std::move(filteredConfigs);
auto result = LargeParcelableBase::parcelableToStableLargeParcelable(vehiclePropConfigs);
if (!result.ok()) {
ALOGE("failed to convert configs to shared memory file, error: %s, code: %d",
@@ -412,9 +453,9 @@
.status = getErrorCode(result),
.prop = {},
});
- } else {
- hardwareRequests.push_back(request);
+ continue;
}
+ hardwareRequests.push_back(request);
}
// The set of request Ids that we would send to hardware.
@@ -815,6 +856,7 @@
if (!result.ok()) {
return StatusError(StatusCode::INVALID_ARG) << getErrorMsg(result);
}
+
const VehiclePropConfig* config = result.value();
const VehicleAreaConfig* areaConfig = getAreaConfig(value, *config);
@@ -899,6 +941,7 @@
dprintf(fd, "Vehicle HAL State: \n");
{
std::scoped_lock<std::mutex> lockGuard(mLock);
+ dprintf(fd, "Interface version: %" PRId32 "\n", getVhalInterfaceVersion());
dprintf(fd, "Containing %zu property configs\n", mConfigsByPropId.size());
dprintf(fd, "Currently have %zu getValues clients\n", mGetValuesClients.size());
dprintf(fd, "Currently have %zu setValues clients\n", mSetValuesClients.size());
diff --git a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
index 63964ef..bb82108 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
@@ -59,6 +59,7 @@
using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
using ::aidl::android::hardware::automotive::vehicle::StatusCode;
using ::aidl::android::hardware::automotive::vehicle::SubscribeOptions;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaWindow;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfigs;
@@ -78,36 +79,37 @@
using ::ndk::SpAIBinder;
using ::testing::ContainsRegex;
+using ::testing::ElementsAre;
using ::testing::Eq;
using ::testing::UnorderedElementsAre;
using ::testing::UnorderedElementsAreArray;
using ::testing::WhenSortedBy;
constexpr int32_t INVALID_PROP_ID = 0;
-// VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
-constexpr int32_t INT32_WINDOW_PROP = 10001 + 0x10000000 + 0x03000000 + 0x00400000;
-// VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-constexpr int32_t GLOBAL_ON_CHANGE_PROP = 10002 + 0x10000000 + 0x01000000 + 0x00400000;
-// VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-constexpr int32_t GLOBAL_CONTINUOUS_PROP = 10003 + 0x10000000 + 0x01000000 + 0x00400000;
-// VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
-constexpr int32_t AREA_ON_CHANGE_PROP = 10004 + 0x10000000 + 0x03000000 + 0x00400000;
-// VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
-constexpr int32_t AREA_CONTINUOUS_PROP = 10005 + 0x10000000 + 0x03000000 + 0x00400000;
-// VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-constexpr int32_t READ_ONLY_PROP = 10006 + 0x10000000 + 0x01000000 + 0x00400000;
-// VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-constexpr int32_t WRITE_ONLY_PROP = 10007 + 0x10000000 + 0x01000000 + 0x00400000;
-// VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-constexpr int32_t GLOBAL_CONTINUOUS_PROP_NO_VUR = 10008 + 0x10000000 + 0x01000000 + 0x00400000;
-// VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-constexpr int32_t GLOBAL_NONE_ACCESS_PROP = 10009 + 0x10000000 + 0x01000000 + 0x00400000;
-// VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
-constexpr int32_t AREA_NONE_ACCESS_PROP = 10010 + 0x10000000 + 0x03000000 + 0x00400000;
+// VehiclePropertyGroup:VENDOR,VehicleArea:WINDOW,VehiclePropertyType:INT32
+constexpr int32_t INT32_WINDOW_PROP = 10001 + 0x20000000 + 0x03000000 + 0x00400000;
+// VehiclePropertyGroup:VENDOR,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+constexpr int32_t GLOBAL_ON_CHANGE_PROP = 10002 + 0x20000000 + 0x01000000 + 0x00400000;
+// VehiclePropertyGroup:VENDOR,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+constexpr int32_t GLOBAL_CONTINUOUS_PROP = 10003 + 0x20000000 + 0x01000000 + 0x00400000;
+// VehiclePropertyGroup:VENDOR,VehicleArea:WINDOW,VehiclePropertyType:INT32
+constexpr int32_t AREA_ON_CHANGE_PROP = 10004 + 0x20000000 + 0x03000000 + 0x00400000;
+// VehiclePropertyGroup:VENDOR,VehicleArea:WINDOW,VehiclePropertyType:INT32
+constexpr int32_t AREA_CONTINUOUS_PROP = 10005 + 0x20000000 + 0x03000000 + 0x00400000;
+// VehiclePropertyGroup:VENDOR,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+constexpr int32_t READ_ONLY_PROP = 10006 + 0x20000000 + 0x01000000 + 0x00400000;
+// VehiclePropertyGroup:VENDOR,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+constexpr int32_t WRITE_ONLY_PROP = 10007 + 0x20000000 + 0x01000000 + 0x00400000;
+// VehiclePropertyGroup:VENDOR,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+constexpr int32_t GLOBAL_CONTINUOUS_PROP_NO_VUR = 10008 + 0x20000000 + 0x01000000 + 0x00400000;
+// VehiclePropertyGroup:VENDOR,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+constexpr int32_t GLOBAL_NONE_ACCESS_PROP = 10009 + 0x20000000 + 0x01000000 + 0x00400000;
+// VehiclePropertyGroup:VENDOR,VehicleArea:WINDOW,VehiclePropertyType:INT32
+constexpr int32_t AREA_NONE_ACCESS_PROP = 10010 + 0x20000000 + 0x03000000 + 0x00400000;
int32_t testInt32VecProp(size_t i) {
- // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
- return static_cast<int32_t>(i) + 0x10000000 + 0x01000000 + 0x00410000;
+ // VehiclePropertyGroup:VENDOR,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+ return static_cast<int32_t>(i) + 0x20000000 + 0x01000000 + 0x00410000;
}
std::string toString(const std::vector<SubscribeOptions>& options) {
@@ -555,10 +557,10 @@
TEST_F(DefaultVehicleHalTest, testGetAllPropConfigsSmall) {
auto testConfigs = std::vector<VehiclePropConfig>({
VehiclePropConfig{
- .prop = 1,
+ .prop = testInt32VecProp(1),
},
VehiclePropConfig{
- .prop = 2,
+ .prop = testInt32VecProp(2),
},
});
@@ -579,7 +581,7 @@
// 5000 VehiclePropConfig exceeds 4k memory limit, so it would be sent through shared memory.
for (size_t i = 0; i < 5000; i++) {
testConfigs.push_back(VehiclePropConfig{
- .prop = static_cast<int32_t>(i),
+ .prop = testInt32VecProp(i),
});
}
@@ -599,13 +601,42 @@
ASSERT_EQ(result.value().getObject()->payloads, testConfigs);
}
+TEST_F(DefaultVehicleHalTest, testGetAllPropConfigsFilterOutUnsupportedPropIdsForThisVersion) {
+ auto testConfigs = std::vector<VehiclePropConfig>({
+ // This is supported from V2.
+ VehiclePropConfig{
+ .prop = toInt(VehicleProperty::PERF_VEHICLE_SPEED),
+ },
+ // This is supported from V3
+ VehiclePropConfig{
+ .prop = toInt(VehicleProperty::ULTRASONICS_SENSOR_POSITION),
+ },
+ });
+
+ auto hardware = std::make_unique<MockVehicleHardware>();
+ hardware->setPropertyConfigs(testConfigs);
+ auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware),
+ /* testInterfaceVersion= */ 2);
+ std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+
+ VehiclePropConfigs output;
+ auto status = client->getAllPropConfigs(&output);
+
+ ASSERT_TRUE(status.isOk()) << "getAllPropConfigs failed: " << status.getMessage();
+ ASSERT_THAT(output.payloads, ElementsAre(VehiclePropConfig{
+ .prop = toInt(VehicleProperty::PERF_VEHICLE_SPEED),
+ }));
+}
+
TEST_F(DefaultVehicleHalTest, testGetPropConfigs) {
+ int32_t propId1 = testInt32VecProp(1);
+ int32_t propId2 = testInt32VecProp(2);
auto testConfigs = std::vector<VehiclePropConfig>({
VehiclePropConfig{
- .prop = 1,
+ .prop = propId1,
},
VehiclePropConfig{
- .prop = 2,
+ .prop = propId2,
},
});
@@ -615,7 +646,7 @@
std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
VehiclePropConfigs output;
- auto status = client->getPropConfigs(std::vector<int32_t>({1, 2}), &output);
+ auto status = client->getPropConfigs(std::vector<int32_t>({propId1, propId2}), &output);
ASSERT_TRUE(status.isOk()) << "getPropConfigs failed: " << status.getMessage();
ASSERT_EQ(output.payloads, testConfigs);
@@ -624,10 +655,10 @@
TEST_F(DefaultVehicleHalTest, testGetPropConfigsInvalidArg) {
auto testConfigs = std::vector<VehiclePropConfig>({
VehiclePropConfig{
- .prop = 1,
+ .prop = testInt32VecProp(1),
},
VehiclePropConfig{
- .prop = 2,
+ .prop = testInt32VecProp(2),
},
});
@@ -637,7 +668,9 @@
std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
VehiclePropConfigs output;
- auto status = client->getPropConfigs(std::vector<int32_t>({1, 2, 3}), &output);
+ auto status = client->getPropConfigs(
+ std::vector<int32_t>({testInt32VecProp(1), testInt32VecProp(2), testInt32VecProp(3)}),
+ &output);
ASSERT_FALSE(status.isOk()) << "getPropConfigs must fail with invalid prop ID";
ASSERT_EQ(status.getServiceSpecificError(), toInt(StatusCode::INVALID_ARG));
diff --git a/automotive/vehicle/aidl/impl/vhal/vhal-default-service.xml b/automotive/vehicle/aidl/impl/vhal/vhal-default-service.xml
index 9834cdb..b0c6ae7 100644
--- a/automotive/vehicle/aidl/impl/vhal/vhal-default-service.xml
+++ b/automotive/vehicle/aidl/impl/vhal/vhal-default-service.xml
@@ -1,7 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.automotive.vehicle</name>
- <version>2</version>
+ <version>3</version>
<fqname>IVehicle/default</fqname>
</hal>
</manifest>
diff --git a/automotive/vehicle/aidl/rust_impl/README.md b/automotive/vehicle/aidl/rust_impl/README.md
new file mode 100644
index 0000000..33f996b
--- /dev/null
+++ b/automotive/vehicle/aidl/rust_impl/README.md
@@ -0,0 +1,12 @@
+# Rust Skeleton VHAL implementation.
+
+WARNING: This is not a reference VHAL implementation and does not contain
+any actual implementation.
+
+This folder contains a skeleton VHAL implementation in Rust to demonstrate
+how vendor may implement a Rust VHAL. To run this VHAL, include
+`android.hardware.automotive.vehicle-V3-rust-service` in your image.
+
+This implementation returns `StatusCode::UNKNOWN_ERROR` for all operations
+and does not pass VTS/CTS. Vendor must replace the logic in
+`default_vehicle_hal.rs` with the actual implementation.
diff --git a/automotive/vehicle/aidl/rust_impl/vhal/Android.bp b/automotive/vehicle/aidl/rust_impl/vhal/Android.bp
new file mode 100644
index 0000000..46f37d8
--- /dev/null
+++ b/automotive/vehicle/aidl/rust_impl/vhal/Android.bp
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+rust_binary {
+ name: "android.hardware.automotive.vehicle-V3-rust-service",
+ relative_install_path: "hw",
+ vendor: true,
+ srcs: ["src/*.rs"],
+ crate_root: "src/main.rs",
+ defaults: ["VehicleHalInterfaceRustDefaults"],
+ vintf_fragments: ["vhal-rust-service.xml"],
+ init_rc: ["vhal-rust-service.rc"],
+ rustlibs: [
+ "libbinder_rs",
+ ],
+}
diff --git a/automotive/vehicle/aidl/rust_impl/vhal/src/default_vehicle_hal.rs b/automotive/vehicle/aidl/rust_impl/vhal/src/default_vehicle_hal.rs
new file mode 100644
index 0000000..1f5dc95
--- /dev/null
+++ b/automotive/vehicle/aidl/rust_impl/vhal/src/default_vehicle_hal.rs
@@ -0,0 +1,55 @@
+use android_hardware_automotive_vehicle::aidl::android::hardware::automotive::vehicle::{
+ IVehicle::IVehicle,
+ IVehicleCallback::IVehicleCallback,
+ VehiclePropConfigs::VehiclePropConfigs,
+ GetValueRequests::GetValueRequests,
+ SetValueRequests::SetValueRequests,
+ SubscribeOptions::SubscribeOptions,
+};
+use binder::{Interface, Result as BinderResult, StatusCode, Strong};
+
+/// This struct is defined to implement IVehicle AIDL interface.
+pub struct DefaultVehicleHal;
+
+impl Interface for DefaultVehicleHal {}
+
+impl IVehicle for DefaultVehicleHal {
+ fn getAllPropConfigs(&self) -> BinderResult<VehiclePropConfigs> {
+ Err(StatusCode::UNKNOWN_ERROR.into())
+ }
+
+ fn getPropConfigs(&self, _props: &[i32]) -> BinderResult<VehiclePropConfigs> {
+ Err(StatusCode::UNKNOWN_ERROR.into())
+ }
+
+ fn getValues(
+ &self, _callback: &Strong<dyn IVehicleCallback>, _requests: &GetValueRequests
+ ) -> BinderResult<()> {
+ Err(StatusCode::UNKNOWN_ERROR.into())
+ }
+
+ fn setValues(
+ &self, _callback: &Strong<dyn IVehicleCallback>, _requests: &SetValueRequests
+ ) -> BinderResult<()> {
+ Err(StatusCode::UNKNOWN_ERROR.into())
+ }
+
+ fn subscribe(
+ &self, _callback: &Strong<dyn IVehicleCallback>, _options: &[SubscribeOptions],
+ _max_shared_memory_file_count: i32
+ ) -> BinderResult<()> {
+ Err(StatusCode::UNKNOWN_ERROR.into())
+ }
+
+ fn unsubscribe(
+ &self, _callback: &Strong<dyn IVehicleCallback>, _prop_ids: &[i32]
+ ) -> BinderResult<()> {
+ Err(StatusCode::UNKNOWN_ERROR.into())
+ }
+
+ fn returnSharedMemory(
+ &self, _callback: &Strong<dyn IVehicleCallback>, _shared_memory_id: i64
+ ) -> BinderResult<()> {
+ Err(StatusCode::UNKNOWN_ERROR.into())
+ }
+}
diff --git a/automotive/vehicle/aidl/rust_impl/vhal/src/main.rs b/automotive/vehicle/aidl/rust_impl/vhal/src/main.rs
new file mode 100644
index 0000000..59b248d
--- /dev/null
+++ b/automotive/vehicle/aidl/rust_impl/vhal/src/main.rs
@@ -0,0 +1,18 @@
+mod default_vehicle_hal;
+
+use android_hardware_automotive_vehicle::aidl::android::hardware::automotive::vehicle::IVehicle::BnVehicle;
+use crate::default_vehicle_hal::DefaultVehicleHal;
+
+fn main() {
+ binder::ProcessState::start_thread_pool();
+ let my_service = DefaultVehicleHal;
+ let service_name = "android.hardware.automotive.vehicle.IVehicle/default";
+ let my_service_binder = BnVehicle::new_binder(
+ my_service,
+ binder::BinderFeatures::default(),
+ );
+ binder::add_service(service_name, my_service_binder.as_binder())
+ .expect(format!("Failed to register {}?", service_name).as_str());
+ // Does not return.
+ binder::ProcessState::join_thread_pool()
+}
diff --git a/automotive/vehicle/aidl/rust_impl/vhal/vhal-rust-service.rc b/automotive/vehicle/aidl/rust_impl/vhal/vhal-rust-service.rc
new file mode 100644
index 0000000..dff9894
--- /dev/null
+++ b/automotive/vehicle/aidl/rust_impl/vhal/vhal-rust-service.rc
@@ -0,0 +1,4 @@
+service vendor.vehicle-hal-default /vendor/bin/hw/android.hardware.automotive.vehicle-V3-rust-service
+ class early_hal
+ user vehicle_network
+ group system inet
diff --git a/automotive/vehicle/aidl/rust_impl/vhal/vhal-rust-service.xml b/automotive/vehicle/aidl/rust_impl/vhal/vhal-rust-service.xml
new file mode 100644
index 0000000..b0c6ae7
--- /dev/null
+++ b/automotive/vehicle/aidl/rust_impl/vhal/vhal-rust-service.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.automotive.vehicle</name>
+ <version>3</version>
+ <fqname>IVehicle/default</fqname>
+ </hal>
+</manifest>
diff --git a/automotive/vehicle/aidl_property/Android.bp b/automotive/vehicle/aidl_property/Android.bp
index db96382..5db39d8 100644
--- a/automotive/vehicle/aidl_property/Android.bp
+++ b/automotive/vehicle/aidl_property/Android.bp
@@ -42,6 +42,9 @@
"com.android.car.framework",
],
},
+ rust: {
+ enabled: true,
+ },
},
versions_with_info: [
{
@@ -53,5 +56,11 @@
imports: [],
},
],
+}
+filegroup {
+ name: "android.hardware.automotive.vehicle.property-files",
+ srcs: [
+ "android/hardware/automotive/vehicle/*.aidl",
+ ],
}
diff --git a/automotive/vehicle/aidl_property/OWNERS b/automotive/vehicle/aidl_property/OWNERS
deleted file mode 100644
index 73e45ca..0000000
--- a/automotive/vehicle/aidl_property/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-tylertrephan@google.com
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CameraServiceState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CameraServiceState.aidl
new file mode 100644
index 0000000..84f5ec7
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CameraServiceState.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum CameraServiceState {
+ UNAVAILABLE = 0,
+ INACTIVE = 1,
+ REQUESTED = 2,
+ ACTIVE = 3,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CrossTrafficMonitoringWarningState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CrossTrafficMonitoringWarningState.aidl
new file mode 100644
index 0000000..90e2d8d
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CrossTrafficMonitoringWarningState.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum CrossTrafficMonitoringWarningState {
+ OTHER = 0,
+ NO_WARNING = 1,
+ WARNING_FRONT_LEFT = 2,
+ WARNING_FRONT_RIGHT = 3,
+ WARNING_FRONT_BOTH = 4,
+ WARNING_REAR_LEFT = 5,
+ WARNING_REAR_RIGHT = 6,
+ WARNING_REAR_BOTH = 7,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDistractionState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDistractionState.aidl
new file mode 100644
index 0000000..54c02d5
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDistractionState.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum DriverDistractionState {
+ OTHER = 0,
+ NOT_DISTRACTED = 1,
+ DISTRACTED = 2,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDistractionWarning.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDistractionWarning.aidl
new file mode 100644
index 0000000..9236b1c
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDistractionWarning.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum DriverDistractionWarning {
+ OTHER = 0,
+ NO_WARNING = 1,
+ WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.aidl
new file mode 100644
index 0000000..22a90f3
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum DriverDrowsinessAttentionState {
+ OTHER = 0,
+ KSS_RATING_1_EXTREMELY_ALERT = 1,
+ KSS_RATING_2_VERY_ALERT = 2,
+ KSS_RATING_3_ALERT = 3,
+ KSS_RATING_4_RATHER_ALERT = 4,
+ KSS_RATING_5_NEITHER_ALERT_NOR_SLEEPY = 5,
+ KSS_RATING_6_SOME_SLEEPINESS = 6,
+ KSS_RATING_7_SLEEPY_NO_EFFORT = 7,
+ KSS_RATING_8_SLEEPY_SOME_EFFORT = 8,
+ KSS_RATING_9_VERY_SLEEPY = 9,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.aidl
new file mode 100644
index 0000000..dbf2364
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum DriverDrowsinessAttentionWarning {
+ OTHER = 0,
+ NO_WARNING = 1,
+ WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ElectronicStabilityControlState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ElectronicStabilityControlState.aidl
new file mode 100644
index 0000000..b061a25
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ElectronicStabilityControlState.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum ElectronicStabilityControlState {
+ OTHER = 0,
+ ENABLED = 1,
+ ACTIVATED = 2,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ImpactSensorLocation.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ImpactSensorLocation.aidl
new file mode 100644
index 0000000..6b75d8c
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ImpactSensorLocation.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum ImpactSensorLocation {
+ OTHER = 0x01,
+ FRONT = 0x02,
+ FRONT_LEFT_DOOR_SIDE = 0x04,
+ FRONT_RIGHT_DOOR_SIDE = 0x08,
+ REAR_LEFT_DOOR_SIDE = 0x10,
+ REAR_RIGHT_DOOR_SIDE = 0x20,
+ REAR = 0x40,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LowSpeedAutomaticEmergencyBrakingState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LowSpeedAutomaticEmergencyBrakingState.aidl
new file mode 100644
index 0000000..70014e1
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LowSpeedAutomaticEmergencyBrakingState.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum LowSpeedAutomaticEmergencyBrakingState {
+ OTHER = 0,
+ ENABLED = 1,
+ ACTIVATED = 2,
+ USER_OVERRIDE = 3,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LowSpeedCollisionWarningState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LowSpeedCollisionWarningState.aidl
new file mode 100644
index 0000000..6f6338b
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LowSpeedCollisionWarningState.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum LowSpeedCollisionWarningState {
+ OTHER = 0,
+ NO_WARNING = 1,
+ WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAirbagLocation.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAirbagLocation.aidl
new file mode 100644
index 0000000..9b966d7
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAirbagLocation.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleAirbagLocation {
+ OTHER = 0x01,
+ FRONT = 0x02,
+ KNEE = 0x04,
+ LEFT_SIDE = 0x08,
+ RIGHT_SIDE = 0x10,
+ CURTAIN = 0x20,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.aidl
index 9720aca..55af2ab 100644
--- a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.aidl
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.aidl
@@ -37,4 +37,5 @@
USER_POWER_ON = 0,
SYSTEM_USER_DETECTION = 1,
SYSTEM_REMOTE_ACCESS = 2,
+ SYSTEM_ENTER_GARAGE_MODE = 3,
}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
index 3fde1c7..8b345b2 100644
--- a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
@@ -40,4 +40,5 @@
SLEEP_IMMEDIATELY = 4,
HIBERNATE_IMMEDIATELY = 5,
CAN_HIBERNATE = 6,
+ EMERGENCY_SHUTDOWN = 7,
}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleArea.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleArea.aidl
index db867f4..b63003a 100644
--- a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleArea.aidl
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleArea.aidl
@@ -40,5 +40,6 @@
SEAT = 0x05000000,
DOOR = 0x06000000,
WHEEL = 0x07000000,
+ VENDOR = 0x08000000,
MASK = 0x0f000000,
}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAutonomousState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAutonomousState.aidl
new file mode 100644
index 0000000..e15e71e
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAutonomousState.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleAutonomousState {
+ LEVEL_0 = 0,
+ LEVEL_1 = 1,
+ LEVEL_2 = 2,
+ LEVEL_3 = 3,
+ LEVEL_4 = 4,
+ LEVEL_5 = 5,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
index 231186f..be8d3ac 100644
--- a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -66,9 +66,11 @@
EV_CHARGE_PORT_CONNECTED = (((0x030B + 0x10000000) + 0x01000000) + 0x00200000) /* 287310603 */,
EV_BATTERY_INSTANTANEOUS_CHARGE_RATE = (((0x030C + 0x10000000) + 0x01000000) + 0x00600000) /* 291504908 */,
RANGE_REMAINING = (((0x0308 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504904 */,
+ EV_BATTERY_AVERAGE_TEMPERATURE = (((0x030E + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.FLOAT) /* 291504910 */,
TIRE_PRESSURE = (((0x0309 + 0x10000000) + 0x07000000) + 0x00600000) /* 392168201 */,
CRITICALLY_LOW_TIRE_PRESSURE = (((0x030A + 0x10000000) + 0x07000000) + 0x00600000) /* 392168202 */,
ENGINE_IDLE_AUTO_STOP_ENABLED = (((0x0320 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287310624 */,
+ IMPACT_DETECTED = (((0x0330 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289407792 */,
GEAR_SELECTION = (((0x0400 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408000 */,
CURRENT_GEAR = (((0x0401 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408001 */,
PARKING_BRAKE_ON = (((0x0402 + 0x10000000) + 0x01000000) + 0x00200000) /* 287310850 */,
@@ -81,6 +83,8 @@
ABS_ACTIVE = (((0x040A + 0x10000000) + 0x01000000) + 0x00200000) /* 287310858 */,
TRACTION_CONTROL_ACTIVE = (((0x040B + 0x10000000) + 0x01000000) + 0x00200000) /* 287310859 */,
EV_STOPPING_MODE = (((0x040D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289408013 */,
+ ELECTRONIC_STABILITY_CONTROL_ENABLED = (((0x040E + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287310862 */,
+ ELECTRONIC_STABILITY_CONTROL_STATE = (((0x040F + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289408015 */,
HVAC_FAN_SPEED = (((0x0500 + 0x10000000) + 0x05000000) + 0x00400000) /* 356517120 */,
HVAC_FAN_DIRECTION = (((0x0501 + 0x10000000) + 0x05000000) + 0x00400000) /* 356517121 */,
HVAC_TEMPERATURE_CURRENT = (((0x0502 + 0x10000000) + 0x05000000) + 0x00600000) /* 358614274 */,
@@ -118,6 +122,8 @@
AP_POWER_BOOTUP_REASON = (((0x0A02 + 0x10000000) + 0x01000000) + 0x00400000) /* 289409538 */,
DISPLAY_BRIGHTNESS = (((0x0A03 + 0x10000000) + 0x01000000) + 0x00400000) /* 289409539 */,
PER_DISPLAY_BRIGHTNESS = (((0x0A04 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475076 */,
+ VALET_MODE_ENABLED = (((0x0A05 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287312389 */,
+ HEAD_UP_DISPLAY_ENABLED = (((0x0A06 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 354421254 */,
HW_KEY_INPUT = (((0x0A10 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475088 */,
HW_KEY_INPUT_V2 = (((0x0A11 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.MIXED) /* 367004177 */,
HW_MOTION_INPUT = (((0x0A12 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.MIXED) /* 367004178 */,
@@ -167,11 +173,13 @@
SEAT_FOOTWELL_LIGHTS_SWITCH = (((0x0B9C + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518812 */,
SEAT_EASY_ACCESS_ENABLED = (((0x0B9D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 354421661 */,
SEAT_AIRBAG_ENABLED = (((0x0B9E + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 354421662 */,
+ SEAT_AIRBAGS_DEPLOYED = (((0x0BA5 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518821 */,
SEAT_CUSHION_SIDE_SUPPORT_POS = (((0x0B9F + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518815 */,
SEAT_CUSHION_SIDE_SUPPORT_MOVE = (((0x0BA0 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518816 */,
SEAT_LUMBAR_VERTICAL_POS = (((0x0BA1 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518817 */,
SEAT_LUMBAR_VERTICAL_MOVE = (((0x0BA2 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518818 */,
SEAT_WALK_IN_POS = (((0x0BA3 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518819 */,
+ SEAT_BELT_PRETENSIONER_DEPLOYED = (((0x0BA6 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 354421670 */,
SEAT_OCCUPANCY = (((0x0BB0 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518832 */,
WINDOW_POS = (((0x0BC0 + 0x10000000) + 0x03000000) + 0x00400000) /* 322964416 */,
WINDOW_MOVE = (((0x0BC1 + 0x10000000) + 0x03000000) + 0x00400000) /* 322964417 */,
@@ -190,6 +198,12 @@
GLOVE_BOX_LOCKED = (((0x0BF1 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 354421745 */,
VEHICLE_MAP_SERVICE = (((0x0C00 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299895808 */,
LOCATION_CHARACTERIZATION = (((0x0C10 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410064 */,
+ ULTRASONICS_SENSOR_POSITION = (((0x0C20 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.VENDOR) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32_VEC) /* 406916128 */,
+ ULTRASONICS_SENSOR_ORIENTATION = (((0x0C21 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.VENDOR) + android.hardware.automotive.vehicle.VehiclePropertyType.FLOAT_VEC) /* 409013281 */,
+ ULTRASONICS_SENSOR_FIELD_OF_VIEW = (((0x0C22 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.VENDOR) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32_VEC) /* 406916130 */,
+ ULTRASONICS_SENSOR_DETECTION_RANGE = (((0x0C23 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.VENDOR) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32_VEC) /* 406916131 */,
+ ULTRASONICS_SENSOR_SUPPORTED_RANGES = (((0x0C24 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.VENDOR) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32_VEC) /* 406916132 */,
+ ULTRASONICS_SENSOR_MEASURED_DISTANCE = (((0x0C25 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.VENDOR) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32_VEC) /* 406916133 */,
OBD2_LIVE_FRAME = (((0x0D00 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896064 */,
OBD2_FREEZE_FRAME = (((0x0D01 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896065 */,
OBD2_FREEZE_FRAME_INFO = (((0x0D02 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896066 */,
@@ -246,6 +260,8 @@
SHUTDOWN_REQUEST = (((0x0F49 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410889 */,
VEHICLE_IN_USE = (((0x0F4A + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313738 */,
CLUSTER_HEARTBEAT = (((0x0F4B + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.MIXED) /* 299896651 */,
+ VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL = (((0x0F4C + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410892 */,
+ CAMERA_SERVICE_CURRENT_STATE = (((0x0F4D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32_VEC) /* 289476429 */,
AUTOMATIC_EMERGENCY_BRAKING_ENABLED = (((0x1000 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313920 */,
AUTOMATIC_EMERGENCY_BRAKING_STATE = (((0x1001 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411073 */,
FORWARD_COLLISION_WARNING_ENABLED = (((0x1002 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313922 */,
@@ -271,4 +287,18 @@
HANDS_ON_DETECTION_ENABLED = (((0x1016 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313942 */,
HANDS_ON_DETECTION_DRIVER_STATE = (((0x1017 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411095 */,
HANDS_ON_DETECTION_WARNING = (((0x1018 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411096 */,
+ DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED = (((0x1019 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313945 */,
+ DRIVER_DROWSINESS_ATTENTION_STATE = (((0x101A + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411098 */,
+ DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED = (((0x101B + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313947 */,
+ DRIVER_DROWSINESS_ATTENTION_WARNING = (((0x101C + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411100 */,
+ DRIVER_DISTRACTION_SYSTEM_ENABLED = (((0x101D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313949 */,
+ DRIVER_DISTRACTION_STATE = (((0x101E + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411102 */,
+ DRIVER_DISTRACTION_WARNING_ENABLED = (((0x101F + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313951 */,
+ DRIVER_DISTRACTION_WARNING = (((0x1020 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411104 */,
+ LOW_SPEED_COLLISION_WARNING_ENABLED = (((0x1021 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313953 */,
+ LOW_SPEED_COLLISION_WARNING_STATE = (((0x1022 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411106 */,
+ CROSS_TRAFFIC_MONITORING_ENABLED = (((0x1023 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313955 */,
+ CROSS_TRAFFIC_MONITORING_WARNING_STATE = (((0x1024 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411108 */,
+ LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED = (((0x1025 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313957 */,
+ LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE = (((0x1026 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411110 */,
}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CameraServiceState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CameraServiceState.aidl
new file mode 100644
index 0000000..0e01913
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CameraServiceState.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.hardware.automotive.vehicle;
+
+/**
+ * Used by CAMERA_SERVICE_CURRENT_STATE to describe current state of CarEvsService types.
+ *
+ * This is consistent with CarEvsManager.SERVICE_STATE_* constants.
+ */
+@VintfStability
+@Backing(type="int")
+enum CameraServiceState {
+ /**
+ * State that a corresponding service type is not available.
+ */
+ UNAVAILABLE = 0,
+
+ /**
+ * State that a corresponding service type is inactive; it's available but not used
+ * by any clients yet.
+ */
+ INACTIVE = 1,
+
+ /**
+ * State that CarEvsService requested launching a registered activity; the service is waiting
+ * for a video request from it.
+ */
+ REQUESTED = 2,
+
+ /**
+ * State that a corresponding service type is actively being used.
+ */
+ ACTIVE = 3,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CrossTrafficMonitoringWarningState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CrossTrafficMonitoringWarningState.aidl
new file mode 100644
index 0000000..05be65d
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CrossTrafficMonitoringWarningState.aidl
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the state of Cross Traffic Monitoring Warning system.
+ */
+@VintfStability
+@Backing(type="int")
+enum CrossTrafficMonitoringWarningState {
+
+ /**
+ * This state is used as an alternative to any CrossTrafficMonitoringWarningState value that is
+ * not defined in the platform. Ideally, implementations of
+ * VehicleProperty#CROSS_TRAFFIC_MONITORING_WARNING_STATE should not use this state. The
+ * framework can use this field to remain backwards compatible if
+ * CrossTrafficMonitoringWarningState is extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * Cross Traffic Monitoring Warning is enabled and monitoring safety, but no potential collision
+ * is detected.
+ */
+ NO_WARNING = 1,
+ /**
+ * Cross Traffic Monitoring Warning is enabled and is actively warning the user of incoming
+ * moving objects coming from the driver's left side in front of the vehicle.
+ */
+ WARNING_FRONT_LEFT = 2,
+ /**
+ * Cross Traffic Monitoring Warning is enabled and is actively warning the user of incoming
+ * moving objects coming from the driver's right side in front of the vehicle.
+ */
+ WARNING_FRONT_RIGHT = 3,
+ /**
+ * Cross Traffic Monitoring Warning is enabled and is actively warning the user of incoming
+ * moving objects coming from both the driver's left side and the driver's right side in front
+ * of the vehicle.
+ */
+ WARNING_FRONT_BOTH = 4,
+ /**
+ * Cross Traffic Monitoring Warning is enabled and is actively warning the user of incoming
+ * moving objects coming from the driver's left side behind the vehicle.
+ */
+ WARNING_REAR_LEFT = 5,
+ /**
+ * Cross Traffic Monitoring Warning is enabled and is actively warning the user of incoming
+ * moving objects coming from the driver's right side behind the vehicle.
+ */
+ WARNING_REAR_RIGHT = 6,
+ /**
+ * Cross Traffic Monitoring Warning is enabled and is actively warning the user of incoming
+ * moving objects coming from the driver's left side and the driver's right side behind the
+ * vehicle.
+ */
+ WARNING_REAR_BOTH = 7,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionState.aidl
new file mode 100644
index 0000000..f350a6c
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionState.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the current state of driver distraction monitoring.
+ *
+ * This enum could be extended in future releases to include additional feature states.
+ */
+@VintfStability
+@Backing(type="int")
+enum DriverDistractionState {
+ /**
+ * This state is used as an alternative for any DriverDistractionState value that is not
+ * defined in the platform. Ideally, implementations of
+ * VehicleProperty#DRIVER_DISTRACTION_STATE should not use this state. The framework
+ * can use this field to remain backwards compatible if DriverDistractionState is
+ * extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * The system detects that the driver is attentive / not distracted.
+ */
+ NOT_DISTRACTED = 1,
+ /**
+ * The system detects that the driver is distracted, which can be anything that reduces the
+ * driver's foucs on the primary task of driving/controlling the vehicle.
+ */
+ DISTRACTED = 2,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionWarning.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionWarning.aidl
new file mode 100644
index 0000000..a4b1984
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionWarning.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the current warning state of the driver distraction monitoring system.
+ */
+@VintfStability
+@Backing(type="int")
+enum DriverDistractionWarning {
+ /**
+ * This state is used as an alternative for any DriverDistractionWarning value that is
+ * defined in the platform. Ideally, implementations of
+ * VehicleProperty#DRIVER_DISTRACTION_WARNING should not use this state. The framework
+ * can use this field to remain backwards compatible if DriverDistractionWarning is
+ * extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * When the driver distraction warning is enabled and the driver's current distraction level
+ * does not warrant the system to send a warning.
+ */
+ NO_WARNING = 1,
+ /**
+ * When the driver distraction warning is enabled and the system is warning the driver based on
+ * its assessment of the driver's current distraction level.
+ */
+ WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.aidl
new file mode 100644
index 0000000..d2aec1f
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.aidl
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the current state of driver drowsiness and attention monitoring.
+ *
+ * This enum could be extended in future releases to include additional feature states.
+ */
+@VintfStability
+@Backing(type="int")
+enum DriverDrowsinessAttentionState {
+ /**
+ * This state is used as an alternative for any DriverDrowsinessAttentionState value that is not
+ * defined in the platform. Ideally, implementations of
+ * VehicleProperty#DRIVER_DROWSINESS_ATTENTION_STATE should not use this state. The framework
+ * can use this field to remain backwards compatible if DriverDrowsinessAttentionState is
+ * extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * Karolinska Sleepiness Scale Rating 1 described as extermely alert.
+ */
+ KSS_RATING_1_EXTREMELY_ALERT = 1,
+ /**
+ * Karolinska Sleepiness Scale Rating 2 described as very alert.
+ */
+ KSS_RATING_2_VERY_ALERT = 2,
+ /**
+ * Karolinska Sleepiness Scale Rating 3 described as alert.
+ */
+ KSS_RATING_3_ALERT = 3,
+ /**
+ * Karolinska Sleepiness Scale Rating 4 described as rather alert.
+ */
+ KSS_RATING_4_RATHER_ALERT = 4,
+ /**
+ * Karolinska Sleepiness Scale Rating 5 described as neither alert nor sleepy.
+ */
+ KSS_RATING_5_NEITHER_ALERT_NOR_SLEEPY = 5,
+ /**
+ * Karolinska Sleepiness Scale Rating 6 described as some signs of sleepiness.
+ */
+ KSS_RATING_6_SOME_SLEEPINESS = 6,
+ /**
+ * Karolinska Sleepiness Scale Rating 7 described as sleepy with no effort to
+ * keep awake.
+ */
+ KSS_RATING_7_SLEEPY_NO_EFFORT = 7,
+ /**
+ * Karolinska Sleepiness Scale Rating 8 described as sleepy with some effort to
+ * keep awake.
+ */
+ KSS_RATING_8_SLEEPY_SOME_EFFORT = 8,
+ /**
+ * Karolinska Sleepiness Scale Rating 9 described as very sleepy, with great
+ * effort to keep away, and fighthing sleep.
+ */
+ KSS_RATING_9_VERY_SLEEPY = 9,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.aidl
new file mode 100644
index 0000000..53b66b9
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the current warning state of the driver drowsiness and attention monitoring
+ * system.
+ */
+@VintfStability
+@Backing(type="int")
+enum DriverDrowsinessAttentionWarning {
+ /**
+ * This state is used as an alternative for any DriverDrowsinessAttentionWarning value that is
+ * defined in the platform. Ideally, implementations of
+ * VehicleProperty#DRIVER_DROWSINESS_ATTENTION_WARNING should not use this state. The framework
+ * can use this field to remain backwards compatible if DriverDrowsinessAttentionWarning is
+ * extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * When the driver drowsiness and attention warning is enabled, and the driver's current
+ * drowsiness and attention level does not warrant the system to send a warning.
+ */
+ NO_WARNING = 1,
+ /**
+ * When the driver drowsiness and attention warning is enabled, and the system is warning the
+ * driver based on its assessment of the driver's current drowsiness and attention level.
+ */
+ WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ElectronicStabilityControlState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ElectronicStabilityControlState.aidl
new file mode 100644
index 0000000..006bbf2
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ElectronicStabilityControlState.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the state of Electronic Stability Control (ESC).
+ */
+@VintfStability
+@Backing(type="int")
+enum ElectronicStabilityControlState {
+
+ /**
+ * This state is used as an alternative to any ElectronicStabilityControlState value that is not
+ * defined in the platform. Ideally, implementations of
+ * VehicleProperty#ELECTRONIC_STABILITY_CONTROL_STATE should not use this state. The framework
+ * can use this field to remain backwards compatible if ElectronicStabilityControlState is
+ * extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * ESC is enabled and monitoring safety, but is not actively controlling the tires to prevent
+ * the car from skidding.
+ */
+ ENABLED = 1,
+ /**
+ * ESC is enabled and is actively controlling the tires to prevent the car from skidding.
+ */
+ ACTIVATED = 2,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ImpactSensorLocation.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ImpactSensorLocation.aidl
new file mode 100644
index 0000000..0fc1a50
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ImpactSensorLocation.aidl
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the various impact sensor locations on the car.
+ */
+@VintfStability
+@Backing(type="int")
+enum ImpactSensorLocation {
+ /**
+ * Other impact sensor location. Ideally this should never be used.
+ */
+ OTHER = 0x01,
+ /**
+ * Frontal impact sensor. Used for the sensor that detects head-on impact.
+ */
+ FRONT = 0x02,
+ /**
+ * Front-left door side impact sensor. Used for the sensor that detects collisions from the
+ * side, in particular on the front-left door.
+ */
+ FRONT_LEFT_DOOR_SIDE = 0x04,
+ /**
+ * Front-right door side impact sensor. Used for the sensor that detects collisions from the
+ * side, in particular on the front-right door.
+ */
+ FRONT_RIGHT_DOOR_SIDE = 0x08,
+ /**
+ * Rear-left door side impact sensor. Used for the sensor that detects collisions from the
+ * side, in particular on the rear-left door.
+ */
+ REAR_LEFT_DOOR_SIDE = 0x10,
+ /**
+ * Rear-right door side impact sensor. Used for the sensor that detects collisions from the
+ * side, in particular on the rear-right door.
+ */
+ REAR_RIGHT_DOOR_SIDE = 0x20,
+ /**
+ * Rear impact sensor. Used for the sensor that detects collisions from the rear.
+ */
+ REAR = 0x40,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LowSpeedAutomaticEmergencyBrakingState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LowSpeedAutomaticEmergencyBrakingState.aidl
new file mode 100644
index 0000000..978da25
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LowSpeedAutomaticEmergencyBrakingState.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the state of Low Speed Automatic Emergency Braking.
+ */
+@VintfStability
+@Backing(type="int")
+enum LowSpeedAutomaticEmergencyBrakingState {
+
+ /**
+ * This state is used as an alternative to any LowSpeedAutomaticEmergencyBrakingState value that
+ * is not defined in the platform. Ideally, implementations of
+ * VehicleProperty#LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE should not use this state. The
+ * framework can use this field to remain backwards compatible if
+ * LowSpeedAutomaticEmergencyBrakingState is extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * Low Speed Automatic Emergency Braking is enabled and monitoring safety, but brakes are not
+ * activated.
+ */
+ ENABLED = 1,
+ /**
+ * Low Speed Automatic Emergency Braking is enabled and currently has the brakes applied for the
+ * vehicle.
+ */
+ ACTIVATED = 2,
+ /**
+ * Many Low Speed Automatic Emergency Braking implementations allow the driver to override Low
+ * Speed Automatic Emergency Braking. This means that the car has determined it should brake,
+ * but a user decides to take over and do something else. This is often done for safety reasons
+ * and to ensure that the driver can always take control of the vehicle. This state should be
+ * set when the user is actively overriding the low speed automatic emergency braking system.
+ */
+ USER_OVERRIDE = 3,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LowSpeedCollisionWarningState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LowSpeedCollisionWarningState.aidl
new file mode 100644
index 0000000..028a2d9
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LowSpeedCollisionWarningState.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the state of Low Speed Collision Warning State.
+ */
+@VintfStability
+@Backing(type="int")
+enum LowSpeedCollisionWarningState {
+
+ /**
+ * This state is used as an alternative to any LowSpeedCollisionWarningState value that is not
+ * defined in the platform. Ideally, implementations of
+ * VehicleProperty#LOW_SPEED_COLLISION_WARNING_STATE should not use this state. The framework
+ * can use this field to remain backwards compatible if LowSpeedCollisionWarningState is
+ * extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * Low Speed Collision Warning is enabled and monitoring for potential collision, but no
+ * potential collision is detected.
+ */
+ NO_WARNING = 1,
+ /**
+ * Low Speed Collision Warning is enabled, detects a potential collision, and is actively
+ * warning the user.
+ */
+ WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAirbagLocation.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAirbagLocation.aidl
new file mode 100644
index 0000000..e4c43f7
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAirbagLocation.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the various airbag locations per seat.
+ */
+@VintfStability
+@Backing(type="int")
+enum VehicleAirbagLocation {
+ /**
+ * This state is used as an alternative to any VehicleAirbagLocation value that is not defined
+ * in the platform. Ideally, implementations of VehicleProperty::SEAT_AIRBAGS_DEPLOYED should
+ * not use this state. The framework can use this field to remain backwards compatible if
+ * VehicleAirbagLocation is extended to include additional states.
+ */
+ OTHER = 0x01,
+ /**
+ * Front airbags. This enum is for the airbags that protect the seated person from the front,
+ * particularly the seated person's torso.
+ */
+ FRONT = 0x02,
+ /**
+ * Knee airbags. This enum is for the airbags that protect the seated person's knees.
+ */
+ KNEE = 0x04,
+ /**
+ * Left side airbags. This enum is for the side airbags that protect the left side of the seated
+ * person.
+ */
+ LEFT_SIDE = 0x08,
+ /**
+ * Right side airbags. This enum is for the side airbags that protect the right side of the
+ * seated person.
+ */
+ RIGHT_SIDE = 0x10,
+ /**
+ * Curtain airbags. This enum is for the airbags lined above the windows of the vehicle.
+ */
+ CURTAIN = 0x20,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.aidl
index e325b38..8c8c2da 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.aidl
@@ -34,7 +34,24 @@
SYSTEM_USER_DETECTION = 1,
/**
* Automatic power on to execute a remote task. This is triggered by
- * receiving a wakeup message from TCU wakeup client.
+ * receiving a wakeup message from an external system in the vehicle.
*/
SYSTEM_REMOTE_ACCESS = 2,
+ /**
+ * Automatic power on to enter garage mode. This is triggered by
+ * receiving a wakeup message from an external system in the vehicle.
+ *
+ * Note that this does not necessarily mean Android will enter
+ * the garage mode since user may enter the vehicle after this is set.
+ * The system will only enter garage mode if VEHICLE_IN_USE is not true
+ * upon check.
+ *
+ * To consider the Time-Of-Check-Time-Of-Use issue, there is a slight chance
+ * that the vehicle become in-use after car service does the VEHICLE_IN_USE
+ * check. The external power controller must also check whether the vehicle
+ * is in use upon receiving the SHUTDOWN_REQUEST, before sending out
+ * SHUTDOWN_PREPARE, to make sure the system does not enter garage mode or
+ * shutdown if the vehicle is currently in use.
+ */
+ SYSTEM_ENTER_GARAGE_MODE = 3,
}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
index a863d14..538b905 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
@@ -20,29 +20,39 @@
@Backing(type="int")
enum VehicleApPowerStateShutdownParam {
/**
- * AP must shutdown immediately. Postponing is not allowed.
+ * AP must shutdown without Garage mode.
+ * If AP need to shutdown as soon as possible, EMERGENCY_SHUTDOWN shall be used.
*/
SHUTDOWN_IMMEDIATELY = 1,
/**
* AP can enter deep sleep instead of shutting down completely.
+ * AP can postpone entering deep sleep to run Garage mode.
*/
CAN_SLEEP = 2,
/**
- * AP can only shutdown with postponing allowed.
+ * AP can only shutdown.
+ * AP can postpone shutdown to run Garage mode.
*/
SHUTDOWN_ONLY = 3,
/**
- * AP may enter deep sleep, but must either sleep or shut down immediately.
- * Postponing is not allowed.
+ * AP can enter deep sleep, without Garage mode.
+ * Depending on the actual implementation, it may shut down immediately
*/
SLEEP_IMMEDIATELY = 4,
/**
- * AP must hibernate (suspend to disk) immediately. Postponing is not allowed.
- * Depending on the actual implementation, it may shut down immediately
+ * AP can hibernate (suspend to disk) without Garage mode.
+ * Depending on the actual implementation, it may shut down immediately.
*/
HIBERNATE_IMMEDIATELY = 5,
/**
* AP can enter hibernation (suspend to disk) instead of shutting down completely.
+ * AP can postpone hibernation to run Garage mode.
*/
CAN_HIBERNATE = 6,
+ /**
+ * AP must shutdown (gracefully) without a delay. AP cannot run Garage mode.
+ * This type must be used only in critical situations when AP must shutdown as soon as possible.
+ * CarService will only notify listeners, but will not wait for completion reports.
+ */
+ EMERGENCY_SHUTDOWN = 7,
}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleArea.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleArea.aidl
index 6f7f783..259b231 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleArea.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleArea.aidl
@@ -49,6 +49,11 @@
DOOR = 0x06000000,
/** WHEEL maps to enum VehicleAreaWheel */
WHEEL = 0x07000000,
+ /**
+ * A property with the VENDOR vehicle area contains area IDs that are vendor defined. Each area
+ * ID within this area type must be unique with no overlapping bits set.
+ */
+ VENDOR = 0x08000000,
MASK = 0x0f000000,
}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAutonomousState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAutonomousState.aidl
new file mode 100644
index 0000000..3860e7f
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAutonomousState.aidl
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the various level of automation that can be expressed by the
+ * VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL property.
+ */
+@VintfStability
+@Backing(type="int")
+enum VehicleAutonomousState {
+ /**
+ * No automation. ADAS systems are limited to providing warnings and momentary assistance. The
+ * driver is in constant supervision of all driving tasks and must steer, brake or accelerate as
+ * needed to maintain safety, and is still responsible for driving while the ADAS systems are
+ * engaged. Usage should be in accordance to Level 0 definition in J3016_202104 version of
+ * vehicle autonomy levels defined by SAE.
+ */
+ LEVEL_0 = 0,
+ /**
+ * Driver assistance. ADAS systems can provide steering or brake/acceleration support to the
+ * driver. The driver is in constant supervision of all driving tasks and must steer, brake or
+ * accelerate as needed to maintain safety, and is still responsible for driving while the ADAS
+ * systems are engaged. Usage should be in accordance to Level 1 definition in J3016_202104
+ * version of vehicle autonomy levels defined by SAE.
+ */
+ LEVEL_1 = 1,
+ /**
+ * Partial automation. ADAS systems can provide both steering and brake/acceleration support to
+ * the driver at the same time. The driver is in constant supervision of all driving tasks and
+ * must steer, brake or accelerate as needed to maintain safety, and is still responsible for
+ * driving while the ADAS systems are engaged. Usage should be in accordance to Level 2
+ * definition in J3016_202104 version of vehicle autonomy levels defined by SAE.
+ */
+ LEVEL_2 = 2,
+ /**
+ * Conditional automation. ADAS systems can drive the vehicle under limited conditions and will
+ * not operate unless all required conditions are met. The driver is required to take over
+ * control of the vehicle when requested to do so by the ADAS systems, however is not
+ * responsible for driving while the ADAS systems are engaged. Usage should be in accordance to
+ * Level 3 definition in J3016_202104 version of vehicle autonomy levels defined by SAE.
+ */
+ LEVEL_3 = 3,
+ /**
+ * High automation. ADAS systems can drive the vehicle under limited conditions and will not
+ * operate unless all required conditions are met. The driver is not required to take over
+ * control of the vehicle and is not responsible for driving while the ADAS systems are engaged.
+ * Usage should be in accordance to Level 4 definition in J3016_202104 version of vehicle
+ * autonomy levels defined by SAE.
+ */
+ LEVEL_4 = 4,
+ /**
+ * Full automation. ADAS systems can drive the vehicle under all conditions. The driver is not
+ * required to take over control of the vehicle and is not responsible for driving while the
+ * ADAS systems are engaged. Usage should be in accordance to Level 5 definition in J3016_202104
+ * version of vehicle autonomy levels defined by SAE.
+ */
+ LEVEL_5 = 5,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
index af2e903..812b9b9 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -52,6 +52,7 @@
*
* @change_mode VehiclePropertyChangeMode.STATIC
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
INFO_VIN = 0x0100 + 0x10000000 + 0x01000000
+ 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
@@ -60,6 +61,7 @@
*
* @change_mode VehiclePropertyChangeMode.STATIC
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
INFO_MAKE = 0x0101 + 0x10000000 + 0x01000000
+ 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
@@ -68,15 +70,17 @@
*
* @change_mode VehiclePropertyChangeMode.STATIC
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
INFO_MODEL = 0x0102 + 0x10000000 + 0x01000000
+ 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
/**
- * Model year of vehicle.
+ * Model year of vehicle in YYYY format based on the Gregorian calendar.
*
* @change_mode VehiclePropertyChangeMode.STATIC
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:YEAR
+ * @version 2
*/
INFO_MODEL_YEAR = 0x0103 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -86,6 +90,7 @@
* @change_mode VehiclePropertyChangeMode.STATIC
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:MILLILITER
+ * @version 2
*/
INFO_FUEL_CAPACITY = 0x0104 + 0x10000000 + 0x01000000
+ 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -105,6 +110,7 @@
* @change_mode VehiclePropertyChangeMode.STATIC
* @access VehiclePropertyAccess.READ
* @data_enum FuelType
+ * @version 2
*/
INFO_FUEL_TYPE = 0x0105 + 0x10000000 + 0x01000000
+ 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -119,6 +125,7 @@
* @change_mode VehiclePropertyChangeMode.STATIC
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:WH
+ * @version 2
*/
INFO_EV_BATTERY_CAPACITY = 0x0106 + 0x10000000 + 0x01000000
+ 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -128,6 +135,7 @@
* @change_mode VehiclePropertyChangeMode.STATIC
* @data_enum EvConnectorType
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
INFO_EV_CONNECTOR_TYPE = 0x0107 + 0x10000000 + 0x01000000
+ 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -137,6 +145,7 @@
* @change_mode VehiclePropertyChangeMode.STATIC
* @data_enum PortLocationType
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
INFO_FUEL_DOOR_LOCATION = 0x0108 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -146,6 +155,7 @@
* @change_mode VehiclePropertyChangeMode.STATIC
* @access VehiclePropertyAccess.READ
* @data_enum PortLocationType
+ * @version 2
*/
INFO_EV_PORT_LOCATION = 0x0109 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -156,6 +166,7 @@
* @change_mode VehiclePropertyChangeMode.STATIC
* @data_enum VehicleAreaSeat
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
INFO_DRIVER_SEAT = 0x010A + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -174,6 +185,7 @@
* @change_mode VehiclePropertyChangeMode.STATIC
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:MILLIMETER
+ * @version 2
*/
INFO_EXTERIOR_DIMENSIONS = 0x010B + 0x10000000 + 0x01000000
+ 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -189,6 +201,7 @@
* @change_mode VehiclePropertyChangeMode.STATIC
* @access VehiclePropertyAccess.READ
* @data_enum PortLocationType
+ * @version 2
*/
INFO_MULTI_EV_PORT_LOCATIONS = 0x010C + 0x10000000 + 0x01000000
+ 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -198,6 +211,7 @@
* @change_mode VehiclePropertyChangeMode.CONTINUOUS
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:KILOMETER
+ * @version 2
*/
PERF_ODOMETER = 0x0204 + 0x10000000 + 0x01000000
+ 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -213,6 +227,7 @@
* @change_mode VehiclePropertyChangeMode.CONTINUOUS
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:METER_PER_SEC
+ * @version 2
*/
PERF_VEHICLE_SPEED = 0x0207 + 0x10000000 + 0x01000000
+ 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -225,6 +240,7 @@
* @change_mode VehiclePropertyChangeMode.CONTINUOUS
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:METER_PER_SEC
+ * @version 2
*/
PERF_VEHICLE_SPEED_DISPLAY = 0x0208 + 0x10000000 + 0x01000000
+ 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -236,6 +252,7 @@
* @change_mode VehiclePropertyChangeMode.CONTINUOUS
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:DEGREES
+ * @version 2
*/
PERF_STEERING_ANGLE = 0x0209 + 0x10000000 + 0x01000000
+ 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -247,6 +264,7 @@
* @change_mode VehiclePropertyChangeMode.CONTINUOUS
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:DEGREES
+ * @version 2
*/
PERF_REAR_STEERING_ANGLE = 0x0210 + 0x10000000 + 0x01000000
+ 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -256,6 +274,7 @@
* @change_mode VehiclePropertyChangeMode.CONTINUOUS
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:CELSIUS
+ * @version 2
*/
ENGINE_COOLANT_TEMP = 0x0301 + 0x10000000 + 0x01000000
+ 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -265,6 +284,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleOilLevel
+ * @version 2
*/
ENGINE_OIL_LEVEL = 0x0303 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -274,6 +294,7 @@
* @change_mode VehiclePropertyChangeMode.CONTINUOUS
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:CELSIUS
+ * @version 2
*/
ENGINE_OIL_TEMP = 0x0304 + 0x10000000 + 0x01000000
+ 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -283,6 +304,7 @@
* @change_mode VehiclePropertyChangeMode.CONTINUOUS
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:RPM
+ * @version 2
*/
ENGINE_RPM = 0x0305 + 0x10000000 + 0x01000000
+ 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -323,6 +345,7 @@
*
* @change_mode VehiclePropertyChangeMode.CONTINUOUS
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
WHEEL_TICK = 0x0306 + 0x10000000 + 0x01000000
+ 0x00510000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64_VEC
@@ -334,6 +357,7 @@
* @change_mode VehiclePropertyChangeMode.CONTINUOUS
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:MILLILITER
+ * @version 2
*/
FUEL_LEVEL = 0x0307 + 0x10000000 + 0x01000000
+ 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -346,6 +370,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
FUEL_DOOR_OPEN = 0x0308 + 0x10000000 + 0x01000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -359,6 +384,7 @@
* @change_mode VehiclePropertyChangeMode.CONTINUOUS
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:WH
+ * @version 2
*/
EV_BATTERY_LEVEL = 0x0309 + 0x10000000 + 0x01000000
+ 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -373,6 +399,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:WH
+ * @version 2
*/
EV_CURRENT_BATTERY_CAPACITY =
0x030D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.FLOAT,
@@ -385,6 +412,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
EV_CHARGE_PORT_OPEN = 0x030A + 0x10000000 + 0x01000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -393,6 +421,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
EV_CHARGE_PORT_CONNECTED = 0x030B + 0x10000000 + 0x01000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -405,6 +434,7 @@
* @change_mode VehiclePropertyChangeMode.CONTINUOUS
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:MW
+ * @version 2
*/
EV_BATTERY_INSTANTANEOUS_CHARGE_RATE = 0x030C + 0x10000000 + 0x01000000
+ 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -423,10 +453,25 @@
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:METER
+ * @version 2
*/
RANGE_REMAINING = 0x0308 + 0x10000000 + 0x01000000
+ 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
/**
+ * EV battery average temperature
+ *
+ * Exposes the temperature of the battery in an EV. If multiple batteries exist in the EV, or
+ * multiple temperature sensors exist, this property should be set to the mean or a meaningful
+ * weighted average that best represents the overall temperature of the battery system.
+ *
+ * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:CELSIUS
+ * @version 3
+ */
+ EV_BATTERY_AVERAGE_TEMPERATURE =
+ 0x030E + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.FLOAT,
+ /**
* Tire pressure
*
* Each tires is identified by its areaConfig.areaId config and their
@@ -450,6 +495,7 @@
* @change_mode VehiclePropertyChangeMode.CONTINUOUS
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:KILOPASCAL
+ * @version 2
*/
TIRE_PRESSURE = 0x0309 + 0x10000000 + 0x07000000
+ 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WHEEL,VehiclePropertyType:FLOAT
@@ -465,6 +511,7 @@
* @change_mode VehiclePropertyChangeMode.STATIC
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:KILOPASCAL
+ * @version 2
*/
CRITICALLY_LOW_TIRE_PRESSURE = 0x030A + 0x10000000 + 0x07000000
+ 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WHEEL,VehiclePropertyType:FLOAT
@@ -480,10 +527,28 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
ENGINE_IDLE_AUTO_STOP_ENABLED =
0x0320 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
/**
+ * Impact detected.
+ *
+ * Bit flag property to relay information on whether an impact has occurred on a particular side
+ * of the vehicle as described through the ImpactSensorLocation enum. As a bit flag property,
+ * this property can be set to multiple ORed together values of the enum when necessary.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all bit flags of ImpactSensorLocation are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum ImpactSensorLocation
+ * @version 3
+ */
+ IMPACT_DETECTED =
+ 0x0330 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+ /**
* Currently selected gear
*
* This is the gear selected by the user.
@@ -500,6 +565,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleGear
+ * @version 2
*/
GEAR_SELECTION = 0x0400 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -519,6 +585,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleGear
+ * @version 2
*/
CURRENT_GEAR = 0x0401 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -530,6 +597,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
PARKING_BRAKE_ON = 0x0402 + 0x10000000 + 0x01000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -547,6 +615,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
PARKING_BRAKE_AUTO_APPLY = 0x0403 + 0x10000000 + 0x01000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -565,6 +634,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
EV_BRAKE_REGENERATION_LEVEL =
0x040C + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -583,6 +653,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
FUEL_LEVEL_LOW = 0x0405 + 0x10000000 + 0x01000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -595,6 +666,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
NIGHT_MODE = 0x0407 + 0x10000000 + 0x01000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -604,6 +676,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleTurnSignal
+ * @version 2
*/
TURN_SIGNAL_STATE = 0x0408 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -613,6 +686,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleIgnitionState
+ * @version 2
*/
IGNITION_STATE = 0x0409 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -625,6 +699,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
ABS_ACTIVE = 0x040A + 0x10000000 + 0x01000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -637,6 +712,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
TRACTION_CONTROL_ACTIVE = 0x040B + 0x10000000 + 0x01000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -655,10 +731,52 @@
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
* @data_enum EvStoppingMode
+ * @version 2
*/
EV_STOPPING_MODE =
0x040D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
/**
+ * Enable or disable Electronic Stability Control (ESC).
+ *
+ * Set true to enable ESC and false to disable ESC. When ESC is enabled, a system in the vehicle
+ * should be controlling the tires during instances with high risk of skidding to actively
+ * prevent the same from happening.
+ *
+ * In general, ELECTRONIC_STABILITY_CONTROL_ENABLED should always return true or false. If the
+ * feature is not available due to some temporary state, such as the vehicle speed being too
+ * high, that information must be conveyed through the ErrorState values in the
+ * ELECTRONIC_STABILITY_CONTROL_STATE property.
+ *
+ * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+ * implement it as VehiclePropertyAccess.READ only.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @access VehiclePropertyAccess.READ
+ * @version 3
+ */
+ ELECTRONIC_STABILITY_CONTROL_ENABLED =
+ 0x040E + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+ /**
+ * Electronic Stability Control (ESC) state.
+ *
+ * Returns the current state of ESC. This property must always return a valid state defined in
+ * ElectronicStabilityControlState or ErrorState. It must not surface errors through StatusCode
+ * and must use the supported error states instead.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both ElectronicStabilityControlState (including OTHER, which is not
+ * recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum ElectronicStabilityControlState
+ * @data_enum ErrorState
+ * @version 2
+ */
+ ELECTRONIC_STABILITY_CONTROL_STATE =
+ 0x040F + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+ /**
* HVAC Properties
*
* Additional rules for mapping non-GLOBAL VehicleArea type HVAC properties
@@ -721,6 +839,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
HVAC_FAN_SPEED = 0x0500 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -734,6 +853,7 @@
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleHvacFanDirection
+ * @version 2
*/
HVAC_FAN_DIRECTION = 0x0501 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -743,6 +863,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:CELSIUS
+ * @version 2
*/
HVAC_TEMPERATURE_CURRENT = 0x0502 + 0x10000000 + 0x05000000
+ 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:FLOAT
@@ -774,6 +895,7 @@
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:CELSIUS
+ * @version 2
*/
HVAC_TEMPERATURE_SET = 0x0503 + 0x10000000 + 0x05000000
+ 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:FLOAT
@@ -786,6 +908,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
HVAC_DEFROSTER = 0x0504 + 0x10000000 + 0x03000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:BOOLEAN
@@ -799,6 +922,7 @@
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
* @config_flags Supported areaIds
+ * @version 2
*/
HVAC_AC_ON = 0x0505 + 0x10000000 + 0x05000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
@@ -816,6 +940,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
HVAC_MAX_AC_ON = 0x0506 + 0x10000000 + 0x05000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
@@ -839,6 +964,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
HVAC_MAX_DEFROST_ON = 0x0507 + 0x10000000 + 0x05000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
@@ -856,6 +982,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
HVAC_RECIRC_ON = 0x0508 + 0x10000000 + 0x05000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
@@ -895,6 +1022,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
HVAC_DUAL_ON = 0x0509 + 0x10000000 + 0x05000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
@@ -917,6 +1045,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
HVAC_AUTO_ON = 0x050A + 0x10000000 + 0x05000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
@@ -939,6 +1068,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
HVAC_SEAT_TEMPERATURE = 0x050B + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -962,6 +1092,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
HVAC_SIDE_MIRROR_HEAT = 0x050C + 0x10000000 + 0x04000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
@@ -985,6 +1116,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
HVAC_STEERING_WHEEL_HEAT = 0x050D + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -1011,6 +1143,7 @@
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleUnit
+ * @version 2
*/
HVAC_TEMPERATURE_DISPLAY_UNITS = 0x050E + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -1019,6 +1152,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
HVAC_ACTUAL_FAN_SPEED_RPM = 0x050F + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -1065,6 +1199,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
HVAC_POWER_ON = 0x0510 + 0x10000000 + 0x05000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
@@ -1084,6 +1219,7 @@
* @change_mode VehiclePropertyChangeMode.STATIC
* @access VehiclePropertyAccess.READ
* @data_enum VehicleHvacFanDirection
+ * @version 2
*/
HVAC_FAN_DIRECTION_AVAILABLE = 0x0511 + 0x10000000 + 0x05000000
+ 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32_VEC
@@ -1100,6 +1236,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
HVAC_AUTO_RECIRC_ON = 0x0512 + 0x10000000 + 0x05000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
@@ -1125,6 +1262,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
HVAC_SEAT_VENTILATION = 0x0513 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -1137,6 +1275,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
HVAC_ELECTRIC_DEFROSTER_ON = 0x0514 + 0x10000000 + 0x03000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:BOOLEAN
@@ -1177,6 +1316,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
+ * @version 2
*/
HVAC_TEMPERATURE_VALUE_SUGGESTION = 0x0515 + 0x10000000 + 0x01000000
+ 0x00610000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT_VEC
@@ -1202,6 +1342,7 @@
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleUnit
+ * @version 2
*/
DISTANCE_DISPLAY_UNITS = 0x0600 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -1226,6 +1367,7 @@
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleUnit
+ * @version 2
*/
FUEL_VOLUME_DISPLAY_UNITS = 0x0601 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -1251,6 +1393,7 @@
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleUnit
+ * @version 2
*/
TIRE_PRESSURE_DISPLAY_UNITS = 0x0602 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -1276,6 +1419,7 @@
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleUnit
+ * @version 2
*/
EV_BATTERY_DISPLAY_UNITS = 0x0603 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -1292,6 +1436,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME = 0x0604 + 0x10000000 + 0x01000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -1315,6 +1460,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
VEHICLE_SPEED_DISPLAY_UNITS = 0x0605 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -1359,6 +1505,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:MILLI_SECS
+ * @version 2
*/
EXTERNAL_CAR_TIME = 0x0608 + 0x10000000 // VehiclePropertyGroup:SYSTEM
+ 0x01000000 // VehicleArea:GLOBAL
@@ -1388,6 +1535,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.WRITE
* @unit VehicleUnit:MILLI_SECS
+ * @version 2
*/
ANDROID_EPOCH_TIME = 0x0606 + 0x10000000 + 0x01000000
+ 0x00500000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64
@@ -1402,6 +1550,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
+ * @version 2
*/
STORAGE_ENCRYPTION_BINDING_SEED = 0x0607 + 0x10000000 + 0x01000000
+ 0x00700000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BYTES
@@ -1411,6 +1560,7 @@
* @change_mode VehiclePropertyChangeMode.CONTINUOUS
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:CELSIUS
+ * @version 2
*/
ENV_OUTSIDE_TEMPERATURE = 0x0703 + 0x10000000 + 0x01000000
+ 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -1429,6 +1579,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
AP_POWER_STATE_REQ = 0x0A00 + 0x10000000 + 0x01000000
+ 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -1443,6 +1594,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
+ * @version 2
*/
AP_POWER_STATE_REPORT = 0x0A01 + 0x10000000 + 0x01000000
+ 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -1457,6 +1609,7 @@
*
* @change_mode VehiclePropertyChangeMode.STATIC
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
AP_POWER_BOOTUP_REASON = 0x0A02 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -1479,6 +1632,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
+ * @version 2
*/
DISPLAY_BRIGHTNESS = 0x0A03 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -1502,10 +1656,45 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
+ * @version 2
*/
PER_DISPLAY_BRIGHTNESS = 0x0A04 + 0x10000000 + 0x01000000
+ 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
/**
+ * Valet mode enabled
+ *
+ * This property allows the user to enable/disable valet mode in their vehicle. Valet mode is
+ * a privacy and security setting that prevents an untrusted driver to access more private areas
+ * in the vehicle, such as the glove box or the trunk(s).
+ *
+ * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+ * implement it as VehiclePropertyAccess.READ only.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @access VehiclePropertyAccess.READ
+ * @version 3
+ */
+ VALET_MODE_ENABLED =
+ 0x0A05 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+ /**
+ * Head up display (HUD) enabled
+ *
+ * This property allows the user to turn on/off the HUD for their seat.
+ *
+ * Each HUD in the vehicle should be assigned to the seat that is intended to use it. For
+ * example, if there is a single HUD in the vehicle that is used by the driver so that they no
+ * longer need to continuously look at the instrument cluster, then this property should be
+ * defined with a single area ID equal to the driver's seat area value.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @access VehiclePropertyAccess.READ
+ * @version 3
+ */
+ HEAD_UP_DISPLAY_ENABLED =
+ 0x0A06 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.BOOLEAN,
+ /**
* Property to feed H/W input events to android
*
* int32Values[0] : action defined by VehicleHwKeyInputAction
@@ -1519,6 +1708,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @config_flags
+ * @version 2
*/
HW_KEY_INPUT = 0x0A10 + 0x10000000 + 0x01000000
+ 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -1541,6 +1731,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @config_flags
+ * @version 2
*/
HW_KEY_INPUT_V2 =
0x0A11 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.MIXED,
@@ -1575,6 +1766,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @config_flags
+ * @version 2
*/
HW_MOTION_INPUT =
0x0A12 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.MIXED,
@@ -1598,6 +1790,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @data_enum RotaryInputType
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
HW_ROTARY_INPUT = 0x0A20 + 0x10000000 + 0x01000000
+ 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -1621,6 +1814,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @data_enum CustomInputType
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
HW_CUSTOM_INPUT = 0X0A30 + 0x10000000 + 0x01000000
+ 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -1665,6 +1859,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
DOOR_POS = 0x0B00 + 0x10000000 + 0x06000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:DOOR,VehiclePropertyType:INT32
@@ -1690,6 +1885,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
DOOR_MOVE = 0x0B01 + 0x10000000 + 0x06000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:DOOR,VehiclePropertyType:INT32
@@ -1704,6 +1900,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
DOOR_LOCK = 0x0B02 + 0x10000000 + 0x06000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:DOOR,VehiclePropertyType:BOOLEAN
@@ -1720,6 +1917,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
DOOR_CHILD_LOCK_ENABLED =
0x0B03 + VehiclePropertyGroup.SYSTEM + VehicleArea.DOOR + VehiclePropertyType.BOOLEAN,
@@ -1746,6 +1944,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
MIRROR_Z_POS = 0x0B40 + 0x10000000 + 0x04000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
@@ -1772,6 +1971,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
MIRROR_Z_MOVE = 0x0B41 + 0x10000000 + 0x04000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
@@ -1798,6 +1998,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
MIRROR_Y_POS = 0x0B42 + 0x10000000 + 0x04000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
@@ -1823,6 +2024,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
MIRROR_Y_MOVE = 0x0B43 + 0x10000000 + 0x04000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
@@ -1837,6 +2039,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
MIRROR_LOCK = 0x0B44 + 0x10000000 + 0x01000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -1851,6 +2054,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
MIRROR_FOLD = 0x0B45 + 0x10000000 + 0x01000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -1868,6 +2072,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
MIRROR_AUTO_FOLD_ENABLED =
@@ -1886,6 +2091,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
MIRROR_AUTO_TILT_ENABLED =
@@ -1905,6 +2111,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.WRITE
+ * @version 2
*/
SEAT_MEMORY_SELECT = 0x0B80 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -1918,6 +2125,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.WRITE
+ * @version 2
*/
SEAT_MEMORY_SET = 0x0B81 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -1935,6 +2143,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_BELT_BUCKLED = 0x0B82 + 0x10000000 + 0x05000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
@@ -1960,6 +2169,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_BELT_HEIGHT_POS = 0x0B83 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -1988,6 +2198,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_BELT_HEIGHT_MOVE = 0x0B84 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2013,6 +2224,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_FORE_AFT_POS = 0x0B85 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2040,6 +2252,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_FORE_AFT_MOVE = 0x0B86 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2067,6 +2280,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_BACKREST_ANGLE_1_POS = 0x0B87 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2094,6 +2308,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_BACKREST_ANGLE_1_MOVE = 0x0B88 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2123,6 +2338,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_BACKREST_ANGLE_2_POS = 0x0B89 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2150,6 +2366,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_BACKREST_ANGLE_2_MOVE = 0x0B8A + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2173,6 +2390,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_HEIGHT_POS = 0x0B8B + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2198,6 +2416,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_HEIGHT_MOVE = 0x0B8C + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2226,6 +2445,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_DEPTH_POS = 0x0B8D + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2252,6 +2472,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_DEPTH_MOVE = 0x0B8E + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2279,6 +2500,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_TILT_POS = 0x0B8F + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2306,6 +2528,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_TILT_MOVE = 0x0B90 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2331,6 +2554,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_LUMBAR_FORE_AFT_POS = 0x0B91 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2359,6 +2583,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_LUMBAR_FORE_AFT_MOVE = 0x0B92 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2384,6 +2609,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_LUMBAR_SIDE_SUPPORT_POS = 0x0B93 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2412,6 +2638,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_LUMBAR_SIDE_SUPPORT_MOVE = 0x0B94 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2432,6 +2659,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_HEADREST_HEIGHT_POS = 0x0B95 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -2459,6 +2687,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_HEADREST_HEIGHT_POS_V2 =
0x0BA4 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
@@ -2488,6 +2717,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_HEADREST_HEIGHT_MOVE = 0x0B96 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2511,6 +2741,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_HEADREST_ANGLE_POS = 0x0B97 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2539,6 +2770,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_HEADREST_ANGLE_MOVE = 0x0B98 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2562,6 +2794,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_HEADREST_FORE_AFT_POS = 0x0B99 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2590,6 +2823,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_HEADREST_FORE_AFT_MOVE = 0x0B9A + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2611,6 +2845,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleLightState
+ * @version 2
*/
SEAT_FOOTWELL_LIGHTS_STATE =
0x0B9B + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
@@ -2636,6 +2871,7 @@
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleLightSwitch
+ * @version 2
*/
SEAT_FOOTWELL_LIGHTS_SWITCH =
0x0B9C + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
@@ -2652,6 +2888,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_EASY_ACCESS_ENABLED =
0x0B9D + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.BOOLEAN,
@@ -2672,10 +2909,34 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 3
*/
SEAT_AIRBAG_ENABLED =
0x0B9E + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.BOOLEAN,
/**
+ * Seat airbags deployed
+ *
+ * Bit flag property to relay information on which airbags have been deployed in the vehicle at
+ * each seat, vs which ones are currently still armed. If SEAT_AIRBAG_ENABLED is set to false at
+ * a particular areaId, this property should return status code UNAVAILABLE at that areaId.
+ *
+ * Enums apply to each seat, not the global vehicle. For example, VehicleAirbagsLocation#CURTAIN
+ * at the driver seat areaId represents whether the driver side curtain airbag has been
+ * deployed. Multiple bit flags can be set to indicate that multiple different airbags have been
+ * deployed for the seat.
+ *
+ * For each seat area ID, the VehicleAreaConfig#supportedEnumValues array must be defined unless
+ * all states of VehicleAirbagLocation are supported (including OTHER, which is not
+ * recommended).
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum VehicleAirbagLocation
+ * @version 2
+ */
+ SEAT_AIRBAGS_DEPLOYED =
+ 0x0BA5 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+ /**
* Represents property for seat’s hipside (bottom cushion’s side) support position.
*
* The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers
@@ -2697,6 +2958,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_CUSHION_SIDE_SUPPORT_POS =
0x0B9F + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
@@ -2725,6 +2987,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_CUSHION_SIDE_SUPPORT_MOVE =
0x0BA0 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
@@ -2748,6 +3011,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_LUMBAR_VERTICAL_POS =
0x0BA1 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
@@ -2774,6 +3038,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_LUMBAR_VERTICAL_MOVE =
0x0BA2 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
@@ -2800,10 +3065,30 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SEAT_WALK_IN_POS =
0x0BA3 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
/**
+ * Seat belt pretensioner deployed.
+ *
+ * Property to relay information on whether the seat belt pretensioner has been deployed for a
+ * particular seat due to a collision. This is different from the regular seat belt tightening
+ * system that continuously adds tension to the seat belts so that they fit snugly around the
+ * person sitting in the seat, nor is it the seat belt retractor system that locks the seat belt
+ * in place during sudden brakes or when the user jerks the seat belt.
+ *
+ * If this property is dependant on the state of other properties, and those properties are
+ * currently in the state that doesn't support this property, this should return
+ * StatusCode#NOT_AVAILABLE
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @version 3
+ */
+ SEAT_BELT_PRETENSIONER_DEPLOYED =
+ 0x0BA6 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.BOOLEAN,
+ /**
* Seat Occupancy
*
* Indicates whether a particular seat is occupied or not, to the best of the car's ability
@@ -2812,6 +3097,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleSeatOccupancyState
+ * @version 2
*/
SEAT_OCCUPANCY = 0x0BB0 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2848,6 +3134,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
WINDOW_POS = 0x0BC0 + 0x10000000 + 0x03000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
@@ -2890,6 +3177,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
WINDOW_MOVE = 0x0BC1 + 0x10000000 + 0x03000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
@@ -2904,6 +3192,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
WINDOW_LOCK = 0x0BC4 + 0x10000000 + 0x03000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:BOOLEAN
@@ -2924,6 +3213,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:MILLI_SECS
+ * @version 2
*/
WINDSHIELD_WIPERS_PERIOD =
0x0BC5 + VehiclePropertyGroup.SYSTEM + VehicleArea.WINDOW + VehiclePropertyType.INT32,
@@ -2945,6 +3235,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @data_enum WindshieldWipersState
+ * @version 2
*/
WINDSHIELD_WIPERS_STATE =
0x0BC6 + VehiclePropertyGroup.SYSTEM + VehicleArea.WINDOW + VehiclePropertyType.INT32,
@@ -2971,6 +3262,7 @@
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
* @data_enum WindshieldWipersSwitch
+ * @version 2
*/
WINDSHIELD_WIPERS_SWITCH =
0x0BC7 + VehiclePropertyGroup.SYSTEM + VehicleArea.WINDOW + VehiclePropertyType.INT32,
@@ -2997,6 +3289,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
STEERING_WHEEL_DEPTH_POS =
0x0BE0 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -3023,6 +3316,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
STEERING_WHEEL_DEPTH_MOVE =
0x0BE1 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -3046,6 +3340,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
STEERING_WHEEL_HEIGHT_POS =
0x0BE2 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -3072,6 +3367,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
STEERING_WHEEL_HEIGHT_MOVE =
0x0BE3 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -3087,6 +3383,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
STEERING_WHEEL_THEFT_LOCK_ENABLED =
0x0BE4 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -3101,6 +3398,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
STEERING_WHEEL_LOCKED =
0x0BE5 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -3116,6 +3414,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
STEERING_WHEEL_EASY_ACCESS_ENABLED =
0x0BE6 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -3143,6 +3442,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
GLOVE_BOX_DOOR_POS =
0x0BF0 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
@@ -3162,6 +3462,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
GLOVE_BOX_LOCKED =
0x0BF1 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.BOOLEAN,
@@ -3181,6 +3482,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
+ * @version 2
*/
VEHICLE_MAP_SERVICE = 0x0C00 + 0x10000000 + 0x01000000
+ 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -3200,9 +3502,187 @@
*
* @change_mode VehiclePropertyChangeMode.STATIC
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
LOCATION_CHARACTERIZATION =
0x0C10 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Static data for the position of each ultrasonic sensor installed on the vehicle.
+ *
+ * Each individual sensor is identified by its unique VehicleAreaConfig#areaId and returns the
+ * sensor's position formatted as [x, y, z] where:
+ *
+ * int32Values[0] = x, the position of the sensor along the x-axis relative to the origin of
+ * the Android Automotive sensor coordinate frame in millimeters
+ * int32Values[1] = y, the position of the sensor along the y-axis relative to the origin of
+ * the Android Automotive sensor coordinate frame in millimeters.
+ * int32Values[2] = z, the position of the sensor along the z-axis relative to the origin of
+ * the Android Automotive sensor coordinate frame in millimeters.
+ *
+ * If the data is aggregated by another ECU, then OEMs have the option of reporting the same
+ * reading across all included sensors or reporting a virtual representation of all the included
+ * sensors as if they were one sensor.
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ * @version 3
+ */
+ ULTRASONICS_SENSOR_POSITION = 0x0C20 + VehiclePropertyGroup.SYSTEM + VehicleArea.VENDOR
+ + VehiclePropertyType.INT32_VEC,
+
+ /**
+ * Static data for the orientation of each ultrasonic sensor installed on the vehicle.
+ *
+ * Each individual sensor is identified by its VehicleAreaConfig#areaId and returns the sensor's
+ * orientation formatted as [qw, qx, qy, qz] where:
+ *
+ * int32Values[0] = qw, the quaternion coefficient w within the quaterinion (w + xi + yj +
+ * zk) describing the rotation of the sensor relative to the Android
+ * Automotive sensor coordinate frame.
+ * int32Values[1] = qx, the quaternion coefficient x within the quaterinion (w + xi + yj +
+ * zk) describing the rotation of the sensor relative to the Android
+ * Automotive sensor coordinate frame.
+ * int32Values[2] = qy, the quaternion coefficient y within the quaterinion (w + xi + yj +
+ * zk) describing the rotation of the sensor relative to the Android
+ * Automotive sensor coordinate frame.
+ * int32Values[3] = qz, the quaternion coefficient z within the quaterinion (w + xi + yj +
+ * zk) describing the rotation of the sensor relative to the Android
+ * Automotive sensor coordinate frame.
+ *
+ * This assumes each sensor uses the same axes conventions as Android Automotive.
+ *
+ * If the data is aggregated by another ECU, then OEMs have the option of reporting the same
+ * reading across all included sensors or reporting a virtual representation of all the included
+ * sensors as if they were one sensor.
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ * @version 3
+ */
+ ULTRASONICS_SENSOR_ORIENTATION = 0x0C21 + VehiclePropertyGroup.SYSTEM + VehicleArea.VENDOR
+ + VehiclePropertyType.FLOAT_VEC,
+
+ /**
+ * Static data for the field of view of each ultrasonic sensor in degrees.
+ *
+ * Each individual sensor is identified by its VehicleAreaConfig#areaId and returns the sensor's
+ * field of view formatted as [horizontal, vertical] where:
+ *
+ * int32Values[0] = horizontal, the horizontal field of view for the specified ultrasonic
+ * sensor in degrees.
+ * int32Values[1] = vertical, the vertical field of view for the associated specified
+ * ultrasonic sensor in degrees.
+ *
+ * This assumes each sensor uses the same axes conventions as Android Automotive.
+ *
+ * If the data is aggregated by another ECU, then OEMs have the option of reporting the same
+ * reading across all included sensors or reporting a virtual representation of all the included
+ * sensors as if they were one sensor.
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ * @version 3
+ */
+ ULTRASONICS_SENSOR_FIELD_OF_VIEW = 0x0C22 + VehiclePropertyGroup.SYSTEM + VehicleArea.VENDOR
+ + VehiclePropertyType.INT32_VEC,
+
+ /**
+ * Static data for the detection range of each ultrasonic sensor in millimeters.
+ *
+ * Each individual sensor is identified by its VehicleAreaConfig#areaId and returns the sensor's
+ * detection range formatted as [minimum, maximum] where:
+ *
+ * int32Values[0] = minimum, the minimum range detectable by the ultrasonic sensor in
+ * millimeters.
+ * int32Values[1] = maximum, the maximum range detectable by the ultrasonic sensor in
+ * millimeters.
+ *
+ * If the data is aggregated by another ECU, then OEMs have the option of reporting the same
+ * reading across all included sensors or reporting a virtual representation of all the included
+ * sensors as if they were one sensor.
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ * @version 3
+ */
+ ULTRASONICS_SENSOR_DETECTION_RANGE = 0x0C23 + VehiclePropertyGroup.SYSTEM + VehicleArea.VENDOR
+ + VehiclePropertyType.INT32_VEC,
+
+ /**
+ * Static data for the supported ranges of each ultrasonic sensor in millimeters.
+ *
+ * For ultrasonic sensors that only support readings within a specific range. For example, if
+ * an ultrasonic sensor detects an object at 700mm, but can only report that an object has been
+ * detected between 500mm and 1000mm.
+ *
+ * Each individual sensor is identified by its VehicleAreaConfig#areaId and returns the sensor's
+ * supported ranges formatted as [range_min_1, range_max_1, range_min_2, range_max_2, ...]
+ * where:
+ *
+ * int32Values[0] = range_min_1, the minimum of one supported range by the specified sensor
+ * in millimeters, inclusive.
+ * int32Values[1] = range_max_1, the maximum of one supported range by the specified sensor
+ * in millimeters, inclusive.
+ * int32Values[2] = range_min_2, the minimum of another supported range by the specified
+ * sensor in millimeters, inclusive.
+ * int32Values[3] = range_max_2, the maximum of another supported range by the specified
+ sensor in millimeters, inclusive.
+ *
+ * Example:
+ * - Ultrasonic sensor supports the following ranges:
+ * - 150mm to 499mm
+ * - 500mm to 999mm
+ * - 1000mm to 1500mm
+ * - The associated supported ranges should be formatted as:
+ * - int32Values[0] = 150
+ * - int32Values[1] = 499
+ * - int32Values[2] = 500
+ * - int32Values[3] = 999
+ * - int32Values[4] = 1000
+ * - int32Values[5] = 1500
+ *
+ * If this property is not defined, all the values within the ULTRASONICS_SENSOR_DETECTION_RANGE
+ * for the specified sensor are assumed to be supported.
+ *
+ * If the data is aggregated by another ECU, then OEMs have the option of reporting the same
+ * reading across all included sensors or reporting a virtual representation of all the included
+ * sensors as if they were one sensor.
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ * @version 3
+ */
+ ULTRASONICS_SENSOR_SUPPORTED_RANGES = 0x0C24 + VehiclePropertyGroup.SYSTEM + VehicleArea.VENDOR
+ + VehiclePropertyType.INT32_VEC,
+
+ /**
+ * The distance reading of the nearest detected object per sensor in millimeters.
+ *
+ * Each individual sensor is identified by its VehicleAreaConfig#areaId and returns the sensor's
+ * measured distance formatted as [distance, distance_error] where:
+ *
+ * int32Values[0] = distance, the measured distance of the nearest object in millimeters.
+ * If only a range is supported, this value must be set to the minimum
+ * supported distance in the detected range as specified in
+ * ULTRASONICS_SENSOR_SUPPORTED_RANGES.
+ * int32Values[1] = distance_error, the error of the measured distance value in
+ * millimeters.
+ *
+ * If no object is detected, an empty vector must be returned. If distance_error is not
+ * available then an array of only the measured distance must be returned.
+ *
+ * If the data is aggregated by another ECU, then OEMs have the option of reporting the same
+ * reading across all included sensors or reporting a virtual representation of all the included
+ * sensors as if they were one sensor.
+ *
+ * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+ * @access VehiclePropertyAccess.READ
+ * @version 3
+ */
+ ULTRASONICS_SENSOR_MEASURED_DISTANCE = 0x0C25 + VehiclePropertyGroup.SYSTEM + VehicleArea.VENDOR
+ + VehiclePropertyType.INT32_VEC,
+
/**
* OBD2 Live Sensor Data
*
@@ -3243,6 +3723,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
OBD2_LIVE_FRAME = 0x0D00 + 0x10000000 + 0x01000000
+ 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -3269,6 +3750,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
OBD2_FREEZE_FRAME = 0x0D01 + 0x10000000 + 0x01000000
+ 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -3286,6 +3768,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
OBD2_FREEZE_FRAME_INFO = 0x0D02 + 0x10000000 + 0x01000000
+ 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -3308,6 +3791,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.WRITE
+ * @version 2
*/
OBD2_FREEZE_FRAME_CLEAR = 0x0D03 + 0x10000000 + 0x01000000
+ 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -3319,6 +3803,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleLightState
+ * @version 2
*/
HEADLIGHTS_STATE = 0x0E00 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -3330,6 +3815,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleLightState
+ * @version 2
*/
HIGH_BEAM_LIGHTS_STATE = 0x0E01 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -3357,6 +3843,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleLightState
+ * @version 2
*/
FOG_LIGHTS_STATE = 0x0E02 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -3368,6 +3855,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleLightState
+ * @version 2
*/
HAZARD_LIGHTS_STATE = 0x0E03 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -3383,6 +3871,7 @@
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleLightSwitch
+ * @version 2
*/
HEADLIGHTS_SWITCH = 0x0E10 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -3398,6 +3887,7 @@
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleLightSwitch
+ * @version 2
*/
HIGH_BEAM_LIGHTS_SWITCH = 0x0E11 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -3429,6 +3919,7 @@
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleLightSwitch
+ * @version 2
*/
FOG_LIGHTS_SWITCH = 0x0E12 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -3444,6 +3935,7 @@
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleLightSwitch
+ * @version 2
*/
HAZARD_LIGHTS_SWITCH = 0x0E13 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -3455,6 +3947,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleLightState
+ * @version 2
*/
CABIN_LIGHTS_STATE = 0x0F01 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -3473,6 +3966,7 @@
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleLightSwitch
+ * @version 2
*/
CABIN_LIGHTS_SWITCH = 0x0F02 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -3484,6 +3978,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleLightState
+ * @version 2
*/
READING_LIGHTS_STATE = 0x0F03 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -3502,6 +3997,7 @@
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleLightSwitch
+ * @version 2
*/
READING_LIGHTS_SWITCH = 0x0F04 + 0x10000000 + 0x05000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -3523,6 +4019,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleLightState
+ * @version 2
*/
STEERING_WHEEL_LIGHTS_STATE =
0x0F0C + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -3548,6 +4045,7 @@
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleLightSwitch
+ * @version 2
*/
STEERING_WHEEL_LIGHTS_SWITCH =
0x0F0D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -3576,6 +4074,7 @@
*
* @change_mode VehiclePropertyChangeMode.STATIC
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SUPPORT_CUSTOMIZE_VENDOR_PERMISSION = 0x0F05 + 0x10000000 + 0x01000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -3592,6 +4091,7 @@
* ex) "com.android.car.user.CarUserNoticeService,storage_monitoring"
* @change_mode VehiclePropertyChangeMode.STATIC
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
DISABLED_OPTIONAL_FEATURES = 0x0F06 + 0x10000000 + 0x01000000
+ 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
@@ -3642,6 +4142,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
+ * @version 2
*/
INITIAL_USER_INFO = 0x0F07 + 0x10000000 + 0x01000000
+ 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -3808,6 +4309,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
+ * @version 2
*/
SWITCH_USER = 0x0F08 + 0x10000000 + 0x01000000
+ 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -3854,6 +4356,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
+ * @version 2
*/
CREATE_USER = 0x0F09 + 0x10000000 + 0x01000000
+ 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -3885,6 +4388,7 @@
*
* @change_mode VehiclePropertyChangeMode.STATIC
* @access VehiclePropertyAccess.WRITE
+ * @version 2
*/
REMOVE_USER = 0x0F0A + 0x10000000 + 0x01000000
+ 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -3960,6 +4464,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
+ * @version 2
*/
USER_IDENTIFICATION_ASSOCIATION = 0x0F0B + 0x10000000 + 0x01000000
+ 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -3979,6 +4484,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
EVS_SERVICE_REQUEST = 0x0F10 + 0x10000000 + 0x01000000
+ 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -3996,6 +4502,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
POWER_POLICY_REQ = 0x0F21 + 0x10000000 + 0x01000000
+ 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
@@ -4015,6 +4522,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
POWER_POLICY_GROUP_REQ = 0x0F22 + 0x10000000 + 0x01000000
+ 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
@@ -4027,6 +4535,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
+ * @version 2
*/
CURRENT_POWER_POLICY = 0x0F23 + 0x10000000 + 0x01000000
+ 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
@@ -4038,6 +4547,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.WRITE
+ * @version 2
*/
WATCHDOG_ALIVE = 0xF31 + 0x10000000 + 0x01000000
+ 0x00500000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64
@@ -4049,6 +4559,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.WRITE
+ * @version 2
*/
WATCHDOG_TERMINATED_PROCESS = 0x0F32 + 0x10000000 + 0x01000000
+ 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -4064,6 +4575,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
VHAL_HEARTBEAT = 0x0F33 + 0x10000000 + 0x01000000
+ 0x00500000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64
@@ -4077,6 +4589,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
CLUSTER_SWITCH_UI = 0x0F34 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4101,6 +4614,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
CLUSTER_DISPLAY_STATE = 0x0F35 + 0x10000000 + 0x01000000
+ 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -4136,6 +4650,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.WRITE
+ * @version 2
*/
CLUSTER_REPORT_STATE = 0x0F36 + 0x10000000 + 0x01000000
+ 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -4150,6 +4665,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.WRITE
+ * @version 2
*/
CLUSTER_REQUEST_DISPLAY = 0x0F37 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4160,6 +4676,7 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.WRITE
+ * @version 2
*/
CLUSTER_NAVIGATION_STATE = 0x0F38 + 0x10000000 + 0x01000000
+ 0x00700000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BYTES
@@ -4173,6 +4690,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @data_enum ElectronicTollCollectionCardType
+ * @version 2
*/
ELECTRONIC_TOLL_COLLECTION_CARD_TYPE = 0x0F39 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4187,6 +4705,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @data_enum ElectronicTollCollectionCardStatus
+ * @version 2
*/
ELECTRONIC_TOLL_COLLECTION_CARD_STATUS = 0x0F3A + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4200,6 +4719,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleLightState
+ * @version 2
*/
FRONT_FOG_LIGHTS_STATE = 0x0F3B + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4218,6 +4738,7 @@
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleLightSwitch
+ * @version 2
*/
FRONT_FOG_LIGHTS_SWITCH = 0x0F3C + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4232,6 +4753,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleLightState
+ * @version 2
*/
REAR_FOG_LIGHTS_STATE = 0x0F3D + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4250,6 +4772,7 @@
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
* @data_enum VehicleLightSwitch
+ * @version 2
*/
REAR_FOG_LIGHTS_SWITCH = 0x0F3E + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4267,6 +4790,7 @@
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:AMPERE
+ * @version 2
*/
EV_CHARGE_CURRENT_DRAW_LIMIT = 0x0F3F + 0x10000000 + 0x01000000
+ 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -4288,6 +4812,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
EV_CHARGE_PERCENT_LIMIT = 0x0F40 + 0x10000000 + 0x01000000
+ 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -4300,6 +4825,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @data_enum EvChargeState
+ * @version 2
*/
EV_CHARGE_STATE = 0x0F41 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4316,6 +4842,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
EV_CHARGE_SWITCH = 0x0F42 + 0x10000000 + 0x01000000
+ 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -4328,6 +4855,7 @@
* @change_mode VehiclePropertyChangeMode.CONTINUOUS
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:SECS
+ * @version 2
*/
EV_CHARGE_TIME_REMAINING = 0x0F43 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4341,6 +4869,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @data_enum EvRegenerativeBrakingState
+ * @version 2
*/
EV_REGENERATIVE_BRAKING_STATE = 0x0F44 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4353,6 +4882,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @data_enum TrailerState
+ * @version 2
*/
TRAILER_PRESENT = 0x0F45 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4376,6 +4906,7 @@
* @change_mode VehiclePropertyChangeMode.STATIC
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:KILOGRAM
+ * @version 2
*/
VEHICLE_CURB_WEIGHT = 0x0F46 + 0x10000000 + 0x01000000
@@ -4390,6 +4921,7 @@
* @change_mode VehiclePropertyChangeMode.STATIC
* @access VehiclePropertyAccess.READ
* @data_enum GsrComplianceRequirementType
+ * @version 2
*/
GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT = 0x0F47 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4414,6 +4946,7 @@
*
* @change_mode VehiclePropertyChangeMode.STATIC
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
SUPPORTED_PROPERTY_IDS = 0x0F48 + 0x10000000 + 0x01000000
+ 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -4421,12 +4954,22 @@
/**
* Request the head unit to be shutdown.
*
+ * <p>This is required for executing a task when the head unit is powered off (remote task
+ * feature). After the head unit is powered-on to execute the task, the head unit should
+ * be shutdown. The head unit will send this message once the task is finished.
+ *
+ * <p>This is not for the case when a user wants to shutdown the head unit.
+ *
* <p>This usually involves telling a separate system outside the head unit (e.g. a power
* controller) to prepare shutting down the head unit.
*
- * <p>This does not mean the head unit will shutdown immediately.
+ * <p>Note that the external system must validate whether this request is valid by checking
+ * whether the vehicle is currently in use. If a user enters the vehicle after a
+ * SHUTDOWN_REQUEST is sent, then the system must ignore this request. It
+ * is recommended to store a VehicleInUse property in the power controller and exposes it
+ * through VEHICLE_IN_USE property. A shutdown request must be ignored if VehicleInUse is true.
*
- * <p>This means that another system will start sending a shutdown signal to the head unit,
+ * <p>If allowed, the external system will start sending a shutdown signal to the head unit,
* which will cause VHAL to send SHUTDOWN_PREPARE message to Android. Android will then start
* the shut down process by handling the message.
*
@@ -4451,6 +4994,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.WRITE
* @data_enum VehicleApPowerStateShutdownParam
+ * @version 2
*/
SHUTDOWN_REQUEST =
0x0F49 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -4483,6 +5027,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
VEHICLE_IN_USE =
0x0F4A + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -4497,10 +5042,55 @@
*
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.WRITE
+ * @version 3
*/
CLUSTER_HEARTBEAT =
0x0F4B + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.MIXED,
+ /**
+ * Current state of vehicle autonomy.
+ *
+ * Defines the level of autonomy currently engaged in the vehicle from the J3016_202104 revision
+ * of the SAE standard levels 0-5, with 0 representing no autonomy and 5 representing full
+ * driving automation. These levels should be used in accordance with the standards defined in
+ * https://www.sae.org/standards/content/j3016_202104/ and
+ * https://www.sae.org/blog/sae-j3016-update
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of VehicleAutonomousState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum VehicleAutonomousState
+ * @version 3
+ */
+ VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL =
+ 0x0F4C + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Reports current state of CarEvsService types.
+ *
+ * Informs other components of current state of each CarEvsService service type with values
+ * defined in CameraServiceState. CarEvsService will update this property whenever a service
+ * type transitions into a new state.
+ *
+ * int32[0]: Current state of REARVIEW service type.
+ * int32[1]: Current state of SURROUNDVIEW service type.
+ * int32[2]: Current state of FRONTVIEW service type.
+ * int32[3]: Current state of LEFTVIEW service type.
+ * int32[4]: Current state of RIGHTVIEW service type.
+ * int32[5]: Current state of DRIVERVIEW service type.
+ * int32[6]: Current state of FRONT_PASSENGERVIEW service type.
+ * int32[7]: Current state of REAR_PASSENGERVIEW service type.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.WRITE
+ * @data_enum CameraServiceState
+ * @version 3
+ */
+ CAMERA_SERVICE_CURRENT_STATE = 0x0F4D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL
+ + VehiclePropertyType.INT32_VEC,
+
/***********************************************************************************************
* Start of ADAS Properties
*
@@ -4511,7 +5101,9 @@
* Enable or disable Automatic Emergency Braking (AEB).
*
* Set true to enable AEB and false to disable AEB. When AEB is enabled, the ADAS system in the
- * vehicle should be turned on and monitoring to avoid potential collisions.
+ * vehicle should be turned on and monitoring to avoid potential collisions. This property
+ * should apply for higher speed applications only. For enabling low speed automatic emergency
+ * braking, LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED should be used.
*
* In general, AUTOMATIC_EMERGENCY_BRAKING_ENABLED should always return true or false. If the
* feature is not available due to some temporary state, such as the vehicle speed being too
@@ -4524,6 +5116,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
AUTOMATIC_EMERGENCY_BRAKING_ENABLED =
0x1000 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -4533,7 +5126,9 @@
*
* Returns the current state of AEB. This property must always return a valid state defined in
* AutomaticEmergencyBrakingState or ErrorState. It must not surface errors through StatusCode
- * and must use the supported error states instead.
+ * and must use the supported error states instead. This property should apply for higher speed
+ * applications only. For representing the state of the low speed automatic emergency braking
+ * system, LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE should be used.
*
* If AEB includes forward collision warnings before activating the brakes, those warnings must
* be surfaced through the Forward Collision Warning (FCW) properties.
@@ -4546,6 +5141,7 @@
* @access VehiclePropertyAccess.READ
* @data_enum AutomaticEmergencyBrakingState
* @data_enum ErrorState
+ * @version 2
*/
AUTOMATIC_EMERGENCY_BRAKING_STATE =
0x1001 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -4567,6 +5163,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
FORWARD_COLLISION_WARNING_ENABLED =
0x1002 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -4586,6 +5183,7 @@
* @access VehiclePropertyAccess.READ
* @data_enum ForwardCollisionWarningState
* @data_enum ErrorState
+ * @version 2
*/
FORWARD_COLLISION_WARNING_STATE =
0x1003 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -4607,6 +5205,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
BLIND_SPOT_WARNING_ENABLED =
0x1004 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -4626,6 +5225,7 @@
* @access VehiclePropertyAccess.READ
* @data_enum BlindSpotWarningState
* @data_enum ErrorState
+ * @version 2
*/
BLIND_SPOT_WARNING_STATE =
0x1005 + VehiclePropertyGroup.SYSTEM + VehicleArea.MIRROR + VehiclePropertyType.INT32,
@@ -4648,6 +5248,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
LANE_DEPARTURE_WARNING_ENABLED =
0x1006 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -4667,6 +5268,7 @@
* @access VehiclePropertyAccess.READ
* @data_enum LaneDepartureWarningState
* @data_enum ErrorState
+ * @version 2
*/
LANE_DEPARTURE_WARNING_STATE =
0x1007 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -4693,6 +5295,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
LANE_KEEP_ASSIST_ENABLED =
0x1008 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -4715,6 +5318,7 @@
* @access VehiclePropertyAccess.READ
* @data_enum LaneKeepAssistState
* @data_enum ErrorState
+ * @version 2
*/
LANE_KEEP_ASSIST_STATE =
0x1009 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -4742,6 +5346,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
LANE_CENTERING_ASSIST_ENABLED =
0x100A + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -4772,6 +5377,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.WRITE
* @data_enum LaneCenteringAssistCommand
+ * @version 2
*/
LANE_CENTERING_ASSIST_COMMAND =
0x100B + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -4794,6 +5400,7 @@
* @access VehiclePropertyAccess.READ
* @data_enum LaneCenteringAssistState
* @data_enum ErrorState
+ * @version 2
*/
LANE_CENTERING_ASSIST_STATE =
0x100C + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -4817,6 +5424,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
EMERGENCY_LANE_KEEP_ASSIST_ENABLED =
0x100D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -4837,6 +5445,7 @@
* @access VehiclePropertyAccess.READ
* @data_enum EmergencyLaneKeepAssistState
* @data_enum ErrorState
+ * @version 2
*/
EMERGENCY_LANE_KEEP_ASSIST_STATE =
0x100E + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -4861,6 +5470,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
CRUISE_CONTROL_ENABLED =
0x100F + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -4889,6 +5499,7 @@
* @access VehiclePropertyAccess.READ
* @data_enum CruiseControlType
* @data_enum ErrorState
+ * @version 2
*/
CRUISE_CONTROL_TYPE =
0x1010 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -4909,6 +5520,7 @@
* @access VehiclePropertyAccess.READ
* @data_enum CruiseControlState
* @data_enum ErrorState
+ * @version 2
*/
CRUISE_CONTROL_STATE =
0x1011 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -4932,6 +5544,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.WRITE
* @data_enum CruiseControlCommand
+ * @version 2
*/
CRUISE_CONTROL_COMMAND =
0x1012 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -4955,6 +5568,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:METER_PER_SEC
+ * @version 2
*/
CRUISE_CONTROL_TARGET_SPEED =
0x1013 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.FLOAT,
@@ -4986,6 +5600,7 @@
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:MILLI_SECS
+ * @version 2
*/
ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP =
0x1014 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -5016,6 +5631,7 @@
* @change_mode VehiclePropertyChangeMode.CONTINUOUS
* @access VehiclePropertyAccess.READ
* @unit VehicleUnit:MILLIMETER
+ * @version 2
*/
ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE =
0x1015 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -5037,6 +5653,7 @@
* @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.READ_WRITE
* @access VehiclePropertyAccess.READ
+ * @version 2
*/
HANDS_ON_DETECTION_ENABLED =
0x1016 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -5061,6 +5678,7 @@
* @access VehiclePropertyAccess.READ
* @data_enum HandsOnDetectionDriverState
* @data_enum ErrorState
+ * @version 2
*/
HANDS_ON_DETECTION_DRIVER_STATE =
0x1017 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -5083,10 +5701,348 @@
* @access VehiclePropertyAccess.READ
* @data_enum HandsOnDetectionWarning
* @data_enum ErrorState
+ * @version 2
*/
HANDS_ON_DETECTION_WARNING =
0x1018 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+ /**
+ * Enable or disable driver drowsiness and attention monitoring.
+ *
+ * Set true to enable driver drowsiness and attention monitoring and false to disable driver
+ * drowsiness and attention monitoring. When driver drowsiness and attention monitoring is
+ * enabled, a system inside the vehicle should be monitoring the drowsiness and attention level
+ * of the driver and warn the driver if needed.
+ *
+ * In general, DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED should always return true or false.
+ * If the feature is not available due to some temporary state, that information must be
+ * conveyed through the ErrorState values in the DRIVER_DROWSINESS_ATTENTION_STATE property.
+ *
+ * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+ * implement it as VehiclePropertyAccess.READ only.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @access VehiclePropertyAccess.READ
+ * @version 3
+ */
+ DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED =
+ 0x1019 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Driver drowsiness and attention level state.
+ *
+ * Returns the current detected state of driver drowiness and attention level based on the
+ * Karolinska Sleepiness scale. If alternative measurement methods are used, the value should be
+ * translated to the Karolinska Sleepiness Scale equivalent.
+ *
+ * Generally, this property should return a valid state defined in the
+ * DriverDrowsinessAttentionState or ErrorState. For example, if the feature is not available
+ * due to some temporary state, that information should be conveyed through ErrorState.
+ *
+ * If the vehicle is sending a warning to the user because the driver is too drowsy, the warning
+ * should be surfaced through {@link #DRIVER_DROWSINESS_ATTENTION_WARNING}.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both DriverDrowsinessAttentionState (including OTHER, which is not
+ * recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum DriverDrowsinessAttentionState
+ * @data_enum ErrorState
+ * @version 3
+ */
+ DRIVER_DROWSINESS_ATTENTION_STATE =
+ 0x101A + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Enable or disable driver drowsiness and attention warnings.
+ *
+ * Set true to enable driver drowsiness and attention warnings and false to disable driver
+ * drowsiness and attention warnings.
+ *
+ * When driver drowsiness and attention warnings are enabled, the driver drowsiness and
+ * attention monitoring system inside the vehicle should warn the driver when it detects the
+ * driver is drowsy or not attentive.
+ *
+ * In general, DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED should always return true or false.
+ * If the feature is not available due to some temporary state, that information must be
+ * conveyed through the ErrorState values in the DRIVER_DROWSINESS_ATTENTION_WARNING property.
+ *
+ * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+ * implement it as VehiclePropertyAccess.READ only.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @access VehiclePropertyAccess.READ
+ * @version 3
+ */
+ DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED =
+ 0x101B + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Driver drowsiness and attention warning.
+ *
+ * Returns whether a warning is being sent to the driver for being drowsy or not attentive.
+ *
+ * Generally, this property should return a valid state defined in
+ * DriverDrowsinessAttentionWarning or ErrorState. For example, if the feature is not available
+ * due to some temporary state, that information should be conveyed through an ErrorState.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both DriverDrowsinessAttentionWarning (including OTHER, which is not
+ * recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum DriverDrowsinessAttentionWarning
+ * @data_enum ErrorState
+ * @version 3
+ */
+ DRIVER_DROWSINESS_ATTENTION_WARNING =
+ 0x101C + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Enable or disable driver distraction monitoring.
+ *
+ * Set true to enable driver distraction monitoring and false to disable driver
+ * distraction monitoring. When driver distraction monitoring is enabled, a system
+ * inside the vehicle should be monitoring the distraction level of the driver and
+ * warn the driver if needed.
+ *
+ * In general, DRIVER_DISTRACTION_SYSTEM_ENABLED should always return true or false. If the
+ * feature is not available due to some temporary state, that information must be conveyed
+ * through the ErrorState values in the DRIVER_DISTRACTION_STATE property.
+ *
+ * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+ * implement it as VehiclePropertyAccess.READ only.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @access VehiclePropertyAccess.READ
+ * @version 3
+ */
+ DRIVER_DISTRACTION_SYSTEM_ENABLED =
+ 0x101D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Driver distraction state.
+ *
+ * Returns the current detected driver distraction state.
+ *
+ * Generally, this property should return a valid state defined in the DriverDistractionState or
+ * ErrorState. For example, if the feature is not available due to some temporary state, that
+ * information should be conveyed through ErrorState.
+ *
+ * If the vehicle is sending a warning to the user because the driver is too distracted, the
+ * warning should be surfaced through {@link #DRIVER_DISTRACTION_WARNING}.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both DriverDistractionState (including OTHER, which is not
+ * recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum DriverDistractionState
+ * @data_enum ErrorState
+ * @version 3
+ */
+ DRIVER_DISTRACTION_STATE =
+ 0x101E + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Enable or disable driver distraction warnings.
+ *
+ * Set true to enable driver distraction warnings and false to disable driver distraction
+ * warnings.
+ *
+ * When driver distraction warnings are enabled, the driver distraction monitoring system inside
+ * the vehicle should warn the driver when it detects the driver is distracted.
+ *
+ * In general, DRIVER_DISTRACTION_WARNING_ENABLED should always return true or false. If the
+ * feature is not available due to some temporary state, that information must be conveyed
+ * through the ErrorState values in the DRIVER_DISTRACTION_WARNING property.
+ *
+ * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+ * implement it as VehiclePropertyAccess.READ only.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @access VehiclePropertyAccess.READ
+ * @version 2
+ */
+ DRIVER_DISTRACTION_WARNING_ENABLED =
+ 0x101F + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Driver distraction warning.
+ *
+ * Returns whether a warning is being sent to the driver for being distracted.
+ *
+ * Generally, this property should return a valid state defined in DriverDistractionWarning or
+ * ErrorState. For example, if the feature is not available due to some temporary state, that
+ * information should be conveyed through an ErrorState.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both DriverDistractionWarning (including OTHER, which is not
+ * recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum DriverDistractionWarning
+ * @data_enum ErrorState
+ * @version 3
+ */
+ DRIVER_DISTRACTION_WARNING =
+ 0x1020 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Enable or disable Low Speed Collision Warning.
+ *
+ * Set true to enable low speed collision warning and false to disable low speed collision
+ * warning. When low speed collision warning is enabled, the ADAS system in the vehicle should
+ * warn the driver of potential collisions at low speeds. This property is different from the
+ * pre-existing FORWARD_COLLISION_WARNING_ENABLED, which should apply to higher speed
+ * applications only. If the vehicle doesn't have a separate collision detection system for low
+ * speed environments, this property should not be implemented.
+ *
+ * In general, LOW_SPEED_COLLISION_WARNING_ENABLED should always return true or false. If the
+ * feature is not available due to some temporary state, such as the vehicle speed being too
+ * high, that information must be conveyed through the ErrorState values in the
+ * LOW_SPEED_COLLISION_WARNING_STATE property.
+ *
+ * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+ * implement it as VehiclePropertyAccess.READ only.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @access VehiclePropertyAccess.READ
+ * @version 3
+ */
+ LOW_SPEED_COLLISION_WARNING_ENABLED =
+ 0x1021 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Low Speed Collision Warning state.
+ *
+ * Returns the current state of Low Speed Collision Warning. This property must always return a
+ * valid state defined in LowSpeedCollisionWarningState or ErrorState. It must not surface
+ * errors through StatusCode and must use the supported error states instead. This property is
+ * different from the pre-existing FORWARD_COLLISION_WARNING_STATE, which should apply to higher
+ * speed applications only. If the vehicle doesn't have a separate collision detection system
+ * for low speed environments, this property should not be implemented.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both LowSpeedCollisionWarningState (including OTHER, which is not
+ * recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum LowSpeedCollisionWarningState
+ * @data_enum ErrorState
+ * @version 3
+ */
+ LOW_SPEED_COLLISION_WARNING_STATE =
+ 0x1022 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Enable or disable Cross Traffic Monitoring.
+ *
+ * Set true to enable Cross Traffic Monitoring and false to disable Cross Traffic Monitoring.
+ * When Cross Traffic Monitoring is enabled, the ADAS system in the vehicle should be turned on
+ * and monitoring for potential sideways collisions.
+ *
+ * In general, CROSS_TRAFFIC_MONITORING_ENABLED should always return true or false. If the
+ * feature is not available due to some temporary state, such as the vehicle speed being too
+ * high, that information must be conveyed through the ErrorState values in the
+ * CROSS_TRAFFIC_MONITORING_STATE property.
+ *
+ * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+ * implement it as VehiclePropertyAccess.READ only.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @access VehiclePropertyAccess.READ
+ * @version 3
+ */
+ CROSS_TRAFFIC_MONITORING_ENABLED =
+ 0x1023 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Cross Traffic Monitoring warning state.
+ *
+ * Returns the current state of Cross Traffic Monitoring Warning. This property must always
+ * return a valid state defined in CrossTrafficMonitoringWarningState or ErrorState. It must not
+ * surface errors through StatusCode and must use the supported error states instead.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both CrossTrafficMonitoringWarningState (including OTHER, which is not
+ * recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum CrossTrafficMonitoringWarningState
+ * @data_enum ErrorState
+ * @version 3
+ */
+ CROSS_TRAFFIC_MONITORING_WARNING_STATE =
+ 0x1024 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Enable or disable Low Speed Automatic Emergency Braking.
+ *
+ * Set true to enable Low Speed Automatic Emergency Braking or false to disable Low Speed
+ * Automatic Emergency Braking. When Low Speed Automatic Emergency Braking is enabled, the ADAS
+ * system in the vehicle should be turned on and monitoring to avoid potential collisions in low
+ * speed conditions. This property is different from the pre-existing
+ * AUTOMATIC_EMERGENCY_BRAKING_ENABLED, which should apply to higher speed applications only. If
+ * the vehicle doesn't have a separate collision avoidance system for low speed environments,
+ * this property should not be implemented.
+ *
+ * In general, LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED should always return true or false.
+ * If the feature is not available due to some temporary state, such as the vehicle speed being
+ * too low, that information must be conveyed through the ErrorState values in the
+ * LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE property.
+ *
+ * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+ * implement it as VehiclePropertyAccess.READ only.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @access VehiclePropertyAccess.READ
+ * @version 3
+ */
+ LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED =
+ 0x1025 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Low Speed Automatic Emergency Braking state.
+ *
+ * Returns the current state of Low Speed Automatic Emergency Braking. This property must always
+ * return a valid state defined in LowSpeedAutomaticEmergencyBrakingState or ErrorState. It must
+ * not surface errors through StatusCode and must use the supported error states instead. This
+ * property is different from the pre-existing AUTOMATIC_EMERGENCY_BRAKING_STATE, which should
+ * apply to higher speed applications only. If the vehicle doesn't have a separate collision
+ * avoidance system for low speed environments, this property should not be implemented.
+ *
+ * If Low Speed Automatic Emergency Braking includes collision warnings before activating the
+ * brakes, those warnings must be surfaced through use of LOW_SPEED_COLLISION_WARNING_ENABLED
+ * and LOW_SPEED_COLLISION_WARNING_STATE.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both LowSpeedAutomaticEmergencyBrakingState (including OTHER, which is
+ * not recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum LowSpeedAutomaticEmergencyBrakingState
+ * @data_enum ErrorState
+ * @version 3
+ */
+ LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE =
+ 0x1026 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
/***************************************************************************
* End of ADAS Properties
**************************************************************************/
diff --git a/automotive/vehicle/tools/generate_annotation_enums.py b/automotive/vehicle/tools/generate_annotation_enums.py
index 05fc99a..93d408e 100755
--- a/automotive/vehicle/tools/generate_annotation_enums.py
+++ b/automotive/vehicle/tools/generate_annotation_enums.py
@@ -42,6 +42,8 @@
'AccessForVehicleProperty.java')
ENUM_JAVA_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/java/' +
'EnumForVehicleProperty.java')
+VERSION_CPP_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/cpp/' +
+ 'VersionForVehicleProperty.h')
SCRIPT_PATH = 'hardware/interfaces/automotive/vehicle/tools/generate_annotation_enums.py'
TAB = ' '
@@ -50,6 +52,7 @@
RE_COMMENT_BEGIN = re.compile('\s*\/\*\*?')
RE_COMMENT_END = re.compile('\s*\*\/')
RE_CHANGE_MODE = re.compile('\s*\* @change_mode (\S+)\s*')
+RE_VERSION = re.compile('\s*\* @version (\S+)\s*')
RE_ACCESS = re.compile('\s*\* @access (\S+)\s*')
RE_DATA_ENUM = re.compile('\s*\* @data_enum (\S+)\s*')
RE_UNIT = re.compile('\s*\* @unit (\S+)\s+')
@@ -81,8 +84,7 @@
"""
-CHANGE_MODE_CPP_HEADER = """#ifndef android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
-#define android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
+CHANGE_MODE_CPP_HEADER = """#pragma once
#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.h>
@@ -98,7 +100,7 @@
std::unordered_map<VehicleProperty, VehiclePropertyChangeMode> ChangeModeForVehicleProperty = {
"""
-CHANGE_MODE_CPP_FOOTER = """
+CPP_FOOTER = """
};
} // namespace vehicle
@@ -106,12 +108,9 @@
} // namespace hardware
} // namespace android
} // aidl
-
-#endif // android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
"""
-ACCESS_CPP_HEADER = """#ifndef android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
-#define android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
+ACCESS_CPP_HEADER = """#pragma once
#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyAccess.h>
@@ -127,16 +126,19 @@
std::unordered_map<VehicleProperty, VehiclePropertyAccess> AccessForVehicleProperty = {
"""
-ACCESS_CPP_FOOTER = """
-};
+VERSION_CPP_HEADER = """#pragma once
-} // namespace vehicle
-} // namespace automotive
-} // namespace hardware
-} // namespace android
-} // aidl
+#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
-#endif // android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
+#include <unordered_map>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+std::unordered_map<VehicleProperty, int32_t> VersionForVehicleProperty = {
"""
CHANGE_MODE_JAVA_HEADER = """package android.hardware.automotive.vehicle;
@@ -148,7 +150,7 @@
public static final Map<Integer, Integer> values = Map.ofEntries(
"""
-CHANGE_MODE_JAVA_FOOTER = """
+JAVA_FOOTER = """
);
}
@@ -163,12 +165,6 @@
public static final Map<Integer, Integer> values = Map.ofEntries(
"""
-ACCESS_JAVA_FOOTER = """
- );
-
-}
-"""
-
ENUM_JAVA_HEADER = """package android.hardware.automotive.vehicle;
import java.util.List;
@@ -179,12 +175,6 @@
public static final Map<Integer, List<Class<?>>> values = Map.ofEntries(
"""
-ENUM_JAVA_FOOTER = """
- );
-
-}
-"""
-
class PropertyConfig:
"""Represents one VHAL property definition in VehicleProperty.aidl."""
@@ -192,10 +182,12 @@
def __init__(self):
self.name = None
self.description = None
+ self.comment = None
self.change_mode = None
self.access_modes = []
self.enum_types = []
self.unit_type = None
+ self.version = None
def __repr__(self):
return self.__str__()
@@ -203,8 +195,9 @@
def __str__(self):
return ('PropertyConfig{{' +
'name: {}, description: {}, change_mode: {}, access_modes: {}, enum_types: {}' +
- ', unit_type: {}}}').format(self.name, self.description, self.change_mode,
- self.access_modes, self.enum_types, self.unit_type)
+ ', unit_type: {}, version: {}, comment: {}}}').format(self.name, self.description,
+ self.change_mode, self.access_modes, self.enum_types, self.unit_type,
+ self.version, self.comment)
class FileParser:
@@ -230,34 +223,59 @@
in_comment = True
config = PropertyConfig()
description = ''
+ continue
+
if RE_COMMENT_END.match(line):
in_comment = False
if in_comment:
- if not config.description:
- sline = line.strip()
- # Skip the first line of comment
- if sline.startswith('*'):
- # Remove the '*'.
- sline = sline[1:].strip()
- # We reach an empty line of comment, the description part is ending.
- if sline == '':
- config.description = description
- else:
- if description != '':
- description += ' '
- description += sline
match = RE_CHANGE_MODE.match(line)
if match:
config.change_mode = match.group(1).replace('VehiclePropertyChangeMode.', '')
+ continue
match = RE_ACCESS.match(line)
if match:
config.access_modes.append(match.group(1).replace('VehiclePropertyAccess.', ''))
+ continue
match = RE_UNIT.match(line)
if match:
config.unit_type = match.group(1)
+ continue
match = RE_DATA_ENUM.match(line)
if match:
config.enum_types.append(match.group(1))
+ continue
+ match = RE_VERSION.match(line)
+ if match:
+ if config.version != None:
+ raise Exception('Duplicate version annotation for property: ' + prop_name)
+ config.version = match.group(1)
+ continue
+
+ sline = line.strip()
+ if sline.startswith('*'):
+ # Remove the '*'.
+ sline = sline[1:].strip()
+
+ if not config.description:
+ # We reach an empty line of comment, the description part is ending.
+ if sline == '':
+ config.description = description
+ else:
+ if description != '':
+ description += ' '
+ description += sline
+ else:
+ if not config.comment:
+ if sline != '':
+ # This is the first line for comment.
+ config.comment = sline
+ else:
+ if sline != '':
+ # Concat this line with the previous line's comment with a space.
+ config.comment += ' ' + sline
+ else:
+ # Treat empty line comment as a new line.
+ config.comment += '\n'
else:
match = RE_VALUE.match(line)
if match:
@@ -270,6 +288,9 @@
if not config.access_modes:
raise Exception(
'No access_mode annotation for property: ' + prop_name)
+ if not config.version:
+ raise Exception(
+ 'no version annotation for property: ' + prop_name)
config.name = prop_name
configs.append(config)
@@ -295,6 +316,9 @@
continue;
if not cpp:
annotation = "List.of(" + ', '.join([class_name + ".class" for class_name in config.enum_types]) + ")"
+ elif field == 'version':
+ if cpp:
+ annotation = config.version
else:
raise Exception('Unknown field: ' + field)
if counter != 0:
@@ -317,7 +341,7 @@
f.write(content)
def outputAsCsv(self, output):
- content = 'name,description,change mode,access mode,enum type,unit type\n'
+ content = 'name,description,change mode,access mode,enum type,unit type,comment\n'
for config in self.configs:
enum_types = None
if not config.enum_types:
@@ -328,14 +352,18 @@
if not unit_type:
unit_type = '/'
access_modes = ''
- content += '"{}","{}","{}","{}","{}","{}"\n'.format(
+ comment = config.comment
+ if not comment:
+ comment = ''
+ content += '"{}","{}","{}","{}","{}","{}", "{}"\n'.format(
config.name,
# Need to escape quote as double quote.
config.description.replace('"', '""'),
config.change_mode,
'/'.join(config.access_modes),
enum_types,
- unit_type)
+ unit_type,
+ comment.replace('"', '""'))
with open(output, 'w+') as f:
f.write(content)
@@ -347,6 +375,69 @@
return f.name
+class GeneratedFile:
+
+ def __init__(self, type):
+ self.type = type
+ self.cpp_file_path = None
+ self.java_file_path = None
+ self.cpp_header = None
+ self.java_header = None
+ self.cpp_footer = None
+ self.java_footer = None
+ self.cpp_output_file = None
+ self.java_output_file = None
+
+ def setCppFilePath(self, cpp_file_path):
+ self.cpp_file_path = cpp_file_path
+
+ def setJavaFilePath(self, java_file_path):
+ self.java_file_path = java_file_path
+
+ def setCppHeader(self, cpp_header):
+ self.cpp_header = cpp_header
+
+ def setCppFooter(self, cpp_footer):
+ self.cpp_footer = cpp_footer
+
+ def setJavaHeader(self, java_header):
+ self.java_header = java_header
+
+ def setJavaFooter(self, java_footer):
+ self.java_footer = java_footer
+
+ def convert(self, file_parser, check_only, temp_files):
+ if self.cpp_file_path:
+ output_file = GeneratedFile._getOutputFile(self.cpp_file_path, check_only, temp_files)
+ file_parser.convert(output_file, self.cpp_header, self.cpp_footer, True, self.type)
+ self.cpp_output_file = output_file
+
+ if self.java_file_path:
+ output_file = GeneratedFile._getOutputFile(self.java_file_path, check_only, temp_files)
+ file_parser.convert(output_file, self.java_header, self.java_footer, False, self.type)
+ self.java_output_file = output_file
+
+ def cmp(self):
+ if self.cpp_file_path:
+ if not filecmp.cmp(self.cpp_output_file, self.cpp_file_path):
+ return False
+
+ if self.java_file_path:
+ if not filecmp.cmp(self.java_output_file, self.java_file_path):
+ return False
+
+ return True
+
+ @staticmethod
+ def _getOutputFile(file_path, check_only, temp_files):
+ if not check_only:
+ return file_path
+
+ temp_file = createTempFile()
+ temp_files.append(temp_file)
+ return temp_file
+
+
def main():
parser = argparse.ArgumentParser(
description='Generate Java and C++ enums based on annotations in VehicleProperty.aidl')
@@ -382,51 +473,52 @@
f.outputAsCsv(args.output_csv)
return
- change_mode_cpp_file = os.path.join(android_top, CHANGE_MODE_CPP_FILE_PATH);
- access_cpp_file = os.path.join(android_top, ACCESS_CPP_FILE_PATH);
- change_mode_java_file = os.path.join(android_top, CHANGE_MODE_JAVA_FILE_PATH);
- access_java_file = os.path.join(android_top, ACCESS_JAVA_FILE_PATH);
- enum_java_file = os.path.join(android_top, ENUM_JAVA_FILE_PATH);
+ generated_files = []
+
+ change_mode = GeneratedFile('change_mode')
+ change_mode.setCppFilePath(os.path.join(android_top, CHANGE_MODE_CPP_FILE_PATH))
+ change_mode.setJavaFilePath(os.path.join(android_top, CHANGE_MODE_JAVA_FILE_PATH))
+ change_mode.setCppHeader(CHANGE_MODE_CPP_HEADER)
+ change_mode.setCppFooter(CPP_FOOTER)
+ change_mode.setJavaHeader(CHANGE_MODE_JAVA_HEADER)
+ change_mode.setJavaFooter(JAVA_FOOTER)
+ generated_files.append(change_mode)
+
+ access_mode = GeneratedFile('access_mode')
+ access_mode.setCppFilePath(os.path.join(android_top, ACCESS_CPP_FILE_PATH))
+ access_mode.setJavaFilePath(os.path.join(android_top, ACCESS_JAVA_FILE_PATH))
+ access_mode.setCppHeader(ACCESS_CPP_HEADER)
+ access_mode.setCppFooter(CPP_FOOTER)
+ access_mode.setJavaHeader(ACCESS_JAVA_HEADER)
+ access_mode.setJavaFooter(JAVA_FOOTER)
+ generated_files.append(access_mode)
+
+ enum_types = GeneratedFile('enum_types')
+ enum_types.setJavaFilePath(os.path.join(android_top, ENUM_JAVA_FILE_PATH))
+ enum_types.setJavaHeader(ENUM_JAVA_HEADER)
+ enum_types.setJavaFooter(JAVA_FOOTER)
+ generated_files.append(enum_types)
+
+ version = GeneratedFile('version')
+ version.setCppFilePath(os.path.join(android_top, VERSION_CPP_FILE_PATH))
+ version.setCppHeader(VERSION_CPP_HEADER)
+ version.setCppFooter(CPP_FOOTER)
+ generated_files.append(version)
+
temp_files = []
- if not args.check_only:
- change_mode_cpp_output = change_mode_cpp_file
- access_cpp_output = access_cpp_file
- change_mode_java_output = change_mode_java_file
- access_java_output = access_java_file
- enum_java_output = enum_java_file
- else:
- change_mode_cpp_output = createTempFile()
- temp_files.append(change_mode_cpp_output)
- access_cpp_output = createTempFile()
- temp_files.append(access_cpp_output)
- change_mode_java_output = createTempFile()
- temp_files.append(change_mode_java_output)
- access_java_output = createTempFile()
- temp_files.append(access_java_output)
- enum_java_output = createTempFile()
- temp_files.append(enum_java_output)
-
try:
- f.convert(change_mode_cpp_output, CHANGE_MODE_CPP_HEADER, CHANGE_MODE_CPP_FOOTER,
- True, 'change_mode')
- f.convert(change_mode_java_output, CHANGE_MODE_JAVA_HEADER,
- CHANGE_MODE_JAVA_FOOTER, False, 'change_mode')
- f.convert(access_cpp_output, ACCESS_CPP_HEADER, ACCESS_CPP_FOOTER, True, 'access_mode')
- f.convert(access_java_output, ACCESS_JAVA_HEADER, ACCESS_JAVA_FOOTER, False, 'access_mode')
- f.convert(enum_java_output, ENUM_JAVA_HEADER, ENUM_JAVA_FOOTER, False, 'enum_types')
+ for generated_file in generated_files:
+ generated_file.convert(f, args.check_only, temp_files)
if not args.check_only:
return
- if ((not filecmp.cmp(change_mode_cpp_output, change_mode_cpp_file)) or
- (not filecmp.cmp(change_mode_java_output, change_mode_java_file)) or
- (not filecmp.cmp(access_cpp_output, access_cpp_file)) or
- (not filecmp.cmp(access_java_output, access_java_file)) or
- (not filecmp.cmp(enum_java_output, enum_java_file))):
- print('The generated enum files for VehicleProperty.aidl requires update, ')
- print('Run \npython ' + android_top + '/' + SCRIPT_PATH)
- sys.exit(1)
+ for generated_file in generated_files:
+ if not generated_file.cmp():
+ print('The generated enum files for VehicleProperty.aidl requires update, ')
+ print('Run \npython ' + android_top + '/' + SCRIPT_PATH)
+ sys.exit(1)
except Exception as e:
print('Error parsing VehicleProperty.aidl')
print(e)
diff --git a/automotive/vehicle/tools/generate_emu_metadata/Android.bp b/automotive/vehicle/tools/generate_emu_metadata/Android.bp
new file mode 100644
index 0000000..4cb6d3b
--- /dev/null
+++ b/automotive/vehicle/tools/generate_emu_metadata/Android.bp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_binary_host {
+ name: "EnumMetadataGenerator",
+ srcs: ["src/**/*.java"],
+ manifest: "manifest.txt",
+ static_libs: [
+ "javaparser",
+ "javaparser-symbol-solver",
+ "json-prebuilt",
+ "androidx.annotation_annotation",
+ ],
+}
+
+// A rule to convert VHAL property AIDL files to java files.
+gensrcs {
+ name: "gen_vehicle_property_java_file",
+ srcs: [
+ ":android.hardware.automotive.vehicle.property-files",
+ ],
+ tools: ["aidl"],
+ cmd: "$(location aidl) --lang=java --structured --stability=vintf $(in) -I hardware/interfaces/automotive/vehicle/aidl_property --out $(genDir)/hardware/interfaces/automotive/vehicle/aidl_property",
+ output_extension: "java",
+}
+
+// A target to check whether android.hardware.automotive.vehicle-types-meta.json
+// needs to be updated. The output is just an empty cpp file to be included
+// in the higher-level build target.
+// It will generate generated.json at output directory based on VHAL property
+// java files and check it against
+// android.hardware.automotive.vehicle-types-meta.json. If not the same, the
+// build will fail.
+genrule {
+ name: "check_generated_enum_metadata_json",
+ tools: ["EnumMetadataGenerator"],
+ srcs: [
+ ":android.hardware.automotive.vehicle-types-meta",
+ ":gen_vehicle_property_java_file",
+ ],
+ cmd: "$(location EnumMetadataGenerator) --check_against $(location :android.hardware.automotive.vehicle-types-meta) --output_empty_file $(out) --output_json $(genDir)/generate_enum_metadata.json --input_files $(locations :gen_vehicle_property_java_file)",
+ out: ["generate_enum_metadata_checked.cpp"],
+}
diff --git a/automotive/vehicle/tools/generate_emu_metadata/manifest.txt b/automotive/vehicle/tools/generate_emu_metadata/manifest.txt
new file mode 100644
index 0000000..07696da
--- /dev/null
+++ b/automotive/vehicle/tools/generate_emu_metadata/manifest.txt
@@ -0,0 +1 @@
+Main-Class: com.android.car.tool.EmuMetadataGenerator
diff --git a/automotive/vehicle/tools/generate_emu_metadata/src/com/android/car/tool/EmuMetadataGenerator.java b/automotive/vehicle/tools/generate_emu_metadata/src/com/android/car/tool/EmuMetadataGenerator.java
new file mode 100644
index 0000000..8e12f67
--- /dev/null
+++ b/automotive/vehicle/tools/generate_emu_metadata/src/com/android/car/tool/EmuMetadataGenerator.java
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.car.tool;
+
+import com.github.javaparser.StaticJavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.ArrayInitializerExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.NormalAnnotationExpr;
+import com.github.javaparser.ast.expr.SingleMemberAnnotationExpr;
+import com.github.javaparser.ast.expr.UnaryExpr;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.javadoc.Javadoc;
+import com.github.javaparser.javadoc.JavadocBlockTag;
+import com.github.javaparser.javadoc.description.JavadocDescription;
+import com.github.javaparser.javadoc.description.JavadocDescriptionElement;
+import com.github.javaparser.javadoc.description.JavadocInlineTag;
+import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.symbolsolver.JavaSymbolSolver;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserFieldDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+public final class EmuMetadataGenerator {
+ private static final String DEFAULT_PACKAGE_NAME = "android.hardware.automotive.vehicle";
+ private static final String INPUT_DIR_OPTION = "--input_dir";
+ private static final String INPUT_FILES_OPTION = "--input_files";
+ private static final String PACKAGE_NAME_OPTION = "--package_name";
+ private static final String OUTPUT_JSON_OPTION = "--output_json";
+ private static final String OUTPUT_EMPTY_FILE_OPTION = "--output_empty_file";
+ private static final String CHECK_AGAINST_OPTION = "--check_against";
+ private static final String USAGE = "EnumMetadataGenerator " + INPUT_DIR_OPTION
+ + " [path_to_aidl_gen_dir] " + INPUT_FILES_OPTION + " [input_files] "
+ + PACKAGE_NAME_OPTION + " [package_name] " + OUTPUT_JSON_OPTION + " [output_json] "
+ + OUTPUT_EMPTY_FILE_OPTION + " [output_header_file] " + CHECK_AGAINST_OPTION
+ + " [json_file_to_check_against]\n"
+ + "Parses the VHAL property AIDL interface generated Java files to a json file to be"
+ + " used by emulator\n"
+ + "Options: \n" + INPUT_DIR_OPTION
+ + ": the path to a directory containing AIDL interface Java files, "
+ + "either this or input_files must be specified\n" + INPUT_FILES_OPTION
+ + ": one or more Java files, this is used to decide the input "
+ + "directory\n" + PACKAGE_NAME_OPTION
+ + ": the optional package name for the interface, by default is " + DEFAULT_PACKAGE_NAME
+ + "\n" + OUTPUT_JSON_OPTION + ": The output JSON file\n" + OUTPUT_EMPTY_FILE_OPTION
+ + ": Only used for check_mode, this file will be created if "
+ + "check passed\n" + CHECK_AGAINST_OPTION
+ + ": An optional JSON file to check against. If specified, the "
+ + "generated output file will be checked against this file, if they are not the same, "
+ + "the script will fail, otherwise, the output_empty_file will be created\n"
+ + "For example: \n"
+ + "EnumMetadataGenerator --input_dir out/soong/.intermediates/hardware/"
+ + "interfaces/automotive/vehicle/aidl_property/android.hardware.automotive.vehicle."
+ + "property-V3-java-source/gen/ --package_name android.hardware.automotive.vehicle "
+ + "--output_json /tmp/android.hardware.automotive.vehicle-types-meta.json";
+ private static final String VEHICLE_PROPERTY_FILE = "VehicleProperty.java";
+ private static final String CHECK_FILE_PATH =
+ "${ANDROID_BUILD_TOP}/hardware/interfaces/automotive/vehicle/aidl/emu_metadata/"
+ + "android.hardware.automotive.vehicle-types-meta.json";
+
+ // Emulator can display at least this many characters before cutting characters.
+ private static final int MAX_PROPERTY_NAME_LENGTH = 30;
+
+ /**
+ * Parses the enum field declaration as an int value.
+ */
+ private static int parseIntEnumField(FieldDeclaration fieldDecl) {
+ VariableDeclarator valueDecl = fieldDecl.getVariables().get(0);
+ Expression expr = valueDecl.getInitializer().get();
+ if (expr.isIntegerLiteralExpr()) {
+ return expr.asIntegerLiteralExpr().asInt();
+ }
+ // For case like -123
+ if (expr.isUnaryExpr() && expr.asUnaryExpr().getOperator() == UnaryExpr.Operator.MINUS) {
+ return -expr.asUnaryExpr().getExpression().asIntegerLiteralExpr().asInt();
+ }
+ System.out.println("Unsupported expression: " + expr);
+ System.exit(1);
+ return 0;
+ }
+
+ private static boolean isPublicAndStatic(FieldDeclaration fieldDecl) {
+ return fieldDecl.isPublic() && fieldDecl.isStatic();
+ }
+
+ private static String getFieldName(FieldDeclaration fieldDecl) {
+ VariableDeclarator valueDecl = fieldDecl.getVariables().get(0);
+ return valueDecl.getName().asString();
+ }
+
+ private static class Enum {
+ Enum(String name, String packageName) {
+ this.name = name;
+ this.packageName = packageName;
+ }
+
+ public String name;
+ public String packageName;
+ public final List<ValueField> valueFields = new ArrayList<>();
+ }
+
+ private static class ValueField {
+ public String name;
+ public Integer value;
+ public final List<String> dataEnums = new ArrayList<>();
+
+ ValueField(String name, Integer value) {
+ this.name = name;
+ this.value = value;
+ }
+ }
+
+ private static Enum parseEnumInterface(
+ String inputDir, String dirName, String packageName, String enumName) throws Exception {
+ Enum enumIntf = new Enum(enumName, packageName);
+ CompilationUnit cu = StaticJavaParser.parse(new File(
+ inputDir + File.separator + dirName + File.separator + enumName + ".java"));
+ AnnotationDeclaration vehiclePropertyIdsClass =
+ cu.getAnnotationDeclarationByName(enumName).get();
+
+ List<FieldDeclaration> variables = vehiclePropertyIdsClass.findAll(FieldDeclaration.class);
+ for (int i = 0; i < variables.size(); i++) {
+ FieldDeclaration propertyDef = variables.get(i).asFieldDeclaration();
+ if (!isPublicAndStatic(propertyDef)) {
+ continue;
+ }
+ ValueField field =
+ new ValueField(getFieldName(propertyDef), parseIntEnumField(propertyDef));
+ enumIntf.valueFields.add(field);
+ }
+ return enumIntf;
+ }
+
+ // A hacky way to make the key in-order in the JSON object.
+ private static final class OrderedJSONObject extends JSONObject {
+ OrderedJSONObject() {
+ try {
+ Field map = JSONObject.class.getDeclaredField("nameValuePairs");
+ map.setAccessible(true);
+ map.set(this, new LinkedHashMap<>());
+ map.setAccessible(false);
+ } catch (IllegalAccessException | NoSuchFieldException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ private static String readFileContent(String fileName) throws Exception {
+ StringBuffer contentBuffer = new StringBuffer();
+ int bufferSize = 1024;
+ try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
+ char buffer[] = new char[bufferSize];
+ while (true) {
+ int read = reader.read(buffer, 0, bufferSize);
+ if (read == -1) {
+ break;
+ }
+ contentBuffer.append(buffer, 0, read);
+ }
+ }
+ return contentBuffer.toString();
+ }
+
+ private static final class Args {
+ public final String inputDir;
+ public final String pkgName;
+ public final String pkgDir;
+ public final String output;
+ public final String checkFile;
+ public final String outputEmptyFile;
+
+ public Args(String[] args) throws IllegalArgumentException {
+ Map<String, List<String>> valuesByKey = new LinkedHashMap<>();
+ String key = null;
+ for (int i = 0; i < args.length; i++) {
+ String arg = args[i];
+ if (arg.startsWith("--")) {
+ key = arg;
+ continue;
+ }
+ if (key == null) {
+ throw new IllegalArgumentException("Missing key for value: " + arg);
+ }
+ if (valuesByKey.get(key) == null) {
+ valuesByKey.put(key, new ArrayList<>());
+ }
+ valuesByKey.get(key).add(arg);
+ }
+ String pkgName;
+ List<String> values = valuesByKey.get(PACKAGE_NAME_OPTION);
+ if (values == null) {
+ pkgName = DEFAULT_PACKAGE_NAME;
+ } else {
+ pkgName = values.get(0);
+ }
+ String pkgDir = pkgName.replace(".", File.separator);
+ this.pkgName = pkgName;
+ this.pkgDir = pkgDir;
+ String inputDir;
+ values = valuesByKey.get(INPUT_DIR_OPTION);
+ if (values == null) {
+ List<String> inputFiles = valuesByKey.get(INPUT_FILES_OPTION);
+ if (inputFiles == null) {
+ throw new IllegalArgumentException("Either " + INPUT_DIR_OPTION + " or "
+ + INPUT_FILES_OPTION + " must be specified");
+ }
+ inputDir = new File(inputFiles.get(0)).getParent().replace(pkgDir, "");
+ } else {
+ inputDir = values.get(0);
+ }
+ this.inputDir = inputDir;
+ values = valuesByKey.get(OUTPUT_JSON_OPTION);
+ if (values == null) {
+ throw new IllegalArgumentException(OUTPUT_JSON_OPTION + " must be specified");
+ }
+ this.output = values.get(0);
+ values = valuesByKey.get(CHECK_AGAINST_OPTION);
+ if (values != null) {
+ this.checkFile = values.get(0);
+ } else {
+ this.checkFile = null;
+ }
+ values = valuesByKey.get(OUTPUT_EMPTY_FILE_OPTION);
+ if (values != null) {
+ this.outputEmptyFile = values.get(0);
+ } else {
+ this.outputEmptyFile = null;
+ }
+ }
+ }
+
+ /**
+ * Main function.
+ */
+ public static void main(final String[] args) throws Exception {
+ Args parsedArgs;
+ try {
+ parsedArgs = new Args(args);
+ } catch (IllegalArgumentException e) {
+ System.out.println("Invalid arguments: " + e.getMessage());
+ System.out.println(USAGE);
+ System.exit(1);
+ // Never reach here.
+ return;
+ }
+
+ TypeSolver typeSolver = new CombinedTypeSolver(
+ new ReflectionTypeSolver(), new JavaParserTypeSolver(parsedArgs.inputDir));
+ StaticJavaParser.getConfiguration().setSymbolResolver(new JavaSymbolSolver(typeSolver));
+
+ Enum vehicleProperty = new Enum("VehicleProperty", parsedArgs.pkgName);
+ CompilationUnit cu = StaticJavaParser.parse(new File(parsedArgs.inputDir + File.separator
+ + parsedArgs.pkgDir + File.separator + VEHICLE_PROPERTY_FILE));
+ AnnotationDeclaration vehiclePropertyIdsClass =
+ cu.getAnnotationDeclarationByName("VehicleProperty").get();
+
+ Set<String> dataEnumTypes = new HashSet<>();
+ List<FieldDeclaration> variables = vehiclePropertyIdsClass.findAll(FieldDeclaration.class);
+ for (int i = 0; i < variables.size(); i++) {
+ FieldDeclaration propertyDef = variables.get(i).asFieldDeclaration();
+ if (!isPublicAndStatic(propertyDef)) {
+ continue;
+ }
+ String propertyName = getFieldName(propertyDef);
+ if (propertyName.equals("INVALID")) {
+ continue;
+ }
+
+ Optional<Comment> maybeComment = propertyDef.getComment();
+ if (!maybeComment.isPresent()) {
+ System.out.println("missing comment for property: " + propertyName);
+ System.exit(1);
+ }
+ Javadoc doc = maybeComment.get().asJavadocComment().parse();
+
+ int propertyId = parseIntEnumField(propertyDef);
+ // We use the first paragraph as the property's name
+ String propertyDescription = doc.getDescription().toText().split("\n\n")[0];
+ String name = propertyDescription;
+ if (propertyDescription.indexOf("\n") != -1
+ || propertyDescription.length() > MAX_PROPERTY_NAME_LENGTH) {
+ // The description is too long, we just use the property name.
+ name = propertyName;
+ }
+ ValueField field = new ValueField(name, propertyId);
+
+ List<JavadocBlockTag> blockTags = doc.getBlockTags();
+ List<Integer> dataEnums = new ArrayList<>();
+ for (int j = 0; j < blockTags.size(); j++) {
+ String commentTagName = blockTags.get(j).getTagName();
+ String commentTagContent = blockTags.get(j).getContent().toText();
+ if (!commentTagName.equals("data_enum")) {
+ continue;
+ }
+ field.dataEnums.add(commentTagContent);
+ dataEnumTypes.add(commentTagContent);
+ }
+
+ vehicleProperty.valueFields.add(field);
+ }
+
+ List<Enum> enumTypes = new ArrayList<>();
+ enumTypes.add(vehicleProperty);
+
+ for (String dataEnumType : dataEnumTypes) {
+ Enum dataEnum = parseEnumInterface(
+ parsedArgs.inputDir, parsedArgs.pkgDir, parsedArgs.pkgName, dataEnumType);
+ enumTypes.add(dataEnum);
+ }
+
+ // Output enumTypes as JSON to output.
+ JSONArray jsonEnums = new JSONArray();
+ for (int i = 0; i < enumTypes.size(); i++) {
+ Enum enumType = enumTypes.get(i);
+
+ JSONObject jsonEnum = new OrderedJSONObject();
+ jsonEnum.put("name", enumType.name);
+ jsonEnum.put("package", enumType.packageName);
+ JSONArray values = new JSONArray();
+ jsonEnum.put("values", values);
+
+ for (int j = 0; j < enumType.valueFields.size(); j++) {
+ ValueField valueField = enumType.valueFields.get(j);
+ JSONObject jsonValueField = new OrderedJSONObject();
+ jsonValueField.put("name", valueField.name);
+ jsonValueField.put("value", valueField.value);
+ if (!valueField.dataEnums.isEmpty()) {
+ JSONArray jsonDataEnums = new JSONArray();
+ for (String dataEnum : valueField.dataEnums) {
+ jsonDataEnums.put(dataEnum);
+ }
+ jsonValueField.put("data_enums", jsonDataEnums);
+ // To be backward compatible with older format where data_enum is a single
+ // entry.
+ jsonValueField.put("data_enum", valueField.dataEnums.get(0));
+ }
+ values.put(jsonValueField);
+ }
+
+ jsonEnums.put(jsonEnum);
+ }
+
+ try (FileOutputStream outputStream = new FileOutputStream(parsedArgs.output)) {
+ outputStream.write(jsonEnums.toString(4).getBytes());
+ }
+ System.out.println("Input at folder: " + parsedArgs.inputDir
+ + " successfully parsed. Output at: " + parsedArgs.output);
+
+ if (parsedArgs.checkFile != null) {
+ String checkFileContent = readFileContent(parsedArgs.checkFile);
+ String generatedFileContent = readFileContent(parsedArgs.output);
+ String generatedFilePath = new File(parsedArgs.output).getAbsolutePath();
+ if (!checkFileContent.equals(generatedFileContent)) {
+ System.out.println("The file: " + CHECK_FILE_PATH + " needs to be updated, run: "
+ + "\n\ncp " + generatedFilePath + " " + CHECK_FILE_PATH + "\n");
+ System.exit(1);
+ }
+
+ if (parsedArgs.outputEmptyFile != null) {
+ try (FileOutputStream outputStream =
+ new FileOutputStream(parsedArgs.outputEmptyFile)) {
+ // Do nothing, just create the file.
+ }
+ }
+ }
+ }
+}
diff --git a/automotive/vehicle/tools/translate_aidl_enums.py b/automotive/vehicle/tools/translate_aidl_enums.py
new file mode 100644
index 0000000..d224f6f
--- /dev/null
+++ b/automotive/vehicle/tools/translate_aidl_enums.py
@@ -0,0 +1,231 @@
+#!/usr/bin/python3
+
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+"""A script to generate ENUM_NAME.java file and test files using ENUM_NAME.aidl file.
+
+ Need ANDROID_BUILD_TOP environmental variable to be set. This script will update ENUM_NAME.java
+ under packages/services/Car/car-lib/src/android/car/hardware/property, as well as the
+ ENUM_NAMETest.java files in cts/tests/tests/car/src/android/car/cts and
+ packages/services/Car/tests/android_car_api_test/src/android/car/apitest
+
+ Usage:
+ $ python translate_aidl_enums.py ENUM_NAME.aidl
+"""
+import os
+import sys
+
+LICENSE = """/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+"""
+
+class EnumParser:
+ def __init__(self, file_path, file_name):
+ self.filePath = file_path
+ self.fileName = file_name
+ self.lowerFileName = self.fileName[0].lower() + self.fileName[1:]
+ self.enums = []
+ self.outputMsg = []
+ self.outputMsg.append(LICENSE)
+ self.outputMsg.append("\npackage android.car.hardware.property;\n")
+ self.outputMsg.append("""
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+
+import com.android.car.internal.util.ConstantDebugUtils;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+""")
+
+ with open(self.filePath, 'r') as f:
+ for line in f.readlines()[16:]:
+ if line in ["package android.hardware.automotive.vehicle;\n",
+ "@VintfStability\n",
+ '@Backing(type="int")\n']:
+ continue
+
+ msg = line
+ msgSplit = msg.strip().split()
+ if len(msgSplit) > 0 and msgSplit[0] == "enum":
+ msgSplit[0] = "public final class"
+ msg = " ".join(msgSplit) + "\n"
+ elif len(msgSplit) > 1 and msgSplit[1] == '=':
+ msgSplit.insert(0, " public static final int")
+ self.enums.append(msgSplit[1])
+ msgSplit[-1] = msgSplit[-1][:-1] + ";\n"
+ msg = " ".join(msgSplit)
+ elif msg == "}\n":
+ self.outputMsg.append("""
+ private {2}() {{}}
+
+ /**
+ * Returns a user-friendly representation of {{@code {2}}}.
+ */
+ @NonNull
+ public static String toString(@{2}Int int {0}) {{
+ String {0}String = ConstantDebugUtils.toName(
+ {2}.class, {0});
+ return ({0}String != null)
+ ? {0}String
+ : "0x" + Integer.toHexString({0});
+ }}
+
+ /** @hide */
+ @IntDef({1})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface {2}Int {{}}\n""".format(self.lowerFileName, "{" + ", ".join(self.enums) + "}",
+ self.fileName))
+ self.outputMsg.append(msg)
+ self.outputMsg.append("TODO: delete this line and manually update this file with app-facing documentation and necessary tags.\n")
+
+ self.outputMsgApiTest = []
+ self.outputMsgApiTest.append(LICENSE)
+ self.outputMsgApiTest.append("""package android.car.apitest;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+@SmallTest
+@RunWith(Parameterized.class)
+public class {0}Test {{
+ private final int mJavaConstantValue;
+ private final int mHalConstantValue;
+
+ public {0}Test(int javaConstantValue, int halConstantValue) {{
+ mJavaConstantValue = javaConstantValue;
+ mHalConstantValue = halConstantValue;
+ }}
+
+ @Parameterized.Parameters
+ public static Collection constantValues() {{
+ return Arrays.asList(
+ new Object[][] {{""".format(self.fileName))
+ for enum in self.enums:
+ self.outputMsgApiTest.append("""
+ {{
+ android.car.hardware.property.{0}.{1},
+ android.hardware.automotive.vehicle.{0}.{1}
+ }},""".format(self.fileName, enum))
+ self.outputMsgApiTest.append("""
+ });
+ }
+
+ @Test
+ public void testMatchWithVehicleHal() {
+ assertWithMessage("Java constant")
+ .that(mJavaConstantValue)
+ .isEqualTo(mHalConstantValue);
+ }
+}
+""")
+
+ self.outputMsgCtsTest = []
+ self.outputMsgCtsTest.append(LICENSE)
+ self.outputMsgCtsTest.append("""
+package android.car.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.car.cts.utils.VehiclePropertyUtils;
+import android.car.hardware.property.{0};
+
+import org.junit.Test;
+
+import java.util.List;
+
+public class {0}Test {{
+
+ @Test
+ public void testToString() {{""".format(self.fileName))
+ for enum in self.enums:
+ self.outputMsgCtsTest.append("""
+ assertThat({0}.toString(
+ {0}.{1}))
+ .isEqualTo("{1}");""".format(self.fileName, enum))
+ self.outputMsgCtsTest.append("""
+ assertThat({0}.toString({1})).isEqualTo("{2}");
+ assertThat({0}.toString(12)).isEqualTo("0xc");
+ }}
+
+ @Test
+ public void testAll{0}sAreMappedInToString() {{
+ List<Integer> {3}s =
+ VehiclePropertyUtils.getIntegersFromDataEnums({0}.class);
+ for (Integer {3} : {3}s) {{
+ String {3}String = {0}.toString(
+ {3});
+ assertWithMessage("%s starts with 0x", {3}String).that(
+ {3}String.startsWith("0x")).isFalse();
+ }}
+ }}
+}}
+""".format(self.fileName, len(self.enums), hex(len(self.enums)), self.lowerFileName))
+
+def main():
+ if len(sys.argv) != 2:
+ print("Usage: {} enum_aidl_file".format(sys.argv[0]))
+ sys.exit(1)
+ print("WARNING: This file only generates the base enum values in the framework layer. The "
+ + "generated files must be reviewed by you and edited if any additional changes are "
+ + "required. The java enum file should be updated with app-developer facing "
+ + "documentation, the @FlaggedApi tag for the new API, and with the @SystemApi tag if "
+ + "the new property is system API")
+ file_path = sys.argv[1]
+ file_name = file_path.split('/')[-1][:-5]
+ parser = EnumParser(file_path, file_name)
+
+ android_top = os.environ['ANDROID_BUILD_TOP']
+ if not android_top:
+ print('ANDROID_BUILD_TOP is not in environmental variable, please run source and lunch '
+ + 'at the android root')
+
+ with open(android_top + "/packages/services/Car/car-lib/src/android/car/hardware/property/"
+ + file_name + ".java", 'w') as f:
+ f.write("".join(parser.outputMsg))
+
+ with open(android_top
+ + "/packages/services/Car/tests/android_car_api_test/src/android/car/apitest/"
+ + file_name + "Test.java", 'w') as f:
+ f.write("".join(parser.outputMsgApiTest))
+
+ with open(android_top + "/cts/tests/tests/car/src/android/car/cts/" + file_name + "Test.java",
+ 'w') as f:
+ f.write("".join(parser.outputMsgCtsTest))
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/automotive/vehicle/vts/Android.bp b/automotive/vehicle/vts/Android.bp
index 736787b..67d0d34 100644
--- a/automotive/vehicle/vts/Android.bp
+++ b/automotive/vehicle/vts/Android.bp
@@ -30,6 +30,7 @@
],
static_libs: [
"libgtest",
+ "libgmock",
"libvhalclient",
],
shared_libs: [
@@ -41,6 +42,9 @@
"use_libaidlvintf_gtest_helper_static",
"vhalclient_defaults",
],
+ header_libs: [
+ "IVehicleGeneratedHeaders",
+ ],
test_suites: [
"general-tests",
"vts",
diff --git a/automotive/vehicle/vts/OWNERS b/automotive/vehicle/vts/OWNERS
index c93a843..0f88eec 100644
--- a/automotive/vehicle/vts/OWNERS
+++ b/automotive/vehicle/vts/OWNERS
@@ -1,3 +1,3 @@
# Bug component: 533426
shanyu@google.com
-kwangsudo@google.com
+tylertrephan@google.com
diff --git a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
index 3dca0ae..d9cd9d5 100644
--- a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
+++ b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
@@ -19,12 +19,15 @@
#include <IVhalClient.h>
#include <VehicleHalTypes.h>
#include <VehicleUtils.h>
+#include <VersionForVehicleProperty.h>
#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
#include <aidl/android/hardware/automotive/vehicle/IVehicle.h>
#include <android-base/stringprintf.h>
#include <android-base/thread_annotations.h>
#include <android/binder_process.h>
+#include <android/hardware/automotive/vehicle/2.0/IVehicle.h>
+#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <hidl/GtestPrinter.h>
#include <hidl/ServiceManagement.h>
@@ -46,8 +49,11 @@
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyChangeMode;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyGroup;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
+using ::aidl::android::hardware::automotive::vehicle::VersionForVehicleProperty;
using ::android::getAidlHalInstanceNames;
+using ::android::uptimeMillis;
using ::android::base::ScopedLockAssertion;
using ::android::base::StringPrintf;
using ::android::frameworks::automotive::vhal::ErrorCode;
@@ -56,11 +62,17 @@
using ::android::frameworks::automotive::vhal::IHalPropValue;
using ::android::frameworks::automotive::vhal::ISubscriptionCallback;
using ::android::frameworks::automotive::vhal::IVhalClient;
+using ::android::frameworks::automotive::vhal::VhalClientResult;
using ::android::hardware::getAllHalInstanceNames;
using ::android::hardware::Sanitize;
+using ::android::hardware::automotive::vehicle::isSystemProp;
+using ::android::hardware::automotive::vehicle::propIdToString;
using ::android::hardware::automotive::vehicle::toInt;
+using ::testing::Ge;
constexpr int32_t kInvalidProp = 0x31600207;
+// The timeout for retrying getting prop value after setting prop value.
+constexpr int64_t kRetryGetPropAfterSetPropTimeoutMillis = 10'000;
struct ServiceDescriptor {
std::string name;
@@ -118,7 +130,12 @@
protected:
bool checkIsSupported(int32_t propertyId);
+ static bool isUnavailable(const VhalClientResult<std::unique_ptr<IHalPropValue>>& result);
+ static bool isResultOkayWithValue(
+ const VhalClientResult<std::unique_ptr<IHalPropValue>>& result, int32_t value);
+
public:
+ void verifyAccessMode(int actualAccess, int expectedAccess);
void verifyProperty(VehicleProperty propId, VehiclePropertyAccess access,
VehiclePropertyChangeMode changeMode, VehiclePropertyGroup group,
VehicleArea area, VehiclePropertyType propertyType);
@@ -202,6 +219,41 @@
ASSERT_NE(result.error().message(), "") << "Expect error message not to be empty";
}
+// Test system property IDs returned by getPropConfigs() are defined in the VHAL property interface.
+TEST_P(VtsHalAutomotiveVehicleTargetTest, testPropConfigs_onlyDefinedSystemPropertyIdsReturned) {
+ if (!mVhalClient->isAidlVhal()) {
+ GTEST_SKIP() << "Skip for HIDL VHAL because HAL interface run-time version is only"
+ << "introduced for AIDL";
+ }
+
+ auto result = mVhalClient->getAllPropConfigs();
+ ASSERT_TRUE(result.ok()) << "Failed to get all property configs, error: "
+ << result.error().message();
+
+ int32_t vhalVersion = mVhalClient->getRemoteInterfaceVersion();
+ const auto& configs = result.value();
+ for (size_t i = 0; i < configs.size(); i++) {
+ int32_t propId = configs[i]->getPropId();
+ if (!isSystemProp(propId)) {
+ continue;
+ }
+
+ std::string propName = propIdToString(propId);
+ auto it = VersionForVehicleProperty.find(static_cast<VehicleProperty>(propId));
+ bool found = (it != VersionForVehicleProperty.end());
+ EXPECT_TRUE(found) << "System Property: " << propName
+ << " is not defined in VHAL property interface";
+ if (!found) {
+ continue;
+ }
+ int32_t requiredVersion = it->second;
+ EXPECT_THAT(vhalVersion, Ge(requiredVersion))
+ << "System Property: " << propName << " requires VHAL version: " << requiredVersion
+ << ", but the current VHAL version"
+ << " is " << vhalVersion << ", must not be supported";
+ }
+}
+
// Test get() return current value for properties.
TEST_P(VtsHalAutomotiveVehicleTargetTest, get) {
ALOGD("VtsHalAutomotiveVehicleTargetTest::get");
@@ -228,6 +280,27 @@
"Expect failure to get property for invalid prop: %" PRId32, kInvalidProp);
}
+bool VtsHalAutomotiveVehicleTargetTest::isResultOkayWithValue(
+ const VhalClientResult<std::unique_ptr<IHalPropValue>>& result, int32_t value) {
+ return result.ok() && result.value() != nullptr &&
+ result.value()->getStatus() == VehiclePropertyStatus::AVAILABLE &&
+ result.value()->getInt32Values().size() == 1 &&
+ result.value()->getInt32Values()[0] == value;
+}
+
+bool VtsHalAutomotiveVehicleTargetTest::isUnavailable(
+ const VhalClientResult<std::unique_ptr<IHalPropValue>>& result) {
+ if (!result.ok()) {
+ return result.error().code() == ErrorCode::NOT_AVAILABLE_FROM_VHAL;
+ }
+ if (result.value() != nullptr &&
+ result.value()->getStatus() == VehiclePropertyStatus::UNAVAILABLE) {
+ return true;
+ }
+
+ return false;
+}
+
// Test set() on read_write properties.
TEST_P(VtsHalAutomotiveVehicleTargetTest, setProp) {
ALOGD("VtsHalAutomotiveVehicleTargetTest::setProp");
@@ -250,11 +323,24 @@
const IHalPropConfig& cfg = *cfgPtr;
int32_t propId = cfg.getPropId();
// test on boolean and writable property
- if (cfg.getAccess() == toInt(VehiclePropertyAccess::READ_WRITE) &&
- isBooleanGlobalProp(propId) && !hvacProps.count(propId)) {
+ bool isReadWrite = (cfg.getAccess() == toInt(VehiclePropertyAccess::READ_WRITE));
+ if (cfg.getAreaConfigSize() != 0 &&
+ cfg.getAreaConfigs()[0]->getAccess() != toInt(VehiclePropertyAccess::NONE)) {
+ isReadWrite = (cfg.getAreaConfigs()[0]->getAccess() ==
+ toInt(VehiclePropertyAccess::READ_WRITE));
+ }
+ if (isReadWrite && isBooleanGlobalProp(propId) && !hvacProps.count(propId)) {
auto propToGet = mVhalClient->createHalPropValue(propId);
auto getValueResult = mVhalClient->getValueSync(*propToGet);
+ if (isUnavailable(getValueResult)) {
+ ALOGW("getProperty for %" PRId32
+ " returns NOT_AVAILABLE, "
+ "skip testing setProp",
+ propId);
+ return;
+ }
+
ASSERT_TRUE(getValueResult.ok())
<< StringPrintf("Failed to get value for property: %" PRId32 ", error: %s",
propId, getValueResult.error().message().c_str());
@@ -267,17 +353,48 @@
"Expect exactly 1 int value for boolean property: %" PRId32 ", got %zu", propId,
intValueSize);
- int setValue = value.getInt32Values()[0] == 1 ? 0 : 1;
+ int32_t setValue = value.getInt32Values()[0] == 1 ? 0 : 1;
auto propToSet = mVhalClient->createHalPropValue(propId);
propToSet->setInt32Values({setValue});
auto setValueResult = mVhalClient->setValueSync(*propToSet);
+ if (!setValueResult.ok() &&
+ setValueResult.error().code() == ErrorCode::NOT_AVAILABLE_FROM_VHAL) {
+ ALOGW("setProperty for %" PRId32
+ " returns NOT_AVAILABLE, "
+ "skip verifying getProperty returns the same value",
+ propId);
+ return;
+ }
+
ASSERT_TRUE(setValueResult.ok())
<< StringPrintf("Failed to set value for property: %" PRId32 ", error: %s",
propId, setValueResult.error().message().c_str());
+ // Retry getting the value until we pass the timeout. getValue might not return
+ // the expected value immediately since setValue is async.
+ auto timeoutMillis = uptimeMillis() + kRetryGetPropAfterSetPropTimeoutMillis;
- // check set success
- getValueResult = mVhalClient->getValueSync(*propToGet);
+ while (true) {
+ getValueResult = mVhalClient->getValueSync(*propToGet);
+ if (isResultOkayWithValue(getValueResult, setValue)) {
+ break;
+ }
+ if (uptimeMillis() >= timeoutMillis) {
+ // Reach timeout, the following assert should fail.
+ break;
+ }
+ // Sleep for 100ms between each getValueSync retry.
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ }
+
+ if (isUnavailable(getValueResult)) {
+ ALOGW("getProperty for %" PRId32
+ " returns NOT_AVAILABLE, "
+ "skip verifying the return value",
+ propId);
+ return;
+ }
+
ASSERT_TRUE(getValueResult.ok())
<< StringPrintf("Failed to get value for property: %" PRId32 ", error: %s",
propId, getValueResult.error().message().c_str());
@@ -469,6 +586,53 @@
}
}
+// Test that access mode is populated in exclusively one of the VehiclePropConfig or the
+// VehicleAreaConfigs. Either VehiclePropConfig.access must be populated, or all the
+// VehicleAreaConfig.access fields should be populated.
+TEST_P(VtsHalAutomotiveVehicleTargetTest, testAccessModeExclusivityAIDL) {
+ if (!mVhalClient->isAidlVhal()) {
+ GTEST_SKIP() << "Skip checking access mode for HIDL because the access mode field is only "
+ "present for AIDL";
+ }
+
+ auto result = mVhalClient->getAllPropConfigs();
+ ASSERT_TRUE(result.ok());
+ for (const auto& cfgPtr : result.value()) {
+ const IHalPropConfig& cfg = *cfgPtr;
+
+ bool propAccessIsSet = (cfg.getAccess() != toInt(VehiclePropertyAccess::NONE));
+ bool unsetAreaAccessExists = false;
+ bool setAreaAccessExists = false;
+
+ for (const auto& areaConfig : cfg.getAreaConfigs()) {
+ if (areaConfig->getAccess() == toInt(VehiclePropertyAccess::NONE)) {
+ unsetAreaAccessExists = true;
+ } else {
+ setAreaAccessExists = true;
+ }
+ }
+
+ ASSERT_FALSE(propAccessIsSet && setAreaAccessExists) << StringPrintf(
+ "Both prop and area config access is set for propertyId %d", cfg.getPropId());
+ ASSERT_FALSE(!propAccessIsSet && !setAreaAccessExists) << StringPrintf(
+ "Neither prop and area config access is set for propertyId %d", cfg.getPropId());
+ ASSERT_FALSE(unsetAreaAccessExists && setAreaAccessExists) << StringPrintf(
+ "Area access is only set in some configs for propertyId %d", cfg.getPropId());
+ }
+}
+
+void VtsHalAutomotiveVehicleTargetTest::verifyAccessMode(int actualAccess, int expectedAccess) {
+ if (expectedAccess == toInt(VehiclePropertyAccess::READ_WRITE)) {
+ ASSERT_TRUE(actualAccess == expectedAccess ||
+ actualAccess == toInt(VehiclePropertyAccess::READ))
+ << StringPrintf("Expect to get VehiclePropertyAccess: %i or %i, got %i",
+ expectedAccess, toInt(VehiclePropertyAccess::READ), actualAccess);
+ return;
+ }
+ ASSERT_EQ(actualAccess, expectedAccess) << StringPrintf(
+ "Expect to get VehiclePropertyAccess: %i, got %i", expectedAccess, actualAccess);
+}
+
// Helper function to compare actual vs expected property config
void VtsHalAutomotiveVehicleTargetTest::verifyProperty(VehicleProperty propId,
VehiclePropertyAccess access,
@@ -511,7 +675,6 @@
const auto& config = result.value().at(0);
int actualPropId = config->getPropId();
- int actualAccess = config->getAccess();
int actualChangeMode = config->getChangeMode();
int actualGroup = actualPropId & toInt(VehiclePropertyGroup::MASK);
int actualArea = actualPropId & toInt(VehicleArea::MASK);
@@ -520,14 +683,17 @@
ASSERT_EQ(actualPropId, expectedPropId)
<< StringPrintf("Expect to get property ID: %i, got %i", expectedPropId, actualPropId);
- if (expectedAccess == toInt(VehiclePropertyAccess::READ_WRITE)) {
- ASSERT_TRUE(actualAccess == expectedAccess ||
- actualAccess == toInt(VehiclePropertyAccess::READ))
- << StringPrintf("Expect to get VehiclePropertyAccess: %i or %i, got %i",
- expectedAccess, toInt(VehiclePropertyAccess::READ), actualAccess);
+ int globalAccess = config->getAccess();
+ if (config->getAreaConfigSize() == 0) {
+ verifyAccessMode(globalAccess, expectedAccess);
} else {
- ASSERT_EQ(actualAccess, expectedAccess) << StringPrintf(
- "Expect to get VehiclePropertyAccess: %i, got %i", expectedAccess, actualAccess);
+ for (const auto& areaConfig : config->getAreaConfigs()) {
+ int areaConfigAccess = areaConfig->getAccess();
+ int actualAccess = (areaConfigAccess != toInt(VehiclePropertyAccess::NONE))
+ ? areaConfigAccess
+ : globalAccess;
+ verifyAccessMode(actualAccess, expectedAccess);
+ }
}
ASSERT_EQ(actualChangeMode, expectedChangeMode)
@@ -548,6 +714,44 @@
VehicleArea::GLOBAL, VehiclePropertyType::INT32);
}
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyUltrasonicsSensorPositionConfig) {
+ verifyProperty(VehicleProperty::ULTRASONICS_SENSOR_POSITION, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::STATIC, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::VENDOR, VehiclePropertyType::INT32_VEC);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyUltrasonicsSensorOrientationConfig) {
+ verifyProperty(VehicleProperty::ULTRASONICS_SENSOR_ORIENTATION, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::STATIC, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::VENDOR, VehiclePropertyType::FLOAT_VEC);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyUltrasonicsSensorFieldOfViewConfig) {
+ verifyProperty(VehicleProperty::ULTRASONICS_SENSOR_FIELD_OF_VIEW, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::STATIC, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::VENDOR, VehiclePropertyType::INT32_VEC);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyUltrasonicsSensorDetectionRangeConfig) {
+ verifyProperty(VehicleProperty::ULTRASONICS_SENSOR_DETECTION_RANGE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::STATIC, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::VENDOR, VehiclePropertyType::INT32_VEC);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyUltrasonicsSensorSupportedRangesConfig) {
+ verifyProperty(VehicleProperty::ULTRASONICS_SENSOR_SUPPORTED_RANGES,
+ VehiclePropertyAccess::READ, VehiclePropertyChangeMode::STATIC,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::VENDOR,
+ VehiclePropertyType::INT32_VEC);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyUltrasonicsSensorMeasuredDistanceConfig) {
+ verifyProperty(VehicleProperty::ULTRASONICS_SENSOR_MEASURED_DISTANCE,
+ VehiclePropertyAccess::READ, VehiclePropertyChangeMode::CONTINUOUS,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::VENDOR,
+ VehiclePropertyType::INT32_VEC);
+}
+
TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyEmergencyLaneKeepAssistEnabledConfig) {
verifyProperty(VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED,
VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
@@ -621,6 +825,54 @@
VehicleArea::GLOBAL, VehiclePropertyType::INT32);
}
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverDrowsinessAttentionSystemEnabledConfig) {
+ verifyProperty(VehicleProperty::DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverDrowsinessAttentionStateConfig) {
+ verifyProperty(VehicleProperty::DRIVER_DROWSINESS_ATTENTION_STATE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverDrowsinessAttentionWarningEnabledConfig) {
+ verifyProperty(VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverDrowsinessAttentionWarningConfig) {
+ verifyProperty(VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING,
+ VehiclePropertyAccess::READ, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverDistractionSystemEnabledConfig) {
+ verifyProperty(VehicleProperty::DRIVER_DISTRACTION_SYSTEM_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverDistractionStateConfig) {
+ verifyProperty(VehicleProperty::DRIVER_DISTRACTION_STATE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverDistractionWarningEnabledConfig) {
+ verifyProperty(VehicleProperty::DRIVER_DISTRACTION_WARNING_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverDistractionWarningConfig) {
+ verifyProperty(VehicleProperty::DRIVER_DISTRACTION_WARNING, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyEvBrakeRegenerationLevelConfig) {
verifyProperty(VehicleProperty::EV_BRAKE_REGENERATION_LEVEL,
VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
@@ -891,6 +1143,102 @@
VehicleArea::GLOBAL, VehiclePropertyType::MIXED);
}
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyVehicleDrivingAutomationCurrentLevelConfig) {
+ verifyProperty(VehicleProperty::VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL,
+ VehiclePropertyAccess::READ, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyCameraServiceCurrentStateConfig) {
+ verifyProperty(VehicleProperty::CAMERA_SERVICE_CURRENT_STATE, VehiclePropertyAccess::WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32_VEC);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatAirbagsDeployedConfig) {
+ verifyProperty(VehicleProperty::SEAT_AIRBAGS_DEPLOYED, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatBeltPretensionerDeployedConfig) {
+ verifyProperty(VehicleProperty::SEAT_BELT_PRETENSIONER_DEPLOYED, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::SEAT, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyImpactDetectedConfig) {
+ verifyProperty(VehicleProperty::IMPACT_DETECTED, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyEvBatteryAverageTemperatureConfig) {
+ verifyProperty(VehicleProperty::EV_BATTERY_AVERAGE_TEMPERATURE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::CONTINUOUS, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::FLOAT);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLowSpeedCollisionWarningEnabledConfig) {
+ verifyProperty(VehicleProperty::LOW_SPEED_COLLISION_WARNING_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLowSpeedCollisionWarningStateConfig) {
+ verifyProperty(VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyValetModeEnabledConfig) {
+ verifyProperty(VehicleProperty::VALET_MODE_ENABLED, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyElectronicStabilityControlEnabledConfig) {
+ verifyProperty(VehicleProperty::ELECTRONIC_STABILITY_CONTROL_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyElectronicStabilityControlStateConfig) {
+ verifyProperty(VehicleProperty::ELECTRONIC_STABILITY_CONTROL_STATE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyCrossTrafficMonitoringEnabledConfig) {
+ verifyProperty(VehicleProperty::CROSS_TRAFFIC_MONITORING_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyCrossTrafficMonitoringWarningStateConfig) {
+ verifyProperty(VehicleProperty::CROSS_TRAFFIC_MONITORING_WARNING_STATE,
+ VehiclePropertyAccess::READ, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyHeadUpDisplayEnabledConfig) {
+ verifyProperty(VehicleProperty::HEAD_UP_DISPLAY_ENABLED, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::SEAT, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLowSpeedAutomaticEmergencyBrakingEnabledConfig) {
+ verifyProperty(VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLowSpeedAutomaticEmergencyBrakingStateConfig) {
+ verifyProperty(VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE,
+ VehiclePropertyAccess::READ, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
bool VtsHalAutomotiveVehicleTargetTest::checkIsSupported(int32_t propertyId) {
auto result = mVhalClient->getPropConfigs({propertyId});
return result.ok();
@@ -904,7 +1252,8 @@
.isAidlService = true,
});
}
- for (std::string name : getAllHalInstanceNames(IVehicle::descriptor)) {
+ for (std::string name : getAllHalInstanceNames(
+ android::hardware::automotive::vehicle::V2_0::IVehicle::descriptor)) {
descriptors.push_back({
.name = name,
.isAidlService = false,
diff --git a/biometrics/common/aidl/Android.bp b/biometrics/common/aidl/Android.bp
index b41a937..8502a82 100644
--- a/biometrics/common/aidl/Android.bp
+++ b/biometrics/common/aidl/Android.bp
@@ -13,7 +13,7 @@
srcs: [
"android/hardware/biometrics/common/*.aidl",
],
- frozen: true,
+ frozen: false,
stability: "vintf",
backend: {
java: {
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/FoldState.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/FoldState.aidl
new file mode 100644
index 0000000..06baf00
--- /dev/null
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/FoldState.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.biometrics.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FoldState {
+ UNKNOWN,
+ HALF_OPENED,
+ FULLY_OPENED,
+ FULLY_CLOSED,
+}
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl
index 378017e..8d913c8 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl
@@ -45,4 +45,6 @@
android.hardware.biometrics.common.WakeReason wakeReason = android.hardware.biometrics.common.WakeReason.UNKNOWN;
android.hardware.biometrics.common.DisplayState displayState = android.hardware.biometrics.common.DisplayState.UNKNOWN;
@nullable android.hardware.biometrics.common.AuthenticateReason authenticateReason;
+ android.hardware.biometrics.common.FoldState foldState = android.hardware.biometrics.common.FoldState.UNKNOWN;
+ @nullable android.hardware.biometrics.common.OperationState operationState;
}
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationState.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationState.aidl
new file mode 100644
index 0000000..fca9525
--- /dev/null
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationState.aidl
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.biometrics.common;
+/* @hide */
+@VintfStability
+union OperationState {
+ android.hardware.biometrics.common.OperationState.FingerprintOperationState fingerprintOperationState;
+ android.hardware.biometrics.common.OperationState.FaceOperationState faceOperationState;
+ @VintfStability
+ parcelable FingerprintOperationState {
+ ParcelableHolder extension;
+ boolean isHardwareIgnoringTouches = false;
+ }
+ @VintfStability
+ parcelable FaceOperationState {
+ ParcelableHolder extension;
+ }
+}
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/FoldState.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/FoldState.aidl
new file mode 100644
index 0000000..03e606a
--- /dev/null
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/FoldState.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics.common;
+
+/**
+ * Fold/Unfold state during an operation.
+ *
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FoldState {
+ /** The fold state is unknown. */
+ UNKNOWN,
+
+ /** The fold state is half opened. */
+ HALF_OPENED,
+
+ /** The fold state is fully opened. */
+ FULLY_OPENED,
+
+ /** The fold state is fully closed. */
+ FULLY_CLOSED,
+}
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl
index f4191d7..5f9844f 100644
--- a/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl
@@ -18,7 +18,9 @@
import android.hardware.biometrics.common.AuthenticateReason;
import android.hardware.biometrics.common.DisplayState;
+import android.hardware.biometrics.common.FoldState;
import android.hardware.biometrics.common.OperationReason;
+import android.hardware.biometrics.common.OperationState;
import android.hardware.biometrics.common.WakeReason;
/**
@@ -71,4 +73,10 @@
* framework may choose to omit the reason at any time based on the device's policy.
*/
@nullable AuthenticateReason authenticateReason;
+
+ /** The current fold/unfold state. */
+ FoldState foldState = FoldState.UNKNOWN;
+
+ /** An associated operation state for this operation. */
+ @nullable OperationState operationState;
}
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/OperationState.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/OperationState.aidl
new file mode 100644
index 0000000..40cf589
--- /dev/null
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/OperationState.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.hardware.biometrics.common;
+
+/**
+ * Additional state associated with an operation
+ *
+ * @hide
+ */
+@VintfStability
+union OperationState {
+ /** Operation state related to fingerprint*/
+ @VintfStability
+ parcelable FingerprintOperationState {
+ ParcelableHolder extension;
+
+ /** Flag indicating if the HAL should ignore touches on the fingerprint sensor */
+ boolean isHardwareIgnoringTouches = false;
+ }
+
+ /** Operation state related to face*/
+ @VintfStability
+ parcelable FaceOperationState {
+ ParcelableHolder extension;
+ }
+
+ OperationState.FingerprintOperationState fingerprintOperationState;
+ OperationState.FaceOperationState faceOperationState;
+}
diff --git a/biometrics/common/util/Android.bp b/biometrics/common/util/Android.bp
index b990812..599c491 100644
--- a/biometrics/common/util/Android.bp
+++ b/biometrics/common/util/Android.bp
@@ -13,6 +13,6 @@
shared_libs: [
"libbase",
"libbinder_ndk",
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
],
}
diff --git a/biometrics/face/aidl/Android.bp b/biometrics/face/aidl/Android.bp
index 6c8cd78..fadcde7 100644
--- a/biometrics/face/aidl/Android.bp
+++ b/biometrics/face/aidl/Android.bp
@@ -14,7 +14,7 @@
"android/hardware/biometrics/face/**/*.aidl",
],
imports: [
- "android.hardware.biometrics.common-V3",
+ "android.hardware.biometrics.common-V4",
"android.hardware.common-V2",
"android.hardware.keymaster-V4",
],
@@ -29,6 +29,9 @@
cpp: {
enabled: false,
},
+ rust: {
+ enabled: false,
+ },
ndk: {
additional_shared_libraries: [
"libnativewindow",
@@ -60,8 +63,16 @@
"android.hardware.keymaster-V4",
],
},
+ {
+ version: "4",
+ imports: [
+ "android.hardware.biometrics.common-V4",
+ "android.hardware.common-V2",
+ "android.hardware.keymaster-V4",
+ ],
+ },
],
- frozen: false,
+ frozen: true,
}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/.hash b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/.hash
new file mode 100644
index 0000000..e9a5aa3
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/.hash
@@ -0,0 +1 @@
+c43fbb9be4a662cc9ace640dba21cccdb84c6c21
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/AcquiredInfo.aidl
new file mode 100644
index 0000000..1420cdc
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/AcquiredInfo.aidl
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.biometrics.face;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum AcquiredInfo {
+ UNKNOWN,
+ GOOD,
+ INSUFFICIENT,
+ TOO_BRIGHT,
+ TOO_DARK,
+ TOO_CLOSE,
+ TOO_FAR,
+ FACE_TOO_HIGH,
+ FACE_TOO_LOW,
+ FACE_TOO_RIGHT,
+ FACE_TOO_LEFT,
+ POOR_GAZE,
+ NOT_DETECTED,
+ TOO_MUCH_MOTION,
+ RECALIBRATE,
+ TOO_DIFFERENT,
+ TOO_SIMILAR,
+ PAN_TOO_EXTREME,
+ TILT_TOO_EXTREME,
+ ROLL_TOO_EXTREME,
+ FACE_OBSCURED,
+ START,
+ SENSOR_DIRTY,
+ VENDOR,
+ FIRST_FRAME_RECEIVED,
+ DARK_GLASSES_DETECTED,
+ MOUTH_COVERING_DETECTED,
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/AuthenticationFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/AuthenticationFrame.aidl
new file mode 100644
index 0000000..bbaca12
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/AuthenticationFrame.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.biometrics.face;
+/* @hide */
+@VintfStability
+parcelable AuthenticationFrame {
+ android.hardware.biometrics.face.BaseFrame data;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/BaseFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/BaseFrame.aidl
new file mode 100644
index 0000000..1dd0a9c
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/BaseFrame.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.biometrics.face;
+/* @hide */
+@VintfStability
+parcelable BaseFrame {
+ android.hardware.biometrics.face.AcquiredInfo acquiredInfo = android.hardware.biometrics.face.AcquiredInfo.UNKNOWN;
+ int vendorCode;
+ float pan;
+ float tilt;
+ float distance;
+ boolean isCancellable;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/Cell.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/Cell.aidl
new file mode 100644
index 0000000..d423a69
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/Cell.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.biometrics.face;
+/* @hide */
+@VintfStability
+parcelable Cell {
+ int x;
+ int y;
+ int z;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentFrame.aidl
new file mode 100644
index 0000000..90be5d0
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentFrame.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.biometrics.face;
+/* @hide */
+@VintfStability
+parcelable EnrollmentFrame {
+ @nullable android.hardware.biometrics.face.Cell cell;
+ android.hardware.biometrics.face.EnrollmentStage stage = android.hardware.biometrics.face.EnrollmentStage.UNKNOWN;
+ android.hardware.biometrics.face.BaseFrame data;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentStage.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentStage.aidl
new file mode 100644
index 0000000..89b06ca
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentStage.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.biometrics.face;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum EnrollmentStage {
+ UNKNOWN,
+ FIRST_FRAME_RECEIVED,
+ WAITING_FOR_CENTERING,
+ HOLD_STILL_IN_CENTER,
+ ENROLLING_MOVEMENT_1,
+ ENROLLING_MOVEMENT_2,
+ ENROLLMENT_FINISHED,
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentStageConfig.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
new file mode 100644
index 0000000..ee1c01a
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.biometrics.face;
+/* @hide */
+@VintfStability
+parcelable EnrollmentStageConfig {
+ android.hardware.biometrics.face.EnrollmentStage stage = android.hardware.biometrics.face.EnrollmentStage.UNKNOWN;
+ List<android.hardware.biometrics.face.Cell> cells;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentType.aidl
new file mode 100644
index 0000000..180ea5d
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.biometrics.face;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum EnrollmentType {
+ DEFAULT,
+ ACCESSIBILITY,
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/Error.aidl
new file mode 100644
index 0000000..5761e31
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/Error.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.biometrics.face;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum Error {
+ UNKNOWN,
+ HW_UNAVAILABLE,
+ UNABLE_TO_PROCESS,
+ TIMEOUT,
+ NO_SPACE,
+ CANCELED,
+ UNABLE_TO_REMOVE,
+ VENDOR,
+ REENROLL_REQUIRED,
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/FaceEnrollOptions.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/FaceEnrollOptions.aidl
new file mode 100644
index 0000000..c961531
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/FaceEnrollOptions.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.biometrics.face;
+/* @hide */
+@VintfStability
+parcelable FaceEnrollOptions {
+ android.hardware.keymaster.HardwareAuthToken hardwareAuthToken;
+ android.hardware.biometrics.face.EnrollmentType enrollmentType;
+ android.hardware.biometrics.face.Feature[] features;
+ /**
+ * @deprecated use {@link surfacePreview} instead {@link NativeHandle} a handle used to render content from the face HAL. Note that only one of [{@link surfacePreview}, {@link nativeHandlePreview}] should be set at one time.
+ */
+ @nullable android.hardware.common.NativeHandle nativeHandlePreview;
+ @nullable android.view.Surface surfacePreview;
+ @nullable android.hardware.biometrics.common.OperationContext context;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/FaceSensorType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/FaceSensorType.aidl
new file mode 100644
index 0000000..ec03733
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/FaceSensorType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.biometrics.face;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum FaceSensorType {
+ UNKNOWN,
+ RGB,
+ IR,
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/Feature.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/Feature.aidl
new file mode 100644
index 0000000..3337df8
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/Feature.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.biometrics.face;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum Feature {
+ REQUIRE_ATTENTION,
+ REQUIRE_DIVERSE_POSES,
+ DEBUG,
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/IFace.aidl
new file mode 100644
index 0000000..1ae76de
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/IFace.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.biometrics.face;
+/* @hide */
+@VintfStability
+interface IFace {
+ android.hardware.biometrics.face.SensorProps[] getSensorProps();
+ android.hardware.biometrics.face.ISession createSession(in int sensorId, in int userId, in android.hardware.biometrics.face.ISessionCallback cb);
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/ISession.aidl
new file mode 100644
index 0000000..b655d5f
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/ISession.aidl
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.biometrics.face;
+/* @hide */
+@VintfStability
+interface ISession {
+ void generateChallenge();
+ void revokeChallenge(in long challenge);
+ android.hardware.biometrics.face.EnrollmentStageConfig[] getEnrollmentConfig(in android.hardware.biometrics.face.EnrollmentType enrollmentType);
+ /**
+ * @deprecated use {@link enrollWithOptions} instead.
+ */
+ android.hardware.biometrics.common.ICancellationSignal enroll(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in @nullable android.hardware.common.NativeHandle previewSurface);
+ android.hardware.biometrics.common.ICancellationSignal authenticate(in long operationId);
+ android.hardware.biometrics.common.ICancellationSignal detectInteraction();
+ void enumerateEnrollments();
+ void removeEnrollments(in int[] enrollmentIds);
+ void getFeatures();
+ void setFeature(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.Feature feature, boolean enabled);
+ void getAuthenticatorId();
+ void invalidateAuthenticatorId();
+ void resetLockout(in android.hardware.keymaster.HardwareAuthToken hat);
+ void close();
+ android.hardware.biometrics.common.ICancellationSignal authenticateWithContext(in long operationId, in android.hardware.biometrics.common.OperationContext context);
+ /**
+ * @deprecated use {@link enrollWithOptions} instead.
+ */
+ android.hardware.biometrics.common.ICancellationSignal enrollWithContext(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in @nullable android.hardware.common.NativeHandle previewSurface, in android.hardware.biometrics.common.OperationContext context);
+ android.hardware.biometrics.common.ICancellationSignal detectInteractionWithContext(in android.hardware.biometrics.common.OperationContext context);
+ void onContextChanged(in android.hardware.biometrics.common.OperationContext context);
+ android.hardware.biometrics.common.ICancellationSignal enrollWithOptions(in android.hardware.biometrics.face.FaceEnrollOptions options);
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/ISessionCallback.aidl
new file mode 100644
index 0000000..c6c035b
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/ISessionCallback.aidl
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.biometrics.face;
+/* @hide */
+@VintfStability
+interface ISessionCallback {
+ void onChallengeGenerated(in long challenge);
+ void onChallengeRevoked(in long challenge);
+ void onAuthenticationFrame(in android.hardware.biometrics.face.AuthenticationFrame frame);
+ void onEnrollmentFrame(in android.hardware.biometrics.face.EnrollmentFrame frame);
+ void onError(in android.hardware.biometrics.face.Error error, in int vendorCode);
+ void onEnrollmentProgress(in int enrollmentId, int remaining);
+ void onAuthenticationSucceeded(in int enrollmentId, in android.hardware.keymaster.HardwareAuthToken hat);
+ void onAuthenticationFailed();
+ void onLockoutTimed(in long durationMillis);
+ void onLockoutPermanent();
+ void onLockoutCleared();
+ void onInteractionDetected();
+ void onEnrollmentsEnumerated(in int[] enrollmentIds);
+ void onFeaturesRetrieved(in android.hardware.biometrics.face.Feature[] features);
+ void onFeatureSet(android.hardware.biometrics.face.Feature feature);
+ void onEnrollmentsRemoved(in int[] enrollmentIds);
+ void onAuthenticatorIdRetrieved(in long authenticatorId);
+ void onAuthenticatorIdInvalidated(in long newAuthenticatorId);
+ void onSessionClosed();
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/SensorProps.aidl
new file mode 100644
index 0000000..918332b
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/SensorProps.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.biometrics.face;
+/* @hide */
+@VintfStability
+parcelable SensorProps {
+ android.hardware.biometrics.common.CommonProps commonProps;
+ android.hardware.biometrics.face.FaceSensorType sensorType = android.hardware.biometrics.face.FaceSensorType.UNKNOWN;
+ boolean halControlsPreview;
+ int previewDisplayId;
+ int enrollPreviewWidth;
+ int enrollPreviewHeight;
+ float enrollTranslationX;
+ float enrollTranslationY;
+ float enrollPreviewScale;
+ boolean supportsDetectInteraction;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl
index 5312ca1..1420cdc 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@Backing(type="byte") @VintfStability
enum AcquiredInfo {
UNKNOWN,
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl
index 20bc767..bbaca12 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@VintfStability
parcelable AuthenticationFrame {
android.hardware.biometrics.face.BaseFrame data;
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl
index 67b5cf4..1dd0a9c 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@VintfStability
parcelable BaseFrame {
android.hardware.biometrics.face.AcquiredInfo acquiredInfo = android.hardware.biometrics.face.AcquiredInfo.UNKNOWN;
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl
index 6be8c8e..d423a69 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@VintfStability
parcelable Cell {
int x;
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl
index 0ea10d6..90be5d0 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@VintfStability
parcelable EnrollmentFrame {
@nullable android.hardware.biometrics.face.Cell cell;
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl
index a203dbe..89b06ca 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@Backing(type="byte") @VintfStability
enum EnrollmentStage {
UNKNOWN,
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
index 48db2cf..ee1c01a 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@VintfStability
parcelable EnrollmentStageConfig {
android.hardware.biometrics.face.EnrollmentStage stage = android.hardware.biometrics.face.EnrollmentStage.UNKNOWN;
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl
index da1e8a3..180ea5d 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@Backing(type="byte") @VintfStability
enum EnrollmentType {
DEFAULT,
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl
index 28eb420..5761e31 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@Backing(type="byte") @VintfStability
enum Error {
UNKNOWN,
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceEnrollOptions.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceEnrollOptions.aidl
index 23fa147..c961531 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceEnrollOptions.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceEnrollOptions.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@VintfStability
parcelable FaceEnrollOptions {
android.hardware.keymaster.HardwareAuthToken hardwareAuthToken;
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl
index bf1677c..ec03733 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@Backing(type="byte") @VintfStability
enum FaceSensorType {
UNKNOWN,
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl
index 924e6af..3337df8 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@Backing(type="byte") @VintfStability
enum Feature {
REQUIRE_ATTENTION,
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl
index fc4a4d0..1ae76de 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@VintfStability
interface IFace {
android.hardware.biometrics.face.SensorProps[] getSensorProps();
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
index 4d99f5a..b655d5f 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@VintfStability
interface ISession {
void generateChallenge();
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl
index bbace29..c6c035b 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@VintfStability
interface ISessionCallback {
void onChallengeGenerated(in long challenge);
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl
index 8b3c51b..918332b 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@VintfStability
parcelable SensorProps {
android.hardware.biometrics.common.CommonProps commonProps;
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl
index cf68421..48b3e8c 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl
@@ -15,7 +15,9 @@
*/
package android.hardware.biometrics.face;
-
+/**
+ * @hide
+ */
@VintfStability
@Backing(type="byte")
enum AcquiredInfo {
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/AuthenticationFrame.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/AuthenticationFrame.aidl
index be61a20..08ef973 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/AuthenticationFrame.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/AuthenticationFrame.aidl
@@ -20,6 +20,7 @@
/**
* Describes an individual frame captured during authentication.
+ * @hide
*/
@VintfStability
parcelable AuthenticationFrame {
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl
index 58ad01a..e407d91 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl
@@ -22,6 +22,7 @@
* Metadata of an individual frame. Can be used by the framework to provide user feedback.
* This parcelable is part of AuthenticationFrame and EnrollmentFrame, and shouldn't be used
* independently of those parcelables.
+ * @hide
*/
@VintfStability
parcelable BaseFrame {
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/Cell.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/Cell.aidl
index 77f33b9..8960d57 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/Cell.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/Cell.aidl
@@ -18,6 +18,7 @@
/**
* Coordinates of an enrollment UI cell in a vendor-defined coordinate system.
+ * @hide
*/
@VintfStability
parcelable Cell {
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl
index ecb0e79..15f019c 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl
@@ -22,6 +22,7 @@
/**
* Describes an individual frame captured during enrollment.
+ * @hide
*/
@VintfStability
parcelable EnrollmentFrame {
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStage.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStage.aidl
index 5974838..1a3c029 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStage.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStage.aidl
@@ -18,6 +18,7 @@
/**
* Enrollment stages that can be mapped to the enrollment UI actions in the framework.
+ * @hide
*/
@VintfStability
@Backing(type="byte")
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
index a8fa9ab..362d752 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
@@ -19,6 +19,9 @@
import android.hardware.biometrics.face.Cell;
import android.hardware.biometrics.face.EnrollmentStage;
+/**
+ * @hide
+ */
@VintfStability
parcelable EnrollmentStageConfig {
/**
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentType.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentType.aidl
index c960933..5d92087 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentType.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentType.aidl
@@ -16,6 +16,9 @@
package android.hardware.biometrics.face;
+/**
+ * @hide
+ */
@VintfStability
@Backing(type="byte")
enum EnrollmentType {
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl
index e99415a..77d4717 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl
@@ -15,7 +15,9 @@
*/
package android.hardware.biometrics.face;
-
+/**
+ * @hide
+ */
@VintfStability
@Backing(type="byte")
enum Error {
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/FaceEnrollOptions.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/FaceEnrollOptions.aidl
index 75e3978..c57fb55 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/FaceEnrollOptions.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/FaceEnrollOptions.aidl
@@ -26,6 +26,7 @@
/**
* Enroll options used to pass information to the HAL when requesting an enroll operation.
+ * @hide
*/
@VintfStability
parcelable FaceEnrollOptions {
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl
index a5ed2e8..bf315a5 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl
@@ -16,6 +16,9 @@
package android.hardware.biometrics.face;
+/**
+ * @hide
+ */
@VintfStability
@Backing(type="byte")
enum FaceSensorType {
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/Feature.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/Feature.aidl
index bff1a02..9cbab55 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/Feature.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/Feature.aidl
@@ -16,6 +16,9 @@
package android.hardware.biometrics.face;
+/**
+ * @hide
+ */
@VintfStability
@Backing(type="byte")
enum Feature {
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl
index 65c589f..0ead435 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl
@@ -20,6 +20,9 @@
import android.hardware.biometrics.face.ISessionCallback;
import android.hardware.biometrics.face.SensorProps;
+/**
+ * @hide
+ */
@VintfStability
interface IFace {
/**
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
index 825af0c..26cb361 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
@@ -42,6 +42,7 @@
* ISession only supports execution of one operation at a time, regardless of whether it's
* cancellable or not. The framework must wait for a corresponding callback indicating the end of
* the current operation before a new operation can be started.
+ * @hide
*/
@VintfStability
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl
index 9eb575c..b38e366 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl
@@ -23,6 +23,9 @@
import android.hardware.biometrics.face.Feature;
import android.hardware.keymaster.HardwareAuthToken;
+/**
+ * @hide
+ */
@VintfStability
interface ISessionCallback {
/**
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl
index 5f881ca..09fd9e5 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl
@@ -19,6 +19,9 @@
import android.hardware.biometrics.common.CommonProps;
import android.hardware.biometrics.face.FaceSensorType;
+/**
+ * @hide
+ */
@VintfStability
parcelable SensorProps {
/**
diff --git a/biometrics/face/aidl/default/Android.bp b/biometrics/face/aidl/default/Android.bp
index ecd0934..4e8390a 100644
--- a/biometrics/face/aidl/default/Android.bp
+++ b/biometrics/face/aidl/default/Android.bp
@@ -30,6 +30,7 @@
"libnativewindow",
],
srcs: [
+ "FakeLockoutTracker.cpp",
"main.cpp",
"Face.cpp",
"FakeFaceEngine.cpp",
@@ -40,7 +41,7 @@
],
stl: "c++_static",
static_libs: [
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
"android.hardware.biometrics.common.thread",
"android.hardware.biometrics.common.util",
"android.hardware.biometrics.face-V4-ndk",
@@ -63,6 +64,7 @@
srcs: [
"tests/FakeFaceEngineTest.cpp",
"FakeFaceEngine.cpp",
+ "FakeLockoutTracker.cpp",
],
shared_libs: [
"libbase",
@@ -75,7 +77,33 @@
static_libs: [
"libandroid.hardware.biometrics.face.VirtualProps",
"android.hardware.biometrics.face-V4-ndk",
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
+ "android.hardware.keymaster-V4-ndk",
+ "android.hardware.biometrics.common.util",
+ ],
+ vendor: true,
+ test_suites: ["general-tests"],
+ require_root: true,
+}
+
+cc_test {
+ name: "android.hardware.biometrics.face.FakeLockoutTrackerTest",
+ srcs: [
+ "tests/FakeLockoutTrackerTest.cpp",
+ "FakeLockoutTracker.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "libnativewindow",
+ ],
+ include_dirs: [
+ "frameworks/native/aidl/gui",
+ ],
+ static_libs: [
+ "libandroid.hardware.biometrics.face.VirtualProps",
+ "android.hardware.biometrics.face-V4-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
"android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
],
diff --git a/biometrics/face/aidl/default/Face.cpp b/biometrics/face/aidl/default/Face.cpp
index 652a7e1..5ae0df6 100644
--- a/biometrics/face/aidl/default/Face.cpp
+++ b/biometrics/face/aidl/default/Face.cpp
@@ -14,11 +14,23 @@
* limitations under the License.
*/
+#undef LOG_TAG
+#define LOG_TAG "FaceVirtualHal"
+
#include "Face.h"
#include "Session.h"
#include "FakeFaceEngine.h"
+#include <android-base/properties.h>
+#include <face.sysprop.h>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+
+using namespace ::android::face::virt;
+
namespace aidl::android::hardware::biometrics::face {
const int kSensorId = 4;
@@ -68,11 +80,105 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus Face::createSession(int32_t /*sensorId*/, int32_t /*userId*/,
+ndk::ScopedAStatus Face::createSession(int32_t sensorId, int32_t userId,
const std::shared_ptr<ISessionCallback>& cb,
std::shared_ptr<ISession>* return_val) {
- *return_val = SharedRefBase::make<Session>(std::make_unique<FakeFaceEngine>(), cb);
+ mSession = SharedRefBase::make<Session>(std::make_unique<FakeFaceEngine>(), cb);
+ *return_val = mSession;
+
+ mSession->linkToDeath(cb->asBinder().get());
+
+ LOG(INFO) << __func__ << ": sensorId:" << sensorId << " userId:" << userId;
return ndk::ScopedAStatus::ok();
}
+binder_status_t Face::dump(int fd, const char** /*args*/, uint32_t numArgs) {
+ if (fd < 0) {
+ LOG(ERROR) << __func__ << "fd invalid: " << fd;
+ return STATUS_BAD_VALUE;
+ } else {
+ LOG(INFO) << __func__ << " fd:" << fd << "numArgs:" << numArgs;
+ }
+
+ dprintf(fd, "----- FaceVirtualHal::dump -----\n");
+ std::vector<SensorProps> sps(1);
+ getSensorProps(&sps);
+ for (auto& sp : sps) {
+ ::android::base::WriteStringToFd(sp.toString(), fd);
+ }
+ if (mSession != nullptr) {
+ ::android::base::WriteStringToFd(mSession->toString(), fd);
+ } else {
+ dprintf(fd, "\nWARNING: no ISession found\n");
+ }
+
+ fsync(fd);
+ return STATUS_OK;
+}
+
+binder_status_t Face::handleShellCommand(int in, int out, int err, const char** args,
+ uint32_t numArgs) {
+ LOG(INFO) << __func__ << " in:" << in << " out:" << out << " err:" << err
+ << " numArgs:" << numArgs;
+
+ if (numArgs == 0) {
+ LOG(INFO) << __func__ << ": available commands";
+ onHelp(out);
+ return STATUS_OK;
+ }
+
+ for (auto&& str : std::vector<std::string_view>(args, args + numArgs)) {
+ std::string option = str.data();
+ if (option.find("clearconfig") != std::string::npos ||
+ option.find("resetconfig") != std::string::npos) {
+ resetConfigToDefault();
+ }
+ if (option.find("help") != std::string::npos) {
+ onHelp(out);
+ }
+ }
+
+ return STATUS_OK;
+}
+
+void Face::onHelp(int fd) {
+ dprintf(fd, "Virtual Face HAL commands:\n");
+ dprintf(fd, " help: print this help\n");
+ dprintf(fd, " resetconfig: reset all configuration to default\n");
+ dprintf(fd, "\n");
+ fsync(fd);
+}
+
+void Face::resetConfigToDefault() {
+ LOG(INFO) << __func__ << ": reset virtual Face HAL configuration to default";
+#define RESET_CONFIG_O(__NAME__) \
+ if (FaceHalProperties::__NAME__()) FaceHalProperties::__NAME__(std::nullopt)
+#define RESET_CONFIG_V(__NAME__) \
+ if (!FaceHalProperties::__NAME__().empty()) FaceHalProperties::__NAME__({std::nullopt})
+
+ RESET_CONFIG_O(type);
+ RESET_CONFIG_O(strength);
+ RESET_CONFIG_V(enrollments);
+ RESET_CONFIG_O(enrollment_hit);
+ RESET_CONFIG_V(features);
+ RESET_CONFIG_O(next_enrollment);
+ RESET_CONFIG_O(authenticator_id);
+ RESET_CONFIG_O(challenge);
+ RESET_CONFIG_O(lockout);
+ RESET_CONFIG_O(operation_authenticate_fails);
+ RESET_CONFIG_O(operation_detect_interaction_fails);
+ RESET_CONFIG_O(operation_enroll_fails);
+ RESET_CONFIG_V(operation_authenticate_latency);
+ RESET_CONFIG_V(operation_detect_interaction_latency);
+ RESET_CONFIG_V(operation_enroll_latency);
+ RESET_CONFIG_O(operation_authenticate_duration);
+ RESET_CONFIG_O(operation_authenticate_error);
+ RESET_CONFIG_O(operation_authenticate_acquired);
+ RESET_CONFIG_O(lockout_enable);
+ RESET_CONFIG_O(lockout_timed_enable);
+ RESET_CONFIG_O(lockout_timed_threshold);
+ RESET_CONFIG_O(lockout_timed_duration);
+ RESET_CONFIG_O(lockout_permanent_threshold);
+}
+
} // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/face/aidl/default/Face.h b/biometrics/face/aidl/default/Face.h
index 786b4f8..93fddb0 100644
--- a/biometrics/face/aidl/default/Face.h
+++ b/biometrics/face/aidl/default/Face.h
@@ -17,16 +17,26 @@
#pragma once
#include <aidl/android/hardware/biometrics/face/BnFace.h>
+#include "Session.h"
namespace aidl::android::hardware::biometrics::face {
class Face : public BnFace {
public:
+ Face() : mSession(nullptr) {}
ndk::ScopedAStatus getSensorProps(std::vector<SensorProps>* _aidl_return) override;
ndk::ScopedAStatus createSession(int32_t sensorId, int32_t userId,
const std::shared_ptr<ISessionCallback>& cb,
std::shared_ptr<ISession>* _aidl_return) override;
+
+ binder_status_t dump(int fd, const char** args, uint32_t numArgs);
+ binder_status_t handleShellCommand(int in, int out, int err, const char** argv, uint32_t argc);
+
+ private:
+ std::shared_ptr<Session> mSession;
+ void resetConfigToDefault();
+ void onHelp(int);
};
} // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/face/aidl/default/FakeFaceEngine.cpp b/biometrics/face/aidl/default/FakeFaceEngine.cpp
index 578231d..bf75874 100644
--- a/biometrics/face/aidl/default/FakeFaceEngine.cpp
+++ b/biometrics/face/aidl/default/FakeFaceEngine.cpp
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#undef LOG_TAG
+#define LOG_TAG "FaceVirtualHalEngine"
+
#include "FakeFaceEngine.h"
#include <android-base/logging.h>
@@ -52,16 +71,7 @@
EnrollmentType /*enrollmentType*/,
const std::vector<Feature>& /*features*/,
const std::future<void>& cancel) {
- BEGIN_OP(FaceHalProperties::operation_start_enroll_latency().value_or(0));
- // format is "<id>,<bucket_id>:<delay>:<succeeds>,<bucket_id>:<delay>:<succeeds>...
- auto nextEnroll = FaceHalProperties::next_enrollment().value_or("");
- // Erase the next enrollment
- FaceHalProperties::next_enrollment({});
-
- AuthenticationFrame frame;
- frame.data.acquiredInfo = AcquiredInfo::START;
- frame.data.vendorCode = 0;
- cb->onAuthenticationFrame(frame);
+ BEGIN_OP(getLatency(FaceHalProperties::operation_enroll_latency()));
// Do proper HAT verification in the real implementation.
if (hat.mac.empty()) {
@@ -70,71 +80,86 @@
return;
}
- if (FaceHalProperties::operation_enroll_fails().value_or(false)) {
- LOG(ERROR) << "Fail: operation_enroll_fails";
+ // Format: <id>:<progress_ms-[acquiredInfo,...],...:<success>
+ // ------:-----------------------------------------:--------------
+ // | | |--->enrollment success (true/false)
+ // | |--> progress_steps
+ // |
+ // |-->enrollment id
+ //
+ //
+ // progress_steps
+ // <progress_duration>-[acquiredInfo,...]+
+ // ---------------------------- ---------------------
+ // | |-> sequence of acquiredInfo code
+ // | --> time duration of the step in ms
+ //
+ // E.g. 1:2000-[21,1108,5,6,1],1000-[1113,4,1]:true
+ // A success enrollement of id 1 by 2 steps
+ // 1st step lasts 2000ms with acquiredInfo codes (21,1108,5,6,1)
+ // 2nd step lasts 1000ms with acquiredInfo codes (1113,4,1)
+ //
+ std::string defaultNextEnrollment =
+ "1:1000-[21,7,1,1103],1500-[1108,1],2000-[1113,1],2500-[1118,1]:true";
+ auto nextEnroll = FaceHalProperties::next_enrollment().value_or(defaultNextEnrollment);
+ auto parts = Util::split(nextEnroll, ":");
+ if (parts.size() != 3) {
+ LOG(ERROR) << "Fail: invalid next_enrollment:" << nextEnroll;
cb->onError(Error::VENDOR, 0 /* vendorError */);
return;
}
-
- auto parts = Util::split(nextEnroll, ",");
- if (parts.size() < 2) {
- LOG(ERROR) << "Fail: invalid next_enrollment for : " << nextEnroll;
- cb->onError(Error::VENDOR, 0 /* vendorError */);
- return;
- }
-
auto enrollmentId = std::stoi(parts[0]);
- const int numBuckets = parts.size() - 1;
- for (size_t i = 1; i < parts.size(); i++) {
- auto enrollHit = Util::split(parts[i], ":");
- if (enrollHit.size() != 3) {
- LOG(ERROR) << "Error when unpacking enrollment hit: " << parts[i];
- cb->onError(Error::VENDOR, 0 /* vendorError */);
- }
- std::string bucket = enrollHit[0];
- std::string delay = enrollHit[1];
- std::string succeeds = enrollHit[2];
+ auto progress = Util::parseEnrollmentCapture(parts[1]);
+ for (size_t i = 0; i < progress.size(); i += 2) {
+ auto left = (progress.size() - i) / 2 - 1;
+ auto duration = progress[i][0];
+ auto acquired = progress[i + 1];
+ auto N = acquired.size();
- SLEEP_MS(std::stoi(delay));
+ for (int j = 0; j < N; j++) {
+ SLEEP_MS(duration / N);
- if (shouldCancel(cancel)) {
- LOG(ERROR) << "Fail: cancel";
- cb->onError(Error::CANCELED, 0 /* vendorCode */);
- return;
+ if (shouldCancel(cancel)) {
+ LOG(ERROR) << "Fail: cancel";
+ cb->onError(Error::CANCELED, 0 /* vendorCode */);
+ return;
+ }
+ EnrollmentFrame frame = {};
+ auto ac = convertAcquiredInfo(acquired[j]);
+ frame.data.acquiredInfo = ac.first;
+ frame.data.vendorCode = ac.second;
+ frame.stage = (i == 0 && j == 0) ? EnrollmentStage::FIRST_FRAME_RECEIVED
+ : (i == progress.size() - 2 && j == N - 1)
+ ? EnrollmentStage::ENROLLMENT_FINISHED
+ : EnrollmentStage::WAITING_FOR_CENTERING;
+ cb->onEnrollmentFrame(frame);
}
- if (!IS_TRUE(succeeds)) { // end and failed
- LOG(ERROR) << "Fail: requested by caller: " << parts[i];
+ if (left == 0 && !IS_TRUE(parts[2])) { // end and failed
+ LOG(ERROR) << "Fail: requested by caller: " << nextEnroll;
+ FaceHalProperties::next_enrollment({});
cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
- return;
- }
-
- EnrollmentFrame frame;
-
- frame.data.acquiredInfo = AcquiredInfo::GOOD;
- frame.data.vendorCode = 0;
- cb->onEnrollmentFrame(frame);
-
- frame.data.acquiredInfo = AcquiredInfo::VENDOR;
- frame.data.vendorCode = std::stoi(bucket);
- cb->onEnrollmentFrame(frame);
-
- int remainingBuckets = numBuckets - i;
- if (remainingBuckets > 0) {
- cb->onEnrollmentProgress(enrollmentId, remainingBuckets);
+ } else { // progress and update props if last time
+ LOG(INFO) << "onEnroll: " << enrollmentId << " left: " << left;
+ if (left == 0) {
+ auto enrollments = FaceHalProperties::enrollments();
+ enrollments.emplace_back(enrollmentId);
+ FaceHalProperties::enrollments(enrollments);
+ FaceHalProperties::next_enrollment({});
+ // change authenticatorId after new enrollment
+ auto id = FaceHalProperties::authenticator_id().value_or(0);
+ auto newId = id + 1;
+ FaceHalProperties::authenticator_id(newId);
+ LOG(INFO) << "Enrolled: " << enrollmentId;
+ }
+ cb->onEnrollmentProgress(enrollmentId, left);
}
}
-
- auto enrollments = FaceHalProperties::enrollments();
- enrollments.push_back(enrollmentId);
- FaceHalProperties::enrollments(enrollments);
- LOG(INFO) << "enrolled : " << enrollmentId;
- cb->onEnrollmentProgress(enrollmentId, 0);
}
void FakeFaceEngine::authenticateImpl(ISessionCallback* cb, int64_t /*operationId*/,
const std::future<void>& cancel) {
- BEGIN_OP(FaceHalProperties::operation_authenticate_latency().value_or(0));
+ BEGIN_OP(getLatency(FaceHalProperties::operation_authenticate_latency()));
auto id = FaceHalProperties::enrollment_hit().value_or(0);
auto enrolls = FaceHalProperties::enrollments();
@@ -180,6 +205,10 @@
return;
}
+ if (mLockoutTracker.checkIfLockout(cb)) {
+ return;
+ }
+
int i = 0;
do {
if (FaceHalProperties::lockout().value_or(false)) {
@@ -191,6 +220,7 @@
if (FaceHalProperties::operation_authenticate_fails().value_or(false)) {
LOG(ERROR) << "Fail: operation_authenticate_fails";
+ mLockoutTracker.addFailedAttempt(cb);
cb->onAuthenticationFailed();
return;
}
@@ -225,10 +255,12 @@
} while (!Util::hasElapsed(now, duration));
if (id > 0 && isEnrolled) {
+ mLockoutTracker.reset();
cb->onAuthenticationSucceeded(id, {} /* hat */);
return;
} else {
LOG(ERROR) << "Fail: face not enrolled";
+ mLockoutTracker.addFailedAttempt(cb);
cb->onAuthenticationFailed();
cb->onError(Error::TIMEOUT, 0 /* vendorError*/);
return;
@@ -260,7 +292,7 @@
}
void FakeFaceEngine::detectInteractionImpl(ISessionCallback* cb, const std::future<void>& cancel) {
- BEGIN_OP(FaceHalProperties::operation_detect_interaction_latency().value_or(0));
+ BEGIN_OP(getLatency(FaceHalProperties::operation_detect_interaction_latency()));
if (FaceHalProperties::operation_detect_interaction_fails().value_or(false)) {
LOG(ERROR) << "Fail: operation_detect_interaction_fails";
@@ -383,7 +415,37 @@
const keymaster::HardwareAuthToken& /*hat*/) {
BEGIN_OP(0);
FaceHalProperties::lockout(false);
+ mLockoutTracker.reset();
cb->onLockoutCleared();
}
+int32_t FakeFaceEngine::getRandomInRange(int32_t bound1, int32_t bound2) {
+ std::uniform_int_distribution<int32_t> dist(std::min(bound1, bound2), std::max(bound1, bound2));
+ return dist(mRandom);
+}
+
+int32_t FakeFaceEngine::getLatency(const std::vector<std::optional<std::int32_t>>& latencyIn) {
+ int32_t res = DEFAULT_LATENCY;
+
+ std::vector<int32_t> latency;
+ for (auto x : latencyIn)
+ if (x.has_value()) latency.push_back(*x);
+
+ switch (latency.size()) {
+ case 0:
+ break;
+ case 1:
+ res = latency[0];
+ break;
+ case 2:
+ res = getRandomInRange(latency[0], latency[1]);
+ break;
+ default:
+ LOG(ERROR) << "ERROR: unexpected input of size " << latency.size();
+ break;
+ }
+
+ return res;
+}
+
} // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/face/aidl/default/FakeFaceEngine.h b/biometrics/face/aidl/default/FakeFaceEngine.h
index 06dd396..b1e1388 100644
--- a/biometrics/face/aidl/default/FakeFaceEngine.h
+++ b/biometrics/face/aidl/default/FakeFaceEngine.h
@@ -16,18 +16,17 @@
#pragma once
-#define LOG_TAG "FaceVirtualHal"
-
#include <aidl/android/hardware/biometrics/common/SensorStrength.h>
#include <aidl/android/hardware/biometrics/face/BnSession.h>
#include <aidl/android/hardware/biometrics/face/FaceSensorType.h>
#include <aidl/android/hardware/biometrics/face/ISessionCallback.h>
-#include <random>
-
#include <future>
+#include <random>
#include <vector>
+#include "FakeLockoutTracker.h"
+
namespace aidl::android::hardware::biometrics::face {
namespace face = aidl::android::hardware::biometrics::face;
@@ -39,6 +38,7 @@
class FakeFaceEngine {
public:
FakeFaceEngine() : mRandom(std::mt19937::default_seed) {}
+ virtual ~FakeFaceEngine() {}
static face::FaceSensorType GetSensorType();
static common::SensorStrength GetSensorStrength();
@@ -60,14 +60,24 @@
void getAuthenticatorIdImpl(ISessionCallback* cb);
void invalidateAuthenticatorIdImpl(ISessionCallback* cb);
void resetLockoutImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& /*hat*/);
+ int32_t getLatency(const std::vector<std::optional<std::int32_t>>& latencyVec);
+
+ virtual std::string toString() const {
+ std::ostringstream os;
+ os << "----- FakeFaceEngine:: -----" << std::endl;
+ os << mLockoutTracker.toString();
+ return os.str();
+ }
std::mt19937 mRandom;
private:
+ int32_t getRandomInRange(int32_t bound1, int32_t bound2);
static constexpr int32_t FACE_ACQUIRED_VENDOR_BASE = 1000;
static constexpr int32_t FACE_ERROR_VENDOR_BASE = 1000;
std::pair<AcquiredInfo, int32_t> convertAcquiredInfo(int32_t code);
std::pair<Error, int32_t> convertError(int32_t code);
+ FakeLockoutTracker mLockoutTracker;
};
} // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/face/aidl/default/FakeLockoutTracker.cpp b/biometrics/face/aidl/default/FakeLockoutTracker.cpp
new file mode 100644
index 0000000..70bf08e
--- /dev/null
+++ b/biometrics/face/aidl/default/FakeLockoutTracker.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "FaceVirtualHalLockoutTracker"
+
+#include "FakeLockoutTracker.h"
+#include <android-base/logging.h>
+#include <face.sysprop.h>
+#include "util/Util.h"
+
+using namespace ::android::face::virt;
+
+namespace aidl::android::hardware::biometrics::face {
+
+void FakeLockoutTracker::reset(bool dueToTimerExpire) {
+ if (!dueToTimerExpire) {
+ mFailedCount = 0;
+ mLastFailedTime = 0;
+ }
+ mTimedFailedCount = 0;
+ mCurrentMode = LockoutMode::kNone;
+ abortTimer();
+}
+
+void FakeLockoutTracker::addFailedAttempt(ISessionCallback* cb) {
+ bool lockoutEnabled = FaceHalProperties::lockout_enable().value_or(false);
+ bool timedLockoutenabled = FaceHalProperties::lockout_timed_enable().value_or(false);
+ if (lockoutEnabled) {
+ mFailedCount++;
+ mTimedFailedCount++;
+ mLastFailedTime = Util::getSystemNanoTime();
+ int32_t lockoutTimedThreshold = FaceHalProperties::lockout_timed_threshold().value_or(3);
+ int32_t lockoutPermanetThreshold =
+ FaceHalProperties::lockout_permanent_threshold().value_or(5);
+ if (mFailedCount >= lockoutPermanetThreshold) {
+ mCurrentMode = LockoutMode::kPermanent;
+ LOG(ERROR) << "FakeLockoutTracker: lockoutPermanent";
+ cb->onLockoutPermanent();
+ abortTimer();
+ } else if (timedLockoutenabled && mTimedFailedCount >= lockoutTimedThreshold) {
+ if (mCurrentMode == LockoutMode::kNone) {
+ mCurrentMode = LockoutMode::kTimed;
+ startLockoutTimer(getTimedLockoutDuration(), cb);
+ }
+ LOG(ERROR) << "FakeLockoutTracker: lockoutTimed";
+ cb->onLockoutTimed(getLockoutTimeLeft());
+ }
+ } else {
+ reset();
+ }
+}
+
+FakeLockoutTracker::LockoutMode FakeLockoutTracker::getMode() {
+ return mCurrentMode;
+}
+
+int32_t FakeLockoutTracker::getTimedLockoutDuration() {
+ return FaceHalProperties::lockout_timed_duration().value_or(10 * 1000);
+}
+
+int64_t FakeLockoutTracker::getLockoutTimeLeft() {
+ int64_t res = 0;
+
+ if (mLastFailedTime > 0) {
+ auto now = Util::getSystemNanoTime();
+ auto elapsed = (now - mLastFailedTime) / 1000000LL;
+ res = getTimedLockoutDuration() - elapsed;
+ LOG(INFO) << "elapsed=" << elapsed << " now = " << now
+ << " mLastFailedTime=" << mLastFailedTime << " res=" << res;
+ }
+
+ return res;
+}
+
+bool FakeLockoutTracker::checkIfLockout(ISessionCallback* cb) {
+ if (mCurrentMode == LockoutMode::kPermanent) {
+ LOG(ERROR) << "Lockout permanent";
+ cb->onLockoutPermanent();
+ return true;
+ } else if (mCurrentMode == LockoutMode::kTimed) {
+ auto timeLeft = getLockoutTimeLeft();
+ LOG(ERROR) << "Lockout timed " << timeLeft;
+ cb->onLockoutTimed(timeLeft);
+ return true;
+ }
+ return false;
+}
+
+void FakeLockoutTracker::startLockoutTimer(int64_t timeout, ISessionCallback* cb) {
+ LOG(ERROR) << "startLockoutTimer: to=" << timeout;
+ if (mIsLockoutTimerStarted) return;
+ std::function<void(ISessionCallback*)> action =
+ std::bind(&FakeLockoutTracker::lockoutTimerExpired, this, std::placeholders::_1);
+ std::thread([timeout, action, cb]() {
+ std::this_thread::sleep_for(std::chrono::milliseconds(timeout));
+ action(cb);
+ }).detach();
+
+ mIsLockoutTimerStarted = true;
+}
+
+void FakeLockoutTracker::lockoutTimerExpired(ISessionCallback* cb) {
+ LOG(INFO) << "lockout timer expired";
+ mIsLockoutTimerStarted = false;
+
+ if (mIsLockoutTimerAborted) {
+ mIsLockoutTimerAborted = false;
+ return;
+ }
+
+ // if more failures seen since the timer started, need to restart timer again
+ auto deltaTime = getLockoutTimeLeft();
+ if (deltaTime <= 0) {
+ cb->onLockoutCleared();
+ reset(true);
+ } else {
+ startLockoutTimer(deltaTime, cb);
+ }
+}
+
+void FakeLockoutTracker::abortTimer() {
+ if (mIsLockoutTimerStarted) mIsLockoutTimerAborted = true;
+}
+
+} // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/face/aidl/default/FakeLockoutTracker.h b/biometrics/face/aidl/default/FakeLockoutTracker.h
new file mode 100644
index 0000000..82cc313
--- /dev/null
+++ b/biometrics/face/aidl/default/FakeLockoutTracker.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/biometrics/face/ISessionCallback.h>
+#include <android/binder_to_string.h>
+#include <stdint.h>
+#include <string>
+
+namespace aidl::android::hardware::biometrics::face {
+
+// Lockout implementation for Face Virtual HAL
+class FakeLockoutTracker {
+ public:
+ FakeLockoutTracker()
+ : mFailedCount(0),
+ mTimedFailedCount(0),
+ mLastFailedTime(0),
+ mCurrentMode(LockoutMode::kNone),
+ mIsLockoutTimerStarted(false),
+ mIsLockoutTimerAborted(false) {}
+ ~FakeLockoutTracker() {}
+
+ enum class LockoutMode : int8_t { kNone = 0, kTimed, kPermanent };
+
+ bool checkIfLockout(ISessionCallback*);
+ void addFailedAttempt(ISessionCallback*);
+ int64_t getLockoutTimeLeft();
+ LockoutMode getMode();
+ void reset(bool dueToTimerExpire = false);
+ inline std::string toString() const {
+ std::ostringstream os;
+ os << "----- FakeLockoutTracker:: -----" << std::endl;
+ os << "mFailedCount:" << mFailedCount;
+ os << ", mCurrentMode:" << (int)mCurrentMode;
+ os << ", mLastFailedTime:" << (int)(mLastFailedTime / 1000000LL);
+ os << ", mIsLockoutTimerStarted:" << mIsLockoutTimerStarted;
+ os << ", mIsLockoutTimerAborted:" << mIsLockoutTimerAborted;
+ os << std::endl;
+ return os.str();
+ }
+
+ private:
+ void startLockoutTimer(int64_t timeout, ISessionCallback* cb);
+ void lockoutTimerExpired(ISessionCallback* cb);
+ int32_t getTimedLockoutDuration();
+ void abortTimer();
+
+ private:
+ int32_t mFailedCount;
+ int32_t mTimedFailedCount;
+ int64_t mLastFailedTime;
+ LockoutMode mCurrentMode;
+ bool mIsLockoutTimerStarted;
+ bool mIsLockoutTimerAborted;
+};
+
+} // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/face/aidl/default/README.md b/biometrics/face/aidl/default/README.md
index 516a7aa..c9a8cfe 100644
--- a/biometrics/face/aidl/default/README.md
+++ b/biometrics/face/aidl/default/README.md
@@ -1,30 +1,35 @@
# Face Virtual HAL (VHAL)
-This is a virtual HAL implementation that is backed by system properties
-instead of actual hardware. It's intended for testing and UI development
-on debuggable builds to allow devices to masquerade as alternative device
-types and for emulators.
-Note: The virtual face HAL feature development will be done in phases. Refer to this doc often for
-the latest supported features
+This is a virtual HAL implementation that is backed by system properties instead
+of actual hardware. It's intended for testing and UI development on debuggable
+builds to allow devices to masquerade as alternative device types and for
+emulators. Note: The virtual face HAL feature development will be done in
+phases. Refer to this doc often for the latest supported features
## Supported Devices
-The face virtual hal is automatically built in in all debug builds (userdebug and eng) for the latest pixel devices and CF.
-The instructions in this doc applies to all
+The face virtual hal is automatically built in in all debug builds (userdebug<br/>
+and eng) for the latest pixel devices and CF. The instructions in this doc<br/>
+applies to all
## Enabling Face Virtual HAL
-On pixel devicse (non-CF), by default (after manufacture reset), Face VHAL is not enabled. Therefore real Face HAL is used.
-Face VHAL enabling is gated by the following two AND conditions:
-1. The Face VHAL feature flag (as part of Trunk-development strategy) must be tured until the flags life-cycle ends.
-2. The Face VHAL must be enabled via sysprop
-See adb commands below
+On pixel devicse (non-CF), by default (after manufacture reset), Face VHAL is <br/>
+not enabled. Therefore real Face HAL is used. Face VHAL enabling is gated by the<br/>
+following two AND conditions:<br/>
+1. The Face VHAL feature flag (as part ofTrunk-development strategy) must be<br/>
+ turned on until the flags life-cycle ends.
+2. The Face VHAL must be enabled via sysprop.
-##Getting Stared
+See the adb commands below
-A basic use case for a successful authentication via Face VHAL is given as an exmple below.
+## Getting Stared
+
+A basic use case for a successful authentication via Face VHAL is given as an
+exmple below.
### Enabling VHAL
+
```shell
$ adb root
$ adb shell device_config put biometrics_framework com.android.server.biometrics.face_vhal_feature true
@@ -35,6 +40,7 @@
```
### Direct Enrollment
+
```shell
$ adb shell locksettings set-pin 0000
$ adb shell setprop persist.vendor.face.virtual.enrollments 1
@@ -42,22 +48,80 @@
```
## Authenticating
-To authenticate successfully, the captured (hit) must match the enrollment id set above. To trigger
-authentication failure, set the hit id to a different value.
-```shell
+
+To authenticate successfully, the captured (hit) must match the enrollment id<br/>
+set above. To trigger authentication failure, set the hit id to a different value.
+`shell
$ adb shell setprop vendor.face.virtual.operation_authenticate_duration 800
-$ adb shell setprop vendor.face.virtual.enrollment_hit 1
-```
-Refer to face.sysprop for full supported features of authentication, such as error and acquiredInfo insertion
+$ adb shell setprop vendor.face.virtual.enrollment_hit 1`
+### AcquiredInfo
-## Enrollment via Setup
+AcquiredInfo codes can be sent during authentication by specifying the sysprop.<br/>
+The codes is sent in sequence and in the interval of operation_authentication_duration/numberOfAcquiredInfoCode
+`shell
+$ adb shell setprop vendor.face.virtual.operation_authenticate_acquired 6,9,1013`
+Refer to [AcquiredInfo.aidl](https://source.corp.google.com/h/googleplex-android/platform/superproject/main/+/main:hardware/interfaces/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl) for full face acquiredInfo codes.
+Note: For vendor specific acquired info, acquiredInfo = 1000 + vendorCode.
+
+### Error Insertion
+
+Error can be inserted during authentction by specifying the authenticate_error
+sysprop. `shell $ adb shell setprop
+vendor.face.virtual.operation_authenticate_error 4` Refer to
+[Error.aidl](https://source.corp.google.com/h/googleplex-android/platform/superproject/main/+/main:hardware/interfaces/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl)
+for full face error codes
+
+## Enrollment via Settings
+
+Enrollment process is specified by sysprop `next_enrollment` in the following
+format
```shell
-# authenticar_id,bucket_id:duration:(true|false)....
-$ adb shell setprop vendor.face.virtual.next_enrollment 1,0:500:true,5:250:true,10:150:true,15:500:true
-$ walk thru the manual enrollment process by following screen instructions
+Format: <id>:<progress_ms-[acquiredInfo,...],...:<success>
+ ----:-----------------------------------:---------
+ | | |--->sucess (true/false)
+ | |--> progress_step(s)
+ |
+ |-->enrollment_id
-# If you would like to get rid of the enrollment, run the follwoing command
-$ adb shell setprop persist.vendor.face.virtual.enrollments \"\"
+E.g.
+$ adb shell setprop vendor.face.virtual.next_enrollment 1:6000-[21,8,1,1108,1,10,1113,1,1118,1124]:true
```
+
+If next_enrollment prop is not set, the following default value is used:<br/>
+ defaultNextEnrollment="1:1000-[21,7,1,1103],1500-[1108,1],2000-[1113,1],2500-[1118,1]:true"<br/>
+Note: Enrollment data and configuration can be supported upon request in case of needs
+
+## Lockout
+
+Device lockout is based on the number of consecutive failed authentication attempts. There are a few
+flavors of lockout mechanisms that are supported by virtula HAL <br/>
+
+### Permanent Lockout
+
+There are two sysprop to control permanent lockout <br/>
+1. general lockout feature enable <br/>
+2. threshold of failed attempts <br/>
+`shell
+$ adb shell setprop persist.vendor.face.virtual.lockout_enable true
+$ adb shell setprop persist.vendor.face.virtual.lockout_permanent_threshold 3`
+
+### Temporary Lockout
+
+There are a few parameters to control temporary lockout (aka timed lockout): <br/>
+1. enable lockout (general lockout feature enable, and timed lcokout enable) <br/>
+2. threshold of failed attempts <br/>
+3. timeout in ms <br/>
+`shell
+$ adb shell setprop persist.vendor.face.virtual.lockout_enable true
+$ adb shell setprop persist.vendor.face.virtual.lockout_timed_enable true
+$ adb shell setprop persist.vendor.face.virtual.lockout_timed_threshold 5
+$ adb shell setprop persist.vendor.face.virtual.lockout_timed_duration 10000`
+
+### Forced Lockout
+
+A permanent lockout can be inserted on next authentication attempt independent of the failed <br/>
+attempt count. This is a feature purely for test purpose.
+`shell
+$ adb shell setprop persist.vendor.face.virtual.lockout true`
diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp
index 6f3f2fc..673d879 100644
--- a/biometrics/face/aidl/default/Session.cpp
+++ b/biometrics/face/aidl/default/Session.cpp
@@ -14,20 +14,38 @@
* limitations under the License.
*/
+#undef LOG_TAG
+#define LOG_TAG "FaceVirtualHalSession"
+
#include <android-base/logging.h>
#include "Session.h"
-#undef LOG_TAG
-#define LOG_TAG "FaceVirtualHalSession"
-
namespace aidl::android::hardware::biometrics::face {
constexpr size_t MAX_WORKER_QUEUE_SIZE = 5;
+void onClientDeath(void* cookie) {
+ LOG(INFO) << "FaceService has died";
+ Session* session = static_cast<Session*>(cookie);
+ if (session && !session->isClosed()) {
+ session->close();
+ }
+}
+
Session::Session(std::unique_ptr<FakeFaceEngine> engine, std::shared_ptr<ISessionCallback> cb)
- : mEngine(std::move(engine)), mCb(std::move(cb)), mRandom(std::mt19937::default_seed) {
+ : mEngine(std::move(engine)),
+ mCb(std::move(cb)),
+ mRandom(std::mt19937::default_seed),
+ mStateClosed(false) {
+ CHECK(mEngine);
+ CHECK(mCb);
mThread = std::make_unique<WorkerThread>(MAX_WORKER_QUEUE_SIZE);
+ mDeathRecipient = AIBinder_DeathRecipient_new(onClientDeath);
+}
+
+binder_status_t Session::linkToDeath(AIBinder* binder) {
+ return AIBinder_linkToDeath(binder, mDeathRecipient, this);
}
ndk::ScopedAStatus Session::generateChallenge() {
@@ -144,9 +162,12 @@
}
ndk::ScopedAStatus Session::close() {
+ LOG(INFO) << "close";
if (mCb) {
mCb->onSessionClosed();
}
+ AIBinder_DeathRecipient_delete(mDeathRecipient);
+ mStateClosed = true;
return ndk::ScopedAStatus::ok();
}
diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h
index ce6e7f1..f79ad00 100644
--- a/biometrics/face/aidl/default/Session.h
+++ b/biometrics/face/aidl/default/Session.h
@@ -33,6 +33,11 @@
using aidl::android::hardware::common::NativeHandle;
+enum class SessionState {
+ IDLING,
+ CLOSED,
+};
+
class Session : public BnSession {
public:
explicit Session(std::unique_ptr<FakeFaceEngine> engine, std::shared_ptr<ISessionCallback> cb);
@@ -93,12 +98,28 @@
const FaceEnrollOptions& options,
std::shared_ptr<common::ICancellationSignal>* out) override;
+ binder_status_t linkToDeath(AIBinder* binder);
+
+ virtual std::string toString() const {
+ std::ostringstream os;
+ os << std::endl << "----- Face::Session:: -----" << std::endl;
+ os << "mStateClosed:" << mStateClosed << std::endl;
+ os << mEngine->toString();
+
+ return os.str();
+ }
+
+ bool isClosed() { return mStateClosed; }
+
private:
std::unique_ptr<FakeFaceEngine> mEngine;
std::shared_ptr<ISessionCallback> mCb;
std::mt19937 mRandom;
std::unique_ptr<WorkerThread> mThread;
- std::shared_ptr<CancellationSignal> mCancellationSignal;
+
+ // Binder death handler.
+ AIBinder_DeathRecipient* mDeathRecipient;
+ bool mStateClosed;
};
} // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/face/aidl/default/api/android.hardware.biometrics.face.VirtualProps-current.txt b/biometrics/face/aidl/default/api/android.hardware.biometrics.face.VirtualProps-current.txt
index 9548920..e69de29 100644
--- a/biometrics/face/aidl/default/api/android.hardware.biometrics.face.VirtualProps-current.txt
+++ b/biometrics/face/aidl/default/api/android.hardware.biometrics.face.VirtualProps-current.txt
@@ -1,98 +0,0 @@
-props {
- owner: Vendor
- module: "android.face.virt.FaceHalProperties"
- prop {
- api_name: "authenticator_id"
- type: Long
- access: ReadWrite
- prop_name: "vendor.face.virtual.authenticator_id"
- }
- prop {
- api_name: "challenge"
- type: Long
- access: ReadWrite
- prop_name: "vendor.face.virtual.challenge"
- }
- prop {
- api_name: "enrollment_hit"
- type: Integer
- access: ReadWrite
- prop_name: "vendor.face.virtual.enrollment_hit"
- }
- prop {
- api_name: "enrollments"
- type: IntegerList
- access: ReadWrite
- prop_name: "persist.vendor.face.virtual.enrollments"
- }
- prop {
- api_name: "features"
- type: IntegerList
- access: ReadWrite
- prop_name: "persist.vendor.face.virtual.features"
- }
- prop {
- api_name: "lockout"
- access: ReadWrite
- prop_name: "vendor.face.virtual.lockout"
- }
- prop {
- api_name: "next_enrollment"
- type: String
- access: ReadWrite
- prop_name: "vendor.face.virtual.next_enrollment"
- }
- prop {
- api_name: "operation_authenticate_duration"
- type: Integer
- access: ReadWrite
- prop_name: "vendor.face.virtual.operation_authenticate_duration"
- }
- prop {
- api_name: "operation_authenticate_fails"
- access: ReadWrite
- prop_name: "vendor.face.virtual.operation_authenticate_fails"
- }
- prop {
- api_name: "operation_authenticate_latency"
- type: Integer
- access: ReadWrite
- prop_name: "vendor.face.virtual.operation_authenticate_latency"
- }
- prop {
- api_name: "operation_detect_interaction_fails"
- access: ReadWrite
- prop_name: "vendor.face.virtual.operation_detect_interaction_fails"
- }
- prop {
- api_name: "operation_detect_interaction_latency"
- type: Integer
- access: ReadWrite
- prop_name: "vendor.face.virtual.operation_detect_interaction_latency"
- }
- prop {
- api_name: "operation_enroll_fails"
- access: ReadWrite
- prop_name: "vendor.face.virtual.operation_enroll_fails"
- }
- prop {
- api_name: "operation_start_enroll_latency"
- type: Integer
- access: ReadWrite
- prop_name: "vendor.face.virtual.operation_start_enroll_latency"
- }
- prop {
- api_name: "strength"
- type: String
- access: ReadWrite
- prop_name: "persist.vendor.face.virtual.strength"
- enum_values: "convenience|weak|strong"
- }
- prop {
- api_name: "type"
- type: String
- access: ReadWrite
- prop_name: "persist.vendor.face.virtual.type"
- enum_values: "IR|RGB"
- }
-}
diff --git a/biometrics/face/aidl/default/face.sysprop b/biometrics/face/aidl/default/face.sysprop
index be32015..997fd67 100644
--- a/biometrics/face/aidl/default/face.sysprop
+++ b/biometrics/face/aidl/default/face.sysprop
@@ -7,7 +7,7 @@
prop {
prop_name: "persist.vendor.face.virtual.type"
type: String
- scope: Public
+ scope: Internal
access: ReadWrite
enum_values: "IR|RGB"
api_name: "type"
@@ -17,7 +17,7 @@
prop {
prop_name: "persist.vendor.face.virtual.strength"
type: String
- scope: Public
+ scope: Internal
access: ReadWrite
enum_values: "convenience|weak|strong"
api_name: "strength"
@@ -27,7 +27,7 @@
prop {
prop_name: "persist.vendor.face.virtual.enrollments"
type: IntegerList
- scope: Public
+ scope: Internal
access: ReadWrite
api_name: "enrollments"
}
@@ -36,7 +36,7 @@
prop {
prop_name: "persist.vendor.face.virtual.features"
type: IntegerList
- scope: Public
+ scope: Internal
access: ReadWrite
api_name: "features"
}
@@ -46,20 +46,11 @@
prop {
prop_name: "vendor.face.virtual.enrollment_hit"
type: Integer
- scope: Public
+ scope: Internal
access: ReadWrite
api_name: "enrollment_hit"
}
-# The initial latency for enrollment
-prop {
- prop_name: "vendor.face.virtual.operation_start_enroll_latency"
- type: Integer
- scope: Public
- access: ReadWrite
- api_name: "operation_start_enroll_latency"
-}
-
# the next enrollment in the format:
# "<id>,<bucket_id>:<delay>:<succeeds>,<bucket_id>..."
# for example: "0:1,0:100:1,1:200:1" indicating that bucket 0 took
@@ -69,7 +60,7 @@
prop {
prop_name: "vendor.face.virtual.next_enrollment"
type: String
- scope: Public
+ scope: Internal
access: ReadWrite
api_name: "next_enrollment"
}
@@ -78,7 +69,7 @@
prop {
prop_name: "vendor.face.virtual.authenticator_id"
type: Long
- scope: Public
+ scope: Internal
access: ReadWrite
api_name: "authenticator_id"
}
@@ -87,16 +78,16 @@
prop {
prop_name: "vendor.face.virtual.challenge"
type: Long
- scope: Public
+ scope: Internal
access: ReadWrite
api_name: "challenge"
}
-# if locked out
+# if forced to lock out (Default to false)
prop {
prop_name: "vendor.face.virtual.lockout"
type: Boolean
- scope: Public
+ scope: Internal
access: ReadWrite
api_name: "lockout"
}
@@ -105,7 +96,7 @@
prop {
prop_name: "vendor.face.virtual.operation_authenticate_fails"
type: Boolean
- scope: Public
+ scope: Internal
access: ReadWrite
api_name: "operation_authenticate_fails"
}
@@ -114,7 +105,7 @@
prop {
prop_name: "vendor.face.virtual.operation_detect_interaction_fails"
type: Boolean
- scope: Public
+ scope: Internal
access: ReadWrite
api_name: "operation_detect_interaction_fails"
}
@@ -123,7 +114,7 @@
prop {
prop_name: "vendor.face.virtual.operation_enroll_fails"
type: Boolean
- scope: Public
+ scope: Internal
access: ReadWrite
api_name: "operation_enroll_fails"
}
@@ -133,8 +124,8 @@
# the HAL will send AcquiredInfo::START and AcquiredInfo::FIRST_FRAME_RECEIVED
prop {
prop_name: "vendor.face.virtual.operation_authenticate_latency"
- type: Integer
- scope: Public
+ type: IntegerList
+ scope: Internal
access: ReadWrite
api_name: "operation_authenticate_latency"
}
@@ -142,18 +133,27 @@
# add a latency to detectInteraction operations
prop {
prop_name: "vendor.face.virtual.operation_detect_interaction_latency"
- type: Integer
- scope: Public
+ type: IntegerList
+ scope: Internal
access: ReadWrite
api_name: "operation_detect_interaction_latency"
}
+# add a latency to enroll operations
+prop {
+ prop_name: "vendor.face.virtual.operation_enroll_latency"
+ type: IntegerList
+ scope: Internal
+ access: ReadWrite
+ api_name: "operation_enroll_latency"
+}
+
# millisecond duration for authenticate operations
# (waits for changes to enrollment_hit)
prop {
prop_name: "vendor.face.virtual.operation_authenticate_duration"
type: Integer
- scope: Public
+ scope: Internal
access: ReadWrite
api_name: "operation_authenticate_duration"
}
@@ -176,3 +176,47 @@
api_name: "operation_authenticate_acquired"
}
+# whether support lockout based on the failed auth attempts (default: false)
+prop {
+ prop_name: "persist.vendor.face.virtual.lockout_enable"
+ type: Boolean
+ scope: Internal
+ access: ReadWrite
+ api_name: "lockout_enable"
+}
+
+# whether support timed_lockout based on the failed auth attempts (default: false)
+prop {
+ prop_name: "persist.vendor.face.virtual.lockout_timed_enable"
+ type: Boolean
+ scope: Internal
+ access: ReadWrite
+ api_name: "lockout_timed_enable"
+}
+
+# temperory lockout threshold in number of consecutive failed auth attempts
+prop {
+ prop_name: "persist.vendor.face.virtual.lockout_timed_threshold"
+ type: Integer
+ scope: Internal
+ access: ReadWrite
+ api_name: "lockout_timed_threshold"
+}
+
+# temporary lockout duration in ms (default: 10000ms)
+prop {
+ prop_name: "persist.vendor.face.virtual.lockout_timed_duration"
+ type: Integer
+ scope: Internal
+ access: ReadWrite
+ api_name: "lockout_timed_duration"
+}
+
+# permanently lockout threshold in number of consecutive failed auth attempts
+prop {
+ prop_name: "persist.vendor.face.virtual.lockout_permanent_threshold"
+ type: Integer
+ scope: Internal
+ access: ReadWrite
+ api_name: "lockout_permanent_threshold"
+}
diff --git a/biometrics/face/aidl/default/tests/FakeFaceEngineTest.cpp b/biometrics/face/aidl/default/tests/FakeFaceEngineTest.cpp
index 6897dc4..8c39b58 100644
--- a/biometrics/face/aidl/default/tests/FakeFaceEngineTest.cpp
+++ b/biometrics/face/aidl/default/tests/FakeFaceEngineTest.cpp
@@ -22,6 +22,7 @@
#include <android-base/logging.h>
#include "FakeFaceEngine.h"
+#include "util/Util.h"
using namespace ::android::face::virt;
using namespace ::aidl::android::hardware::biometrics::face;
@@ -45,6 +46,7 @@
};
::ndk::ScopedAStatus onEnrollmentProgress(int32_t enrollmentId, int32_t remaining) override {
if (remaining == 0) mLastEnrolled = enrollmentId;
+ mRemaining = remaining;
return ndk::ScopedAStatus::ok();
};
@@ -128,6 +130,7 @@
bool mAuthenticatorIdInvalidated = false;
bool mLockoutPermanent = false;
int mInteractionDetectedCount = 0;
+ int mRemaining = -1;
};
class FakeFaceEngineTest : public ::testing::Test {
@@ -135,11 +138,15 @@
void SetUp() override {
LOG(ERROR) << "JRM SETUP";
mCallback = ndk::SharedRefBase::make<TestSessionCallback>();
+ }
+
+ void TearDown() override {
FaceHalProperties::enrollments({});
FaceHalProperties::challenge({});
FaceHalProperties::features({});
FaceHalProperties::authenticator_id({});
FaceHalProperties::strength("");
+ FaceHalProperties::operation_detect_interaction_latency({});
}
FakeFaceEngine mEngine;
@@ -193,7 +200,7 @@
}
TEST_F(FakeFaceEngineTest, Enroll) {
- FaceHalProperties::next_enrollment("1,0:30:true,1:0:true,2:0:true,3:0:true,4:0:true");
+ FaceHalProperties::next_enrollment("1,0:1000-[21,5,6,7,1],1100-[1118,1108,1]:true");
keymaster::HardwareAuthToken hat{.mac = {2, 4}};
mEngine.enrollImpl(mCallback.get(), hat, {} /*enrollmentType*/, {} /*features*/,
mCancel.get_future());
@@ -201,10 +208,11 @@
ASSERT_EQ(1, FaceHalProperties::enrollments().size());
ASSERT_EQ(1, FaceHalProperties::enrollments()[0].value());
ASSERT_EQ(1, mCallback->mLastEnrolled);
+ ASSERT_EQ(0, mCallback->mRemaining);
}
TEST_F(FakeFaceEngineTest, EnrollFails) {
- FaceHalProperties::next_enrollment("1,0:30:true,1:0:true,2:0:true,3:0:true,4:0:false");
+ FaceHalProperties::next_enrollment("1,0:1000-[21,5,6,7,1],1100-[1118,1108,1]:false");
keymaster::HardwareAuthToken hat{.mac = {2, 4}};
mEngine.enrollImpl(mCallback.get(), hat, {} /*enrollmentType*/, {} /*features*/,
mCancel.get_future());
@@ -213,7 +221,7 @@
}
TEST_F(FakeFaceEngineTest, EnrollCancel) {
- FaceHalProperties::next_enrollment("1,0:30:true,1:0:true,2:0:true,3:0:true,4:0:false");
+ FaceHalProperties::next_enrollment("1:2000-[21,8,9],300:false");
keymaster::HardwareAuthToken hat{.mac = {2, 4}};
mCancel.set_value();
mEngine.enrollImpl(mCallback.get(), hat, {} /*enrollmentType*/, {} /*features*/,
@@ -221,7 +229,7 @@
ASSERT_EQ(Error::CANCELED, mCallback->mError);
ASSERT_EQ(-1, mCallback->mLastEnrolled);
ASSERT_EQ(0, FaceHalProperties::enrollments().size());
- ASSERT_FALSE(FaceHalProperties::next_enrollment().has_value());
+ ASSERT_TRUE(FaceHalProperties::next_enrollment().has_value());
}
TEST_F(FakeFaceEngineTest, Authenticate) {
@@ -380,4 +388,26 @@
ASSERT_FALSE(mCallback->mAuthenticateFailed);
}
+TEST_F(FakeFaceEngineTest, LatencyDefault) {
+ FaceHalProperties::operation_detect_interaction_latency({});
+ ASSERT_EQ(DEFAULT_LATENCY,
+ mEngine.getLatency(FaceHalProperties::operation_detect_interaction_latency()));
+}
+
+TEST_F(FakeFaceEngineTest, LatencyFixed) {
+ FaceHalProperties::operation_detect_interaction_latency({10});
+ ASSERT_EQ(10, mEngine.getLatency(FaceHalProperties::operation_detect_interaction_latency()));
+}
+
+TEST_F(FakeFaceEngineTest, LatencyRandom) {
+ FaceHalProperties::operation_detect_interaction_latency({1, 1000});
+ std::set<int32_t> latencySet;
+ for (int i = 0; i < 100; i++) {
+ auto x = mEngine.getLatency(FaceHalProperties::operation_detect_interaction_latency());
+ ASSERT_TRUE(x >= 1 && x <= 1000);
+ latencySet.insert(x);
+ }
+ ASSERT_TRUE(latencySet.size() > 95); // unique values
+}
+
} // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/face/aidl/default/tests/FakeLockoutTrackerTest.cpp b/biometrics/face/aidl/default/tests/FakeLockoutTrackerTest.cpp
new file mode 100644
index 0000000..fa07d1d
--- /dev/null
+++ b/biometrics/face/aidl/default/tests/FakeLockoutTrackerTest.cpp
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/biometrics/face/BnSessionCallback.h>
+#include <android/binder_process.h>
+#include <face.sysprop.h>
+#include <gtest/gtest.h>
+
+#include <android-base/logging.h>
+
+#include "FakeLockoutTracker.h"
+#include "util/Util.h"
+
+using namespace ::android::face::virt;
+using namespace ::aidl::android::hardware::biometrics::face;
+
+namespace aidl::android::hardware::biometrics::face {
+
+class TestSessionCallback : public BnSessionCallback {
+ public:
+ ndk::ScopedAStatus onChallengeGenerated(int64_t /*challenge*/) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onChallengeRevoked(int64_t /*challenge*/) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onError(face::Error, int32_t /*vendorCode*/) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onEnrollmentProgress(int32_t /*enrollmentId*/,
+ int32_t /*remaining*/) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onAuthenticationSucceeded(int32_t /*enrollmentId*/,
+ const keymaster::HardwareAuthToken&) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onAuthenticationFailed() override { return ndk::ScopedAStatus::ok(); };
+ ::ndk::ScopedAStatus onInteractionDetected() override { return ndk::ScopedAStatus::ok(); };
+ ::ndk::ScopedAStatus onEnrollmentsEnumerated(const std::vector<int32_t>&) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onEnrollmentsRemoved(
+ const std::vector<int32_t>& /*enrollmentIds*/) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t /*authenticatorId*/) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onAuthenticatorIdInvalidated(int64_t /*authenticatorId*/) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onEnrollmentFrame(const EnrollmentFrame&) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onFeaturesRetrieved(const std::vector<Feature>&) {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onFeatureSet(Feature) override { return ndk::ScopedAStatus::ok(); }
+ ::ndk::ScopedAStatus onSessionClosed() override { return ndk::ScopedAStatus::ok(); }
+ ::ndk::ScopedAStatus onAuthenticationFrame(const AuthenticationFrame&) override {
+ return ndk::ScopedAStatus::ok();
+ }
+
+ ndk::ScopedAStatus onLockoutTimed(int64_t timeLeft) override {
+ mLockoutTimed++;
+ mTimeLeft = timeLeft;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onLockoutPermanent() override {
+ mLockoutPermanent++;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onLockoutCleared() override {
+ mTimeLeft = 0;
+ mLockoutTimed = 0;
+ mLockoutPermanent = 0;
+ return ndk::ScopedAStatus::ok();
+ };
+
+ int64_t mTimeLeft = 0;
+ int mLockoutTimed = 0;
+ int mLockoutPermanent = 0;
+};
+
+class FakeLockoutTrackerTest : public ::testing::Test {
+ protected:
+ static constexpr int32_t LOCKOUT_TIMED_THRESHOLD = 3;
+ static constexpr int32_t LOCKOUT_PERMANENT_THRESHOLD = 5;
+ static constexpr int32_t LOCKOUT_TIMED_DURATION = 100;
+
+ void SetUp() override {
+ FaceHalProperties::lockout_timed_threshold(LOCKOUT_TIMED_THRESHOLD);
+ FaceHalProperties::lockout_timed_duration(LOCKOUT_TIMED_DURATION);
+ FaceHalProperties::lockout_permanent_threshold(LOCKOUT_PERMANENT_THRESHOLD);
+ mCallback = ndk::SharedRefBase::make<TestSessionCallback>();
+ }
+
+ void TearDown() override {
+ // reset to default
+ FaceHalProperties::lockout_timed_threshold(5);
+ FaceHalProperties::lockout_timed_duration(20);
+ FaceHalProperties::lockout_permanent_threshold(10000);
+ FaceHalProperties::lockout_enable(false);
+ FaceHalProperties::lockout(false);
+ }
+
+ FakeLockoutTracker mLockoutTracker;
+ std::shared_ptr<TestSessionCallback> mCallback;
+};
+
+TEST_F(FakeLockoutTrackerTest, addFailedAttemptDisable) {
+ FaceHalProperties::lockout_enable(false);
+ for (int i = 0; i < LOCKOUT_TIMED_THRESHOLD + 1; i++)
+ mLockoutTracker.addFailedAttempt(mCallback.get());
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kNone);
+ ASSERT_EQ(0, mCallback->mLockoutTimed);
+}
+
+TEST_F(FakeLockoutTrackerTest, addFailedAttemptPermanent) {
+ FaceHalProperties::lockout_enable(true);
+ ASSERT_FALSE(mLockoutTracker.checkIfLockout(mCallback.get()));
+ for (int i = 0; i < LOCKOUT_PERMANENT_THRESHOLD - 1; i++)
+ mLockoutTracker.addFailedAttempt(mCallback.get());
+ ASSERT_NE(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kPermanent);
+ ASSERT_EQ(0, mCallback->mLockoutPermanent);
+ mLockoutTracker.addFailedAttempt(mCallback.get());
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kPermanent);
+ ASSERT_EQ(1, mCallback->mLockoutPermanent);
+ ASSERT_TRUE(mLockoutTracker.checkIfLockout(mCallback.get()));
+ ASSERT_EQ(2, mCallback->mLockoutPermanent);
+}
+
+TEST_F(FakeLockoutTrackerTest, addFailedAttemptLockoutTimed) {
+ FaceHalProperties::lockout_enable(true);
+ FaceHalProperties::lockout_timed_enable(true);
+ ASSERT_FALSE(mLockoutTracker.checkIfLockout(mCallback.get()));
+ for (int i = 0; i < LOCKOUT_TIMED_THRESHOLD; i++)
+ mLockoutTracker.addFailedAttempt(mCallback.get());
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kTimed);
+ ASSERT_EQ(1, mCallback->mLockoutTimed);
+ ASSERT_TRUE(mLockoutTracker.checkIfLockout(mCallback.get()));
+ ASSERT_EQ(2, mCallback->mLockoutTimed);
+ // time left
+ int N = 5;
+ int64_t prevTimeLeft = INT_MAX;
+ for (int i = 0; i < N; i++) {
+ SLEEP_MS(LOCKOUT_TIMED_DURATION / N + 1);
+ int64_t currTimeLeft = mLockoutTracker.getLockoutTimeLeft();
+ ASSERT_TRUE(currTimeLeft < prevTimeLeft);
+ prevTimeLeft = currTimeLeft;
+ }
+ SLEEP_MS(LOCKOUT_TIMED_DURATION / N);
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kNone);
+}
+
+TEST_F(FakeLockoutTrackerTest, addFailedAttemptLockout_TimedThenPermanent) {
+ FaceHalProperties::lockout_enable(true);
+ FaceHalProperties::lockout_timed_enable(true);
+ ASSERT_FALSE(mLockoutTracker.checkIfLockout(mCallback.get()));
+ for (int i = 0; i < LOCKOUT_TIMED_THRESHOLD; i++)
+ mLockoutTracker.addFailedAttempt(mCallback.get());
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kTimed);
+ SLEEP_MS(LOCKOUT_TIMED_DURATION + 20);
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kNone);
+ for (int i = 0; i < LOCKOUT_PERMANENT_THRESHOLD - LOCKOUT_TIMED_THRESHOLD; i++)
+ mLockoutTracker.addFailedAttempt(mCallback.get());
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kPermanent);
+}
+
+TEST_F(FakeLockoutTrackerTest, addFailedAttemptLockoutTimedTwice) {
+ FaceHalProperties::lockout_enable(true);
+ FaceHalProperties::lockout_timed_enable(true);
+ ASSERT_FALSE(mLockoutTracker.checkIfLockout(mCallback.get()));
+ ASSERT_EQ(0, mCallback->mLockoutTimed);
+ for (int i = 0; i < LOCKOUT_TIMED_THRESHOLD; i++)
+ mLockoutTracker.addFailedAttempt(mCallback.get());
+ SLEEP_MS(LOCKOUT_TIMED_DURATION / 2);
+ mLockoutTracker.addFailedAttempt(mCallback.get());
+ SLEEP_MS(LOCKOUT_TIMED_DURATION);
+ ASSERT_EQ(2, mCallback->mLockoutTimed);
+ ASSERT_TRUE(mLockoutTracker.checkIfLockout(mCallback.get()));
+ SLEEP_MS(LOCKOUT_TIMED_DURATION);
+ ASSERT_FALSE(mLockoutTracker.checkIfLockout(mCallback.get()));
+}
+
+TEST_F(FakeLockoutTrackerTest, resetLockout) {
+ FaceHalProperties::lockout_enable(true);
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kNone);
+ for (int i = 0; i < LOCKOUT_PERMANENT_THRESHOLD; i++)
+ mLockoutTracker.addFailedAttempt(mCallback.get());
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kPermanent);
+ mLockoutTracker.reset();
+ ASSERT_FALSE(mLockoutTracker.checkIfLockout(mCallback.get()));
+}
+
+} // namespace aidl::android::hardware::biometrics::face
+
+int main(int argc, char** argv) {
+ testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/biometrics/fingerprint/aidl/Android.bp b/biometrics/fingerprint/aidl/Android.bp
index c543a93..1a099a5 100644
--- a/biometrics/fingerprint/aidl/Android.bp
+++ b/biometrics/fingerprint/aidl/Android.bp
@@ -14,7 +14,7 @@
"android/hardware/biometrics/fingerprint/**/*.aidl",
],
imports: [
- "android.hardware.biometrics.common-V3",
+ "android.hardware.biometrics.common-V4",
"android.hardware.keymaster-V4",
],
stability: "vintf",
@@ -50,5 +50,5 @@
},
],
- frozen: true,
+ frozen: false,
}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
index 4fdcefc..feb6ba3 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -62,5 +62,8 @@
void onPointerUpWithContext(in android.hardware.biometrics.fingerprint.PointerContext context);
void onContextChanged(in android.hardware.biometrics.common.OperationContext context);
void onPointerCancelWithContext(in android.hardware.biometrics.fingerprint.PointerContext context);
+ /**
+ * @deprecated use isHardwareIgnoringTouches in OperationContext from onContextChanged instead
+ */
void setIgnoreDisplayTouches(in boolean shouldIgnore);
}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
index 83e7bbc..07e22c2 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -544,6 +544,8 @@
* whenever it's appropriate.
*
* @param shouldIgnore whether the display touches should be ignored.
+
+ * @deprecated use isHardwareIgnoringTouches in OperationContext from onContextChanged instead
*/
void setIgnoreDisplayTouches(in boolean shouldIgnore);
}
diff --git a/biometrics/fingerprint/aidl/default/Android.bp b/biometrics/fingerprint/aidl/default/Android.bp
index a173a00..c3ec4d0 100644
--- a/biometrics/fingerprint/aidl/default/Android.bp
+++ b/biometrics/fingerprint/aidl/default/Android.bp
@@ -30,8 +30,8 @@
static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
"libbase",
- "android.hardware.biometrics.fingerprint-V3-ndk",
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.fingerprint-V4-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
"android.hardware.biometrics.common.thread",
"android.hardware.biometrics.common.util",
"android.hardware.keymaster-V4-ndk",
@@ -54,8 +54,8 @@
],
static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
- "android.hardware.biometrics.fingerprint-V3-ndk",
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.fingerprint-V4-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
"android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
],
@@ -80,8 +80,8 @@
],
static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
- "android.hardware.biometrics.fingerprint-V3-ndk",
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.fingerprint-V4-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
"android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
],
@@ -104,8 +104,8 @@
],
static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
- "android.hardware.biometrics.fingerprint-V3-ndk",
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.fingerprint-V4-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
"android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
],
@@ -130,8 +130,8 @@
],
static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
- "android.hardware.biometrics.fingerprint-V3-ndk",
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.fingerprint-V4-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
"android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
],
diff --git a/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
index 4e80052..a7acf3d 100644
--- a/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
+++ b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
@@ -62,12 +62,17 @@
return;
}
+ waitForFingerDown(cb, cancel);
+
updateContext(WorkMode::kEnroll, cb, const_cast<std::future<void>&>(cancel), 0, hat);
}
void FakeFingerprintEngine::authenticateImpl(ISessionCallback* cb, int64_t operationId,
const std::future<void>& cancel) {
BEGIN_OP(0);
+
+ waitForFingerDown(cb, cancel);
+
updateContext(WorkMode::kAuthenticate, cb, const_cast<std::future<void>&>(cancel), operationId,
keymaster::HardwareAuthToken());
}
@@ -84,6 +89,8 @@
return;
}
+ waitForFingerDown(cb, cancel);
+
updateContext(WorkMode::kDetectInteract, cb, const_cast<std::future<void>&>(cancel), 0,
keymaster::HardwareAuthToken());
}
@@ -398,6 +405,7 @@
ndk::ScopedAStatus FakeFingerprintEngine::onPointerUpImpl(int32_t /*pointerId*/) {
BEGIN_OP(0);
+ mFingerIsDown = false;
return ndk::ScopedAStatus::ok();
}
@@ -533,4 +541,17 @@
isLockoutTimerStarted = false;
isLockoutTimerAborted = false;
}
+
+void FakeFingerprintEngine::waitForFingerDown(ISessionCallback* cb,
+ const std::future<void>& cancel) {
+ while (!mFingerIsDown) {
+ if (shouldCancel(cancel)) {
+ LOG(ERROR) << "waitForFingerDown, Fail: cancel";
+ cb->onError(Error::CANCELED, 0 /* vendorCode */);
+ return;
+ }
+ SLEEP_MS(10);
+ }
+}
+
} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp
index c06c931..0dd6603 100644
--- a/biometrics/fingerprint/aidl/default/Session.cpp
+++ b/biometrics/fingerprint/aidl/default/Session.cpp
@@ -249,6 +249,7 @@
ndk::ScopedAStatus Session::onPointerDown(int32_t pointerId, int32_t x, int32_t y, float minor,
float major) {
LOG(INFO) << "onPointerDown";
+ mEngine->notifyFingerdown();
mWorker->schedule(Callable::from([this, pointerId, x, y, minor, major] {
mEngine->onPointerDownImpl(pointerId, x, y, minor, major);
enterIdling();
diff --git a/biometrics/fingerprint/aidl/default/fingerprint-example.xml b/biometrics/fingerprint/aidl/default/fingerprint-example.xml
index e977b98..827813f 100644
--- a/biometrics/fingerprint/aidl/default/fingerprint-example.xml
+++ b/biometrics/fingerprint/aidl/default/fingerprint-example.xml
@@ -1,7 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.biometrics.fingerprint</name>
- <version>3</version>
+ <version>4</version>
<fqname>IFingerprint/virtual</fqname>
</hal>
</manifest>
diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
index 15d8360..0d53575 100644
--- a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
+++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
@@ -75,6 +75,7 @@
enum class WorkMode : int8_t { kIdle = 0, kAuthenticate, kEnroll, kDetectInteract };
WorkMode getWorkMode() { return mWorkMode; }
+ void notifyFingerdown() { mFingerIsDown = true; }
virtual std::string toString() const {
std::ostringstream os;
@@ -100,6 +101,7 @@
keymaster::HardwareAuthToken mHat;
std::future<void> mCancel;
int64_t mOperationId;
+ bool mFingerIsDown;
private:
static constexpr int32_t FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
@@ -109,6 +111,7 @@
int32_t getRandomInRange(int32_t bound1, int32_t bound2);
bool checkSensorLockout(ISessionCallback*);
void clearLockout(ISessionCallback* cb);
+ void waitForFingerDown(ISessionCallback* cb, const std::future<void>& cancel);
FakeLockoutTracker mLockoutTracker;
diff --git a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
index eedcae1..8b06c8e 100644
--- a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
+++ b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
@@ -185,6 +185,7 @@
FingerprintHalProperties::enrollments({});
FingerprintHalProperties::next_enrollment("4:0,0:true");
keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+ mEngine.notifyFingerdown();
mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kEnroll);
mEngine.fingerDownAction();
@@ -202,6 +203,7 @@
FingerprintHalProperties::next_enrollment(next);
keymaster::HardwareAuthToken hat{.mac = {2, 4}};
mCancel.set_value();
+ mEngine.notifyFingerdown();
mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
mEngine.fingerDownAction();
ASSERT_EQ(Error::CANCELED, mCallback->mError);
@@ -215,6 +217,7 @@
auto next = "2:0,0:false";
FingerprintHalProperties::next_enrollment(next);
keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+ mEngine.notifyFingerdown();
mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
mEngine.fingerDownAction();
ASSERT_EQ(Error::UNABLE_TO_PROCESS, mCallback->mError);
@@ -228,6 +231,7 @@
FingerprintHalProperties::next_enrollment("4:0,5-[12,1013]:true");
keymaster::HardwareAuthToken hat{.mac = {2, 4}};
int32_t prevCnt = mCallback->mLastAcquiredCount;
+ mEngine.notifyFingerdown();
mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
mEngine.fingerDownAction();
ASSERT_FALSE(FingerprintHalProperties::next_enrollment().has_value());
@@ -242,6 +246,7 @@
TEST_F(FakeFingerprintEngineTest, Authenticate) {
FingerprintHalProperties::enrollments({1, 2});
FingerprintHalProperties::enrollment_hit(2);
+ mEngine.notifyFingerdown();
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kAuthenticate);
mEngine.fingerDownAction();
@@ -255,6 +260,7 @@
FingerprintHalProperties::enrollments({2});
FingerprintHalProperties::enrollment_hit(2);
mCancel.set_value();
+ mEngine.notifyFingerdown();
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
mEngine.fingerDownAction();
ASSERT_EQ(Error::CANCELED, mCallback->mError);
@@ -264,6 +270,7 @@
TEST_F(FakeFingerprintEngineTest, AuthenticateNotSet) {
FingerprintHalProperties::enrollments({1, 2});
FingerprintHalProperties::enrollment_hit({});
+ mEngine.notifyFingerdown();
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
mEngine.fingerDownAction();
ASSERT_TRUE(mCallback->mAuthenticateFailed);
@@ -272,6 +279,7 @@
TEST_F(FakeFingerprintEngineTest, AuthenticateNotEnrolled) {
FingerprintHalProperties::enrollments({1, 2});
FingerprintHalProperties::enrollment_hit(3);
+ mEngine.notifyFingerdown();
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
mEngine.fingerDownAction();
ASSERT_TRUE(mCallback->mAuthenticateFailed);
@@ -282,6 +290,7 @@
FingerprintHalProperties::enrollments({22, 2});
FingerprintHalProperties::enrollment_hit(2);
FingerprintHalProperties::lockout(true);
+ mEngine.notifyFingerdown();
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
mEngine.fingerDownAction();
ASSERT_TRUE(mCallback->mLockoutPermanent);
@@ -290,6 +299,7 @@
TEST_F(FakeFingerprintEngineTest, AuthenticateError8) {
FingerprintHalProperties::operation_authenticate_error(8);
+ mEngine.notifyFingerdown();
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
mEngine.fingerDownAction();
ASSERT_EQ(mCallback->mError, (Error)8);
@@ -298,6 +308,7 @@
TEST_F(FakeFingerprintEngineTest, AuthenticateError9) {
FingerprintHalProperties::operation_authenticate_error(1009);
+ mEngine.notifyFingerdown();
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
mEngine.fingerDownAction();
ASSERT_EQ(mCallback->mError, (Error)7);
@@ -306,6 +317,7 @@
TEST_F(FakeFingerprintEngineTest, AuthenticateFails) {
FingerprintHalProperties::operation_authenticate_fails(true);
+ mEngine.notifyFingerdown();
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
mEngine.fingerDownAction();
ASSERT_TRUE(mCallback->mAuthenticateFailed);
@@ -318,6 +330,7 @@
FingerprintHalProperties::enrollment_hit(2);
FingerprintHalProperties::operation_authenticate_acquired("4,1009");
int32_t prevCount = mCallback->mLastAcquiredCount;
+ mEngine.notifyFingerdown();
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
mEngine.fingerDownAction();
ASSERT_FALSE(mCallback->mAuthenticateFailed);
@@ -332,6 +345,7 @@
FingerprintHalProperties::enrollments({1, 2});
FingerprintHalProperties::enrollment_hit(2);
FingerprintHalProperties::operation_detect_interaction_acquired("");
+ mEngine.notifyFingerdown();
mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kDetectInteract);
mEngine.fingerDownAction();
@@ -345,6 +359,7 @@
FingerprintHalProperties::enrollments({1, 2});
FingerprintHalProperties::enrollment_hit(2);
mCancel.set_value();
+ mEngine.notifyFingerdown();
mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
mEngine.fingerDownAction();
ASSERT_EQ(Error::CANCELED, mCallback->mError);
@@ -355,6 +370,7 @@
FingerprintHalProperties::detect_interaction(true);
FingerprintHalProperties::enrollments({1, 2});
FingerprintHalProperties::enrollment_hit({});
+ mEngine.notifyFingerdown();
mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
mEngine.fingerDownAction();
ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
@@ -363,6 +379,7 @@
TEST_F(FakeFingerprintEngineTest, InteractionDetectNotEnrolled) {
FingerprintHalProperties::enrollments({1, 2});
FingerprintHalProperties::enrollment_hit(25);
+ mEngine.notifyFingerdown();
mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
mEngine.fingerDownAction();
ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
@@ -371,6 +388,7 @@
TEST_F(FakeFingerprintEngineTest, InteractionDetectError) {
FingerprintHalProperties::detect_interaction(true);
FingerprintHalProperties::operation_detect_interaction_error(8);
+ mEngine.notifyFingerdown();
mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
mEngine.fingerDownAction();
ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
@@ -384,6 +402,7 @@
FingerprintHalProperties::enrollment_hit(2);
FingerprintHalProperties::operation_detect_interaction_acquired("4,1013");
int32_t prevCount = mCallback->mLastAcquiredCount;
+ mEngine.notifyFingerdown();
mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
mEngine.fingerDownAction();
ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
diff --git a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp
index f551899..5a30db1 100644
--- a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp
+++ b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp
@@ -145,6 +145,7 @@
TEST_F(FakeFingerprintEngineUdfpsTest, authenticate) {
std::shared_ptr<TestSessionCallback> cb = ndk::SharedRefBase::make<TestSessionCallback>();
std::promise<void> cancel;
+ mEngine.notifyFingerdown();
mEngine.authenticateImpl(cb.get(), 1, cancel.get_future());
ASSERT_TRUE(mEngine.getWorkMode() == FakeFingerprintEngineUdfps::WorkMode::kAuthenticate);
mEngine.onPointerDownImpl(1, 2, 3, 4.0, 5.0);
@@ -158,6 +159,7 @@
std::promise<void> cancel;
keymaster::HardwareAuthToken hat{.mac = {5, 6}};
FingerprintHalProperties::next_enrollment("5:0,0:true");
+ mEngine.notifyFingerdown();
mEngine.enrollImpl(cb.get(), hat, cancel.get_future());
ASSERT_TRUE(mEngine.getWorkMode() == FakeFingerprintEngineUdfps::WorkMode::kEnroll);
mEngine.onPointerDownImpl(1, 2, 3, 4.0, 5.0);
@@ -173,6 +175,7 @@
FingerprintHalProperties::operation_detect_interaction_acquired("");
std::shared_ptr<TestSessionCallback> cb = ndk::SharedRefBase::make<TestSessionCallback>();
std::promise<void> cancel;
+ mEngine.notifyFingerdown();
mEngine.detectInteractionImpl(cb.get(), cancel.get_future());
ASSERT_TRUE(mEngine.getWorkMode() == FakeFingerprintEngineUdfps::WorkMode::kDetectInteract);
mEngine.onPointerDownImpl(1, 2, 3, 4.0, 5.0);
diff --git a/bluetooth/aidl/default/net_bluetooth_mgmt.cpp b/bluetooth/aidl/default/net_bluetooth_mgmt.cpp
index 937cd57..0699781 100644
--- a/bluetooth/aidl/default/net_bluetooth_mgmt.cpp
+++ b/bluetooth/aidl/default/net_bluetooth_mgmt.cpp
@@ -162,9 +162,9 @@
(struct mgmt_ev_read_index_list*)ev.data;
for (int i = 0; i < data->num_controllers; i++) {
- if (data->index[i] == hci_interface) {
- ALOGI("hci interface %d found", hci_interface);
- ret = 0;
+ if (data->index[i] >= hci_interface) {
+ ALOGI("hci interface %d found", data->index[i]);
+ ret = data->index[i];
goto end;
}
}
@@ -253,8 +253,9 @@
rfkill(1);
// Wait for the HCI interface to complete initialization or to come online.
- if (waitHciDev(hci_interface)) {
- ALOGE("hci interface %d not found", hci_interface);
+ hci_interface = waitHciDev(hci_interface);
+ if (hci_interface < 0) {
+ ALOGE("hci interface not found");
return -1;
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpConfiguration.aidl
new file mode 100644
index 0000000..9e67b15
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.audio;
+@VintfStability
+parcelable A2dpConfiguration {
+ int remoteSeid;
+ android.hardware.bluetooth.audio.CodecId id;
+ android.hardware.bluetooth.audio.CodecParameters parameters;
+ byte[] configuration;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpConfigurationHint.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpConfigurationHint.aidl
new file mode 100644
index 0000000..0a5b489
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpConfigurationHint.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.audio;
+@VintfStability
+parcelable A2dpConfigurationHint {
+ byte[6] bdAddr;
+ android.hardware.bluetooth.audio.AudioContext audioContext;
+ @nullable android.hardware.bluetooth.audio.CodecId codecId;
+ @nullable android.hardware.bluetooth.audio.CodecParameters codecParameters;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpRemoteCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpRemoteCapabilities.aidl
new file mode 100644
index 0000000..9c1e971
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpRemoteCapabilities.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.audio;
+@VintfStability
+parcelable A2dpRemoteCapabilities {
+ int seid;
+ android.hardware.bluetooth.audio.CodecId id;
+ byte[] capabilities;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpStatus.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpStatus.aidl
new file mode 100644
index 0000000..ac22e25
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpStatus.aidl
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum A2dpStatus {
+ OK = 0,
+ BAD_LENGTH = 0x11u8,
+ BAD_PAYLOAD_FORMAT = 0x18u8,
+ INVALID_CODEC_TYPE = 0xC1u8,
+ NOT_SUPPORTED_CODEC_TYPE = 0xC2u8,
+ INVALID_SAMPLING_FREQUENCY = 0xC3u8,
+ NOT_SUPPORTED_SAMPLING_FREQUENCY = 0xC4u8,
+ INVALID_CHANNEL_MODE = 0xC5u8,
+ NOT_SUPPORTED_CHANNEL_MODE = 0xC6u8,
+ INVALID_SUBBANDS = 0xC7u8,
+ NOT_SUPPORTED_SUBBANDS = 0xC8u8,
+ INVALID_ALLOCATION_METHOD = 0xC9u8,
+ NOT_SUPPORTED_ALLOCATION_METHOD = 0xCAu8,
+ INVALID_MINIMUM_BITPOOL_VALUE = 0xCBu8,
+ NOT_SUPPORTED_MINIMUM_BITPOOL_VALUE = 0xCCu8,
+ INVALID_MAXIMUM_BITPOOL_VALUE = 0xCDu8,
+ NOT_SUPPORTED_MAXIMUM_BITPOOL_VALUE = 0xCEu8,
+ NOT_SUPPORTED_VBR = 0xD3u8,
+ NOT_SUPPORTED_BIT_RATE = 0xD5u8,
+ INVALID_OBJECT_TYPE = 0xD6u8,
+ NOT_SUPPORTED_OBJECT_TYPE = 0xD7u8,
+ INVALID_CHANNELS = 0xD8u8,
+ NOT_SUPPORTED_CHANNELS = 0xD9u8,
+ INVALID_BLOCK_LENGTH = 0xDDu8,
+ INVALID_CODEC_PARAMETER = 0xE2u8,
+ NOT_SUPPORTED_CODEC_PARAMETER = 0xE3u8,
+ INVALID_DRC = 0xE4u8,
+ NOT_SUPPORTED_DRC = 0xE5u8,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpStreamConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpStreamConfiguration.aidl
new file mode 100644
index 0000000..ff5a1bc
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpStreamConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.audio;
+@VintfStability
+parcelable A2dpStreamConfiguration {
+ int peerMtu;
+ @nullable byte[1] cpHeaderScmst;
+ android.hardware.bluetooth.audio.CodecId codecId;
+ byte[] configuration;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl
index 2148244..418dd7a 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl
@@ -34,8 +34,8 @@
package android.hardware.bluetooth.audio;
@Backing(type="byte") @VintfStability
enum AacObjectType {
- MPEG2_LC = 0,
- MPEG4_LC = 1,
- MPEG4_LTP = 2,
- MPEG4_SCALABLE = 3,
+ MPEG2_LC,
+ MPEG4_LC,
+ MPEG4_LTP,
+ MPEG4_SCALABLE,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveChannelMode.aidl
index 0499b70..675f9f2 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveChannelMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveChannelMode.aidl
@@ -38,5 +38,5 @@
MONO = 1,
DUAL_MONO = 2,
TWS_STEREO = 4,
- UNKNOWN = 255,
+ UNKNOWN = 0xFF,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveInputMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveInputMode.aidl
index f702939..a18303e 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveInputMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveInputMode.aidl
@@ -34,6 +34,6 @@
package android.hardware.bluetooth.audio;
@Backing(type="int") @VintfStability
enum AptxAdaptiveInputMode {
- STEREO = 0,
- DUAL_MONO = 1,
+ STEREO = 0x00,
+ DUAL_MONO = 0x01,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxMode.aidl
index d5dd9d9..dd8cf08 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxMode.aidl
@@ -34,8 +34,8 @@
package android.hardware.bluetooth.audio;
@Backing(type="int") @VintfStability
enum AptxMode {
- UNKNOWN = 0,
- HIGH_QUALITY = 4096,
- LOW_LATENCY = 8192,
- ULTRA_LOW_LATENCY = 16384,
+ UNKNOWN = 0x00,
+ HIGH_QUALITY = 0x1000,
+ LOW_LATENCY = 0x2000,
+ ULTRA_LOW_LATENCY = 0x4000,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl
index 3abfb31..2c40267 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl
@@ -38,4 +38,6 @@
android.hardware.bluetooth.audio.CodecConfiguration a2dpConfig;
android.hardware.bluetooth.audio.LeAudioConfiguration leAudioConfig;
android.hardware.bluetooth.audio.LeAudioBroadcastConfiguration leAudioBroadcastConfig;
+ android.hardware.bluetooth.audio.HfpConfiguration hfpConfig;
+ android.hardware.bluetooth.audio.A2dpStreamConfiguration a2dp;
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioContext.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioContext.aidl
new file mode 100644
index 0000000..5aafeb7
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioContext.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.audio;
+@VintfStability
+parcelable AudioContext {
+ int bitmask;
+ const int UNSPECIFIED = 0x0001;
+ const int CONVERSATIONAL = 0x0002;
+ const int MEDIA = 0x0004;
+ const int GAME = 0x0008;
+ const int INSTRUCTIONAL = 0x0010;
+ const int VOICE_ASSISTANTS = 0x0020;
+ const int LIVE_AUDIO = 0x0040;
+ const int SOUND_EFFECTS = 0x0080;
+ const int NOTIFICATIONS = 0x0100;
+ const int RINGTONE_ALERTS = 0x0200;
+ const int ALERTS = 0x0400;
+ const int EMERGENCY_ALARM = 0x0800;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl
index 319a5e2..941344c 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl
@@ -35,6 +35,6 @@
@Backing(type="int") @VintfStability
enum AudioLocation {
UNKNOWN = 1,
- FRONT_LEFT = 2,
- FRONT_RIGHT = 4,
+ FRONT_LEFT = (1 << 1) /* 2 */,
+ FRONT_RIGHT = (1 << 2) /* 4 */,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl
index feacb80..2bb5cd8 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl
@@ -34,8 +34,8 @@
package android.hardware.bluetooth.audio;
@Backing(type="byte") @VintfStability
enum ChannelMode {
- UNKNOWN = 0,
- MONO = 1,
- STEREO = 2,
- DUALMONO = 3,
+ UNKNOWN,
+ MONO,
+ STEREO,
+ DUALMONO,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecId.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecId.aidl
new file mode 100644
index 0000000..f3b4102
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecId.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.audio;
+@VintfStability
+union CodecId {
+ android.hardware.bluetooth.audio.CodecId.A2dp a2dp = android.hardware.bluetooth.audio.CodecId.A2dp.SBC;
+ android.hardware.bluetooth.audio.CodecId.Core core;
+ android.hardware.bluetooth.audio.CodecId.Vendor vendor;
+ enum A2dp {
+ SBC = 0,
+ AAC = 2,
+ }
+ enum Core {
+ CVSD = 2,
+ MSBC = 5,
+ LC3 = 6,
+ }
+ parcelable Vendor {
+ int id;
+ int codecId;
+ }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecInfo.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecInfo.aidl
new file mode 100644
index 0000000..2727d6e
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecInfo.aidl
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.audio;
+@VintfStability
+parcelable CodecInfo {
+ android.hardware.bluetooth.audio.CodecId id;
+ String name;
+ android.hardware.bluetooth.audio.CodecInfo.Transport transport;
+ parcelable A2dp {
+ byte[] capabilities;
+ android.hardware.bluetooth.audio.ChannelMode[] channelMode;
+ int[] samplingFrequencyHz;
+ int[] bitdepth;
+ boolean lossless;
+ }
+ parcelable Hfp {
+ int inputDataPath = 1;
+ int outputDataPath = 1;
+ boolean useControllerCodec = true;
+ }
+ parcelable LeAudio {
+ android.hardware.bluetooth.audio.ChannelMode[] channelMode;
+ int[] samplingFrequencyHz;
+ int[] frameDurationUs;
+ int[] bitdepth;
+ @nullable android.hardware.bluetooth.audio.ConfigurationFlags flags;
+ }
+ union Transport {
+ android.hardware.bluetooth.audio.CodecInfo.LeAudio leAudio;
+ android.hardware.bluetooth.audio.CodecInfo.A2dp a2dp;
+ android.hardware.bluetooth.audio.CodecInfo.Hfp hfp;
+ }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecParameters.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecParameters.aidl
new file mode 100644
index 0000000..ac63c28
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecParameters.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.audio;
+@VintfStability
+parcelable CodecParameters {
+ android.hardware.bluetooth.audio.ChannelMode channelMode;
+ int samplingFrequencyHz;
+ int bitdepth;
+ int minBitrate;
+ int maxBitrate;
+ boolean lowLatency = false;
+ boolean lossless = false;
+ byte[] vendorSpecificParameters;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecSpecificCapabilitiesLtv.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecSpecificCapabilitiesLtv.aidl
new file mode 100644
index 0000000..60c276b
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecSpecificCapabilitiesLtv.aidl
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.audio;
+@VintfStability
+union CodecSpecificCapabilitiesLtv {
+ android.hardware.bluetooth.audio.CodecSpecificCapabilitiesLtv.SupportedSamplingFrequencies supportedSamplingFrequencies;
+ android.hardware.bluetooth.audio.CodecSpecificCapabilitiesLtv.SupportedFrameDurations supportedFrameDurations;
+ android.hardware.bluetooth.audio.CodecSpecificCapabilitiesLtv.SupportedAudioChannelCounts supportedAudioChannelCounts;
+ android.hardware.bluetooth.audio.CodecSpecificCapabilitiesLtv.SupportedOctetsPerCodecFrame supportedOctetsPerCodecFrame;
+ android.hardware.bluetooth.audio.CodecSpecificCapabilitiesLtv.SupportedMaxCodecFramesPerSDU supportedMaxCodecFramesPerSDU;
+ parcelable SupportedSamplingFrequencies {
+ int bitmask;
+ const int HZ8000 = 0x0001;
+ const int HZ11025 = 0x0002;
+ const int HZ16000 = 0x0004;
+ const int HZ22050 = 0x0008;
+ const int HZ24000 = 0x0010;
+ const int HZ32000 = 0x0020;
+ const int HZ44100 = 0x0040;
+ const int HZ48000 = 0x0080;
+ const int HZ88200 = 0x0100;
+ const int HZ96000 = 0x0200;
+ const int HZ176400 = 0x0400;
+ const int HZ192000 = 0x0800;
+ const int HZ384000 = 0x1000;
+ }
+ parcelable SupportedFrameDurations {
+ int bitmask;
+ const int US7500 = 0x01;
+ const int US10000 = 0x02;
+ const int US7500PREFERRED = 0x10;
+ const int US10000PREFERRED = 0x20;
+ }
+ parcelable SupportedAudioChannelCounts {
+ int bitmask;
+ const int ONE = 0x01;
+ const int TWO = 0x02;
+ const int THREE = 0x04;
+ const int FOUR = 0x08;
+ const int FIVE = 0x10;
+ const int SIX = 0x20;
+ const int SEVEN = 0x40;
+ const int EIGHT = 0x80;
+ }
+ parcelable SupportedOctetsPerCodecFrame {
+ int min;
+ int max;
+ }
+ parcelable SupportedMaxCodecFramesPerSDU {
+ int value;
+ }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecSpecificConfigurationLtv.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecSpecificConfigurationLtv.aidl
new file mode 100644
index 0000000..943d396
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecSpecificConfigurationLtv.aidl
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.audio;
+@VintfStability
+union CodecSpecificConfigurationLtv {
+ android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv.CodecFrameBlocksPerSDU codecFrameBlocksPerSDU;
+ android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv.SamplingFrequency samplingFrequency;
+ android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv.FrameDuration frameDuration;
+ android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv.AudioChannelAllocation audioChannelAllocation;
+ android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv.OctetsPerCodecFrame octetsPerCodecFrame;
+ @Backing(type="byte")
+ enum SamplingFrequency {
+ HZ8000 = 0x01,
+ HZ11025 = 0x02,
+ HZ16000 = 0x03,
+ HZ22050 = 0x04,
+ HZ24000 = 0x05,
+ HZ32000 = 0x06,
+ HZ44100 = 0x07,
+ HZ48000 = 0x08,
+ HZ88200 = 0x09,
+ HZ96000 = 0x0A,
+ HZ176400 = 0x0B,
+ HZ192000 = 0x0C,
+ HZ384000 = 0x0D,
+ }
+ @Backing(type="byte")
+ enum FrameDuration {
+ US7500 = 0x00,
+ US10000 = 0x01,
+ }
+ parcelable AudioChannelAllocation {
+ int bitmask;
+ const int NOT_ALLOWED = 0x00000000;
+ const int FRONT_LEFT = 0x00000001;
+ const int FRONT_RIGHT = 0x00000002;
+ const int FRONT_CENTER = 0x00000004;
+ const int LOW_FREQUENCY_EFFECTS_1 = 0x00000008;
+ const int BACK_LEFT = 0x00000010;
+ const int BACK_RIGHT = 0x00000020;
+ const int FRONT_LEFT_OF_CENTER = 0x00000040;
+ const int FRONT_RIGHT_OF_CENTER = 0x00000080;
+ const int BACK_CENTER = 0x00000100;
+ const int LOW_FREQUENCY_EFFECTS_2 = 0x00000200;
+ const int SIDE_LEFT = 0x00000400;
+ const int SIDE_RIGHT = 0x00000800;
+ const int TOP_FRONT_LEFT = 0x00001000;
+ const int TOP_FRONT_RIGHT = 0x00002000;
+ const int TOP_FRONT_CENTER = 0x00004000;
+ const int TOP_CENTER = 0x00008000;
+ const int TOP_BACK_LEFT = 0x00010000;
+ const int TOP_BACK_RIGHT = 0x00020000;
+ const int TOP_SIDE_LEFT = 0x00040000;
+ const int TOP_SIDE_RIGHT = 0x00080000;
+ const int TOP_BACK_CENTER = 0x00100000;
+ const int BOTTOM_FRONT_CENTER = 0x00200000;
+ const int BOTTOM_FRONT_LEFT = 0x00400000;
+ const int BOTTOM_FRONT_RIGHT = 0x00800000;
+ const int FRONT_LEFT_WIDE = 0x01000000;
+ const int FRONT_RIGHT_WIDE = 0x02000000;
+ const int LEFT_SURROUND = 0x04000000;
+ const int RIGHT_SURROUND = 0x08000000;
+ }
+ parcelable OctetsPerCodecFrame {
+ int value;
+ }
+ parcelable CodecFrameBlocksPerSDU {
+ int value;
+ }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
index 3e204f9..d4f205e 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
@@ -34,16 +34,16 @@
package android.hardware.bluetooth.audio;
@Backing(type="int") @VintfStability
enum CodecType {
- UNKNOWN = 0,
- SBC = 1,
- AAC = 2,
- APTX = 3,
- APTX_HD = 4,
- LDAC = 5,
- LC3 = 6,
- VENDOR = 7,
- APTX_ADAPTIVE = 8,
- OPUS = 9,
- APTX_ADAPTIVE_LE = 10,
- APTX_ADAPTIVE_LEX = 11,
+ UNKNOWN,
+ SBC,
+ AAC,
+ APTX,
+ APTX_HD,
+ LDAC,
+ LC3,
+ VENDOR,
+ APTX_ADAPTIVE,
+ OPUS,
+ APTX_ADAPTIVE_LE,
+ APTX_ADAPTIVE_LEX,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ConfigurationFlags.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ConfigurationFlags.aidl
new file mode 100644
index 0000000..6b3cf72
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ConfigurationFlags.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.audio;
+@VintfStability
+parcelable ConfigurationFlags {
+ int bitmask;
+ const int NONE = 0x0000;
+ const int LOSSLESS = 0x0001;
+ const int LOW_LATENCY = 0x0002;
+ const int ALLOW_ASYMMETRIC_CONFIGURATIONS = 0x0004;
+ const int SPATIAL_AUDIO = 0x0008;
+ const int PROVIDE_ASE_METADATA = 0x0010;
+ const int MONO_MIC_CONFIGURATION = 0x0020;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/HfpConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/HfpConfiguration.aidl
new file mode 100644
index 0000000..490a05d
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/HfpConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.audio;
+@VintfStability
+parcelable HfpConfiguration {
+ android.hardware.bluetooth.audio.CodecId codecId;
+ int connectionHandle;
+ boolean nrec;
+ boolean controllerCodec;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
index 267af0f..8d46c01 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
@@ -40,4 +40,160 @@
void streamSuspended(in android.hardware.bluetooth.audio.BluetoothAudioStatus status);
void updateAudioConfiguration(in android.hardware.bluetooth.audio.AudioConfiguration audioConfig);
void setLowLatencyModeAllowed(in boolean allowed);
+ android.hardware.bluetooth.audio.A2dpStatus parseA2dpConfiguration(in android.hardware.bluetooth.audio.CodecId codecId, in byte[] configuration, out android.hardware.bluetooth.audio.CodecParameters codecParameters);
+ @nullable android.hardware.bluetooth.audio.A2dpConfiguration getA2dpConfiguration(in android.hardware.bluetooth.audio.A2dpRemoteCapabilities[] remoteA2dpCapabilities, in android.hardware.bluetooth.audio.A2dpConfigurationHint hint);
+ void setCodecPriority(in android.hardware.bluetooth.audio.CodecId codecId, int priority);
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseConfigurationSetting[] getLeAudioAseConfiguration(in @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDeviceCapabilities[] remoteSinkAudioCapabilities, in @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDeviceCapabilities[] remoteSourceAudioCapabilities, in android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioConfigurationRequirement[] requirements);
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfigurationPair getLeAudioAseQosConfiguration(in android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfigurationRequirement qosRequirement);
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfigurationPair getLeAudioAseDatapathConfiguration(in @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.StreamConfig sinkConfig, in @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.StreamConfig sourceConfig);
+ void onSinkAseMetadataChanged(in android.hardware.bluetooth.audio.IBluetoothAudioProvider.AseState state, int cigId, int cisId, in @nullable android.hardware.bluetooth.audio.MetadataLtv[] metadata);
+ void onSourceAseMetadataChanged(in android.hardware.bluetooth.audio.IBluetoothAudioProvider.AseState state, int cigId, int cisId, in @nullable android.hardware.bluetooth.audio.MetadataLtv[] metadata);
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioBroadcastConfigurationSetting getLeAudioBroadcastConfiguration(in @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDeviceCapabilities[] remoteSinkAudioCapabilities, in android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioBroadcastConfigurationRequirement requirement);
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfiguration getLeAudioBroadcastDatapathConfiguration(in android.hardware.bluetooth.audio.AudioContext audioContext, in android.hardware.bluetooth.audio.LeAudioBroadcastConfiguration.BroadcastStreamMap[] streamMap);
+ const int CODEC_PRIORITY_DISABLED = (-1) /* -1 */;
+ const int CODEC_PRIORITY_NONE = 0;
+ @VintfStability
+ parcelable LeAudioDeviceCapabilities {
+ android.hardware.bluetooth.audio.CodecId codecId;
+ android.hardware.bluetooth.audio.CodecSpecificCapabilitiesLtv[] codecSpecificCapabilities;
+ @nullable byte[] vendorCodecSpecificCapabilities;
+ @nullable android.hardware.bluetooth.audio.MetadataLtv[] metadata;
+ }
+ @VintfStability
+ parcelable LeAudioDataPathConfiguration {
+ int dataPathId;
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfiguration.DataPathConfiguration dataPathConfiguration;
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfiguration.IsoDataPathConfiguration isoDataPathConfiguration;
+ @VintfStability
+ parcelable IsoDataPathConfiguration {
+ android.hardware.bluetooth.audio.CodecId codecId;
+ boolean isTransparent;
+ int controllerDelayUs;
+ @nullable byte[] configuration;
+ }
+ @VintfStability
+ parcelable DataPathConfiguration {
+ @nullable byte[] configuration;
+ }
+ }
+ @VintfStability
+ parcelable LeAudioAseQosConfiguration {
+ int sduIntervalUs;
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.Framing framing;
+ android.hardware.bluetooth.audio.Phy[] phy;
+ int maxTransportLatencyMs;
+ int maxSdu;
+ int retransmissionNum;
+ }
+ @Backing(type="byte") @VintfStability
+ enum Packing {
+ SEQUENTIAL = 0x00,
+ INTERLEAVED = 0x01,
+ }
+ @Backing(type="byte") @VintfStability
+ enum Framing {
+ UNFRAMED = 0x00,
+ FRAMED = 0x01,
+ }
+ @VintfStability
+ parcelable LeAudioAseConfigurationSetting {
+ android.hardware.bluetooth.audio.AudioContext audioContext;
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.Packing packing;
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseConfigurationSetting.AseDirectionConfiguration[] sinkAseConfiguration;
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseConfigurationSetting.AseDirectionConfiguration[] sourceAseConfiguration;
+ @nullable android.hardware.bluetooth.audio.ConfigurationFlags flags;
+ @VintfStability
+ parcelable AseDirectionConfiguration {
+ android.hardware.bluetooth.audio.LeAudioAseConfiguration aseConfiguration;
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfiguration qosConfiguration;
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfiguration dataPathConfiguration;
+ }
+ }
+ @VintfStability
+ parcelable LeAudioConfigurationRequirement {
+ android.hardware.bluetooth.audio.AudioContext audioContext;
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioConfigurationRequirement.AseDirectionRequirement[] sinkAseRequirement;
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioConfigurationRequirement.AseDirectionRequirement[] sourceAseRequirement;
+ @nullable android.hardware.bluetooth.audio.ConfigurationFlags flags;
+ @VintfStability
+ parcelable AseDirectionRequirement {
+ android.hardware.bluetooth.audio.LeAudioAseConfiguration aseConfiguration;
+ }
+ }
+ @VintfStability
+ parcelable LeAudioAseQosConfigurationRequirement {
+ android.hardware.bluetooth.audio.AudioContext audioContext;
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfigurationRequirement.AseQosDirectionRequirement sinkAseQosRequirement;
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfigurationRequirement.AseQosDirectionRequirement sourceAseQosRequirement;
+ @nullable android.hardware.bluetooth.audio.ConfigurationFlags flags;
+ @VintfStability
+ parcelable AseQosDirectionRequirement {
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.Framing framing;
+ android.hardware.bluetooth.audio.Phy[] preferredPhy;
+ int preferredRetransmissionNum;
+ int maxTransportLatencyMs;
+ int presentationDelayMinUs;
+ int presentationDelayMaxUs;
+ int preferredPresentationDelayMinUs;
+ int preferredPresentationDelayMaxUs;
+ android.hardware.bluetooth.audio.LeAudioAseConfiguration aseConfiguration;
+ }
+ }
+ @VintfStability
+ parcelable LeAudioAseQosConfigurationPair {
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfiguration sinkQosConfiguration;
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfiguration sourceQosConfiguration;
+ }
+ parcelable LeAudioDataPathConfigurationPair {
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfiguration inputConfig;
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfiguration outputConfig;
+ }
+ parcelable StreamConfig {
+ android.hardware.bluetooth.audio.AudioContext audioContext;
+ android.hardware.bluetooth.audio.LeAudioConfiguration.StreamMap[] streamMap;
+ }
+ @Backing(type="byte") @VintfStability
+ enum AseState {
+ ENABLING = 0x00,
+ STREAMING = 0x01,
+ DISABLING = 0x02,
+ }
+ @Backing(type="byte") @VintfStability
+ enum BroadcastQuality {
+ STANDARD,
+ HIGH,
+ }
+ @VintfStability
+ parcelable LeAudioBroadcastSubgroupConfigurationRequirement {
+ android.hardware.bluetooth.audio.AudioContext audioContext;
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.BroadcastQuality quality;
+ int bisNumPerSubgroup;
+ }
+ @VintfStability
+ parcelable LeAudioBroadcastConfigurationRequirement {
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioBroadcastSubgroupConfigurationRequirement[] subgroupConfigurationRequirements;
+ }
+ @VintfStability
+ parcelable LeAudioSubgroupBisConfiguration {
+ int numBis;
+ android.hardware.bluetooth.audio.LeAudioBisConfiguration bisConfiguration;
+ }
+ @VintfStability
+ parcelable LeAudioBroadcastSubgroupConfiguration {
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioSubgroupBisConfiguration[] bisConfigurations;
+ @nullable byte[] vendorCodecConfiguration;
+ }
+ @VintfStability
+ parcelable LeAudioBroadcastConfigurationSetting {
+ int sduIntervalUs;
+ int numBis;
+ int maxSduOctets;
+ int maxTransportLatencyMs;
+ int retransmitionNum;
+ android.hardware.bluetooth.audio.Phy[] phy;
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.Packing packing;
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.Framing framing;
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfiguration dataPathConfiguration;
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioBroadcastSubgroupConfiguration[] subgroupsConfigurations;
+ }
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
index 5e33deb..edb79a3 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
@@ -36,4 +36,11 @@
interface IBluetoothAudioProviderFactory {
android.hardware.bluetooth.audio.AudioCapabilities[] getProviderCapabilities(in android.hardware.bluetooth.audio.SessionType sessionType);
android.hardware.bluetooth.audio.IBluetoothAudioProvider openProvider(in android.hardware.bluetooth.audio.SessionType sessionType);
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProviderFactory.ProviderInfo getProviderInfo(in android.hardware.bluetooth.audio.SessionType sessionType);
+ @VintfStability
+ parcelable ProviderInfo {
+ String name;
+ android.hardware.bluetooth.audio.CodecInfo[] codecInfos;
+ boolean supportsMultidirectionalCapabilities;
+ }
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl
index 88d6faf..3d80c4b 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl
@@ -34,8 +34,8 @@
package android.hardware.bluetooth.audio;
@Backing(type="byte") @VintfStability
enum LdacChannelMode {
- UNKNOWN = 0,
- STEREO = 1,
- DUAL = 2,
- MONO = 3,
+ UNKNOWN,
+ STEREO,
+ DUAL,
+ MONO,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
index 35e4358..a332dc5 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
@@ -34,8 +34,8 @@
package android.hardware.bluetooth.audio;
@Backing(type="byte") @VintfStability
enum LdacQualityIndex {
- HIGH = 0,
- MID = 1,
- LOW = 2,
- ABR = 3,
+ HIGH,
+ MID,
+ LOW,
+ ABR,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioAseConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioAseConfiguration.aidl
new file mode 100644
index 0000000..bffc88b
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioAseConfiguration.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.audio;
+@VintfStability
+parcelable LeAudioAseConfiguration {
+ android.hardware.bluetooth.audio.LeAudioAseConfiguration.TargetLatency targetLatency;
+ android.hardware.bluetooth.audio.Phy targetPhy;
+ @nullable android.hardware.bluetooth.audio.CodecId codecId;
+ android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv[] codecConfiguration;
+ @nullable byte[] vendorCodecConfiguration;
+ @nullable android.hardware.bluetooth.audio.MetadataLtv[] metadata;
+ @Backing(type="byte") @VintfStability
+ enum TargetLatency {
+ UNDEFINED = 0x00,
+ LOWER = 0x01,
+ BALANCED_LATENCY_RELIABILITY = 0x02,
+ HIGHER_RELIABILITY = 0x03,
+ }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBisConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBisConfiguration.aidl
new file mode 100644
index 0000000..b09d34f
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBisConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.audio;
+@VintfStability
+parcelable LeAudioBisConfiguration {
+ android.hardware.bluetooth.audio.CodecId codecId;
+ android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv[] codecConfiguration;
+ byte[] vendorCodecConfiguration;
+ @nullable android.hardware.bluetooth.audio.MetadataLtv[] metadata;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
index 2945710..efd3b02 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
@@ -42,5 +42,7 @@
int audioChannelAllocation;
android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCodecConfig;
char pcmStreamId;
+ @nullable android.hardware.bluetooth.audio.LeAudioBisConfiguration bisConfiguration;
+ @nullable android.hardware.bluetooth.audio.ConfigurationFlags flags;
}
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
index 2d9ebae..25a9797 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
@@ -44,5 +44,16 @@
char streamHandle;
int audioChannelAllocation;
boolean isStreamActive;
+ @nullable android.hardware.bluetooth.audio.LeAudioAseConfiguration aseConfiguration;
+ @nullable android.hardware.bluetooth.audio.ConfigurationFlags flags;
+ @nullable android.hardware.bluetooth.audio.LeAudioConfiguration.StreamMap.BluetoothDeviceAddress bluetoothDeviceAddress;
+ parcelable BluetoothDeviceAddress {
+ byte[6] deviceAddress;
+ android.hardware.bluetooth.audio.LeAudioConfiguration.StreamMap.BluetoothDeviceAddress.DeviceAddressType deviceAddressType;
+ enum DeviceAddressType {
+ BLE_ADDRESS_PUBLIC = 0x00,
+ BLE_ADDRESS_RANDOM = 0x01,
+ }
+ }
}
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/MetadataLtv.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/MetadataLtv.aidl
new file mode 100644
index 0000000..5e8a2ae
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/MetadataLtv.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.audio;
+@VintfStability
+union MetadataLtv {
+ android.hardware.bluetooth.audio.MetadataLtv.PreferredAudioContexts preferredAudioContexts;
+ android.hardware.bluetooth.audio.MetadataLtv.StreamingAudioContexts streamingAudioContexts;
+ android.hardware.bluetooth.audio.MetadataLtv.VendorSpecific vendorSpecific;
+ parcelable PreferredAudioContexts {
+ android.hardware.bluetooth.audio.AudioContext values;
+ }
+ parcelable StreamingAudioContexts {
+ android.hardware.bluetooth.audio.AudioContext values;
+ }
+ parcelable VendorSpecific {
+ int companyId;
+ byte[] opaqueValue;
+ }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Phy.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Phy.aidl
new file mode 100644
index 0000000..bfeabcd
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Phy.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum Phy {
+ UNDEFINED = 0x00,
+ ONE_M = 0x01,
+ TWO_M = 0x02,
+ CODED = 0x03,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
index 091f6d7..9cf65d5 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
@@ -34,6 +34,6 @@
package android.hardware.bluetooth.audio;
@Backing(type="byte") @VintfStability
enum SbcAllocMethod {
- ALLOC_MD_S = 0,
- ALLOC_MD_L = 1,
+ ALLOC_MD_S,
+ ALLOC_MD_L,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl
index 6441a99..7779aa0 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl
@@ -34,9 +34,9 @@
package android.hardware.bluetooth.audio;
@Backing(type="byte") @VintfStability
enum SbcChannelMode {
- UNKNOWN = 0,
- JOINT_STEREO = 1,
- STEREO = 2,
- DUAL = 3,
- MONO = 4,
+ UNKNOWN,
+ JOINT_STEREO,
+ STEREO,
+ DUAL,
+ MONO,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
index 33a3187..71cca53 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
@@ -34,16 +34,19 @@
package android.hardware.bluetooth.audio;
@Backing(type="byte") @VintfStability
enum SessionType {
- UNKNOWN = 0,
- A2DP_SOFTWARE_ENCODING_DATAPATH = 1,
- A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH = 2,
- HEARING_AID_SOFTWARE_ENCODING_DATAPATH = 3,
- LE_AUDIO_SOFTWARE_ENCODING_DATAPATH = 4,
- LE_AUDIO_SOFTWARE_DECODING_DATAPATH = 5,
- LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH = 6,
- LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH = 7,
- LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH = 8,
- LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH = 9,
- A2DP_SOFTWARE_DECODING_DATAPATH = 10,
- A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH = 11,
+ UNKNOWN,
+ A2DP_SOFTWARE_ENCODING_DATAPATH,
+ A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
+ LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
+ LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
+ LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
+ LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ A2DP_SOFTWARE_DECODING_DATAPATH,
+ A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ HFP_SOFTWARE_ENCODING_DATAPATH,
+ HFP_SOFTWARE_DECODING_DATAPATH,
+ HFP_HARDWARE_OFFLOAD_DATAPATH,
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpConfiguration.aidl
new file mode 100644
index 0000000..db5212f
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpConfiguration.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.CodecId;
+import android.hardware.bluetooth.audio.CodecParameters;
+
+/**
+ * A2DP Service Configuration
+ */
+@VintfStability
+parcelable A2dpConfiguration {
+ /**
+ * Remote Stream Endpoint Identifier
+ * This matches `A2dpRemoteCapabilities.seid` given by the framework.
+ */
+ int remoteSeid;
+
+ /**
+ * Codec Selection and configuration, in a generic way with `parameters`
+ * and as defined by A2DP for codec interoperability requirements, with
+ * `configuration`. Using `id.a2dp`, the format is given by the `Codec
+ * Specific Information Elements` [A2DP - 4.3-6.2], and using `id.vendor`,
+ * by `Vendor Specific Value` [A2DP - 4.7.2].
+ * In any case, this byte array must be limited to 128 bytes.
+ */
+ CodecId id;
+ CodecParameters parameters;
+ byte[] configuration;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpConfigurationHint.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpConfigurationHint.aidl
new file mode 100644
index 0000000..f707a8a
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpConfigurationHint.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AudioContext;
+import android.hardware.bluetooth.audio.CodecId;
+import android.hardware.bluetooth.audio.CodecParameters;
+
+/**
+ * A2DP Configuration Hints
+ */
+@VintfStability
+parcelable A2dpConfigurationHint {
+ /**
+ * Bluetooth Device Address, intended to be used for interoperabilities.
+ */
+ byte[6] bdAddr;
+
+ /**
+ * Audio configuration hints:
+ * - The starting audio context of the session
+ * - An optional preference of codec and / or parameters
+ */
+
+ AudioContext audioContext;
+ @nullable CodecId codecId;
+ @nullable CodecParameters codecParameters;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpRemoteCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpRemoteCapabilities.aidl
new file mode 100644
index 0000000..224bb60
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpRemoteCapabilities.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.CodecId;
+
+/**
+ * A2DP Remote Capabilites
+ */
+@VintfStability
+parcelable A2dpRemoteCapabilities {
+ /**
+ * Remote Stream Endpoint identifier
+ * Allocated by the remote device to identify a specific codec and capabilities,
+ * in the meaning of the AVDTP standard.
+ */
+ int seid;
+
+ /**
+ * Codec Identifier and `capabilities` as defined by A2DP for codec
+ * interoperability requirements. Using `id.a2dp`, the format is given
+ * by the `Codec Specific Information Elements` [A2DP - 4.3-6.2], and
+ * using `id.vendor`, by `Vendor Specific Value` [A2DP - 4.7.2].
+ */
+ CodecId id;
+ byte[] capabilities;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpStatus.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpStatus.aidl
new file mode 100644
index 0000000..8eba3c9
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpStatus.aidl
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+@VintfStability
+@Backing(type="byte")
+enum A2dpStatus {
+
+ OK = 0,
+
+ /**
+ * Error codes defined by AVDTP [AVDTP - 8.20.6.2]
+ */
+
+ BAD_LENGTH = 0x11u8,
+ BAD_PAYLOAD_FORMAT = 0x18u8,
+
+ /**
+ * Error codecs defined by A2DP for AVDTP Interoperability [A2DP - 5.1.3]
+ */
+
+ INVALID_CODEC_TYPE = 0xC1u8,
+ NOT_SUPPORTED_CODEC_TYPE = 0xC2u8,
+ INVALID_SAMPLING_FREQUENCY = 0xC3u8,
+ NOT_SUPPORTED_SAMPLING_FREQUENCY = 0xC4u8,
+ INVALID_CHANNEL_MODE = 0xC5u8,
+ NOT_SUPPORTED_CHANNEL_MODE = 0xC6u8,
+ INVALID_SUBBANDS = 0xC7u8,
+ NOT_SUPPORTED_SUBBANDS = 0xC8u8,
+ INVALID_ALLOCATION_METHOD = 0xC9u8,
+ NOT_SUPPORTED_ALLOCATION_METHOD = 0xCAu8,
+ INVALID_MINIMUM_BITPOOL_VALUE = 0xCBu8,
+ NOT_SUPPORTED_MINIMUM_BITPOOL_VALUE = 0xCCu8,
+ INVALID_MAXIMUM_BITPOOL_VALUE = 0xCDu8,
+ NOT_SUPPORTED_MAXIMUM_BITPOOL_VALUE = 0xCEu8,
+ NOT_SUPPORTED_VBR = 0xD3u8,
+ NOT_SUPPORTED_BIT_RATE = 0xD5u8,
+ INVALID_OBJECT_TYPE = 0xD6u8,
+ NOT_SUPPORTED_OBJECT_TYPE = 0xD7u8,
+ INVALID_CHANNELS = 0xD8u8,
+ NOT_SUPPORTED_CHANNELS = 0xD9u8,
+ INVALID_BLOCK_LENGTH = 0xDDu8,
+ INVALID_CODEC_PARAMETER = 0xE2u8,
+ NOT_SUPPORTED_CODEC_PARAMETER = 0xE3u8,
+ INVALID_DRC = 0xE4u8,
+ NOT_SUPPORTED_DRC = 0xE5u8,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpStreamConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpStreamConfiguration.aidl
new file mode 100644
index 0000000..b8521f4
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpStreamConfiguration.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.CodecId;
+
+@VintfStability
+parcelable A2dpStreamConfiguration {
+ /**
+ * Peer Maximum Transfer Unit (MTU), 16 bits value [Core - 3.A.5.1]
+ * It's the remote device indication of the maximum amount of data that
+ * can be received on the AVDTP Stream Channel.
+ */
+ int peerMtu;
+
+ /**
+ * Optional SCMS-T Content Protection header
+ * that precedes audio content when enabled [A2DP - 3.2.1-2].
+ * The content protection byte is defined by [Assigned Number - 6.3.2].
+ * When the content protection is not enabled, this field should be left `null`.
+ */
+ @nullable byte[1] cpHeaderScmst;
+
+ /**
+ * Codec Identifier and `configuration` as defined by A2DP for codec
+ * interoperability requirements. Using `codecId.a2dp`, the format is given
+ * by the `Codec Specific Information Elements` [A2DP - 4.3-6.2], and
+ * using `codecId.vendor`, by `Vendor Specific Value` [A2DP - 4.7.2].
+ */
+ CodecId codecId;
+ byte[] configuration;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl
index a06337e..5317dfb 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl
@@ -16,7 +16,9 @@
package android.hardware.bluetooth.audio;
+import android.hardware.bluetooth.audio.A2dpStreamConfiguration;
import android.hardware.bluetooth.audio.CodecConfiguration;
+import android.hardware.bluetooth.audio.HfpConfiguration;
import android.hardware.bluetooth.audio.LeAudioBroadcastConfiguration;
import android.hardware.bluetooth.audio.LeAudioConfiguration;
import android.hardware.bluetooth.audio.PcmConfiguration;
@@ -30,4 +32,6 @@
CodecConfiguration a2dpConfig;
LeAudioConfiguration leAudioConfig;
LeAudioBroadcastConfiguration leAudioBroadcastConfig;
+ HfpConfiguration hfpConfig;
+ A2dpStreamConfiguration a2dp;
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioContext.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioContext.aidl
new file mode 100644
index 0000000..306e897
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioContext.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+/**
+ * Context of the audio configuration.
+ * Defined by PACS (Le Audio) and used either by A2DP or LE Audio.
+ * The `bitmask` is any combination of BT Sig standardized values
+ * [Assigned Numbers - 6.12.3], defined in this scope.
+ */
+@VintfStability
+parcelable AudioContext {
+ const int UNSPECIFIED = 0x0001;
+ const int CONVERSATIONAL = 0x0002;
+ const int MEDIA = 0x0004;
+ const int GAME = 0x0008;
+ const int INSTRUCTIONAL = 0x0010;
+ const int VOICE_ASSISTANTS = 0x0020;
+ const int LIVE_AUDIO = 0x0040;
+ const int SOUND_EFFECTS = 0x0080;
+ const int NOTIFICATIONS = 0x0100;
+ const int RINGTONE_ALERTS = 0x0200;
+ const int ALERTS = 0x0400;
+ const int EMERGENCY_ALARM = 0x0800;
+
+ int bitmask;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecId.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecId.aidl
new file mode 100644
index 0000000..2243957
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecId.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+@VintfStability
+union CodecId {
+ /**
+ * Codec Identifier defined for A2DP
+ * The values are assigned by BT Sig [Assigned Numbers - 6.5.1]
+ */
+ enum A2dp { SBC = 0, AAC = 2 }
+
+ /**
+ * Codec Identifier defined for the Bluetooth Core Specification
+ * The values are assigned by BT Sig [Assigned Numbers - 2.11]
+ */
+ enum Core { CVSD = 2, MSBC = 5, LC3 = 6 }
+
+ /**
+ * Vendor Codec:
+ * id 16 bits - Vendor identifier, assigned by BT Sig [Assigned Numbers - 7.1]
+ * codecId 16 bits - Assigned by the vendor
+ */
+ parcelable Vendor {
+ int id;
+ int codecId;
+ }
+
+ /**
+ * Standard (A2DP or Core numbering space) or vendor
+ */
+ A2dp a2dp = A2dp.SBC;
+ Core core;
+ Vendor vendor;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecInfo.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecInfo.aidl
new file mode 100644
index 0000000..b60d70f
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecInfo.aidl
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.ChannelMode;
+import android.hardware.bluetooth.audio.CodecId;
+import android.hardware.bluetooth.audio.ConfigurationFlags;
+
+/**
+ * General information about a Codec
+ */
+@VintfStability
+parcelable CodecInfo {
+ /**
+ * Codec identifier
+ */
+ CodecId id;
+ /**
+ * Human readable name used to present codec to the user and for debug logs
+ */
+ String name;
+
+ /**
+ * A2DP Context
+ */
+ parcelable A2dp {
+ /**
+ * The capabilities as defined by A2DP for codec interoperability
+ * requirements. With `id.a2dp`, the format is given by the `Codec
+ * Specific Information Elements` [A2DP - 4.3-6.2], and with `id.vendor`,
+ * by `Vendor Specific Value` [A2DP - 4.7.2].
+ */
+ byte[] capabilities;
+
+ /**
+ * PCM characteristics:
+ * - Mono, Dual-Mono or Stereo
+ * - Supported sampling frequencies, in Hz.
+ * - Fixed point resolution, basically 16, 24 or 32 bits by samples.
+ * The value 32 should be used for floating point representation.
+ *
+ * When the bitdepth is not an encoding/decoding parameter (don't take part
+ * in the interoperability), the `bitdepth` list shall have a single element
+ * indicating the bitdepth selected for the platform.
+ */
+ ChannelMode[] channelMode;
+ int[] samplingFrequencyHz;
+ int[] bitdepth;
+
+ /**
+ * Lossless capable characteristic
+ */
+ boolean lossless;
+ }
+
+ /**
+ * HFP Context
+ */
+ parcelable Hfp {
+ /**
+ * Vendor-specific identifiers of stream data paths, set in the
+ * HCI Command Enhanced Setup Synchronous Connection [Core - 4.E.7.1.45],
+ * in the command parameters respectively `Input_Data_Path` and
+ * `Output_Data_Path`. The value range from 0x01 to 0xFE.
+ * The stack operates as a pass-through; the client SHALL NOT
+ * interpret the values.
+ */
+ int inputDataPath = 1;
+ int outputDataPath = 1;
+
+ /**
+ * Whether the audio stream is encoded and decoded in the controller or
+ * locally; enable the controller transparent mode when the audio
+ * stream is locally processed.
+ */
+ boolean useControllerCodec = true;
+ }
+
+ /**
+ * LE Audio Context
+ */
+ parcelable LeAudio {
+ /**
+ * List of independently supported channel modes: Mono, Dual-Mono, or
+ * Stereo.
+ */
+ ChannelMode[] channelMode;
+
+ /**
+ * List of supported sampling frequencies, in Hz.
+ */
+ int[] samplingFrequencyHz;
+
+ /**
+ * List of supported FrameDurations in microseconds.
+ */
+ int[] frameDurationUs;
+
+ /**
+ * - Fixed point resolution, basically 16, 24 or 32 bits by samples.
+ * The value 32 should be used for floating point representation.
+ *
+ * When the bitdepth is not an encoding/decoding parameter (don't take
+ * part in the interoperability), the `bitdepth` list shall have a
+ * single element indicating the bitdepth selected for the platform.
+ */
+ int[] bitdepth;
+
+ /**
+ * Additional configuration flags
+ */
+ @nullable ConfigurationFlags flags;
+ }
+
+ /**
+ * Specific informations,
+ * depending on transport.
+ */
+ union Transport {
+ LeAudio leAudio;
+ A2dp a2dp;
+ Hfp hfp;
+ }
+
+ Transport transport;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecParameters.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecParameters.aidl
new file mode 100644
index 0000000..37f8942
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecParameters.aidl
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.ChannelMode;
+
+/**
+ * Used to exchange generic codec parameters between the stack and the provider.
+ */
+@VintfStability
+parcelable CodecParameters {
+ /**
+ * PCM related parameters:
+ * - Mono, Dual-Mono or Stereo
+ * - Sampling frequencies, in Hz.
+ * - Fixed point resolution, basically 16, 24 or 32 bits by samples.
+ * The value 32 should be used for floating point representation..
+ */
+ ChannelMode channelMode;
+ int samplingFrequencyHz;
+ int bitdepth;
+
+ /**
+ * Bitrate limits on a frame basis, defined in bits per second.
+ * The encoder bitrate mode can be encoded following this rule:
+ * . minBitrate equals to maxBitrate for constant bitrate
+ * . minBitrate set to 0, for VBR with peak bitrate at maxBitratre value.
+ * . minBitrate greater than 0, for ABR, the bitrate of the stream varies
+ * between minBitrate to maxBitrate according to link quality.
+ * The 0 value for both means "undefined" or "don't care".
+ */
+ int minBitrate;
+ int maxBitrate;
+
+ /**
+ * Low-latency configuration. The interpretation is vendor specific.
+ * When returned to the client, the assessment of the low latency configuration is left
+ * to the vendor's discretion. When set by the client, it indicates that we are entering
+ * a low-latency context (e.g. gaming), and such a configuration should be privileged.
+ */
+ boolean lowLatency = false;
+
+ /**
+ * Lossless effort indication. The 'False' value can be used as "don't care"
+ */
+ boolean lossless = false;
+
+ /**
+ * Vendor specific parameters, inserted in the Vendor Specific HCI Command
+ * `Start A2DP Offload` as it is. The stack operates as a pass-through;
+ * the data SHALL NOT be inspected nor written by the client.
+ * The size is limited to 128 bytes by the client; a larger size is
+ * interpreted as a zero-sized buffer.
+ */
+ byte[] vendorSpecificParameters;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecSpecificCapabilitiesLtv.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecSpecificCapabilitiesLtv.aidl
new file mode 100644
index 0000000..fa302e3
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecSpecificCapabilitiesLtv.aidl
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+/**
+ * Used to exchange generic remote device codec specific capabilities between
+ * the stack and the provider. As defined in Bluetooth Assigned Numbers,
+ * Sec. 6.12.4.
+ */
+@VintfStability
+union CodecSpecificCapabilitiesLtv {
+ /**
+ * Supported sampling frequencies in Hertz
+ */
+ parcelable SupportedSamplingFrequencies {
+ const int HZ8000 = 0x0001;
+ const int HZ11025 = 0x0002;
+ const int HZ16000 = 0x0004;
+ const int HZ22050 = 0x0008;
+ const int HZ24000 = 0x0010;
+ const int HZ32000 = 0x0020;
+ const int HZ44100 = 0x0040;
+ const int HZ48000 = 0x0080;
+ const int HZ88200 = 0x0100;
+ const int HZ96000 = 0x0200;
+ const int HZ176400 = 0x0400;
+ const int HZ192000 = 0x0800;
+ const int HZ384000 = 0x1000;
+
+ /* 16 bits wide bit mask */
+ int bitmask;
+ }
+ /**
+ * Supported frame durations in microseconds
+ */
+ parcelable SupportedFrameDurations {
+ const int US7500 = 0x01;
+ const int US10000 = 0x02;
+ /* Bits 2-3 are RFU */
+ const int US7500PREFERRED = 0x10;
+ const int US10000PREFERRED = 0x20;
+
+ /* 8 bit wide bit mask */
+ int bitmask;
+ }
+ parcelable SupportedAudioChannelCounts {
+ const int ONE = 0x01;
+ const int TWO = 0x02;
+ const int THREE = 0x04;
+ const int FOUR = 0x08;
+ const int FIVE = 0x10;
+ const int SIX = 0x20;
+ const int SEVEN = 0x40;
+ const int EIGHT = 0x80;
+
+ /* 8 bit wide bit mask */
+ int bitmask;
+ }
+ parcelable SupportedOctetsPerCodecFrame {
+ int min;
+ int max;
+ }
+ parcelable SupportedMaxCodecFramesPerSDU {
+ int value;
+ }
+
+ SupportedSamplingFrequencies supportedSamplingFrequencies;
+ SupportedFrameDurations supportedFrameDurations;
+ SupportedAudioChannelCounts supportedAudioChannelCounts;
+ SupportedOctetsPerCodecFrame supportedOctetsPerCodecFrame;
+ SupportedMaxCodecFramesPerSDU supportedMaxCodecFramesPerSDU;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecSpecificConfigurationLtv.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecSpecificConfigurationLtv.aidl
new file mode 100644
index 0000000..c099ebe
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecSpecificConfigurationLtv.aidl
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+/**
+ * Used to exchange generic remote device configuration between the stack and
+ * the provider. As defined in Bluetooth Assigned Numbers, Sec. 6.12.5.
+ */
+@VintfStability
+union CodecSpecificConfigurationLtv {
+ @Backing(type="byte")
+ enum SamplingFrequency {
+ HZ8000 = 0x01,
+ HZ11025 = 0x02,
+ HZ16000 = 0x03,
+ HZ22050 = 0x04,
+ HZ24000 = 0x05,
+ HZ32000 = 0x06,
+ HZ44100 = 0x07,
+ HZ48000 = 0x08,
+ HZ88200 = 0x09,
+ HZ96000 = 0x0A,
+ HZ176400 = 0x0B,
+ HZ192000 = 0x0C,
+ HZ384000 = 0x0D,
+ }
+
+ @Backing(type="byte")
+ enum FrameDuration {
+ US7500 = 0x00,
+ US10000 = 0x01,
+ }
+
+ parcelable AudioChannelAllocation {
+ const int NOT_ALLOWED = 0x00000000;
+ const int FRONT_LEFT = 0x00000001;
+ const int FRONT_RIGHT = 0x00000002;
+ const int FRONT_CENTER = 0x00000004;
+ const int LOW_FREQUENCY_EFFECTS_1 = 0x00000008;
+ const int BACK_LEFT = 0x00000010;
+ const int BACK_RIGHT = 0x00000020;
+ const int FRONT_LEFT_OF_CENTER = 0x00000040;
+ const int FRONT_RIGHT_OF_CENTER = 0x00000080;
+ const int BACK_CENTER = 0x00000100;
+ const int LOW_FREQUENCY_EFFECTS_2 = 0x00000200;
+ const int SIDE_LEFT = 0x00000400;
+ const int SIDE_RIGHT = 0x00000800;
+ const int TOP_FRONT_LEFT = 0x00001000;
+ const int TOP_FRONT_RIGHT = 0x00002000;
+ const int TOP_FRONT_CENTER = 0x00004000;
+ const int TOP_CENTER = 0x00008000;
+ const int TOP_BACK_LEFT = 0x00010000;
+ const int TOP_BACK_RIGHT = 0x00020000;
+ const int TOP_SIDE_LEFT = 0x00040000;
+ const int TOP_SIDE_RIGHT = 0x00080000;
+ const int TOP_BACK_CENTER = 0x00100000;
+ const int BOTTOM_FRONT_CENTER = 0x00200000;
+ const int BOTTOM_FRONT_LEFT = 0x00400000;
+ const int BOTTOM_FRONT_RIGHT = 0x00800000;
+ const int FRONT_LEFT_WIDE = 0x01000000;
+ const int FRONT_RIGHT_WIDE = 0x02000000;
+ const int LEFT_SURROUND = 0x04000000;
+ const int RIGHT_SURROUND = 0x08000000;
+
+ // Bit mask of Audio Locations
+ int bitmask;
+ }
+
+ parcelable OctetsPerCodecFrame {
+ int value;
+ }
+
+ parcelable CodecFrameBlocksPerSDU {
+ int value;
+ }
+
+ CodecFrameBlocksPerSDU codecFrameBlocksPerSDU;
+ SamplingFrequency samplingFrequency;
+ FrameDuration frameDuration;
+ AudioChannelAllocation audioChannelAllocation;
+ OctetsPerCodecFrame octetsPerCodecFrame;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ConfigurationFlags.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ConfigurationFlags.aidl
new file mode 100644
index 0000000..a12af49
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ConfigurationFlags.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+/**
+ * Coding fetures
+ */
+@VintfStability
+parcelable ConfigurationFlags {
+ const int NONE = 0x0000;
+ /**
+ * Set for the lossless configurations
+ */
+ const int LOSSLESS = 0x0001;
+ /**
+ * Set for the low latency configurations
+ */
+ const int LOW_LATENCY = 0x0002;
+ /**
+ * When set, asymmetric configuration for SINK and SOURCE can be used.
+ * e.g. in GAMING mode stream for 32kHz and back channel for 16 kHz
+ */
+ const int ALLOW_ASYMMETRIC_CONFIGURATIONS = 0x0004;
+ /**
+ * Set for the spatial audio configurations
+ */
+ const int SPATIAL_AUDIO = 0x0008;
+ /**
+ * When set, BluetoothAudioProvider requests to receive ASE metadata.
+ * In such case onSinkAseMetadataChanged() and onSourceAseMetadataChanged
+ * will be called.
+ */
+ const int PROVIDE_ASE_METADATA = 0x0010;
+ /**
+ * Set for mono microphone configurations
+ */
+ const int MONO_MIC_CONFIGURATION = 0x0020;
+
+ int bitmask;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/HfpConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/HfpConfiguration.aidl
new file mode 100644
index 0000000..9494bb9
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/HfpConfiguration.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.CodecId;
+
+@VintfStability
+parcelable HfpConfiguration {
+ /**
+ * Codec identifier.
+ */
+ CodecId codecId;
+
+ /**
+ * The connection handle used for SCO connection.
+ * Range: 0x0000 to 0x0EFF.
+ */
+ int connectionHandle;
+
+ /**
+ * Echo canceling and noise reduction functions resident in the AG.
+ */
+ boolean nrec;
+
+ /**
+ * Indicate whether the codec is encoded and decoded in the controller.
+ * If the codec is inside the DSP, then it would be transparent mode.
+ */
+ boolean controllerCodec;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
index d5c051e..33af8a4 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
@@ -16,10 +16,26 @@
package android.hardware.bluetooth.audio;
+import android.hardware.bluetooth.audio.A2dpConfiguration;
+import android.hardware.bluetooth.audio.A2dpConfigurationHint;
+import android.hardware.bluetooth.audio.A2dpRemoteCapabilities;
+import android.hardware.bluetooth.audio.A2dpStatus;
import android.hardware.bluetooth.audio.AudioConfiguration;
+import android.hardware.bluetooth.audio.AudioContext;
import android.hardware.bluetooth.audio.BluetoothAudioStatus;
+import android.hardware.bluetooth.audio.CodecId;
+import android.hardware.bluetooth.audio.CodecParameters;
+import android.hardware.bluetooth.audio.CodecSpecificCapabilitiesLtv;
+import android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv;
+import android.hardware.bluetooth.audio.ConfigurationFlags;
import android.hardware.bluetooth.audio.IBluetoothAudioPort;
import android.hardware.bluetooth.audio.LatencyMode;
+import android.hardware.bluetooth.audio.LeAudioAseConfiguration;
+import android.hardware.bluetooth.audio.LeAudioBisConfiguration;
+import android.hardware.bluetooth.audio.LeAudioBroadcastConfiguration.BroadcastStreamMap;
+import android.hardware.bluetooth.audio.LeAudioConfiguration.StreamMap;
+import android.hardware.bluetooth.audio.MetadataLtv;
+import android.hardware.bluetooth.audio.Phy;
import android.hardware.common.fmq.MQDescriptor;
import android.hardware.common.fmq.SynchronizedReadWrite;
@@ -59,9 +75,8 @@
* audioConfig.pcmConfig parameter. Invalid if streaming is offloaded
* from/to hardware or on failure
*/
- MQDescriptor<byte, SynchronizedReadWrite> startSession(
- in IBluetoothAudioPort hostIf, in AudioConfiguration audioConfig,
- in LatencyMode[] supportedLatencyModes);
+ MQDescriptor<byte, SynchronizedReadWrite> startSession(in IBluetoothAudioPort hostIf,
+ in AudioConfiguration audioConfig, in LatencyMode[] supportedLatencyModes);
/**
* Callback for IBluetoothAudioPort.startStream()
*
@@ -93,4 +108,724 @@
* mode, the API will be called with supported is false.
*/
void setLowLatencyModeAllowed(in boolean allowed);
+
+ /**
+ * Validate and parse an A2DP Configuration,
+ * shall be used with A2DP session types
+ *
+ * @param codecId Identify the codec
+ * @param The configuration as defined by the A2DP's `Codec Specific
+ * Information Elements`, or `Vendor Specific Value` when CodecId
+ * format is set to `VENDOR`.
+ * @param codecParameters result of parsing, when the validation succeeded.
+ * @return A2DP Status of the parsing
+ */
+ A2dpStatus parseA2dpConfiguration(
+ in CodecId codecId, in byte[] configuration, out CodecParameters codecParameters);
+
+ /**
+ * Return a configuration, from a list of remote Capabilites,
+ * shall be used with A2DP session types
+ *
+ * @param remoteCapabilities The capabilities of the remote device
+ * @param hint Hint on selection (audio context and/or codec)
+ * @return The requested configuration. A null value value is returned
+ * when no suitable configuration has been found.
+ */
+ @nullable A2dpConfiguration getA2dpConfiguration(
+ in A2dpRemoteCapabilities[] remoteA2dpCapabilities, in A2dpConfigurationHint hint);
+
+ /**
+ * Predefined values for the codec priority, used by `setCodecPriority()`.
+ * Besides these special values, the codec priority can be set to 1 for
+ * the highest possible priority, or to any other 4 bytes wide integer N,
+ * where N has the higher priority than N + 1.
+ */
+ const int CODEC_PRIORITY_DISABLED = -1;
+ const int CODEC_PRIORITY_NONE = 0;
+
+ /**
+ * Set specific codec priority
+ *
+ * It should be assumed that the external module will start with all its
+ * integrated codecs priority set to `CODEC_PRIORITY_NONE` by default.
+ *
+ * Note: If the BT stack sets a particular codec priority to
+ * CODEC_PRIORITY_DISABLED, the configuration provider shal not return
+ * a particular codec when asked for the configuration. Other priority
+ * levels and the prioritization mechanism details are not specified
+ * and the vendor can implement them as desired.
+ *
+ * @param codecId: codecId
+ * @param priority: `CODEC_PRIORITY_NONE` for no priority,
+ * `CODEC_PRIORITY_DISABLED` for the disabled codec, or priority
+ * level from 1 to N, where the priority of N + 1 is lower than N,
+ * and N equal to 1 is the highest possible codec priority.
+ */
+ void setCodecPriority(in CodecId codecId, int priority);
+
+ /**
+ * LE Audio device Capabilities - as defined in Bluetooth Published Audio
+ * Capabilities Service specification, v1.0.1, Sec. 3.1: "Sink PAC", and
+ * Sec. 3.3: "Source PAC".
+ */
+ @VintfStability
+ parcelable LeAudioDeviceCapabilities {
+ /**
+ * Codec Identifier
+ */
+ CodecId codecId;
+ /**
+ * Codec capabilities, packed as LTV.
+ */
+ CodecSpecificCapabilitiesLtv[] codecSpecificCapabilities;
+ /**
+ * Vendor codec specific capabilities.
+ *
+ * This will not be parsed by the BT stack, but passed to the vendor
+ * module who can interpret this and based on that select the proper
+ * vendor specific codec configuration.
+ */
+ @nullable byte[] vendorCodecSpecificCapabilities;
+ /**
+ * Audio capabilities metadata, packed as LTV.
+ */
+ @nullable MetadataLtv[] metadata;
+ }
+
+ @VintfStability
+ parcelable LeAudioDataPathConfiguration {
+ /**
+ * Vendor specific data path identifier
+ */
+ int dataPathId;
+
+ /**
+ * Used in the HCI_LE_Setup_ISO_Data_Path (0x006E).
+ * As defined in Bluetooth Core Specification Version
+ * 5.3, Vol 4, Part E, Sec. 7.8.109: "LE Setup ISO Data Path command".
+ */
+ @VintfStability
+ parcelable IsoDataPathConfiguration {
+ /**
+ * Codec ID - Valid Codec Identifier matching the selected codec
+ */
+ CodecId codecId;
+ /**
+ * Whether the transparent air mode should be set as a coding format
+ * in the HCI_LE_Setup_ISO_Data_Path command, indicating that the
+ * codec is not in the controller.
+ *
+ * If set to true, 0x03 (transparent air mode) will be used as a
+ * Codec_ID coding format and the `byte[] configuration` field shall
+ * remain empty. Otherwise the Codec_ID field will be set to
+ * according to BT specification (0xFF coding format, company ID,
+ * codec ID for vendor codecs, or according to Codec_ID identifiers
+ * defined in the Assigned Numbers for the non-vendor codecs).
+ */
+ boolean isTransparent;
+ /**
+ * Controller delay (in microseconds)
+ */
+ int controllerDelayUs;
+ /**
+ * Codec specific LE Audio ISO data path configuration
+ * must be null when codec ID is 0x03 transparent
+ */
+ @nullable byte[] configuration;
+ }
+
+ /**
+ * Used in HCI_Configure_Data_Path (0x0083)
+ * As defined in Bluetooth Core Specification Version
+ * 5.3, Vol 4, Part E, Sec. 7.3.101: "Configure Data Path command".
+ */
+ @VintfStability
+ parcelable DataPathConfiguration {
+ /**
+ * Vendor specific data path configuration
+ */
+ @nullable byte[] configuration;
+ }
+ /**
+ * Data path configuration
+ */
+ DataPathConfiguration dataPathConfiguration;
+ /**
+ * ISO data path configuration
+ */
+ IsoDataPathConfiguration isoDataPathConfiguration;
+ }
+
+ /**
+ * All the LeAudioAseQosConfiguration parameters are defined by the
+ * Bluetooth Audio Stream Control Service specification v.1.0, Sec. 5: "ASE
+ * Control Operations".
+ */
+ @VintfStability
+ parcelable LeAudioAseQosConfiguration {
+ /**
+ * SDU Interval (in microseconds) used in Set CIG Parameters command and
+ * Configure QoS.
+ */
+ int sduIntervalUs;
+ /**
+ * Framing used in Set CIG Parameters command and Configure QoS
+ */
+ Framing framing;
+ /**
+ * Phy used in Set CIG Parameters command and Configure QoS
+ */
+ Phy[] phy;
+ /**
+ * Max transport latency (in milliseconds) used in Set CIG Parameters
+ * command and Configure QoS.
+ */
+ int maxTransportLatencyMs;
+ /**
+ * Max SDU used in Set CIG Parameters command and Configure QoS
+ */
+ int maxSdu;
+ /**
+ * Retransmission number used in Set CIG Parameters command and
+ * Configure QoS
+ */
+ int retransmissionNum;
+ }
+
+ /**
+ * Connected Isochronous Channel arrangement within the Connected
+ * Isochronous Group. As defined in Bluetooth Core Specification Version
+ * 5.3, Vol 4, Part E, Sec. 7.8.97.
+ */
+ @VintfStability
+ @Backing(type="byte")
+ enum Packing {
+ SEQUENTIAL = 0x00,
+ INTERLEAVED = 0x01,
+ }
+
+ /**
+ * Isochronous Data PDU framing parameter. As defined in Bluetooth Core
+ * Specification Version 5.3, Vol 4, Part E, Sec. 7.8.97.
+ */
+ @VintfStability
+ @Backing(type="byte")
+ enum Framing {
+ UNFRAMED = 0x00,
+ FRAMED = 0x01,
+ }
+
+ @VintfStability
+ parcelable LeAudioAseConfigurationSetting {
+ /**
+ * Audio Context that this configuration apply to
+ */
+ AudioContext audioContext;
+ /**
+ * Sequential or interleave packing used in Set CIG Parameters command
+ */
+ Packing packing;
+
+ @VintfStability
+ parcelable AseDirectionConfiguration {
+ /**
+ * ASE configuration
+ */
+ LeAudioAseConfiguration aseConfiguration;
+ /**
+ * QoS Configuration
+ */
+ @nullable LeAudioAseQosConfiguration qosConfiguration;
+ /**
+ * Data path configuration
+ * If not provided, getLeAudioAseDatapathConfiguration() will be
+ * called during the configuration, increasing the stream
+ * establishment time (not recommended).
+ */
+ @nullable LeAudioDataPathConfiguration dataPathConfiguration;
+ }
+ /**
+ * Sink ASEs configuration
+ */
+ @nullable AseDirectionConfiguration[] sinkAseConfiguration;
+ /**
+ * Source ASEs configuration
+ */
+ @nullable AseDirectionConfiguration[] sourceAseConfiguration;
+ /**
+ * Additional flags, used for configurations with special features
+ */
+ @nullable ConfigurationFlags flags;
+ }
+
+ /**
+ * ASE configuration requirements set by the BT stack.
+ */
+ @VintfStability
+ parcelable LeAudioConfigurationRequirement {
+ /**
+ * Audio Contect that this requirements apply to
+ */
+ AudioContext audioContext;
+
+ @VintfStability
+ parcelable AseDirectionRequirement {
+ /**
+ * Optional ASE configurations requirements
+ *
+ * Note that the Host can set as many or as little parameters in
+ * the `aseConfiguration.codecConfiguration` field as needed, to
+ * closely or loosely specify the requirements. If any parameter
+ * is not specified, the offloader can choose it freely. The
+ * offloader should put all the specified parameters into the
+ * `aseConfiguration.codecConfiguration` field of the returned
+ * configuration to let the BT stack verify if the requirements
+ * were met. The mandatory requirement set by the BT stack will be
+ * the Audio Location.
+ */
+ LeAudioAseConfiguration aseConfiguration;
+ }
+ /**
+ * Sink ASEs configuration setting
+ */
+ @nullable AseDirectionRequirement[] sinkAseRequirement;
+ /**
+ * Source ASEs configuration setting
+ */
+ @nullable AseDirectionRequirement[] sourceAseRequirement;
+ /**
+ * Additional flags, used to request configurations with special
+ * features
+ */
+ @nullable ConfigurationFlags flags;
+ }
+
+ /**
+ * Method that returns a proposed ASE configuration settings for each
+ * requested audio context type
+ *
+ * Note: _ENCODING session provides SINK ASE configuration
+ * and _DECODING session provides SOURCE ASE configuration unless
+ * BluetoothAudioProvider sets supportsMultidirectionalCapabilities to
+ * true in ProviderInfo.
+ * If supportsMultidirectionalCapabilities is set to true then the
+ * BluetoothStack expects to get configuration list for SINK and SOURCE
+ * on either _ENCODING or _DECODING session.
+ *
+ * Note: When the requirements are not met, either for one or both
+ * directions, the corresponding returned AseDirectionConfiguration
+ * can be set to null. Otherwise it shall contain an ASE configuration
+ * array with the number of configurations equal to the number of ASEs
+ * which should be configured by the BT stack for this particular
+ * direction.
+ * The provider shall match all the requirements set by the Bluetooth
+ * stack or return a null configuration for the direction when these
+ * requirements are not met. In response, the BT Stack may decide to
+ * reduce the requirements to the minimum, which is the `audioContext`
+ * and the `LeAudioAseConfiguration.codecConfiguration` with the
+ * mandatory `CodecSpecificConfigurationLtv.SamplingFrequency` and
+ * `CodecSpecificConfigurationLtv.AudioChannelAllocation` fields set.
+ * When these minimum requirements are not met as well, the Bt stack
+ * may set either `sinkAseRequirement` or `sourceAseRequirement`, or
+ * both to null. In such case the provider has the freedom of
+ * providing a configuration for the null-ed direction requirements or
+ * not for the particular audio context. However returning neither of
+ * the direction configurations (both nulled) is considered as an
+ * invalid behavior.
+ * If the returned configurations are not complete (either
+ * `qosConfiguration` or `dataPathConfiguration` are null), the BT
+ * stack will ask for these dynamically during the stream
+ * establishment, using the corresponding
+ * `getLeAudioAseQosConfiguration()` and
+ * `getLeAudioAseDatapathConfiguration()` API calls. This behavior
+ * is not desired as it slows down the stream establishment, and
+ * should be implemented only if really needed (e.g. when the provider
+ * needs to monitor the remote device ASE states, using the
+ * `onSinkAseMetadataChanged()` and `onSourceAseMetadataChanged()`
+ * callbacks to derive the valid QoS and/or data path configuration).
+ *
+ * @param remoteSinkAudioCapabilities Array of remote sink capabilities
+ * supported by an active group devices.
+ * @param remoteSourceAudioCapabilities Array of remote source capabilities
+ * supported by an active group devices.
+ * @param requirements ASE configuration requirements
+ *
+ * @return LeAudioAseConfigurationSetting[]
+ */
+ LeAudioAseConfigurationSetting[] getLeAudioAseConfiguration(
+ in @nullable LeAudioDeviceCapabilities[] remoteSinkAudioCapabilities,
+ in @nullable LeAudioDeviceCapabilities[] remoteSourceAudioCapabilities,
+ in LeAudioConfigurationRequirement[] requirements);
+
+ @VintfStability
+ parcelable LeAudioAseQosConfigurationRequirement {
+ /**
+ * Audio Contect Type that this requirements apply to
+ */
+ AudioContext audioContext;
+
+ /**
+ * QoS preferences received in Codec Configured ASE state. As defined in
+ * bluetooth service specification: Audio Stream Control Service" V1.0,
+ * Sec. 4.1 Audio Stream Endpoints, Table 4.3:"Additional_ASE_Parameters
+ * format when ASE_State = 0x01 (Codec Configured)".
+ */
+ @VintfStability
+ parcelable AseQosDirectionRequirement {
+ /**
+ * Support for unframed Isochronous Adaptation Layer PDUs.
+ * When set to FRAMED, the unframed PDUs are not supported.
+ */
+ Framing framing;
+ /**
+ * Preferred value for the PHY parameter to be written by the client
+ * for this ASE in the Config QoS operation
+ */
+ Phy[] preferredPhy;
+ /**
+ * Preferred value for the Retransmission Number parameter to be
+ * written by the client for this ASE in the Config QoS operation.
+ */
+ int preferredRetransmissionNum;
+ /**
+ * Preferred value for the Max Transport Latency parameter to be
+ * written by the client for this ASE in the Config QoS operation.
+ */
+ int maxTransportLatencyMs;
+ /**
+ * Minimum server supported Presentation Delay (in microseconds) for
+ * an ASE.
+ */
+ int presentationDelayMinUs;
+ /**
+ * Maximum server supported Presentation Delay (in microseconds) for
+ * an ASE.
+ */
+ int presentationDelayMaxUs;
+ /**
+ * Preferred minimum Presentation Delay (in microseconds) for an
+ * ASE.
+ */
+ int preferredPresentationDelayMinUs;
+ /**
+ * Preferred maximum Presentation Delay (in microseconds) for an
+ * ASE.
+ */
+ int preferredPresentationDelayMaxUs;
+
+ /**
+ * ASE configuration
+ */
+ LeAudioAseConfiguration aseConfiguration;
+ }
+ /**
+ * Sink ASEs configuration setting
+ */
+ @nullable AseQosDirectionRequirement sinkAseQosRequirement;
+ /**
+ * Source ASEs configuration setting
+ */
+ @nullable AseQosDirectionRequirement sourceAseQosRequirement;
+ /**
+ * Additional configuration flags requirements
+ */
+ @nullable ConfigurationFlags flags;
+ }
+
+ /**
+ * A directional pair for QoS configuration. Either one or both directions
+ * can be set, depending on the audio context and the requirements provided
+ * to getLeAudioAseQosConfiguration().
+ */
+ @VintfStability
+ parcelable LeAudioAseQosConfigurationPair {
+ @nullable LeAudioAseQosConfiguration sinkQosConfiguration;
+ @nullable LeAudioAseQosConfiguration sourceQosConfiguration;
+ }
+
+ /**
+ * Method that returns an ASE QoS configuration settings for the given ASE
+ * configuration,taking an ASE preferenced QoS parameters. It should be used
+ * to negotiaite the QoS parameters, when the initialy received QoS
+ * parameters are not within the boundaries received from the remote device
+ * after configuring the ASEs.
+ *
+ * Note: When the requirements are not met, either for one or both
+ * directions, the corresponding configurations in the returned
+ * LeAudioAseQosConfigurationPair can be set to null. The minimum
+ * requirement can have only the `audioContext` field set and just a
+ * single (either sink or source) AseQosDirectionRequirement, where
+ * only the preferred parameter fields are not specified. The
+ * configuration provider should always be able to satisfy such
+ * requirement for all the audio contexts specified by Bluetooth SIG.
+ * The Bluetooth stack can reduce the requirements to the minimum,
+ * when more precisely specified requirements are not met by the
+ * configuration provider.
+ *
+ * @param qosRequirement ASE QoS configurations requirements
+ *
+ * @return LeAudioAseQosConfigurationPair
+ */
+ LeAudioAseQosConfigurationPair getLeAudioAseQosConfiguration(
+ in LeAudioAseQosConfigurationRequirement qosRequirement);
+
+ /**
+ * Audio data path configuration.
+ */
+ parcelable LeAudioDataPathConfigurationPair {
+ /* Host to Controller data path */
+ @nullable LeAudioDataPathConfiguration inputConfig;
+ /* Controller to Host data path */
+ @nullable LeAudioDataPathConfiguration outputConfig;
+ }
+
+ /**
+ * Stream Configuration
+ */
+ parcelable StreamConfig {
+ /**
+ * Streaming Audio Context.
+ * This can serve as a hint for selecting the proper configuration by
+ * the offloader.
+ */
+ AudioContext audioContext;
+ /**
+ * Stream configuration, including connection handles and audio channel
+ * allocations.
+ */
+ StreamMap[] streamMap;
+ }
+
+ /**
+ * Used to get a data path configuration which dynamically depends on CIS
+ * connection handles in StreamMap. This is used if non-dynamic data path
+ * was not provided in LeAudioAseConfigurationSetting. Calling this during
+ * the unicast audio stream establishment might slightly delay the stream
+ * start.
+ *
+ * @param sinkConfig - remote sink device stream configuration
+ * @param sourceConfig - remote source device stream configuration
+ *
+ * Note: The provider shall provide a data path configuration for each
+ * of the non-null configurations passed to this function if these
+ * configurations are supported by the configuration provider.
+ * The Bluetooth stack can set either only sink or source
+ * configuration if it expects just a single direction data path
+ * configuration. Not providing a valid data path configuration for
+ * the stream configured with the codec parameters provided by the
+ * configuration provider will be considered an invalid behavior.
+ * The BT stack can pass asymmetric sink and source configurations
+ * if `ALLOW_ASYMMETRIC_CONFIGURATIONS` flag was set by the provider
+ * in the `CodecInfo` information for the particular codec.
+ *
+ * @return LeAudioDataPathConfigurationPair
+ */
+ LeAudioDataPathConfigurationPair getLeAudioAseDatapathConfiguration(
+ in @nullable StreamConfig sinkConfig,
+ in @nullable StreamConfig sourceConfig);
+
+ /**
+ * Audio Stream Endpoint state used to report Metadata changes on the remote
+ * device audio endpoints.
+ */
+ @VintfStability
+ @Backing(type="byte")
+ enum AseState {
+ ENABLING = 0x00,
+ STREAMING = 0x01,
+ DISABLING = 0x02,
+ }
+
+ /**
+ * Used to report sink endpoint metadata changes to the provider. This
+ * allows for a pseudo communication channel between the remote device and
+ * the provider, using the vendor specific metadata of the changing ASE
+ * state. It is used only when Audio Stream Endpoint (ASE) is using
+ * configurations marked with the `PROVIDE_ASE_METADATA` flag.
+ *
+ * @param state - current Audio Stream Endpoint state of the remote device
+ * @param cigId - Coordinate Isochronous Group identifier
+ * @param cisId - Coordinate Isochronous Stream identifier
+ * @param metadata - remote sink device metadata for the given ASE
+ */
+ void onSinkAseMetadataChanged(
+ in AseState state, int cigId, int cisId, in @nullable MetadataLtv[] metadata);
+
+ /**
+ * Used to report source endpoint metadata changes to the provider. This
+ * allows for a pseudo communication channel between the remote device and
+ * the provider, using the vendor specific metadata of the changing ASE
+ * state. It is used only when Audio Stream Endpoint (ASE) is using
+ * configurations marked with the `PROVIDE_ASE_METADATA` flag.
+ *
+ * @param state - current Audio Stream Endpoint state of the remote device
+ * @param cigId - Coordinate Isochronous Group identifier
+ * @param cisId - Coordinate Isochronous Stream identifier
+ * @param metadata - remote source device metadata for the given ASE
+ */
+ void onSourceAseMetadataChanged(
+ in AseState state, int cigId, int cisId, in @nullable MetadataLtv[] metadata);
+
+ /**
+ * Broadcast quality index
+ */
+ @VintfStability
+ @Backing(type="byte")
+ enum BroadcastQuality {
+ STANDARD,
+ HIGH,
+ }
+
+ /**
+ * It is used in LeAudioBroadcastConfigurationRequirement
+ */
+ @VintfStability
+ parcelable LeAudioBroadcastSubgroupConfigurationRequirement {
+ /**
+ * Streaming Audio Context for the given subgroup.
+ * This can serve as a hint for selecting the proper configuration by
+ * the offloader.
+ */
+ AudioContext audioContext;
+ /**
+ * Streaming Broadcast Audio Quality
+ */
+ BroadcastQuality quality;
+ /**
+ * Number of BISes for the given subgroup
+ */
+ int bisNumPerSubgroup;
+ }
+
+ /**
+ * It is used in getLeAudioBroadcastConfiguration method
+ * If any group id is provided, the Provider should check Pacs capabilities
+ * of the group(s) and provide Broadcast configuration supported by the
+ * group.
+ */
+ @VintfStability
+ parcelable LeAudioBroadcastConfigurationRequirement {
+ LeAudioBroadcastSubgroupConfigurationRequirement[] subgroupConfigurationRequirements;
+ }
+
+ /**
+ * Subgroup BIS configuration
+ *
+ */
+ @VintfStability
+ parcelable LeAudioSubgroupBisConfiguration {
+ /**
+ * The number of BISes with the given configuration
+ */
+ int numBis;
+ /**
+ * LE Audio BIS configuration for the `numBis` number of BISes
+ */
+ LeAudioBisConfiguration bisConfiguration;
+ }
+
+ /**
+ * Subgroup configuration with a list of BIS configurations
+ */
+ @VintfStability
+ parcelable LeAudioBroadcastSubgroupConfiguration {
+ LeAudioSubgroupBisConfiguration[] bisConfigurations;
+
+ /**
+ * Vendor specific codec configuration for all the BISes inside this
+ * subgroup. Only the vendor specific part is needed, since the BT stack
+ * can derive the common subgroup configuration by intersecting the LTV
+ * formatted configuration of every BIS inside the subgroup.
+ * This will not be parsed by the BT stack but will be set as the codec
+ * specific configuration for the ongoing audio stream at the subgroup
+ * level of the audio announcement,The remote device will receive this
+ * information when being configured for receiveing a brodcast audio
+ * stream.
+ */
+ @nullable byte[] vendorCodecConfiguration;
+ }
+
+ /**
+ * LeAudioBroadcastConfigurationSetting is a result of
+ * getLeAudioBroadcastConfiguration. It is used in HCI_LE_Create_BIG command
+ * and for creating the Broadcast Announcements.
+ */
+ @VintfStability
+ parcelable LeAudioBroadcastConfigurationSetting {
+ /**
+ * SDU Interval (in microseconds) used in LE Create BIG command
+ */
+ int sduIntervalUs;
+ /**
+ * Total number of BISes in the BIG
+ */
+ int numBis;
+ /**
+ * Maximum size of an SDU in octets
+ */
+ int maxSduOctets;
+ /**
+ * Maximum transport latency (in milliseconds)
+ */
+ int maxTransportLatencyMs;
+ /**
+ * The number of times every PDU should be retransmitted
+ */
+ int retransmitionNum;
+ /**
+ * A list of PHYs used for transmission of PDUs of BISes in the BIG.
+ */
+ Phy[] phy;
+ /**
+ * The preferred method of arranging subevents of multiple BISes
+ */
+ Packing packing;
+ /**
+ * format for sending BIS Data PDUs
+ */
+ Framing framing;
+
+ /**
+ * Data path configuration
+ * If not provided, getLeAudioBroadcastDatapathConfiguration() will be
+ * called during the configuration, increasing the stream establishment
+ * time (not recommended).
+ */
+ @nullable LeAudioDataPathConfiguration dataPathConfiguration;
+
+ /**
+ * An array of subgroup configurations in the broadcast.
+ */
+ LeAudioBroadcastSubgroupConfiguration[] subgroupsConfigurations;
+ }
+
+ /**
+ * Get Broadcast configuration. Output of this function will be used
+ * in HCI_LE_Create_BIG (0x0068) command and also to create BIG INFO
+ *
+ * @param remoteSinkAudioCapabilities - remote device sink endpoint
+ * capabilities
+ * @param requirement - requested configuration requirements
+ *
+ * @return the whole broadcast audio stream configuration
+ */
+ LeAudioBroadcastConfigurationSetting getLeAudioBroadcastConfiguration(
+ in @nullable LeAudioDeviceCapabilities[] remoteSinkAudioCapabilities,
+ in LeAudioBroadcastConfigurationRequirement requirement);
+
+ /**
+ * Used to get a data path configuration which dynamically depends on BIS
+ * handles in BroadcastStreamMap. This is used if non-dynamic data path was
+ * not provided in LeAudioBroadcastConfigurationSetting. Calling this during
+ * the broadcast audio stream establishment might slightly delay the stream
+ * start.
+ *
+ * @param audioContext - audio stream context for the given stream map
+ * @param streamMap - channel map with BIS configurations
+ *
+ * @return broadcast audio stream data path configuration
+ */
+ LeAudioDataPathConfiguration getLeAudioBroadcastDatapathConfiguration(
+ in AudioContext audioContext, in BroadcastStreamMap[] streamMap);
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
index 3cde22c..ea9c4e1 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
@@ -17,8 +17,10 @@
package android.hardware.bluetooth.audio;
import android.hardware.bluetooth.audio.AudioCapabilities;
+import android.hardware.bluetooth.audio.CodecInfo;
import android.hardware.bluetooth.audio.IBluetoothAudioProvider;
import android.hardware.bluetooth.audio.SessionType;
+
/**
* This factory allows a HAL implementation to be split into multiple
* independent providers.
@@ -62,4 +64,38 @@
* @return provider The provider of the specified session type
*/
IBluetoothAudioProvider openProvider(in SessionType sessionType);
+
+ /**
+ * General information relative to a provider
+ * - An optional name
+ * - A list of codec information
+ * - supportsMultidirectionalCapabilities if is set to false it means each
+ * session i.e. _ENCODING and _DECODING is responsible to provide
+ * configuration for a single direction:
+ * _ENCODING for SINK ASE
+ * _DECODING for SOURCE ASE
+ *
+ * If supportsMultidirectionalCapabilities is set to true, then either
+ * _ENCODING or _DECODING session can provide the configurations for either
+ * direction.
+ */
+ @VintfStability
+ parcelable ProviderInfo {
+ String name;
+ CodecInfo[] codecInfos;
+ boolean supportsMultidirectionalCapabilities;
+ }
+
+ /**
+ * Get general information relative to a provider.
+ *
+ * This can be called at any time, or just once during the BT stack
+ * initialization.
+ *
+ * @param sessionType Hardware Offload provider (*_HARDWARE_OFFLOAD_*)
+ * @return General information relative to the provider.
+ * The `null` value can be returned when the provider is not
+ * available
+ */
+ @nullable ProviderInfo getProviderInfo(in SessionType sessionType);
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioAseConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioAseConfiguration.aidl
new file mode 100644
index 0000000..9fb2ecf
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioAseConfiguration.aidl
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.CodecId;
+import android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv;
+import android.hardware.bluetooth.audio.MetadataLtv;
+import android.hardware.bluetooth.audio.Phy;
+
+/**
+ * All the LeAudioAseConfiguration parameters are defined by the Bluetooth Audio
+ * Stream Control Service specification v.1.0, Sec. 5: "ASE Control Operations".
+ */
+@VintfStability
+parcelable LeAudioAseConfiguration {
+ @VintfStability
+ @Backing(type="byte")
+ enum TargetLatency {
+ UNDEFINED = 0x00,
+ LOWER = 0x01,
+ BALANCED_LATENCY_RELIABILITY = 0x02,
+ HIGHER_RELIABILITY = 0x03,
+ }
+
+ /**
+ * Target latency used in Configure Codec command - Can be UNDEFINED when
+ * used inside the AseDirectionRequirement, but shall not be UNDEFINED when
+ * used inside LeAudioAseConfigurationSetting.
+ */
+ TargetLatency targetLatency;
+
+ /**
+ * Target PHY used in Configure Codec command - Can be UNDEFINED when used
+ * inside the AseDirectionRequirement, but shall not be UNDEFINED when used
+ * inside LeAudioAseConfigurationSetting.
+ */
+ Phy targetPhy;
+
+ /**
+ * Codec ID - Can be Null when used inside the AseDirectionRequirement, but
+ * shall not be Null when used inside LeAudioAseConfigurationSetting.
+ */
+ @nullable CodecId codecId;
+
+ /**
+ * Codec configuration for ASE represented in the LTV types defined by
+ * Bluetooth SIG. Regardless of vendor specific configuration being used or
+ * not, this shall contain Bluetooth LTV types describing the common stream
+ * parameters, at least CodecSpecificConfigurationLtv.SamplingFrequency and
+ * CodecSpecificConfigurationLtv.AudioChannelAllocation. In addition, it
+ * should match aseConfiguration provided in LeAudioConfigurationRequirement
+ * as this will also be used to verify the requirements on the known LTV
+ * types.
+ */
+ CodecSpecificConfigurationLtv[] codecConfiguration;
+
+ /**
+ * Vendor specific codec configuration for ASE.
+ *
+ * This will not be parsed by the BT stack but will be written to the remote
+ * device as the codec specific configuration as part of the codec configure
+ * control point operation. If this is populated, only the
+ * `vendorCodecConfiguration` will be used for the ASE configuration,
+ * otherwise `codecConfiguration` will be used. The BT stack will not merge
+ * it with the codecConfiguration for any purpose.
+ */
+ @nullable byte[] vendorCodecConfiguration;
+
+ /**
+ * Metadata, packed as LTV - used to enable ASE. This is optional
+ */
+ @nullable MetadataLtv[] metadata;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBisConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBisConfiguration.aidl
new file mode 100644
index 0000000..4d6cfde
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBisConfiguration.aidl
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.CodecId;
+import android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv;
+import android.hardware.bluetooth.audio.MetadataLtv;
+
+/**
+ * LE Audio BIS configuration. This will be part of the streaming broadcast
+ * audio announcement advertised by the BT stack during the broadcast audio
+ * stream to inform the remote devices about the broadcast audio configuration.
+ * It will also be passed back to the vendor module as part of the currently
+ * active LeAudioBroadcastConfiguration for the encoder setup.
+ * As defined in Bluetooth Basic Audio Profile Specification, v.1.0.1,
+ * Sec. 3.7.2.2, Table 3.15, Level 3.
+ */
+@VintfStability
+parcelable LeAudioBisConfiguration {
+ /**
+ * Codec ID
+ */
+ CodecId codecId;
+
+ /**
+ * Codec configuration for BIS or group of BISes represented in the LTV
+ * types defined by Bluetooht SIG. Regardless of vendor specific
+ * configuration being used or not, this shall contain Bluetooth LTV types
+ * describing the common stream parameters, at least
+ * CodecSpecificConfigurationLtv.SamplingFrequency and
+ * CodecSpecificConfigurationLtv.AudioChannelAllocation.
+ * This will also be used to verify the requirements on the known LTV types.
+ */
+ CodecSpecificConfigurationLtv[] codecConfiguration;
+
+ /**
+ * Vendor specific codec configuration.
+ * This will not be parsed by the BT stack but will be set as the codec
+ * specific configuration for the ongoing audio stream, encoded by the
+ * vendor module. The remote device will receive this information when being
+ * configured for receiveing a brodcast audio stream. If this is populated,
+ * only the `vendorCodecConfiguration` will be used when configuring the
+ * remote device, otherwise `codecConfiguration` will be used.
+ */
+ byte[] vendorCodecConfiguration;
+
+ /**
+ * Metadata for the particular BIS or group of BISes. This is optional.
+ */
+ @nullable MetadataLtv[] metadata;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
index 16503fb..da90373 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
@@ -17,6 +17,8 @@
package android.hardware.bluetooth.audio;
import android.hardware.bluetooth.audio.CodecType;
+import android.hardware.bluetooth.audio.ConfigurationFlags;
+import android.hardware.bluetooth.audio.LeAudioBisConfiguration;
import android.hardware.bluetooth.audio.LeAudioCodecConfiguration;
@VintfStability
@@ -39,6 +41,15 @@
* Pcm stream id to identify the source for given streamHandle.
*/
char pcmStreamId;
+ /*
+ * LE Audio BIS configuration
+ */
+ @nullable LeAudioBisConfiguration bisConfiguration;
+ /*
+ * Additional flags, used to request configurations with special
+ * features
+ */
+ @nullable ConfigurationFlags flags;
}
CodecType codecType;
BroadcastStreamMap[] streamMap;
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
index 7302aea..db753ad 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
@@ -17,6 +17,8 @@
package android.hardware.bluetooth.audio;
import android.hardware.bluetooth.audio.CodecType;
+import android.hardware.bluetooth.audio.ConfigurationFlags;
+import android.hardware.bluetooth.audio.LeAudioAseConfiguration;
import android.hardware.bluetooth.audio.LeAudioCodecConfiguration;
@VintfStability
@@ -29,16 +31,40 @@
*/
char streamHandle;
/*
- * Audio channel allocation is a bit field, each enabled bit means that given audio
- * direction, i.e. "left", or "right" is used. Ordering of audio channels comes from the
- * least significant bit to the most significant bit. The valus follows the Bluetooth SIG
- * Audio Location assigned number.
+ * Audio channel allocation is a bit field, each enabled bit means that
+ * given audio direction, i.e. "left", or "right" is used. Ordering of
+ * audio channels comes from the least significant bit to the most
+ * significant bit. The valus follows the Bluetooth SIG Audio Location
+ * assigned number.
*/
int audioChannelAllocation;
/*
* The stream handle status
*/
boolean isStreamActive;
+ /*
+ * LE Audio device ASE configuration
+ */
+ @nullable LeAudioAseConfiguration aseConfiguration;
+ /*
+ * Additional flags, used for configurations with special features
+ */
+ @nullable ConfigurationFlags flags;
+ parcelable BluetoothDeviceAddress {
+ enum DeviceAddressType {
+ BLE_ADDRESS_PUBLIC = 0x00,
+ BLE_ADDRESS_RANDOM = 0x01,
+ }
+ /**
+ * Peer device address. It should be non zero when isStreamActive is true
+ */
+ byte[6] deviceAddress;
+ /**
+ * Peer device address type.
+ */
+ DeviceAddressType deviceAddressType;
+ }
+ @nullable BluetoothDeviceAddress bluetoothDeviceAddress;
}
CodecType codecType;
StreamMap[] streamMap;
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/MetadataLtv.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/MetadataLtv.aidl
new file mode 100644
index 0000000..afe76ce
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/MetadataLtv.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AudioContext;
+
+/**
+ * Used to exchange generic metadata between the stack and the provider.
+ * As defined in Bluetooth Assigned Numbers, Sec. 6.12.6.
+ */
+@VintfStability
+union MetadataLtv {
+ parcelable PreferredAudioContexts {
+ AudioContext values;
+ }
+ parcelable StreamingAudioContexts {
+ AudioContext values;
+ }
+ /**
+ * This is an opaque container for passing metadata between the provider and
+ * the remote device. It shall not be inspected by the BT stack.
+ */
+ parcelable VendorSpecific {
+ int companyId;
+ byte[] opaqueValue;
+ }
+
+ PreferredAudioContexts preferredAudioContexts;
+ StreamingAudioContexts streamingAudioContexts;
+ VendorSpecific vendorSpecific;
+}
diff --git a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Phy.aidl
similarity index 64%
copy from health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
copy to bluetooth/audio/aidl/android/hardware/bluetooth/audio/Phy.aidl
index aba6cc3..cbffdd5 100644
--- a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Phy.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,12 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "include/StorageHealthDefault.h"
-void get_storage_info(std::vector<struct StorageInfo>&) {
- // Use defaults.
-}
+package android.hardware.bluetooth.audio;
-void get_disk_stats(std::vector<struct DiskStats>&) {
- // Use defaults
+/**
+ * Used to exchange generic Phy parameter between the stack and the provider.
+ */
+@VintfStability
+@Backing(type="byte")
+enum Phy {
+ UNDEFINED = 0x00,
+ ONE_M = 0x01,
+ TWO_M = 0x02,
+ CODED = 0x03,
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
index 7acb5c6..35292a1 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
@@ -70,4 +70,17 @@
* The decoding of AVDTP media is done by HW and there is control only
*/
A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ /**
+ * Used when audio is encoded by Bluetooth Stack and is streaming to HFP device.
+ */
+ HFP_SOFTWARE_ENCODING_DATAPATH,
+ /**
+ * Used when audio is decoded by Bluetooth Stack and is streaming to HFP device.
+ */
+ HFP_SOFTWARE_DECODING_DATAPATH,
+ /**
+ * Used when encoded and decoded by hardware offload and is streamed to HFP device.
+ * This is a control path only.
+ */
+ HFP_HARDWARE_OFFLOAD_DATAPATH,
}
diff --git a/bluetooth/audio/aidl/default/A2dpBits.h b/bluetooth/audio/aidl/default/A2dpBits.h
new file mode 100644
index 0000000..fb7587c
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpBits.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+class A2dpBits {
+ const uint8_t* cdata_;
+ uint8_t* data_;
+
+ public:
+ A2dpBits(const std::vector<uint8_t>& vector)
+ : cdata_(vector.data()), data_(nullptr) {}
+
+ A2dpBits(std::vector<uint8_t>& vector)
+ : cdata_(vector.data()), data_(vector.data()) {}
+
+ struct Range {
+ const int first, len;
+ constexpr Range(int first, int last)
+ : first(first), len(last - first + 1) {}
+ constexpr Range(int index) : first(index), len(1) {}
+ };
+
+ constexpr bool get(int bit) const {
+ return (cdata_[bit >> 3] >> (7 - (bit & 7))) & 1;
+ }
+
+ constexpr unsigned get(const Range& range) const {
+ unsigned v(0);
+ for (int i = 0; i < range.len; i++)
+ v |= get(range.first + i) << ((range.len - 1) - i);
+ return v;
+ }
+
+ constexpr void set(int bit, int value = 1) {
+ uint8_t m = 1 << (7 - (bit & 7));
+ if (value)
+ data_[bit >> 3] |= m;
+ else
+ data_[bit >> 3] &= ~m;
+ }
+
+ constexpr void set(const Range& range, int value) {
+ for (int i = 0; i < range.len; i++)
+ set(range.first + i, (value >> ((range.len - 1) - i)) & 1);
+ }
+
+ constexpr int find_active_bit(const Range& range) const {
+ unsigned v = get(range);
+ int i = 0;
+ for (; i < range.len && ((v >> i) & 1) == 0; i++)
+ ;
+ return i < range.len && (v ^ (1 << i)) == 0
+ ? range.first + (range.len - 1) - i
+ : -1;
+ }
+};
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp
index 2d0d8c9..1eb6a6d 100644
--- a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp
@@ -22,23 +22,30 @@
#include <BluetoothAudioSessionReport.h>
#include <android-base/logging.h>
+#include "A2dpOffloadCodecAac.h"
+#include "A2dpOffloadCodecSbc.h"
+
namespace aidl {
namespace android {
namespace hardware {
namespace bluetooth {
namespace audio {
-A2dpOffloadEncodingAudioProvider::A2dpOffloadEncodingAudioProvider()
- : A2dpOffloadAudioProvider() {
+A2dpOffloadEncodingAudioProvider::A2dpOffloadEncodingAudioProvider(
+ const A2dpOffloadCodecFactory& codec_factory)
+ : A2dpOffloadAudioProvider(codec_factory) {
session_type_ = SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
}
-A2dpOffloadDecodingAudioProvider::A2dpOffloadDecodingAudioProvider()
- : A2dpOffloadAudioProvider() {
+A2dpOffloadDecodingAudioProvider::A2dpOffloadDecodingAudioProvider(
+ const A2dpOffloadCodecFactory& codec_factory)
+ : A2dpOffloadAudioProvider(codec_factory) {
session_type_ = SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH;
}
-A2dpOffloadAudioProvider::A2dpOffloadAudioProvider() {}
+A2dpOffloadAudioProvider::A2dpOffloadAudioProvider(
+ const A2dpOffloadCodecFactory& codec_factory)
+ : codec_factory_(codec_factory) {}
bool A2dpOffloadAudioProvider::isValid(const SessionType& session_type) {
return (session_type == session_type_);
@@ -48,19 +55,56 @@
const std::shared_ptr<IBluetoothAudioPort>& host_if,
const AudioConfiguration& audio_config,
const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return) {
- if (audio_config.getTag() != AudioConfiguration::a2dpConfig) {
+ if (audio_config.getTag() == AudioConfiguration::Tag::a2dp) {
+ auto a2dp_config = audio_config.get<AudioConfiguration::Tag::a2dp>();
+ A2dpStatus a2dp_status = A2dpStatus::NOT_SUPPORTED_CODEC_TYPE;
+
+ auto codec = codec_factory_.GetCodec(a2dp_config.codecId);
+ if (!codec) {
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+ << " - CodecId=" << a2dp_config.codecId.toString()
+ << " is not found";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+
+ if (codec->info.id == CodecId(CodecId::A2dp::SBC)) {
+ SbcParameters sbc_parameters;
+
+ auto codec_sbc =
+ std::static_pointer_cast<const A2dpOffloadCodecSbc>(codec);
+ a2dp_status = codec_sbc->ParseConfiguration(a2dp_config.configuration,
+ &sbc_parameters);
+
+ } else if (codec->info.id == CodecId(CodecId::A2dp::AAC)) {
+ AacParameters aac_parameters;
+
+ auto codec_aac =
+ std::static_pointer_cast<const A2dpOffloadCodecAac>(codec);
+ a2dp_status = codec_aac->ParseConfiguration(a2dp_config.configuration,
+ &aac_parameters);
+ }
+ if (a2dp_status != A2dpStatus::OK) {
+ LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
+ << audio_config.toString();
+ *_aidl_return = DataMQDesc();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ } else if (audio_config.getTag() == AudioConfiguration::Tag::a2dpConfig) {
+ if (!BluetoothAudioCodecs::IsOffloadCodecConfigurationValid(
+ session_type_,
+ audio_config.get<AudioConfiguration::a2dpConfig>())) {
+ LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
+ << audio_config.toString();
+ *_aidl_return = DataMQDesc();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ } else {
LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
<< audio_config.toString();
*_aidl_return = DataMQDesc();
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
- if (!BluetoothAudioCodecs::IsOffloadCodecConfigurationValid(
- session_type_, audio_config.get<AudioConfiguration::a2dpConfig>())) {
- LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
- << audio_config.toString();
- *_aidl_return = DataMQDesc();
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
- }
+
return BluetoothAudioProvider::startSession(
host_if, audio_config, latency_modes, _aidl_return);
}
@@ -73,6 +117,48 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus A2dpOffloadAudioProvider::parseA2dpConfiguration(
+ const CodecId& codec_id, const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters, A2dpStatus* _aidl_return) {
+ if (!kEnableA2dpCodecExtensibility) {
+ // parseA2dpConfiguration must not be implemented if A2dp codec
+ // extensibility is not supported.
+ return ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_TRANSACTION);
+ }
+
+ auto codec = codec_factory_.GetCodec(codec_id);
+ if (!codec) {
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+ << " - CodecId=" << codec_id.toString() << " is not found";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+
+ *_aidl_return = codec->ParseConfiguration(configuration, codec_parameters);
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus A2dpOffloadAudioProvider::getA2dpConfiguration(
+ const std::vector<A2dpRemoteCapabilities>& remote_a2dp_capabilities,
+ const A2dpConfigurationHint& hint,
+ std::optional<audio::A2dpConfiguration>* _aidl_return) {
+ if (!kEnableA2dpCodecExtensibility) {
+ // getA2dpConfiguration must not be implemented if A2dp codec
+ // extensibility is not supported.
+ return ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_TRANSACTION);
+ }
+
+ *_aidl_return = std::nullopt;
+ A2dpConfiguration avdtp_configuration;
+
+ if (codec_factory_.GetConfiguration(remote_a2dp_capabilities, hint,
+ &avdtp_configuration))
+ *_aidl_return =
+ std::make_optional<A2dpConfiguration>(std::move(avdtp_configuration));
+
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace audio
} // namespace bluetooth
} // namespace hardware
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h
index e6f188b..a2d03fe 100644
--- a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h
+++ b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h
@@ -16,6 +16,7 @@
#pragma once
+#include "A2dpOffloadCodecFactory.h"
#include "BluetoothAudioProvider.h"
namespace aidl {
@@ -26,28 +27,40 @@
class A2dpOffloadAudioProvider : public BluetoothAudioProvider {
public:
- A2dpOffloadAudioProvider();
-
bool isValid(const SessionType& session_type) override;
ndk::ScopedAStatus startSession(
const std::shared_ptr<IBluetoothAudioPort>& host_if,
const AudioConfiguration& audio_config,
const std::vector<LatencyMode>& latency_modes,
- DataMQDesc* _aidl_return);
+ DataMQDesc* _aidl_return) override;
+
+ ndk::ScopedAStatus parseA2dpConfiguration(
+ const CodecId& codec_id, const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters, A2dpStatus* _aidl_return) override;
+
+ ndk::ScopedAStatus getA2dpConfiguration(
+ const std::vector<A2dpRemoteCapabilities>& remote_a2dp_capabilities,
+ const A2dpConfigurationHint& hint,
+ std::optional<audio::A2dpConfiguration>* _aidl_return) override;
+
+ protected:
+ A2dpOffloadAudioProvider(const A2dpOffloadCodecFactory&);
private:
+ const A2dpOffloadCodecFactory& codec_factory_;
+
ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override;
};
class A2dpOffloadEncodingAudioProvider : public A2dpOffloadAudioProvider {
public:
- A2dpOffloadEncodingAudioProvider();
+ A2dpOffloadEncodingAudioProvider(const A2dpOffloadCodecFactory&);
};
class A2dpOffloadDecodingAudioProvider : public A2dpOffloadAudioProvider {
public:
- A2dpOffloadDecodingAudioProvider();
+ A2dpOffloadDecodingAudioProvider(const A2dpOffloadCodecFactory&);
};
} // namespace audio
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadCodec.h b/bluetooth/audio/aidl/default/A2dpOffloadCodec.h
new file mode 100644
index 0000000..2f51c73
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpOffloadCodec.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/bluetooth/audio/A2dpStatus.h>
+#include <aidl/android/hardware/bluetooth/audio/ChannelMode.h>
+#include <aidl/android/hardware/bluetooth/audio/CodecInfo.h>
+#include <aidl/android/hardware/bluetooth/audio/CodecParameters.h>
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+class A2dpOffloadCodec {
+ protected:
+ A2dpOffloadCodec(const CodecInfo& info) : info(info) {}
+ virtual ~A2dpOffloadCodec() {}
+
+ public:
+ const CodecInfo& info;
+
+ const CodecId& GetCodecId() const { return info.id; }
+
+ virtual A2dpStatus ParseConfiguration(
+ const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters) const = 0;
+
+ virtual bool BuildConfiguration(
+ const std::vector<uint8_t>& remote_capabilities,
+ const std::optional<CodecParameters>& hint,
+ std::vector<uint8_t>* configuration) const = 0;
+};
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadCodecAac.cpp b/bluetooth/audio/aidl/default/A2dpOffloadCodecAac.cpp
new file mode 100644
index 0000000..1570cd8
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpOffloadCodecAac.cpp
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "A2dpOffloadCodecAac.h"
+
+#include "A2dpBits.h"
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+/**
+ * AAC Local Capabilities
+ */
+
+enum : bool {
+ kEnableObjectTypeMpeg2AacLc = true,
+ kEnableObjectTypeMpeg4AacLc = true,
+};
+
+enum : bool {
+ kEnableSamplingFrequency44100 = true,
+ kEnableSamplingFrequency48000 = true,
+ kEnableSamplingFrequency88200 = false,
+ kEnableSamplingFrequency96000 = false,
+};
+
+enum : bool {
+ kEnableChannels1 = true,
+ kEnableChannels2 = true,
+};
+
+enum : bool {
+ kEnableVbrSupported = true,
+};
+
+enum : int {
+ kBitdepth = 24,
+};
+
+/**
+ * AAC Signaling format [A2DP - 4.5]
+ */
+
+// clang-format off
+
+constexpr A2dpBits::Range kObjectType ( 0, 6 );
+constexpr A2dpBits::Range kDrcEnable ( 7 );
+constexpr A2dpBits::Range kSamplingFrequency ( 8, 19 );
+constexpr A2dpBits::Range kChannels ( 20, 23 );
+constexpr A2dpBits::Range kVbrSupported ( 24 );
+constexpr A2dpBits::Range kBitrate ( 25, 47 );
+constexpr size_t kCapabilitiesSize = 48/8;
+
+// clang-format on
+
+enum {
+ kObjectTypeMpeg2AacLc = kObjectType.first,
+ kObjectTypeMpeg4AacLc,
+ kObjectTypeMpeg4AacLtp,
+ kObjectTypeMpeg4AacScalable,
+ kObjectTypeMpeg4AacHeV1,
+ kObjectTypeMpeg4AacHeV2,
+ kObjectTypeMpeg4AacEldV2
+};
+
+enum {
+ kSamplingFrequency8000 = kSamplingFrequency.first,
+ kSamplingFrequency11025,
+ kSamplingFrequency12000,
+ kSamplingFrequency16000,
+ kSamplingFrequency22050,
+ kSamplingFrequency24000,
+ kSamplingFrequency32000,
+ kSamplingFrequency44100,
+ kSamplingFrequency48000,
+ kSamplingFrequency64000,
+ kSamplingFrequency88200,
+ kSamplingFrequency96000
+};
+
+enum { kChannels1 = kChannels.first, kChannels2, kChannels51, kChannels71 };
+
+/**
+ * AAC Conversion functions
+ */
+
+static AacParameters::ObjectType GetObjectTypeEnum(int object_type) {
+ switch (object_type) {
+ case kObjectTypeMpeg2AacLc:
+ return AacParameters::ObjectType::MPEG2_AAC_LC;
+ case kObjectTypeMpeg4AacLc:
+ default:
+ return AacParameters::ObjectType::MPEG4_AAC_LC;
+ }
+}
+
+static int GetSamplingFrequencyBit(int32_t sampling_frequency) {
+ switch (sampling_frequency) {
+ case 8000:
+ return kSamplingFrequency8000;
+ case 11025:
+ return kSamplingFrequency11025;
+ case 12000:
+ return kSamplingFrequency12000;
+ case 16000:
+ return kSamplingFrequency16000;
+ case 22050:
+ return kSamplingFrequency22050;
+ case 24000:
+ return kSamplingFrequency24000;
+ case 32000:
+ return kSamplingFrequency32000;
+ case 44100:
+ return kSamplingFrequency44100;
+ case 48000:
+ return kSamplingFrequency48000;
+ case 64000:
+ return kSamplingFrequency64000;
+ case 88200:
+ return kSamplingFrequency88200;
+ case 96000:
+ return kSamplingFrequency96000;
+ default:
+ return -1;
+ }
+}
+
+static int32_t GetSamplingFrequencyValue(int sampling_frequency) {
+ switch (sampling_frequency) {
+ case kSamplingFrequency8000:
+ return 8000;
+ case kSamplingFrequency11025:
+ return 11025;
+ case kSamplingFrequency12000:
+ return 12000;
+ case kSamplingFrequency16000:
+ return 16000;
+ case kSamplingFrequency22050:
+ return 22050;
+ case kSamplingFrequency24000:
+ return 24000;
+ case kSamplingFrequency32000:
+ return 32000;
+ case kSamplingFrequency44100:
+ return 44100;
+ case kSamplingFrequency48000:
+ return 48000;
+ case kSamplingFrequency64000:
+ return 64000;
+ case kSamplingFrequency88200:
+ return 88200;
+ case kSamplingFrequency96000:
+ return 96000;
+ default:
+ return 0;
+ }
+}
+
+static int GetChannelsBit(ChannelMode channel_mode) {
+ switch (channel_mode) {
+ case ChannelMode::MONO:
+ return kChannels1;
+ case ChannelMode::STEREO:
+ return kChannels2;
+ default:
+ return -1;
+ }
+}
+
+static ChannelMode GetChannelModeEnum(int channel_mode) {
+ switch (channel_mode) {
+ case kChannels1:
+ return ChannelMode::MONO;
+ case kChannels2:
+ return ChannelMode::STEREO;
+ default:
+ return ChannelMode::UNKNOWN;
+ }
+}
+
+/**
+ * AAC Class implementation
+ */
+
+A2dpOffloadCodecAac::A2dpOffloadCodecAac()
+ : A2dpOffloadCodec(info_),
+ info_({.id = CodecId(CodecId::A2dp::AAC), .name = "AAC"}) {
+ info_.transport.set<CodecInfo::Transport::Tag::a2dp>();
+ auto& a2dp_info = info_.transport.get<CodecInfo::Transport::Tag::a2dp>();
+
+ /* --- Setup Capabilities --- */
+
+ a2dp_info.capabilities.resize(kCapabilitiesSize);
+ std::fill(begin(a2dp_info.capabilities), end(a2dp_info.capabilities), 0);
+
+ auto capabilities = A2dpBits(a2dp_info.capabilities);
+
+ capabilities.set(kObjectTypeMpeg2AacLc, kEnableObjectTypeMpeg2AacLc);
+ capabilities.set(kObjectTypeMpeg4AacLc, kEnableObjectTypeMpeg4AacLc);
+
+ capabilities.set(kSamplingFrequency44100, kEnableSamplingFrequency44100);
+ capabilities.set(kSamplingFrequency48000, kEnableSamplingFrequency48000);
+ capabilities.set(kSamplingFrequency88200, kEnableSamplingFrequency88200);
+ capabilities.set(kSamplingFrequency96000, kEnableSamplingFrequency96000);
+
+ capabilities.set(kChannels1, kEnableChannels1);
+ capabilities.set(kChannels2, kEnableChannels2);
+
+ capabilities.set(kVbrSupported, kEnableVbrSupported);
+
+ /* --- Setup Sampling Frequencies --- */
+
+ auto& sampling_frequency = a2dp_info.samplingFrequencyHz;
+
+ for (auto v : {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
+ 64000, 88200, 96000})
+ if (capabilities.get(GetSamplingFrequencyBit(int32_t(v))))
+ sampling_frequency.push_back(v);
+
+ /* --- Setup Channel Modes --- */
+
+ auto& channel_modes = a2dp_info.channelMode;
+
+ for (auto v : {ChannelMode::MONO, ChannelMode::STEREO})
+ if (capabilities.get(GetChannelsBit(v))) channel_modes.push_back(v);
+
+ /* --- Setup Bitdepth --- */
+
+ a2dp_info.bitdepth.push_back(kBitdepth);
+}
+
+A2dpStatus A2dpOffloadCodecAac::ParseConfiguration(
+ const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters, AacParameters* aac_parameters) const {
+ auto& a2dp_info = info.transport.get<CodecInfo::Transport::Tag::a2dp>();
+
+ if (configuration.size() != a2dp_info.capabilities.size())
+ return A2dpStatus::BAD_LENGTH;
+
+ auto config = A2dpBits(configuration);
+ auto lcaps = A2dpBits(a2dp_info.capabilities);
+
+ /* --- Check Object Type --- */
+
+ int object_type = config.find_active_bit(kObjectType);
+ if (object_type < 0) return A2dpStatus::INVALID_OBJECT_TYPE;
+ if (!lcaps.get(object_type)) return A2dpStatus::NOT_SUPPORTED_OBJECT_TYPE;
+
+ /* --- Check Sampling Frequency --- */
+
+ int sampling_frequency = config.find_active_bit(kSamplingFrequency);
+ if (sampling_frequency < 0) return A2dpStatus::INVALID_SAMPLING_FREQUENCY;
+ if (!lcaps.get(sampling_frequency))
+ return A2dpStatus::NOT_SUPPORTED_SAMPLING_FREQUENCY;
+
+ /* --- Check Channels --- */
+
+ int channels = config.find_active_bit(kChannels);
+ if (channels < 0) return A2dpStatus::INVALID_CHANNELS;
+ if (!lcaps.get(channels)) return A2dpStatus::NOT_SUPPORTED_CHANNELS;
+
+ /* --- Check Bitrate --- */
+
+ bool vbr = config.get(kVbrSupported);
+ if (vbr && !lcaps.get(kVbrSupported)) return A2dpStatus::NOT_SUPPORTED_VBR;
+
+ int bitrate = config.get(kBitrate);
+ if (vbr && lcaps.get(kBitrate) && bitrate > lcaps.get(kBitrate))
+ return A2dpStatus::NOT_SUPPORTED_BIT_RATE;
+
+ /* --- Return --- */
+
+ codec_parameters->channelMode = GetChannelModeEnum(channels);
+ codec_parameters->samplingFrequencyHz =
+ GetSamplingFrequencyValue(sampling_frequency);
+ codec_parameters->bitdepth = kBitdepth;
+
+ codec_parameters->minBitrate = vbr ? 0 : bitrate;
+ codec_parameters->maxBitrate = bitrate;
+
+ if (aac_parameters)
+ aac_parameters->object_type = GetObjectTypeEnum(object_type);
+
+ return A2dpStatus::OK;
+}
+
+bool A2dpOffloadCodecAac::BuildConfiguration(
+ const std::vector<uint8_t>& remote_capabilities,
+ const std::optional<CodecParameters>& hint,
+ std::vector<uint8_t>* configuration) const {
+ auto& a2dp_info = info_.transport.get<CodecInfo::Transport::Tag::a2dp>();
+
+ if (remote_capabilities.size() != a2dp_info.capabilities.size()) return false;
+
+ auto lcaps = A2dpBits(a2dp_info.capabilities);
+ auto rcaps = A2dpBits(remote_capabilities);
+
+ configuration->resize(a2dp_info.capabilities.size());
+ std::fill(begin(*configuration), end(*configuration), 0);
+ auto config = A2dpBits(*configuration);
+
+ /* --- Select Object Type --- */
+
+ if (lcaps.get(kObjectTypeMpeg2AacLc) && rcaps.get(kObjectTypeMpeg2AacLc))
+ config.set(kObjectTypeMpeg2AacLc);
+ else if (lcaps.get(kObjectTypeMpeg4AacLc) && rcaps.get(kObjectTypeMpeg4AacLc))
+ config.set(kObjectTypeMpeg4AacLc);
+ else
+ return false;
+
+ /* --- Select Sampling Frequency --- */
+
+ auto sf_hint = hint ? GetSamplingFrequencyBit(hint->samplingFrequencyHz) : -1;
+
+ if (sf_hint >= 0 && lcaps.get(sf_hint) && rcaps.get(sf_hint))
+ config.set(sf_hint);
+ else if (lcaps.get(kSamplingFrequency96000) &&
+ rcaps.get(kSamplingFrequency96000))
+ config.set(kSamplingFrequency96000);
+ else if (lcaps.get(kSamplingFrequency88200) &&
+ rcaps.get(kSamplingFrequency88200))
+ config.set(kSamplingFrequency88200);
+ else if (lcaps.get(kSamplingFrequency48000) &&
+ rcaps.get(kSamplingFrequency48000))
+ config.set(kSamplingFrequency48000);
+ else if (lcaps.get(kSamplingFrequency44100) &&
+ rcaps.get(kSamplingFrequency44100))
+ config.set(kSamplingFrequency44100);
+ else
+ return false;
+
+ /* --- Select Channels --- */
+
+ auto ch_hint = hint ? GetChannelsBit(hint->channelMode) : -1;
+
+ if (ch_hint >= 0 && lcaps.get(ch_hint) && rcaps.get(ch_hint))
+ config.set(ch_hint);
+ else if (lcaps.get(kChannels2) && rcaps.get(kChannels2))
+ config.set(kChannels2);
+ else if (lcaps.get(kChannels1) && rcaps.get(kChannels1))
+ config.set(kChannels1);
+ else
+ return false;
+
+ /* --- Select Bitrate --- */
+
+ if (!hint || hint->minBitrate == 0)
+ config.set(kVbrSupported,
+ lcaps.get(kVbrSupported) && rcaps.get(kVbrSupported));
+
+ int32_t bitrate = lcaps.get(kBitrate);
+ if (hint && hint->maxBitrate > 0 && bitrate)
+ bitrate = std::min(hint->maxBitrate, bitrate);
+ else if (hint && hint->maxBitrate > 0)
+ bitrate = hint->maxBitrate;
+ config.set(kBitrate, bitrate);
+
+ return true;
+}
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadCodecAac.h b/bluetooth/audio/aidl/default/A2dpOffloadCodecAac.h
new file mode 100644
index 0000000..65e927d
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpOffloadCodecAac.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "A2dpOffloadCodec.h"
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+struct AacParameters : public CodecParameters {
+ enum class ObjectType { MPEG2_AAC_LC, MPEG4_AAC_LC };
+
+ ObjectType object_type;
+};
+
+class A2dpOffloadCodecAac : public A2dpOffloadCodec {
+ CodecInfo info_;
+
+ A2dpStatus ParseConfiguration(const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters,
+ AacParameters* aac_parameters) const;
+
+ public:
+ A2dpOffloadCodecAac();
+
+ A2dpStatus ParseConfiguration(
+ const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters) const override {
+ return ParseConfiguration(configuration, codec_parameters, nullptr);
+ }
+
+ A2dpStatus ParseConfiguration(const std::vector<uint8_t>& configuration,
+ AacParameters* aac_parameters) const {
+ return ParseConfiguration(configuration, aac_parameters, aac_parameters);
+ }
+
+ bool BuildConfiguration(const std::vector<uint8_t>& remote_capabilities,
+ const std::optional<CodecParameters>& hint,
+ std::vector<uint8_t>* configuration) const override;
+};
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadCodecFactory.cpp b/bluetooth/audio/aidl/default/A2dpOffloadCodecFactory.cpp
new file mode 100644
index 0000000..658073c
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpOffloadCodecFactory.cpp
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "A2dpOffloadCodecFactory.h"
+
+#include <algorithm>
+#include <cassert>
+
+#include "A2dpOffloadCodecAac.h"
+#include "A2dpOffloadCodecSbc.h"
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+/**
+ * Local Capabilities Configuration
+ */
+
+enum : bool {
+ kEnableAac = true,
+ kEnableSbc = true,
+};
+
+/**
+ * Class implementation
+ */
+
+A2dpOffloadCodecFactory::A2dpOffloadCodecFactory()
+ : name("Offload"), codecs(ranked_codecs_) {
+ ranked_codecs_.reserve(kEnableAac + kEnableSbc);
+
+ if (kEnableAac)
+ ranked_codecs_.push_back(std::make_shared<A2dpOffloadCodecAac>());
+ if (kEnableSbc)
+ ranked_codecs_.push_back(std::make_shared<A2dpOffloadCodecSbc>());
+}
+
+std::shared_ptr<const A2dpOffloadCodec> A2dpOffloadCodecFactory::GetCodec(
+ CodecId id) const {
+ auto codec = std::find_if(begin(ranked_codecs_), end(ranked_codecs_),
+ [&](auto c) { return id == c->info.id; });
+
+ return codec != end(ranked_codecs_) ? *codec : nullptr;
+}
+
+bool A2dpOffloadCodecFactory::GetConfiguration(
+ const std::vector<A2dpRemoteCapabilities>& remote_capabilities,
+ const A2dpConfigurationHint& hint, A2dpConfiguration* configuration) const {
+ decltype(ranked_codecs_) codecs;
+
+ codecs.reserve(ranked_codecs_.size());
+
+ auto hinted_codec =
+ std::find_if(begin(ranked_codecs_), end(ranked_codecs_),
+ [&](auto c) { return hint.codecId == c->info.id; });
+
+ if (hinted_codec != end(ranked_codecs_)) codecs.push_back(*hinted_codec);
+
+ std::copy_if(begin(ranked_codecs_), end(ranked_codecs_),
+ std::back_inserter(codecs),
+ [&](auto c) { return c != *hinted_codec; });
+
+ for (auto codec : codecs) {
+ auto rc =
+ std::find_if(begin(remote_capabilities), end(remote_capabilities),
+ [&](auto& rc__) { return codec->info.id == rc__.id; });
+
+ if ((rc == end(remote_capabilities)) ||
+ !codec->BuildConfiguration(rc->capabilities, hint.codecParameters,
+ &configuration->configuration))
+ continue;
+
+ configuration->id = codec->info.id;
+ A2dpStatus status = codec->ParseConfiguration(configuration->configuration,
+ &configuration->parameters);
+ assert(status == A2dpStatus::OK);
+
+ configuration->remoteSeid = rc->seid;
+
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadCodecFactory.h b/bluetooth/audio/aidl/default/A2dpOffloadCodecFactory.h
new file mode 100644
index 0000000..1546cc4
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpOffloadCodecFactory.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/bluetooth/audio/A2dpConfiguration.h>
+#include <aidl/android/hardware/bluetooth/audio/A2dpConfigurationHint.h>
+#include <aidl/android/hardware/bluetooth/audio/A2dpRemoteCapabilities.h>
+
+#include <memory>
+
+#include "A2dpOffloadCodec.h"
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+class A2dpOffloadCodecFactory {
+ std::vector<std::shared_ptr<const A2dpOffloadCodec>> ranked_codecs_;
+
+ public:
+ const std::string name;
+ const std::vector<std::shared_ptr<const A2dpOffloadCodec>>& codecs;
+
+ A2dpOffloadCodecFactory();
+
+ std::shared_ptr<const A2dpOffloadCodec> GetCodec(CodecId id) const;
+
+ bool GetConfiguration(const std::vector<A2dpRemoteCapabilities>&,
+ const A2dpConfigurationHint& hint,
+ A2dpConfiguration* configuration) const;
+};
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.cpp b/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.cpp
new file mode 100644
index 0000000..6b9046c
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.cpp
@@ -0,0 +1,505 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "A2dpOffloadCodecSbc.h"
+
+#include <algorithm>
+
+#include "A2dpBits.h"
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+/**
+ * SBC Local Capabilities
+ */
+
+enum : bool {
+ kEnableSamplingFrequency44100 = true,
+ kEnableSamplingFrequency48000 = true,
+};
+
+enum : bool {
+ kEnableChannelModeMono = true,
+ kEnableChannelModeDualChannel = true,
+ kEnableChannelModeStereo = true,
+ kEnableChannelModeJointStereo = true,
+};
+
+enum : bool {
+ kEnableBlockLength4 = true,
+ kEnableBlockLength8 = true,
+ kEnableBlockLength12 = true,
+ kEnableBlockLength16 = true,
+};
+
+enum : bool {
+ kEnableSubbands4 = true,
+ kEnableSubbands8 = true,
+};
+
+enum : bool {
+ kEnableAllocationMethodSnr = true,
+ kEnableAllocationMethodLoudness = true,
+};
+
+enum : uint8_t {
+ kDefaultMinimumBitpool = 2,
+ kDefaultMaximumBitpool = 250,
+};
+
+enum : int {
+ kBitdepth = 16,
+};
+
+/**
+ * SBC Signaling format [A2DP - 4.3]
+ */
+
+// clang-format off
+
+constexpr A2dpBits::Range kSamplingFrequency ( 0, 3 );
+constexpr A2dpBits::Range kChannelMode ( 4, 7 );
+constexpr A2dpBits::Range kBlockLength ( 8, 11 );
+constexpr A2dpBits::Range kSubbands ( 12, 13 );
+constexpr A2dpBits::Range kAllocationMethod ( 14, 15 );
+constexpr A2dpBits::Range kMinimumBitpool ( 16, 23 );
+constexpr A2dpBits::Range kMaximumBitpool ( 24, 31 );
+constexpr size_t kCapabilitiesSize = 32/8;
+
+// clang-format on
+
+enum {
+ kSamplingFrequency16000 = kSamplingFrequency.first,
+ kSamplingFrequency32000,
+ kSamplingFrequency44100,
+ kSamplingFrequency48000
+};
+
+enum {
+ kChannelModeMono = kChannelMode.first,
+ kChannelModeDualChannel,
+ kChannelModeStereo,
+ kChannelModeJointStereo
+};
+
+enum {
+ kBlockLength4 = kBlockLength.first,
+ kBlockLength8,
+ kBlockLength12,
+ kBlockLength16
+};
+
+enum { kSubbands8 = kSubbands.first, kSubbands4 };
+
+enum {
+ kAllocationMethodSnr = kAllocationMethod.first,
+ kAllocationMethodLoudness
+};
+
+/**
+ * SBC Conversion functions
+ */
+
+static int GetSamplingFrequencyBit(int32_t sampling_frequency) {
+ switch (sampling_frequency) {
+ case 16000:
+ return kSamplingFrequency16000;
+ case 32000:
+ return kSamplingFrequency32000;
+ case 44100:
+ return kSamplingFrequency44100;
+ case 48000:
+ return kSamplingFrequency48000;
+ default:
+ return -1;
+ }
+}
+
+static int32_t GetSamplingFrequencyValue(int sampling_frequency) {
+ switch (sampling_frequency) {
+ case kSamplingFrequency16000:
+ return 16000;
+ case kSamplingFrequency32000:
+ return 32000;
+ case kSamplingFrequency44100:
+ return 44100;
+ case kSamplingFrequency48000:
+ return 48000;
+ default:
+ return 0;
+ }
+}
+
+static int GetChannelModeBit(ChannelMode channel_mode) {
+ switch (channel_mode) {
+ case ChannelMode::STEREO:
+ return kChannelModeJointStereo | kChannelModeStereo;
+ case ChannelMode::DUALMONO:
+ return kChannelModeDualChannel;
+ case ChannelMode::MONO:
+ return kChannelModeMono;
+ default:
+ return -1;
+ }
+}
+
+static ChannelMode GetChannelModeEnum(int channel_mode) {
+ switch (channel_mode) {
+ case kChannelModeMono:
+ return ChannelMode::MONO;
+ case kChannelModeDualChannel:
+ return ChannelMode::DUALMONO;
+ case kChannelModeStereo:
+ case kChannelModeJointStereo:
+ return ChannelMode::STEREO;
+ default:
+ return ChannelMode::UNKNOWN;
+ }
+}
+
+static int32_t GetBlockLengthValue(int block_length) {
+ switch (block_length) {
+ case kBlockLength4:
+ return 4;
+ case kBlockLength8:
+ return 8;
+ case kBlockLength12:
+ return 12;
+ case kBlockLength16:
+ return 16;
+ default:
+ return 0;
+ }
+}
+
+static int32_t GetSubbandsValue(int subbands) {
+ switch (subbands) {
+ case kSubbands4:
+ return 4;
+ case kSubbands8:
+ return 8;
+ default:
+ return 0;
+ }
+}
+
+static SbcParameters::AllocationMethod GetAllocationMethodEnum(
+ int allocation_method) {
+ switch (allocation_method) {
+ case kAllocationMethodSnr:
+ return SbcParameters::AllocationMethod::SNR;
+ case kAllocationMethodLoudness:
+ default:
+ return SbcParameters::AllocationMethod::LOUDNESS;
+ }
+}
+
+static int32_t GetSamplingFrequencyValue(const A2dpBits& configuration) {
+ return GetSamplingFrequencyValue(
+ configuration.find_active_bit(kSamplingFrequency));
+}
+
+static int32_t GetBlockLengthValue(const A2dpBits& configuration) {
+ return GetBlockLengthValue(configuration.find_active_bit(kBlockLength));
+}
+
+static int32_t GetSubbandsValue(const A2dpBits& configuration) {
+ return GetSubbandsValue(configuration.find_active_bit(kSubbands));
+}
+
+static int GetFrameSize(const A2dpBits& configuration, int bitpool) {
+ const int kSbcHeaderSize = 4;
+ int subbands = GetSubbandsValue(configuration);
+ int blocks = GetBlockLengthValue(configuration);
+
+ unsigned bits =
+ ((4 * subbands) << !configuration.get(kChannelModeMono)) +
+ ((blocks * bitpool) << configuration.get(kChannelModeDualChannel)) +
+ ((configuration.get(kChannelModeJointStereo) ? subbands : 0));
+
+ return kSbcHeaderSize + ((bits + 7) >> 3);
+}
+
+static int GetBitrate(const A2dpBits& configuration, int bitpool) {
+ int sampling_frequency = GetSamplingFrequencyValue(configuration);
+ int subbands = GetSubbandsValue(configuration);
+ int blocks = GetBlockLengthValue(configuration);
+ int bits = 8 * GetFrameSize(configuration, bitpool);
+
+ return (bits * sampling_frequency) / (blocks * subbands);
+}
+
+static uint8_t GetBitpool(const A2dpBits& configuration, int bitrate) {
+ int bitpool = 0;
+
+ for (int i = 128; i; i >>= 1)
+ if (bitrate > GetBitrate(configuration, bitpool + i)) {
+ bitpool += i;
+ }
+
+ return std::clamp(bitpool, 2, 250);
+}
+
+/**
+ * SBC Class implementation
+ */
+
+A2dpOffloadCodecSbc::A2dpOffloadCodecSbc()
+ : A2dpOffloadCodec(info_),
+ info_({.id = CodecId(CodecId::A2dp::SBC), .name = "SBC"}) {
+ info_.transport.set<CodecInfo::Transport::Tag::a2dp>();
+ auto& a2dp_info = info_.transport.get<CodecInfo::Transport::Tag::a2dp>();
+
+ /* --- Setup Capabilities --- */
+
+ a2dp_info.capabilities.resize(kCapabilitiesSize);
+ std::fill(begin(a2dp_info.capabilities), end(a2dp_info.capabilities), 0);
+
+ auto capabilities = A2dpBits(a2dp_info.capabilities);
+
+ capabilities.set(kSamplingFrequency44100, kEnableSamplingFrequency44100);
+ capabilities.set(kSamplingFrequency48000, kEnableSamplingFrequency48000);
+
+ capabilities.set(kChannelModeMono, kEnableChannelModeMono);
+ capabilities.set(kChannelModeDualChannel, kEnableChannelModeDualChannel);
+ capabilities.set(kChannelModeStereo, kEnableChannelModeStereo);
+ capabilities.set(kChannelModeJointStereo, kEnableChannelModeJointStereo);
+
+ capabilities.set(kBlockLength4, kEnableBlockLength4);
+ capabilities.set(kBlockLength8, kEnableBlockLength8);
+ capabilities.set(kBlockLength12, kEnableBlockLength12);
+ capabilities.set(kBlockLength16, kEnableBlockLength16);
+
+ capabilities.set(kSubbands4, kEnableSubbands4);
+ capabilities.set(kSubbands8, kEnableSubbands8);
+
+ capabilities.set(kSubbands4, kEnableSubbands4);
+ capabilities.set(kSubbands8, kEnableSubbands8);
+
+ capabilities.set(kAllocationMethodSnr, kEnableAllocationMethodSnr);
+ capabilities.set(kAllocationMethodLoudness, kEnableAllocationMethodLoudness);
+
+ capabilities.set(kMinimumBitpool, kDefaultMinimumBitpool);
+ capabilities.set(kMaximumBitpool, kDefaultMaximumBitpool);
+
+ /* --- Setup Sampling Frequencies --- */
+
+ auto& sampling_frequency = a2dp_info.samplingFrequencyHz;
+
+ for (auto v : {16000, 32000, 44100, 48000})
+ if (capabilities.get(GetSamplingFrequencyBit(int32_t(v))))
+ sampling_frequency.push_back(v);
+
+ /* --- Setup Channel Modes --- */
+
+ auto& channel_modes = a2dp_info.channelMode;
+
+ for (auto v : {ChannelMode::MONO, ChannelMode::DUALMONO, ChannelMode::STEREO})
+ if (capabilities.get(GetChannelModeBit(v))) channel_modes.push_back(v);
+
+ /* --- Setup Bitdepth --- */
+
+ a2dp_info.bitdepth.push_back(kBitdepth);
+}
+
+A2dpStatus A2dpOffloadCodecSbc::ParseConfiguration(
+ const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters, SbcParameters* sbc_parameters) const {
+ auto& a2dp_info = info.transport.get<CodecInfo::Transport::Tag::a2dp>();
+
+ if (configuration.size() != a2dp_info.capabilities.size())
+ return A2dpStatus::BAD_LENGTH;
+
+ auto config = A2dpBits(configuration);
+ auto lcaps = A2dpBits(a2dp_info.capabilities);
+
+ /* --- Check Sampling Frequency --- */
+
+ int sampling_frequency = config.find_active_bit(kSamplingFrequency);
+ if (sampling_frequency < 0) return A2dpStatus::INVALID_SAMPLING_FREQUENCY;
+ if (!lcaps.get(sampling_frequency))
+ return A2dpStatus::NOT_SUPPORTED_SAMPLING_FREQUENCY;
+
+ /* --- Check Channel Mode --- */
+
+ int channel_mode = config.find_active_bit(kChannelMode);
+ if (channel_mode < 0) return A2dpStatus::INVALID_CHANNEL_MODE;
+ if (!lcaps.get(channel_mode)) return A2dpStatus::NOT_SUPPORTED_CHANNEL_MODE;
+
+ /* --- Check Block Length --- */
+
+ int block_length = config.find_active_bit(kBlockLength);
+ if (block_length < 0) return A2dpStatus::INVALID_BLOCK_LENGTH;
+
+ /* --- Check Subbands --- */
+
+ int subbands = config.find_active_bit(kSubbands);
+ if (subbands < 0) return A2dpStatus::INVALID_SUBBANDS;
+ if (!lcaps.get(subbands)) return A2dpStatus::NOT_SUPPORTED_SUBBANDS;
+
+ /* --- Check Allocation Method --- */
+
+ int allocation_method = config.find_active_bit(kAllocationMethod);
+ if (allocation_method < 0) return A2dpStatus::INVALID_ALLOCATION_METHOD;
+ if (!lcaps.get(allocation_method))
+ return A2dpStatus::NOT_SUPPORTED_ALLOCATION_METHOD;
+
+ /* --- Check Bitpool --- */
+
+ uint8_t min_bitpool = config.get(kMinimumBitpool);
+ if (min_bitpool < 2 || min_bitpool > 250)
+ return A2dpStatus::INVALID_MINIMUM_BITPOOL_VALUE;
+ if (min_bitpool < lcaps.get(kMinimumBitpool))
+ return A2dpStatus::NOT_SUPPORTED_MINIMUM_BITPOOL_VALUE;
+
+ uint8_t max_bitpool = config.get(kMaximumBitpool);
+ if (max_bitpool < 2 || max_bitpool > 250)
+ return A2dpStatus::INVALID_MAXIMUM_BITPOOL_VALUE;
+ if (max_bitpool > lcaps.get(kMaximumBitpool))
+ return A2dpStatus::NOT_SUPPORTED_MAXIMUM_BITPOOL_VALUE;
+
+ /* --- Return --- */
+
+ codec_parameters->channelMode = GetChannelModeEnum(channel_mode);
+ codec_parameters->samplingFrequencyHz =
+ GetSamplingFrequencyValue(sampling_frequency);
+ codec_parameters->bitdepth = kBitdepth;
+
+ codec_parameters->minBitrate = GetBitrate(config, min_bitpool);
+ codec_parameters->maxBitrate = GetBitrate(config, max_bitpool);
+
+ if (sbc_parameters) {
+ sbc_parameters->block_length = GetBlockLengthValue(block_length);
+ sbc_parameters->subbands = GetSubbandsValue(subbands);
+ sbc_parameters->allocation_method =
+ GetAllocationMethodEnum(allocation_method);
+ sbc_parameters->min_bitpool = min_bitpool;
+ sbc_parameters->max_bitpool = max_bitpool;
+ }
+
+ return A2dpStatus::OK;
+}
+
+bool A2dpOffloadCodecSbc::BuildConfiguration(
+ const std::vector<uint8_t>& remote_capabilities,
+ const std::optional<CodecParameters>& hint,
+ std::vector<uint8_t>* configuration) const {
+ auto& a2dp_info = info.transport.get<CodecInfo::Transport::Tag::a2dp>();
+
+ if (remote_capabilities.size() != a2dp_info.capabilities.size()) return false;
+
+ auto lcaps = A2dpBits(a2dp_info.capabilities);
+ auto rcaps = A2dpBits(remote_capabilities);
+
+ configuration->resize(a2dp_info.capabilities.size());
+ std::fill(begin(*configuration), end(*configuration), 0);
+ auto config = A2dpBits(*configuration);
+
+ /* --- Select Sampling Frequency --- */
+
+ auto sf_hint = hint ? GetSamplingFrequencyBit(hint->samplingFrequencyHz) : -1;
+
+ if (sf_hint >= 0 && lcaps.get(sf_hint) && rcaps.get(sf_hint))
+ config.set(sf_hint);
+ else if (lcaps.get(kSamplingFrequency44100) &&
+ rcaps.get(kSamplingFrequency44100))
+ config.set(kSamplingFrequency44100);
+ else if (lcaps.get(kSamplingFrequency48000) &&
+ rcaps.get(kSamplingFrequency48000))
+ config.set(kSamplingFrequency48000);
+ else
+ return false;
+
+ /* --- Select Channel Mode --- */
+
+ auto cm_hint = hint ? GetChannelModeBit(hint->channelMode) : -1;
+
+ if (cm_hint >= 0 && lcaps.get(cm_hint) && rcaps.get(cm_hint))
+ config.set(cm_hint);
+ else if (lcaps.get(kChannelModeJointStereo) &&
+ rcaps.get(kChannelModeJointStereo))
+ config.set(kChannelModeJointStereo);
+ else if (lcaps.get(kChannelModeStereo) && rcaps.get(kChannelModeStereo))
+ config.set(kChannelModeStereo);
+ else if (lcaps.get(kChannelModeDualChannel) &&
+ rcaps.get(kChannelModeDualChannel))
+ config.set(kChannelModeDualChannel);
+ else if (lcaps.get(kChannelModeMono) && rcaps.get(kChannelModeMono))
+ config.set(kChannelModeMono);
+ else
+ return false;
+
+ /* --- Select Block Length --- */
+
+ if (lcaps.get(kBlockLength16) && rcaps.get(kBlockLength16))
+ config.set(kBlockLength16);
+ else if (lcaps.get(kBlockLength12) && rcaps.get(kBlockLength12))
+ config.set(kBlockLength12);
+ else if (lcaps.get(kBlockLength8) && rcaps.get(kBlockLength8))
+ config.set(kBlockLength8);
+ else if (lcaps.get(kBlockLength4) && rcaps.get(kBlockLength4))
+ config.set(kBlockLength4);
+ else
+ return false;
+
+ /* --- Select Subbands --- */
+
+ if (lcaps.get(kSubbands8) && rcaps.get(kSubbands8))
+ config.set(kSubbands8);
+ else if (lcaps.get(kSubbands4) && rcaps.get(kSubbands4))
+ config.set(kSubbands4);
+ else
+ return false;
+
+ /* --- Select Allocation method --- */
+
+ if (lcaps.get(kAllocationMethodLoudness) &&
+ rcaps.get(kAllocationMethodLoudness))
+ config.set(kAllocationMethodLoudness);
+ else if (lcaps.get(kAllocationMethodSnr) && rcaps.get(kAllocationMethodSnr))
+ config.set(kAllocationMethodSnr);
+ else
+ return false;
+
+ /* --- Select Bitpool --- */
+
+ uint8_t min_bitpool = rcaps.get(kMinimumBitpool);
+ uint8_t max_bitpool = rcaps.get(kMaximumBitpool);
+
+ if (min_bitpool < 2 || min_bitpool > 250 || max_bitpool < 2 ||
+ max_bitpool > 250 || min_bitpool > max_bitpool) {
+ min_bitpool = 2;
+ max_bitpool = 250;
+ }
+
+ min_bitpool = std::max(min_bitpool, uint8_t(lcaps.get(kMinimumBitpool)));
+ max_bitpool = std::max(max_bitpool, uint8_t(lcaps.get(kMaximumBitpool)));
+
+ if (hint) {
+ min_bitpool =
+ std::max(min_bitpool, GetBitpool(*configuration, hint->minBitrate));
+ if (hint->maxBitrate && hint->maxBitrate >= hint->minBitrate)
+ max_bitpool =
+ std::min(max_bitpool, GetBitpool(*configuration, hint->maxBitrate));
+ }
+
+ config.set(kMinimumBitpool, min_bitpool);
+ config.set(kMaximumBitpool, max_bitpool);
+
+ return true;
+}
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.h b/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.h
new file mode 100644
index 0000000..a39d779
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "A2dpOffloadCodec.h"
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+struct SbcParameters : public CodecParameters {
+ enum class AllocationMethod { SNR, LOUDNESS };
+
+ AllocationMethod allocation_method;
+ int block_length;
+ int subbands;
+ int min_bitpool;
+ int max_bitpool;
+};
+
+class A2dpOffloadCodecSbc : public A2dpOffloadCodec {
+ CodecInfo info_;
+
+ A2dpStatus ParseConfiguration(const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters,
+ SbcParameters* sbc_parameters) const;
+
+ public:
+ A2dpOffloadCodecSbc();
+
+ A2dpStatus ParseConfiguration(
+ const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters) const override {
+ return ParseConfiguration(configuration, codec_parameters, nullptr);
+ }
+
+ A2dpStatus ParseConfiguration(const std::vector<uint8_t>& configuration,
+ SbcParameters* sbc_parameters) const {
+ return ParseConfiguration(configuration, sbc_parameters, sbc_parameters);
+ }
+
+ bool BuildConfiguration(const std::vector<uint8_t>& remote_capabilities,
+ const std::optional<CodecParameters>& hint,
+ std::vector<uint8_t>* configuration) const override;
+};
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/Android.bp b/bluetooth/audio/aidl/default/Android.bp
index 40aea32..69db1b3 100644
--- a/bluetooth/audio/aidl/default/Android.bp
+++ b/bluetooth/audio/aidl/default/Android.bp
@@ -18,8 +18,13 @@
"BluetoothAudioProvider.cpp",
"BluetoothAudioProviderFactory.cpp",
"A2dpOffloadAudioProvider.cpp",
+ "A2dpOffloadCodecAac.cpp",
+ "A2dpOffloadCodecFactory.cpp",
+ "A2dpOffloadCodecSbc.cpp",
"A2dpSoftwareAudioProvider.cpp",
"HearingAidAudioProvider.cpp",
+ "HfpOffloadAudioProvider.cpp",
+ "HfpSoftwareAudioProvider.cpp",
"LeAudioOffloadAudioProvider.cpp",
"LeAudioSoftwareAudioProvider.cpp",
"service.cpp",
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
index 9c72e19..8d03fae 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
@@ -21,6 +21,8 @@
#include <BluetoothAudioSessionReport.h>
#include <android-base/logging.h>
+#include "A2dpOffloadCodecFactory.h"
+
namespace aidl {
namespace android {
namespace hardware {
@@ -164,8 +166,146 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus BluetoothAudioProvider::parseA2dpConfiguration(
+ [[maybe_unused]] const CodecId& codec_id,
+ [[maybe_unused]] const std::vector<uint8_t>& configuration,
+ [[maybe_unused]] CodecParameters* codec_parameters,
+ [[maybe_unused]] A2dpStatus* _aidl_return) {
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+ << " is illegal";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+}
+
+ndk::ScopedAStatus BluetoothAudioProvider::getA2dpConfiguration(
+ [[maybe_unused]] const std::vector<A2dpRemoteCapabilities>&
+ remote_a2dp_capabilities,
+ [[maybe_unused]] const A2dpConfigurationHint& hint,
+ [[maybe_unused]] std::optional<audio::A2dpConfiguration>* _aidl_return) {
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+ << " is illegal";
+
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+}
+
+ndk::ScopedAStatus BluetoothAudioProvider::setCodecPriority(
+ const ::aidl::android::hardware::bluetooth::audio::CodecId& in_codecId,
+ int32_t in_priority) {
+ /* TODO: Implement */
+ (void)in_codecId;
+ (void)in_priority;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+};
+
+ndk::ScopedAStatus BluetoothAudioProvider::getLeAudioAseConfiguration(
+ const std::optional<std::vector<std::optional<
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioDeviceCapabilities>>>& in_remoteSinkAudioCapabilities,
+ const std::optional<std::vector<std::optional<
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioDeviceCapabilities>>>& in_remoteSourceAudioCapabilities,
+ const std::vector<
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioConfigurationRequirement>& in_requirements,
+ std::vector<::aidl::android::hardware::bluetooth::audio::
+ IBluetoothAudioProvider::LeAudioAseConfigurationSetting>*
+ _aidl_return) {
+ /* TODO: Implement */
+ (void)in_remoteSinkAudioCapabilities;
+ (void)in_remoteSourceAudioCapabilities;
+ (void)in_requirements;
+ (void)_aidl_return;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+};
+
+ndk::ScopedAStatus BluetoothAudioProvider::getLeAudioAseQosConfiguration(
+ const ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioAseQosConfigurationRequirement& in_qosRequirement,
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioAseQosConfigurationPair* _aidl_return) {
+ /* TODO: Implement */
+ (void)in_qosRequirement;
+ (void)_aidl_return;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+};
+
+ndk::ScopedAStatus BluetoothAudioProvider::getLeAudioAseDatapathConfiguration(
+ const std::optional<::aidl::android::hardware::bluetooth::audio::
+ IBluetoothAudioProvider::StreamConfig>&
+ in_sinkConfig,
+ const std::optional<::aidl::android::hardware::bluetooth::audio::
+ IBluetoothAudioProvider::StreamConfig>&
+ in_sourceConfig,
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioDataPathConfigurationPair* _aidl_return) {
+ /* TODO: Implement */
+ (void)in_sinkConfig;
+ (void)in_sourceConfig;
+ (void)_aidl_return;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus BluetoothAudioProvider::onSinkAseMetadataChanged(
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ AseState in_state,
+ int32_t cigId, int32_t cisId,
+ const std::optional<std::vector<std::optional<
+ ::aidl::android::hardware::bluetooth::audio::MetadataLtv>>>&
+ in_metadata) {
+ /* TODO: Implement */
+ (void)in_state;
+ (void)cigId;
+ (void)cisId;
+ (void)in_metadata;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+};
+
+ndk::ScopedAStatus BluetoothAudioProvider::onSourceAseMetadataChanged(
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ AseState in_state,
+ int32_t cigId, int32_t cisId,
+ const std::optional<std::vector<std::optional<
+ ::aidl::android::hardware::bluetooth::audio::MetadataLtv>>>&
+ in_metadata) {
+ /* TODO: Implement */
+ (void)in_state;
+ (void)cigId;
+ (void)cisId;
+ (void)in_metadata;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+};
+
+ndk::ScopedAStatus BluetoothAudioProvider::getLeAudioBroadcastConfiguration(
+ const std::optional<std::vector<std::optional<
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioDeviceCapabilities>>>& in_remoteSinkAudioCapabilities,
+ const ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioBroadcastConfigurationRequirement& in_requirement,
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioBroadcastConfigurationSetting* _aidl_return) {
+ /* TODO: Implement */
+ (void)in_remoteSinkAudioCapabilities;
+ (void)in_requirement;
+ (void)_aidl_return;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+};
+
+ndk::ScopedAStatus
+BluetoothAudioProvider::getLeAudioBroadcastDatapathConfiguration(
+ const ::aidl::android::hardware::bluetooth::audio::AudioContext& in_context,
+ const std::vector<::aidl::android::hardware::bluetooth::audio::
+ LeAudioBroadcastConfiguration::BroadcastStreamMap>&
+ in_streamMap,
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioDataPathConfiguration* _aidl_return) {
+ /* TODO: Implement */
+ (void)in_context;
+ (void)in_streamMap;
+ (void)_aidl_return;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
} // namespace audio
} // namespace bluetooth
} // namespace hardware
} // namespace android
-} // namespace aidl
\ No newline at end of file
+} // namespace aidl
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
index b6e07a1..866eaeb 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
@@ -35,20 +35,106 @@
namespace bluetooth {
namespace audio {
+/// Enable flag for the reference implementation for A2dp Codec
+/// Extensibility.
+///
+/// A2dp Codec extensibility cannot be enabled until the following
+/// requirements are fulfilled.
+///
+/// 1. The Bluetooth controller must support the HCI Requirements
+/// v1.04 or later, and must support the vendor HCI command
+/// A2DP Offload Start (v2), A2DP Offload Stop (v2) as indicated
+/// by the field a2dp_offload_v2 of the vendor capabilities.
+///
+/// 2. The implementation of the provider must be completed with
+/// DSP configuration for streaming.
+enum : bool {
+ kEnableA2dpCodecExtensibility = false,
+};
+
class BluetoothAudioProvider : public BnBluetoothAudioProvider {
public:
BluetoothAudioProvider();
ndk::ScopedAStatus startSession(
const std::shared_ptr<IBluetoothAudioPort>& host_if,
const AudioConfiguration& audio_config,
- const std::vector<LatencyMode>& latency_modes,
- DataMQDesc* _aidl_return);
+ const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return);
ndk::ScopedAStatus endSession();
ndk::ScopedAStatus streamStarted(BluetoothAudioStatus status);
ndk::ScopedAStatus streamSuspended(BluetoothAudioStatus status);
ndk::ScopedAStatus updateAudioConfiguration(
const AudioConfiguration& audio_config);
ndk::ScopedAStatus setLowLatencyModeAllowed(bool allowed);
+ ndk::ScopedAStatus setCodecPriority(
+ const ::aidl::android::hardware::bluetooth::audio::CodecId& in_codecId,
+ int32_t in_priority) override;
+ ndk::ScopedAStatus getLeAudioAseConfiguration(
+ const std::optional<std::vector<std::optional<
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioDeviceCapabilities>>>& in_remoteSinkAudioCapabilities,
+ const std::optional<std::vector<std::optional<
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioDeviceCapabilities>>>& in_remoteSourceAudioCapabilities,
+ const std::vector<
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioConfigurationRequirement>& in_requirements,
+ std::vector<::aidl::android::hardware::bluetooth::audio::
+ IBluetoothAudioProvider::LeAudioAseConfigurationSetting>*
+ _aidl_return) override;
+ ndk::ScopedAStatus getLeAudioAseQosConfiguration(
+ const ::aidl::android::hardware::bluetooth::audio::
+ IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement&
+ in_qosRequirement,
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioAseQosConfigurationPair* _aidl_return) override;
+ ndk::ScopedAStatus getLeAudioAseDatapathConfiguration(
+ const std::optional<::aidl::android::hardware::bluetooth::audio::
+ IBluetoothAudioProvider::StreamConfig>&
+ in_sinkConfig,
+ const std::optional<::aidl::android::hardware::bluetooth::audio::
+ IBluetoothAudioProvider::StreamConfig>&
+ in_sourceConfig,
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioDataPathConfigurationPair* _aidl_return) override;
+ ndk::ScopedAStatus onSinkAseMetadataChanged(
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ AseState in_state,
+ int32_t cigId, int32_t cisId,
+ const std::optional<std::vector<std::optional<
+ ::aidl::android::hardware::bluetooth::audio::MetadataLtv>>>&
+ in_metadata) override;
+ ndk::ScopedAStatus onSourceAseMetadataChanged(
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ AseState in_state,
+ int32_t cigId, int32_t cisId,
+ const std::optional<std::vector<std::optional<
+ ::aidl::android::hardware::bluetooth::audio::MetadataLtv>>>&
+ in_metadata) override;
+ ndk::ScopedAStatus getLeAudioBroadcastConfiguration(
+ const std::optional<std::vector<std::optional<
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioDeviceCapabilities>>>& in_remoteSinkAudioCapabilities,
+ const ::aidl::android::hardware::bluetooth::audio::
+ IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement&
+ in_requirement,
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioBroadcastConfigurationSetting* _aidl_return) override;
+ ndk::ScopedAStatus getLeAudioBroadcastDatapathConfiguration(
+ const ::aidl::android::hardware::bluetooth::audio::AudioContext&
+ in_context,
+ const std::vector<::aidl::android::hardware::bluetooth::audio::
+ LeAudioBroadcastConfiguration::BroadcastStreamMap>&
+ in_streamMap,
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioDataPathConfiguration* _aidl_return) override;
+
+ ndk::ScopedAStatus parseA2dpConfiguration(
+ const CodecId& codec_id, const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters, A2dpStatus* _aidl_return);
+ ndk::ScopedAStatus getA2dpConfiguration(
+ const std::vector<A2dpRemoteCapabilities>& remote_a2dp_capabilities,
+ const A2dpConfigurationHint& hint,
+ std::optional<audio::A2dpConfiguration>* _aidl_return);
virtual bool isValid(const SessionType& sessionType) = 0;
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
index 91731d4..584640b 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
@@ -25,6 +25,8 @@
#include "A2dpSoftwareAudioProvider.h"
#include "BluetoothAudioProvider.h"
#include "HearingAidAudioProvider.h"
+#include "HfpOffloadAudioProvider.h"
+#include "HfpSoftwareAudioProvider.h"
#include "LeAudioOffloadAudioProvider.h"
#include "LeAudioSoftwareAudioProvider.h"
@@ -34,6 +36,9 @@
namespace bluetooth {
namespace audio {
+static const std::string kLeAudioOffloadProviderName =
+ "LE_AUDIO_OFFLOAD_HARDWARE_OFFLOAD_PROVIDER";
+
BluetoothAudioProviderFactory::BluetoothAudioProviderFactory() {}
ndk::ScopedAStatus BluetoothAudioProviderFactory::openProvider(
@@ -47,7 +52,8 @@
provider = ndk::SharedRefBase::make<A2dpSoftwareEncodingAudioProvider>();
break;
case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
- provider = ndk::SharedRefBase::make<A2dpOffloadEncodingAudioProvider>();
+ provider = ndk::SharedRefBase::make<A2dpOffloadEncodingAudioProvider>(
+ a2dp_offload_codec_factory_);
break;
case SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
provider = ndk::SharedRefBase::make<HearingAidAudioProvider>();
@@ -76,7 +82,17 @@
provider = ndk::SharedRefBase::make<A2dpSoftwareDecodingAudioProvider>();
break;
case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH:
- provider = ndk::SharedRefBase::make<A2dpOffloadDecodingAudioProvider>();
+ provider = ndk::SharedRefBase::make<A2dpOffloadDecodingAudioProvider>(
+ a2dp_offload_codec_factory_);
+ break;
+ case SessionType::HFP_SOFTWARE_ENCODING_DATAPATH:
+ provider = ndk::SharedRefBase::make<HfpSoftwareOutputAudioProvider>();
+ break;
+ case SessionType::HFP_SOFTWARE_DECODING_DATAPATH:
+ provider = ndk::SharedRefBase::make<HfpSoftwareInputAudioProvider>();
+ break;
+ case SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH:
+ provider = ndk::SharedRefBase::make<HfpOffloadAudioProvider>();
break;
default:
provider = nullptr;
@@ -135,8 +151,49 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus BluetoothAudioProviderFactory::getProviderInfo(
+ SessionType session_type, std::optional<ProviderInfo>* _aidl_return) {
+ *_aidl_return = std::nullopt;
+
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type);
+
+ if (session_type == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+ session_type == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+ if (!kEnableA2dpCodecExtensibility) {
+ // Implementing getProviderInfo equates supporting
+ // A2dp codec extensibility.
+ return ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_TRANSACTION);
+ }
+
+ auto& provider_info = _aidl_return->emplace();
+
+ provider_info.name = a2dp_offload_codec_factory_.name;
+ for (auto codec : a2dp_offload_codec_factory_.codecs)
+ provider_info.codecInfos.push_back(codec->info);
+ }
+
+ if (session_type ==
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+ session_type ==
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
+ session_type ==
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+ std::vector<CodecInfo> db_codec_info =
+ BluetoothAudioCodecs::GetLeAudioOffloadCodecInfo(session_type);
+ if (!db_codec_info.empty()) {
+ auto& provider_info = _aidl_return->emplace();
+ provider_info.name = kLeAudioOffloadProviderName;
+ provider_info.codecInfos = db_codec_info;
+ *_aidl_return = provider_info;
+ return ndk::ScopedAStatus::ok();
+ }
+ }
+
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace audio
} // namespace bluetooth
} // namespace hardware
} // namespace android
-} // namespace aidl
\ No newline at end of file
+} // namespace aidl
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.h b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.h
index b38cfd2..6931884 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.h
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.h
@@ -18,6 +18,8 @@
#include <aidl/android/hardware/bluetooth/audio/BnBluetoothAudioProviderFactory.h>
+#include "A2dpOffloadCodecFactory.h"
+
namespace aidl {
namespace android {
namespace hardware {
@@ -25,6 +27,8 @@
namespace audio {
class BluetoothAudioProviderFactory : public BnBluetoothAudioProviderFactory {
+ const A2dpOffloadCodecFactory a2dp_offload_codec_factory_;
+
public:
BluetoothAudioProviderFactory();
@@ -35,6 +39,10 @@
ndk::ScopedAStatus getProviderCapabilities(
const SessionType session_type,
std::vector<AudioCapabilities>* _aidl_return) override;
+
+ ndk::ScopedAStatus getProviderInfo(
+ SessionType in_sessionType,
+ std::optional<ProviderInfo>* _aidl_return) override;
};
} // namespace audio
diff --git a/bluetooth/audio/aidl/default/HfpOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/HfpOffloadAudioProvider.cpp
new file mode 100644
index 0000000..7196bb6
--- /dev/null
+++ b/bluetooth/audio/aidl/default/HfpOffloadAudioProvider.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BTAudioProviderHfpHW"
+
+#include "HfpOffloadAudioProvider.h"
+
+#include <BluetoothAudioCodecs.h>
+#include <BluetoothAudioSessionReport.h>
+#include <android-base/logging.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+HfpOffloadAudioProvider::HfpOffloadAudioProvider() {
+ session_type_ = SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH;
+}
+
+bool HfpOffloadAudioProvider::isValid(const SessionType& session_type) {
+ return (session_type == session_type_);
+}
+
+ndk::ScopedAStatus HfpOffloadAudioProvider::startSession(
+ const std::shared_ptr<IBluetoothAudioPort>& host_if,
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return) {
+ if (audio_config.getTag() != AudioConfiguration::hfpConfig) {
+ LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
+ << audio_config.toString();
+ *_aidl_return = DataMQDesc();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ return BluetoothAudioProvider::startSession(host_if, audio_config,
+ latency_modes, _aidl_return);
+}
+
+ndk::ScopedAStatus HfpOffloadAudioProvider::onSessionReady(
+ DataMQDesc* _aidl_return) {
+ *_aidl_return = DataMQDesc();
+ BluetoothAudioSessionReport::OnSessionStarted(
+ session_type_, stack_iface_, nullptr, *audio_config_, latency_modes_);
+ return ndk::ScopedAStatus::ok();
+}
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/bluetooth/audio/aidl/default/HfpOffloadAudioProvider.h b/bluetooth/audio/aidl/default/HfpOffloadAudioProvider.h
new file mode 100644
index 0000000..5526b46
--- /dev/null
+++ b/bluetooth/audio/aidl/default/HfpOffloadAudioProvider.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "BluetoothAudioProvider.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+class HfpOffloadAudioProvider : public BluetoothAudioProvider {
+ public:
+ HfpOffloadAudioProvider();
+
+ bool isValid(const SessionType& sessionType) override;
+
+ ndk::ScopedAStatus startSession(
+ const std::shared_ptr<IBluetoothAudioPort>& host_if,
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return);
+
+ private:
+ ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override;
+};
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/bluetooth/audio/aidl/default/HfpSoftwareAudioProvider.cpp b/bluetooth/audio/aidl/default/HfpSoftwareAudioProvider.cpp
new file mode 100644
index 0000000..0f96046
--- /dev/null
+++ b/bluetooth/audio/aidl/default/HfpSoftwareAudioProvider.cpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BTAudioProviderHfpSW"
+
+#include "HfpSoftwareAudioProvider.h"
+
+#include <BluetoothAudioCodecs.h>
+#include <BluetoothAudioSessionReport.h>
+#include <android-base/logging.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+static constexpr uint32_t kBufferCount = 2; // two frame buffer
+
+HfpSoftwareOutputAudioProvider::HfpSoftwareOutputAudioProvider()
+ : HfpSoftwareAudioProvider() {
+ session_type_ = SessionType::HFP_SOFTWARE_ENCODING_DATAPATH;
+}
+
+HfpSoftwareInputAudioProvider::HfpSoftwareInputAudioProvider()
+ : HfpSoftwareAudioProvider() {
+ session_type_ = SessionType::HFP_SOFTWARE_DECODING_DATAPATH;
+}
+
+HfpSoftwareAudioProvider::HfpSoftwareAudioProvider()
+ : BluetoothAudioProvider(), data_mq_(nullptr) {
+}
+
+bool HfpSoftwareAudioProvider::isValid(const SessionType& sessionType) {
+ return (sessionType == session_type_);
+}
+
+ndk::ScopedAStatus HfpSoftwareAudioProvider::startSession(
+ const std::shared_ptr<IBluetoothAudioPort>& host_if,
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return) {
+ if (audio_config.getTag() != AudioConfiguration::pcmConfig) {
+ LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
+ << audio_config.toString();
+ *_aidl_return = DataMQDesc();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ const PcmConfiguration& pcm_config =
+ audio_config.get<AudioConfiguration::pcmConfig>();
+ if (!BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid(pcm_config)) {
+ LOG(WARNING) << __func__ << " - Unsupported PCM Configuration="
+ << pcm_config.toString();
+ *_aidl_return = DataMQDesc();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+
+ bool isValidConfig = true;
+
+ if (pcm_config.bitsPerSample != 16) {
+ isValidConfig = false;
+ }
+
+ if (pcm_config.sampleRateHz != 8000 && pcm_config.sampleRateHz != 16000 &&
+ pcm_config.sampleRateHz != 32000) {
+ isValidConfig = false;
+ }
+
+ if (pcm_config.channelMode != ChannelMode::MONO) {
+ isValidConfig = false;
+ }
+
+ if (pcm_config.dataIntervalUs != 7500) {
+ isValidConfig = false;
+ }
+
+ int bytes_per_sample = pcm_config.bitsPerSample / 8;
+
+ uint32_t data_mq_size = kBufferCount * bytes_per_sample *
+ (pcm_config.sampleRateHz / 1000) *
+ pcm_config.dataIntervalUs / 1000;
+ if (!isValidConfig) {
+ LOG(ERROR) << __func__ << "Unexpected audio buffer size: " << data_mq_size
+ << ", SampleRateHz: " << pcm_config.sampleRateHz
+ << ", ChannelMode: " << toString(pcm_config.channelMode)
+ << ", BitsPerSample: "
+ << static_cast<int>(pcm_config.bitsPerSample)
+ << ", BytesPerSample: " << bytes_per_sample
+ << ", DataIntervalUs: " << pcm_config.dataIntervalUs
+ << ", SessionType: " << toString(session_type_);
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+
+ LOG(INFO) << __func__ << " - size of audio buffer " << data_mq_size
+ << " byte(s)";
+
+ std::unique_ptr<DataMQ> temp_data_mq(
+ new DataMQ(data_mq_size, /* EventFlag */ true));
+ if (temp_data_mq == nullptr || !temp_data_mq->isValid()) {
+ ALOGE_IF(!temp_data_mq, "failed to allocate data MQ");
+ ALOGE_IF(temp_data_mq && !temp_data_mq->isValid(), "data MQ is invalid");
+ *_aidl_return = DataMQDesc();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ data_mq_ = std::move(temp_data_mq);
+
+ return BluetoothAudioProvider::startSession(host_if, audio_config,
+ latency_modes, _aidl_return);
+}
+
+ndk::ScopedAStatus HfpSoftwareAudioProvider::onSessionReady(
+ DataMQDesc* _aidl_return) {
+ if (data_mq_ == nullptr || !data_mq_->isValid()) {
+ *_aidl_return = DataMQDesc();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ *_aidl_return = data_mq_->dupeDesc();
+ auto desc = data_mq_->dupeDesc();
+ BluetoothAudioSessionReport::OnSessionStarted(
+ session_type_, stack_iface_, &desc, *audio_config_, latency_modes_);
+ return ndk::ScopedAStatus::ok();
+}
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/bluetooth/audio/aidl/default/HfpSoftwareAudioProvider.h b/bluetooth/audio/aidl/default/HfpSoftwareAudioProvider.h
new file mode 100644
index 0000000..ef51065
--- /dev/null
+++ b/bluetooth/audio/aidl/default/HfpSoftwareAudioProvider.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "BluetoothAudioProvider.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+class HfpSoftwareAudioProvider : public BluetoothAudioProvider {
+ public:
+ HfpSoftwareAudioProvider();
+
+ bool isValid(const SessionType& sessionType) override;
+
+ ndk::ScopedAStatus startSession(
+ const std::shared_ptr<IBluetoothAudioPort>& host_if,
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return);
+
+ private:
+ // audio data queue for software encoding
+ std::unique_ptr<DataMQ> data_mq_;
+
+ ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override;
+};
+
+class HfpSoftwareOutputAudioProvider : public HfpSoftwareAudioProvider {
+ public:
+ HfpSoftwareOutputAudioProvider();
+};
+
+class HfpSoftwareInputAudioProvider : public HfpSoftwareAudioProvider {
+ public:
+ HfpSoftwareInputAudioProvider();
+};
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
index 7f610ef..a692d84 100644
--- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
@@ -28,6 +28,73 @@
namespace bluetooth {
namespace audio {
+constexpr uint8_t kLeAudioDirectionSink = 0x01;
+constexpr uint8_t kLeAudioDirectionSource = 0x02;
+
+const std::map<CodecSpecificConfigurationLtv::SamplingFrequency, uint32_t>
+ freq_to_support_bitmask_map = {
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ8000,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ8000},
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ11025,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ11025},
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ16000},
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ22050,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ22050},
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ24000,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ24000},
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ32000,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ32000},
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ48000,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ48000},
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ88200,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ88200},
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ96000,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ96000},
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ176400,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ176400},
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ192000,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ192000},
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ384000,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ384000},
+};
+
+// Helper map from capability's tag to configuration's tag
+std::map<CodecSpecificCapabilitiesLtv::Tag, CodecSpecificConfigurationLtv::Tag>
+ cap_to_cfg_tag_map = {
+ {CodecSpecificCapabilitiesLtv::Tag::supportedSamplingFrequencies,
+ CodecSpecificConfigurationLtv::Tag::samplingFrequency},
+ {CodecSpecificCapabilitiesLtv::Tag::supportedMaxCodecFramesPerSDU,
+ CodecSpecificConfigurationLtv::Tag::codecFrameBlocksPerSDU},
+ {CodecSpecificCapabilitiesLtv::Tag::supportedFrameDurations,
+ CodecSpecificConfigurationLtv::Tag::frameDuration},
+ {CodecSpecificCapabilitiesLtv::Tag::supportedAudioChannelCounts,
+ CodecSpecificConfigurationLtv::Tag::audioChannelAllocation},
+ {CodecSpecificCapabilitiesLtv::Tag::supportedOctetsPerCodecFrame,
+ CodecSpecificConfigurationLtv::Tag::octetsPerCodecFrame},
+};
+
+const std::map<CodecSpecificConfigurationLtv::FrameDuration, uint32_t>
+ fduration_to_support_fduration_map = {
+ {CodecSpecificConfigurationLtv::FrameDuration::US7500,
+ CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US7500},
+ {CodecSpecificConfigurationLtv::FrameDuration::US10000,
+ CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US10000},
+};
+
+std::map<int32_t, CodecSpecificConfigurationLtv::SamplingFrequency>
+ sampling_freq_map = {
+ {16000, CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000},
+ {48000, CodecSpecificConfigurationLtv::SamplingFrequency::HZ48000},
+ {96000, CodecSpecificConfigurationLtv::SamplingFrequency::HZ96000},
+};
+
+std::map<int32_t, CodecSpecificConfigurationLtv::FrameDuration>
+ frame_duration_map = {
+ {7500, CodecSpecificConfigurationLtv::FrameDuration::US7500},
+ {10000, CodecSpecificConfigurationLtv::FrameDuration::US10000},
+};
+
LeAudioOffloadOutputAudioProvider::LeAudioOffloadOutputAudioProvider()
: LeAudioOffloadAudioProvider() {
session_type_ = SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
@@ -70,8 +137,8 @@
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
- return BluetoothAudioProvider::startSession(
- host_if, audio_config, latency_modes, _aidl_return);
+ return BluetoothAudioProvider::startSession(host_if, audio_config,
+ latency_modes, _aidl_return);
}
ndk::ScopedAStatus LeAudioOffloadAudioProvider::onSessionReady(
@@ -81,6 +148,647 @@
*_aidl_return = DataMQDesc();
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus LeAudioOffloadAudioProvider::setCodecPriority(
+ const CodecId& in_codecId, int32_t in_priority) {
+ codec_priority_map_[in_codecId] = in_priority;
+ return ndk::ScopedAStatus::ok();
+};
+
+bool LeAudioOffloadAudioProvider::isMatchedValidCodec(CodecId cfg_codec,
+ CodecId req_codec) {
+ auto priority = codec_priority_map_.find(cfg_codec);
+ if (priority != codec_priority_map_.end() &&
+ priority->second ==
+ LeAudioOffloadAudioProvider::CODEC_PRIORITY_DISABLED) {
+ return false;
+ }
+ return cfg_codec == req_codec;
+}
+
+bool LeAudioOffloadAudioProvider::isCapabilitiesMatchedContext(
+ AudioContext setting_context,
+ const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities) {
+ // If has no metadata, assume match
+ if (!capabilities.metadata.has_value()) return true;
+
+ for (auto metadata : capabilities.metadata.value()) {
+ if (!metadata.has_value()) continue;
+ if (metadata.value().getTag() == MetadataLtv::Tag::preferredAudioContexts) {
+ // Check all pref audio context to see if anything matched
+ auto& context = metadata.value()
+ .get<MetadataLtv::Tag::preferredAudioContexts>()
+ .values;
+ if (setting_context.bitmask & context.bitmask) return true;
+ }
+ }
+
+ return false;
+}
+
+bool LeAudioOffloadAudioProvider::isMatchedSamplingFreq(
+ CodecSpecificConfigurationLtv::SamplingFrequency& cfg_freq,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies&
+ capability_freq) {
+ for (auto [freq, bitmask] : freq_to_support_bitmask_map)
+ if (cfg_freq == freq) return (capability_freq.bitmask & bitmask);
+ return false;
+}
+
+bool LeAudioOffloadAudioProvider::isMatchedFrameDuration(
+ CodecSpecificConfigurationLtv::FrameDuration& cfg_fduration,
+ CodecSpecificCapabilitiesLtv::SupportedFrameDurations&
+ capability_fduration) {
+ for (auto [fduration, bitmask] : fduration_to_support_fduration_map)
+ if (cfg_fduration == fduration)
+ return (capability_fduration.bitmask & bitmask);
+ return false;
+}
+
+bool LeAudioOffloadAudioProvider::isMatchedAudioChannel(
+ CodecSpecificConfigurationLtv::AudioChannelAllocation&
+ /*cfg_channel*/,
+ CodecSpecificCapabilitiesLtv::SupportedAudioChannelCounts&
+ /*capability_channel*/) {
+ bool isMatched = true;
+ // TODO: how to match?
+ return isMatched;
+}
+
+bool LeAudioOffloadAudioProvider::isMatchedCodecFramesPerSDU(
+ CodecSpecificConfigurationLtv::CodecFrameBlocksPerSDU& cfg_frame_sdu,
+ CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU&
+ capability_frame_sdu) {
+ return cfg_frame_sdu.value <= capability_frame_sdu.value;
+}
+
+bool LeAudioOffloadAudioProvider::isMatchedOctetsPerCodecFrame(
+ CodecSpecificConfigurationLtv::OctetsPerCodecFrame& cfg_octets,
+ CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame&
+ capability_octets) {
+ return cfg_octets.value >= capability_octets.min &&
+ cfg_octets.value <= capability_octets.max;
+}
+
+bool LeAudioOffloadAudioProvider::isCapabilitiesMatchedCodecConfiguration(
+ std::vector<CodecSpecificConfigurationLtv>& codec_cfg,
+ std::vector<CodecSpecificCapabilitiesLtv> codec_capabilities) {
+ // Convert all codec_cfg into a map of tags -> correct data
+ std::map<CodecSpecificConfigurationLtv::Tag, CodecSpecificConfigurationLtv>
+ cfg_tag_map;
+ for (auto codec_cfg_data : codec_cfg)
+ cfg_tag_map[codec_cfg_data.getTag()] = codec_cfg_data;
+
+ for (auto& codec_capability : codec_capabilities) {
+ auto cfg = cfg_tag_map.find(cap_to_cfg_tag_map[codec_capability.getTag()]);
+ // Cannot find tag for the capability:
+ if (cfg == cfg_tag_map.end()) return false;
+
+ // Matching logic for sampling frequency
+ if (codec_capability.getTag() ==
+ CodecSpecificCapabilitiesLtv::Tag::supportedSamplingFrequencies) {
+ if (!isMatchedSamplingFreq(
+ cfg->second
+ .get<CodecSpecificConfigurationLtv::Tag::samplingFrequency>(),
+ codec_capability.get<CodecSpecificCapabilitiesLtv::Tag::
+ supportedSamplingFrequencies>()))
+ return false;
+ } else if (codec_capability.getTag() ==
+ CodecSpecificCapabilitiesLtv::Tag::supportedFrameDurations) {
+ if (!isMatchedFrameDuration(
+ cfg->second
+ .get<CodecSpecificConfigurationLtv::Tag::frameDuration>(),
+ codec_capability.get<CodecSpecificCapabilitiesLtv::Tag::
+ supportedFrameDurations>()))
+ return false;
+ } else if (codec_capability.getTag() ==
+ CodecSpecificCapabilitiesLtv::Tag::supportedAudioChannelCounts) {
+ if (!isMatchedAudioChannel(
+ cfg->second.get<
+ CodecSpecificConfigurationLtv::Tag::audioChannelAllocation>(),
+ codec_capability.get<CodecSpecificCapabilitiesLtv::Tag::
+ supportedAudioChannelCounts>()))
+ return false;
+ } else if (codec_capability.getTag() == CodecSpecificCapabilitiesLtv::Tag::
+ supportedMaxCodecFramesPerSDU) {
+ if (!isMatchedCodecFramesPerSDU(
+ cfg->second.get<
+ CodecSpecificConfigurationLtv::Tag::codecFrameBlocksPerSDU>(),
+ codec_capability.get<CodecSpecificCapabilitiesLtv::Tag::
+ supportedMaxCodecFramesPerSDU>()))
+ return false;
+ } else if (codec_capability.getTag() == CodecSpecificCapabilitiesLtv::Tag::
+ supportedOctetsPerCodecFrame) {
+ if (!isMatchedOctetsPerCodecFrame(
+ cfg->second.get<
+ CodecSpecificConfigurationLtv::Tag::octetsPerCodecFrame>(),
+ codec_capability.get<CodecSpecificCapabilitiesLtv::Tag::
+ supportedOctetsPerCodecFrame>()))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool LeAudioOffloadAudioProvider::isMatchedAseConfiguration(
+ LeAudioAseConfiguration setting_cfg,
+ LeAudioAseConfiguration requirement_cfg) {
+ // Check matching for codec configuration <=> requirement ASE codec
+ // Also match if no CodecId requirement
+ if (requirement_cfg.codecId.has_value()) {
+ if (!setting_cfg.codecId.has_value()) return false;
+ if (!isMatchedValidCodec(setting_cfg.codecId.value(),
+ requirement_cfg.codecId.value()))
+ return false;
+ }
+
+ if (setting_cfg.targetLatency != requirement_cfg.targetLatency) return false;
+ // Ignore PHY requirement
+
+ // Check all codec configuration
+ std::map<CodecSpecificConfigurationLtv::Tag, CodecSpecificConfigurationLtv>
+ cfg_tag_map;
+ for (auto cfg : setting_cfg.codecConfiguration)
+ cfg_tag_map[cfg.getTag()] = cfg;
+
+ for (auto requirement_cfg : requirement_cfg.codecConfiguration) {
+ // Directly compare CodecSpecificConfigurationLtv
+ auto cfg = cfg_tag_map.find(requirement_cfg.getTag());
+ if (cfg == cfg_tag_map.end()) return false;
+
+ if (cfg->second != requirement_cfg) return false;
+ }
+ // Ignore vendor configuration and metadata requirement
+
+ return true;
+}
+
+bool LeAudioOffloadAudioProvider::isMatchedBISConfiguration(
+ LeAudioBisConfiguration bis_cfg,
+ const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities) {
+ if (!isMatchedValidCodec(bis_cfg.codecId, capabilities.codecId)) return false;
+ if (!isCapabilitiesMatchedCodecConfiguration(
+ bis_cfg.codecConfiguration, capabilities.codecSpecificCapabilities))
+ return false;
+ return true;
+}
+
+void LeAudioOffloadAudioProvider::filterCapabilitiesAseDirectionConfiguration(
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ direction_configurations,
+ const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities,
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ valid_direction_configurations) {
+ for (auto direction_configuration : direction_configurations) {
+ if (!direction_configuration.has_value()) continue;
+ if (!direction_configuration.value().aseConfiguration.codecId.has_value())
+ continue;
+ if (!isMatchedValidCodec(
+ direction_configuration.value().aseConfiguration.codecId.value(),
+ capabilities.codecId))
+ continue;
+ // Check matching for codec configuration <=> codec capabilities
+ if (!isCapabilitiesMatchedCodecConfiguration(
+ direction_configuration.value().aseConfiguration.codecConfiguration,
+ capabilities.codecSpecificCapabilities))
+ continue;
+ valid_direction_configurations.push_back(direction_configuration);
+ }
+}
+
+void LeAudioOffloadAudioProvider::filterRequirementAseDirectionConfiguration(
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ direction_configurations,
+ const std::optional<std::vector<std::optional<AseDirectionRequirement>>>&
+ requirements,
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ valid_direction_configurations) {
+ for (auto direction_configuration : direction_configurations) {
+ if (!requirements.has_value()) {
+ // If there's no requirement, all are valid
+ valid_direction_configurations.push_back(direction_configuration);
+ continue;
+ }
+ if (!direction_configuration.has_value()) continue;
+
+ for (auto& requirement : requirements.value()) {
+ if (!requirement.has_value()) continue;
+ if (!isMatchedAseConfiguration(
+ direction_configuration.value().aseConfiguration,
+ requirement.value().aseConfiguration))
+ continue;
+ // Valid if match any requirement.
+ valid_direction_configurations.push_back(direction_configuration);
+ break;
+ }
+ }
+}
+
+/* Get a new LeAudioAseConfigurationSetting by matching a setting with a
+ * capabilities. The new setting will have a filtered list of
+ * AseDirectionConfiguration that matched the capabilities */
+std::optional<LeAudioAseConfigurationSetting>
+LeAudioOffloadAudioProvider::getCapabilitiesMatchedAseConfigurationSettings(
+ IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting,
+ const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities,
+ uint8_t direction) {
+ // Try to match context in metadata.
+ if (!isCapabilitiesMatchedContext(setting.audioContext, capabilities))
+ return std::nullopt;
+
+ // Get a list of all matched AseDirectionConfiguration
+ // for the input direction
+ std::vector<std::optional<AseDirectionConfiguration>>*
+ direction_configuration = nullptr;
+ if (direction == kLeAudioDirectionSink) {
+ if (!setting.sinkAseConfiguration.has_value()) return std::nullopt;
+ direction_configuration = &setting.sinkAseConfiguration.value();
+ } else {
+ if (!setting.sourceAseConfiguration.has_value()) return std::nullopt;
+ direction_configuration = &setting.sourceAseConfiguration.value();
+ }
+ std::vector<std::optional<AseDirectionConfiguration>>
+ valid_direction_configuration;
+ filterCapabilitiesAseDirectionConfiguration(
+ *direction_configuration, capabilities, valid_direction_configuration);
+ if (valid_direction_configuration.empty()) return std::nullopt;
+
+ // Create a new LeAudioAseConfigurationSetting and return
+ LeAudioAseConfigurationSetting filtered_setting;
+ filtered_setting.audioContext = setting.audioContext;
+ filtered_setting.packing = setting.packing;
+ if (direction == kLeAudioDirectionSink) {
+ filtered_setting.sinkAseConfiguration = valid_direction_configuration;
+ } else {
+ filtered_setting.sourceAseConfiguration = valid_direction_configuration;
+ }
+ filtered_setting.flags = setting.flags;
+
+ return filtered_setting;
+}
+
+/* Get a new LeAudioAseConfigurationSetting by matching a setting with a
+ * requirement. The new setting will have a filtered list of
+ * AseDirectionConfiguration that matched the requirement */
+std::optional<LeAudioAseConfigurationSetting>
+LeAudioOffloadAudioProvider::getRequirementMatchedAseConfigurationSettings(
+ IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting,
+ const IBluetoothAudioProvider::LeAudioConfigurationRequirement&
+ requirement) {
+ // Try to match context in metadata.
+ if (setting.audioContext != requirement.audioContext) return std::nullopt;
+
+ // Check requirement for the correct direction
+ const std::optional<std::vector<std::optional<AseDirectionRequirement>>>*
+ direction_requirement;
+ std::vector<std::optional<AseDirectionConfiguration>>*
+ direction_configuration;
+ if (setting.sinkAseConfiguration.has_value()) {
+ direction_configuration = &setting.sinkAseConfiguration.value();
+ direction_requirement = &requirement.sinkAseRequirement;
+ } else {
+ direction_configuration = &setting.sourceAseConfiguration.value();
+ direction_requirement = &requirement.sourceAseRequirement;
+ }
+
+ std::vector<std::optional<AseDirectionConfiguration>>
+ valid_direction_configuration;
+ filterRequirementAseDirectionConfiguration(*direction_configuration,
+ *direction_requirement,
+ valid_direction_configuration);
+ if (valid_direction_configuration.empty()) return std::nullopt;
+
+ // Create a new LeAudioAseConfigurationSetting and return
+ LeAudioAseConfigurationSetting filtered_setting;
+ filtered_setting.audioContext = setting.audioContext;
+ filtered_setting.packing = setting.packing;
+ if (setting.sinkAseConfiguration.has_value())
+ filtered_setting.sinkAseConfiguration = valid_direction_configuration;
+ else
+ filtered_setting.sourceAseConfiguration = valid_direction_configuration;
+ filtered_setting.flags = setting.flags;
+
+ return filtered_setting;
+}
+
+ndk::ScopedAStatus LeAudioOffloadAudioProvider::getLeAudioAseConfiguration(
+ const std::optional<std::vector<
+ std::optional<IBluetoothAudioProvider::LeAudioDeviceCapabilities>>>&
+ in_remoteSinkAudioCapabilities,
+ const std::optional<std::vector<
+ std::optional<IBluetoothAudioProvider::LeAudioDeviceCapabilities>>>&
+ in_remoteSourceAudioCapabilities,
+ const std::vector<IBluetoothAudioProvider::LeAudioConfigurationRequirement>&
+ in_requirements,
+ std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>*
+ _aidl_return) {
+ // Get all configuration settings
+ std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+ ase_configuration_settings =
+ BluetoothAudioCodecs::GetLeAudioAseConfigurationSettings();
+
+ // Currently won't handle case where both sink and source capabilities
+ // are passed in. Only handle one of them.
+ const std::optional<std::vector<
+ std::optional<IBluetoothAudioProvider::LeAudioDeviceCapabilities>>>*
+ in_remoteAudioCapabilities;
+ uint8_t direction = 0;
+ if (in_remoteSinkAudioCapabilities.has_value()) {
+ direction = kLeAudioDirectionSink;
+ in_remoteAudioCapabilities = &in_remoteSinkAudioCapabilities;
+ } else {
+ direction = kLeAudioDirectionSource;
+ in_remoteAudioCapabilities = &in_remoteSourceAudioCapabilities;
+ }
+
+ std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+ capability_matched_ase_configuration_settings;
+ // Matching with remote capabilities
+ for (auto& setting : ase_configuration_settings) {
+ for (auto& capability : in_remoteAudioCapabilities->value()) {
+ if (!capability.has_value()) continue;
+ auto filtered_ase_configuration_setting =
+ getCapabilitiesMatchedAseConfigurationSettings(
+ setting, capability.value(), direction);
+ if (filtered_ase_configuration_setting.has_value()) {
+ capability_matched_ase_configuration_settings.push_back(
+ filtered_ase_configuration_setting.value());
+ }
+ }
+ }
+
+ // Matching with requirements
+ std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting> result;
+ for (auto& setting : capability_matched_ase_configuration_settings) {
+ for (auto& requirement : in_requirements) {
+ auto filtered_ase_configuration_setting =
+ getRequirementMatchedAseConfigurationSettings(setting, requirement);
+ if (filtered_ase_configuration_setting.has_value()) {
+ result.push_back(filtered_ase_configuration_setting.value());
+ }
+ }
+ }
+
+ *_aidl_return = result;
+ return ndk::ScopedAStatus::ok();
+};
+
+bool LeAudioOffloadAudioProvider::isMatchedQosRequirement(
+ LeAudioAseQosConfiguration setting_qos,
+ AseQosDirectionRequirement requirement_qos) {
+ if (setting_qos.retransmissionNum !=
+ requirement_qos.preferredRetransmissionNum)
+ return false;
+ if (setting_qos.maxTransportLatencyMs > requirement_qos.maxTransportLatencyMs)
+ return false;
+ // Ignore other parameters, as they are not populated in the setting_qos
+ return true;
+}
+
+ndk::ScopedAStatus LeAudioOffloadAudioProvider::getLeAudioAseQosConfiguration(
+ const IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement&
+ in_qosRequirement,
+ IBluetoothAudioProvider::LeAudioAseQosConfigurationPair* _aidl_return) {
+ IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
+ // Get all configuration settings
+ std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+ ase_configuration_settings =
+ BluetoothAudioCodecs::GetLeAudioAseConfigurationSettings();
+
+ // Direction QoS matching
+ // Only handle one direction input case
+ uint8_t direction = 0;
+ std::optional<AseQosDirectionRequirement> direction_qos_requirement =
+ std::nullopt;
+ if (in_qosRequirement.sinkAseQosRequirement.has_value()) {
+ direction_qos_requirement = in_qosRequirement.sinkAseQosRequirement.value();
+ direction = kLeAudioDirectionSink;
+ } else if (in_qosRequirement.sourceAseQosRequirement.has_value()) {
+ direction_qos_requirement =
+ in_qosRequirement.sourceAseQosRequirement.value();
+ direction = kLeAudioDirectionSource;
+ }
+
+ for (auto& setting : ase_configuration_settings) {
+ // Context matching
+ if (setting.audioContext != in_qosRequirement.audioContext) continue;
+
+ // Match configuration flags
+ // Currently configuration flags are not populated, ignore.
+
+ // Get a list of all matched AseDirectionConfiguration
+ // for the input direction
+ std::vector<std::optional<AseDirectionConfiguration>>*
+ direction_configuration = nullptr;
+ if (direction == kLeAudioDirectionSink) {
+ if (!setting.sinkAseConfiguration.has_value()) continue;
+ direction_configuration = &setting.sinkAseConfiguration.value();
+ } else {
+ if (!setting.sourceAseConfiguration.has_value()) continue;
+ direction_configuration = &setting.sourceAseConfiguration.value();
+ }
+
+ for (auto cfg : *direction_configuration) {
+ if (!cfg.has_value()) continue;
+ // If no requirement, return the first QoS
+ if (!direction_qos_requirement.has_value()) {
+ result.sinkQosConfiguration = cfg.value().qosConfiguration;
+ result.sourceQosConfiguration = cfg.value().qosConfiguration;
+ *_aidl_return = result;
+ return ndk::ScopedAStatus::ok();
+ }
+
+ // If has requirement, return the first matched QoS
+ // Try to match the ASE configuration
+ // and QoS with requirement
+ if (!cfg.value().qosConfiguration.has_value()) continue;
+ if (isMatchedAseConfiguration(
+ cfg.value().aseConfiguration,
+ direction_qos_requirement.value().aseConfiguration) &&
+ isMatchedQosRequirement(cfg.value().qosConfiguration.value(),
+ direction_qos_requirement.value())) {
+ if (direction == kLeAudioDirectionSink)
+ result.sinkQosConfiguration = cfg.value().qosConfiguration;
+ else
+ result.sourceQosConfiguration = cfg.value().qosConfiguration;
+ *_aidl_return = result;
+ return ndk::ScopedAStatus::ok();
+ }
+ }
+ }
+
+ // No match, return empty QoS
+ *_aidl_return = result;
+ return ndk::ScopedAStatus::ok();
+};
+
+ndk::ScopedAStatus LeAudioOffloadAudioProvider::onSinkAseMetadataChanged(
+ IBluetoothAudioProvider::AseState in_state, int32_t /*in_cigId*/,
+ int32_t /*in_cisId*/,
+ const std::optional<std::vector<std::optional<MetadataLtv>>>& in_metadata) {
+ (void)in_state;
+ (void)in_metadata;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+};
+
+ndk::ScopedAStatus LeAudioOffloadAudioProvider::onSourceAseMetadataChanged(
+ IBluetoothAudioProvider::AseState in_state, int32_t /*in_cigId*/,
+ int32_t /*in_cisId*/,
+ const std::optional<std::vector<std::optional<MetadataLtv>>>& in_metadata) {
+ (void)in_state;
+ (void)in_metadata;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+};
+
+void LeAudioOffloadAudioProvider::getBroadcastSettings() {
+ if (!broadcast_settings.empty()) return;
+
+ LOG(INFO) << __func__ << ": Loading broadcast settings from provider info";
+
+ std::vector<CodecInfo> db_codec_info =
+ BluetoothAudioCodecs::GetLeAudioOffloadCodecInfo(
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+ broadcast_settings.clear();
+ CodecSpecificConfigurationLtv::AudioChannelAllocation default_allocation;
+ default_allocation.bitmask =
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_CENTER;
+
+ for (auto& codec_info : db_codec_info) {
+ if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
+ continue;
+ auto& transport = codec_info.transport.get<CodecInfo::Transport::leAudio>();
+ LeAudioBroadcastConfigurationSetting setting;
+ // Default setting
+ setting.numBis = 1;
+ setting.phy = {Phy::TWO_M};
+ // Populate BIS configuration info using codec_info
+ LeAudioBisConfiguration bis_cfg;
+ bis_cfg.codecId = codec_info.id;
+
+ CodecSpecificConfigurationLtv::OctetsPerCodecFrame octets;
+ octets.value = transport.bitdepth[0];
+
+ bis_cfg.codecConfiguration = {
+ sampling_freq_map[transport.samplingFrequencyHz[0]], octets,
+ frame_duration_map[transport.frameDurationUs[0]], default_allocation};
+
+ // Add information to structure
+ IBluetoothAudioProvider::LeAudioSubgroupBisConfiguration sub_bis_cfg;
+ sub_bis_cfg.numBis = 1;
+ sub_bis_cfg.bisConfiguration = bis_cfg;
+ IBluetoothAudioProvider::LeAudioBroadcastSubgroupConfiguration sub_cfg;
+ sub_cfg.bisConfigurations = {sub_bis_cfg};
+ setting.subgroupsConfigurations = {sub_cfg};
+
+ broadcast_settings.push_back(setting);
+ }
+
+ LOG(INFO) << __func__
+ << ": Done loading broadcast settings from provider info";
+}
+
+/* Get a new LeAudioAseConfigurationSetting by matching a setting with a
+ * capabilities. The new setting will have a filtered list of
+ * AseDirectionConfiguration that matched the capabilities */
+std::optional<LeAudioBroadcastConfigurationSetting>
+LeAudioOffloadAudioProvider::
+ getCapabilitiesMatchedBroadcastConfigurationSettings(
+ LeAudioBroadcastConfigurationSetting& setting,
+ const IBluetoothAudioProvider::LeAudioDeviceCapabilities&
+ capabilities) {
+ std::vector<IBluetoothAudioProvider::LeAudioBroadcastSubgroupConfiguration>
+ filter_subgroup;
+ for (auto& sub_cfg : setting.subgroupsConfigurations) {
+ std::vector<IBluetoothAudioProvider::LeAudioSubgroupBisConfiguration>
+ filtered_bis_cfg;
+ for (auto& bis_cfg : sub_cfg.bisConfigurations)
+ if (isMatchedBISConfiguration(bis_cfg.bisConfiguration, capabilities)) {
+ filtered_bis_cfg.push_back(bis_cfg);
+ }
+ if (!filtered_bis_cfg.empty()) {
+ IBluetoothAudioProvider::LeAudioBroadcastSubgroupConfiguration
+ subgroup_cfg;
+ subgroup_cfg.bisConfigurations = filtered_bis_cfg;
+ filter_subgroup.push_back(subgroup_cfg);
+ }
+ }
+ if (filter_subgroup.empty()) return std::nullopt;
+
+ // Create a new LeAudioAseConfigurationSetting and return
+ LeAudioBroadcastConfigurationSetting filtered_setting(setting);
+ filtered_setting.subgroupsConfigurations = filter_subgroup;
+
+ return filtered_setting;
+}
+
+ndk::ScopedAStatus
+LeAudioOffloadAudioProvider::getLeAudioBroadcastConfiguration(
+ const std::optional<std::vector<
+ std::optional<IBluetoothAudioProvider::LeAudioDeviceCapabilities>>>&
+ in_remoteSinkAudioCapabilities,
+ const IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement&
+ in_requirement,
+ LeAudioBroadcastConfigurationSetting* _aidl_return) {
+ getBroadcastSettings();
+ _aidl_return = nullptr;
+
+ // Match and filter capability
+ std::vector<LeAudioBroadcastConfigurationSetting> filtered_settings;
+ if (!in_remoteSinkAudioCapabilities.has_value()) {
+ LOG(WARNING) << __func__ << ": Empty capability";
+ return ndk::ScopedAStatus::ok();
+ }
+ for (auto& setting : broadcast_settings) {
+ for (auto& capability : in_remoteSinkAudioCapabilities.value()) {
+ if (!capability.has_value()) continue;
+ auto filtered_setting =
+ getCapabilitiesMatchedBroadcastConfigurationSettings(
+ setting, capability.value());
+ if (filtered_setting.has_value())
+ filtered_settings.push_back(filtered_setting.value());
+ }
+ }
+
+ if (filtered_settings.empty()) {
+ LOG(WARNING) << __func__ << ": Cannot match any remote capability";
+ return ndk::ScopedAStatus::ok();
+ }
+
+ // Match and return the first matched requirement
+ if (in_requirement.subgroupConfigurationRequirements.empty()) {
+ LOG(INFO) << __func__ << ": Empty requirement";
+ *_aidl_return = filtered_settings[0];
+ return ndk::ScopedAStatus::ok();
+ }
+
+ for (auto& setting : filtered_settings) {
+ // Further filter out bis configuration
+ LeAudioBroadcastConfigurationSetting filtered_setting(setting);
+ filtered_setting.subgroupsConfigurations.clear();
+ for (auto& sub_cfg : setting.subgroupsConfigurations) {
+ bool isMatched = false;
+ for (auto& sub_req : in_requirement.subgroupConfigurationRequirements) {
+ // Matching number of BIS
+ if (sub_req.bisNumPerSubgroup != sub_cfg.bisConfigurations.size())
+ continue;
+ // Currently will ignore quality and context hint.
+ isMatched = true;
+ break;
+ }
+ if (isMatched)
+ filtered_setting.subgroupsConfigurations.push_back(sub_cfg);
+ }
+ // Return the first match
+ if (!filtered_setting.subgroupsConfigurations.empty()) {
+ LOG(INFO) << __func__ << ": Matched requirement";
+ *_aidl_return = filtered_setting;
+ return ndk::ScopedAStatus::ok();
+ }
+ }
+
+ LOG(WARNING) << __func__ << ": Cannot match any requirement";
+ return ndk::ScopedAStatus::ok();
+};
} // namespace audio
} // namespace bluetooth
diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
index 614c794..2785e7f 100644
--- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
+++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
@@ -16,7 +16,12 @@
#pragma once
+#include <map>
+
#include "BluetoothAudioProvider.h"
+#include "aidl/android/hardware/bluetooth/audio/LeAudioAseConfiguration.h"
+#include "aidl/android/hardware/bluetooth/audio/MetadataLtv.h"
+#include "aidl/android/hardware/bluetooth/audio/SessionType.h"
namespace aidl {
namespace android {
@@ -24,6 +29,19 @@
namespace bluetooth {
namespace audio {
+using LeAudioAseConfigurationSetting =
+ IBluetoothAudioProvider::LeAudioAseConfigurationSetting;
+using AseDirectionRequirement = IBluetoothAudioProvider::
+ LeAudioConfigurationRequirement::AseDirectionRequirement;
+using AseDirectionConfiguration = IBluetoothAudioProvider::
+ LeAudioAseConfigurationSetting::AseDirectionConfiguration;
+using AseQosDirectionRequirement = IBluetoothAudioProvider::
+ LeAudioAseQosConfigurationRequirement::AseQosDirectionRequirement;
+using LeAudioAseQosConfiguration =
+ IBluetoothAudioProvider::LeAudioAseQosConfiguration;
+using LeAudioBroadcastConfigurationSetting =
+ IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting;
+
class LeAudioOffloadAudioProvider : public BluetoothAudioProvider {
public:
LeAudioOffloadAudioProvider();
@@ -33,11 +51,112 @@
ndk::ScopedAStatus startSession(
const std::shared_ptr<IBluetoothAudioPort>& host_if,
const AudioConfiguration& audio_config,
- const std::vector<LatencyMode>& latency_modes,
- DataMQDesc* _aidl_return);
+ const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return);
+ ndk::ScopedAStatus setCodecPriority(const CodecId& in_codecId,
+ int32_t in_priority) override;
+ ndk::ScopedAStatus getLeAudioAseConfiguration(
+ const std::optional<std::vector<
+ std::optional<IBluetoothAudioProvider::LeAudioDeviceCapabilities>>>&
+ in_remoteSinkAudioCapabilities,
+ const std::optional<std::vector<
+ std::optional<IBluetoothAudioProvider::LeAudioDeviceCapabilities>>>&
+ in_remoteSourceAudioCapabilities,
+ const std::vector<
+ IBluetoothAudioProvider::LeAudioConfigurationRequirement>&
+ in_requirements,
+ std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>*
+ _aidl_return) override;
+ ndk::ScopedAStatus getLeAudioAseQosConfiguration(
+ const IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement&
+ in_qosRequirement,
+ IBluetoothAudioProvider::LeAudioAseQosConfigurationPair* _aidl_return)
+ override;
+ ndk::ScopedAStatus onSourceAseMetadataChanged(
+ IBluetoothAudioProvider::AseState in_state, int32_t in_cigId,
+ int32_t in_cisId,
+ const std::optional<std::vector<std::optional<MetadataLtv>>>& in_metadata)
+ override;
+ ndk::ScopedAStatus onSinkAseMetadataChanged(
+ IBluetoothAudioProvider::AseState in_state, int32_t in_cigId,
+ int32_t in_cisId,
+ const std::optional<std::vector<std::optional<MetadataLtv>>>& in_metadata)
+ override;
+ ndk::ScopedAStatus getLeAudioBroadcastConfiguration(
+ const std::optional<std::vector<
+ std::optional<IBluetoothAudioProvider::LeAudioDeviceCapabilities>>>&
+ in_remoteSinkAudioCapabilities,
+ const IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement&
+ in_requirement,
+ LeAudioBroadcastConfigurationSetting* _aidl_return) override;
private:
ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override;
+ std::map<CodecId, uint32_t> codec_priority_map_;
+ std::vector<LeAudioBroadcastConfigurationSetting> broadcast_settings;
+
+ // Private matching function definitions
+ bool isMatchedValidCodec(CodecId cfg_codec, CodecId req_codec);
+ bool isCapabilitiesMatchedContext(
+ AudioContext setting_context,
+ const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities);
+ bool isMatchedSamplingFreq(
+ CodecSpecificConfigurationLtv::SamplingFrequency& cfg_freq,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies&
+ capability_freq);
+ bool isMatchedFrameDuration(
+ CodecSpecificConfigurationLtv::FrameDuration& cfg_fduration,
+ CodecSpecificCapabilitiesLtv::SupportedFrameDurations&
+ capability_fduration);
+ bool isMatchedAudioChannel(
+ CodecSpecificConfigurationLtv::AudioChannelAllocation& cfg_channel,
+ CodecSpecificCapabilitiesLtv::SupportedAudioChannelCounts&
+ capability_channel);
+ bool isMatchedCodecFramesPerSDU(
+ CodecSpecificConfigurationLtv::CodecFrameBlocksPerSDU& cfg_frame_sdu,
+ CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU&
+ capability_frame_sdu);
+ bool isMatchedOctetsPerCodecFrame(
+ CodecSpecificConfigurationLtv::OctetsPerCodecFrame& cfg_octets,
+ CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame&
+ capability_octets);
+ bool isCapabilitiesMatchedCodecConfiguration(
+ std::vector<CodecSpecificConfigurationLtv>& codec_cfg,
+ std::vector<CodecSpecificCapabilitiesLtv> codec_capabilities);
+ bool isMatchedAseConfiguration(LeAudioAseConfiguration setting_cfg,
+ LeAudioAseConfiguration requirement_cfg);
+ bool isMatchedBISConfiguration(
+ LeAudioBisConfiguration bis_cfg,
+ const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities);
+ void filterCapabilitiesAseDirectionConfiguration(
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ direction_configurations,
+ const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities,
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ valid_direction_configurations);
+ void filterRequirementAseDirectionConfiguration(
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ direction_configurations,
+ const std::optional<std::vector<std::optional<AseDirectionRequirement>>>&
+ requirements,
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ valid_direction_configurations);
+ std::optional<LeAudioAseConfigurationSetting>
+ getCapabilitiesMatchedAseConfigurationSettings(
+ IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting,
+ const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities,
+ uint8_t direction);
+ std::optional<LeAudioAseConfigurationSetting>
+ getRequirementMatchedAseConfigurationSettings(
+ IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting,
+ const IBluetoothAudioProvider::LeAudioConfigurationRequirement&
+ requirement);
+ bool isMatchedQosRequirement(LeAudioAseQosConfiguration setting_qos,
+ AseQosDirectionRequirement requirement_qos);
+ std::optional<LeAudioBroadcastConfigurationSetting>
+ getCapabilitiesMatchedBroadcastConfigurationSettings(
+ LeAudioBroadcastConfigurationSetting& setting,
+ const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities);
+ void getBroadcastSettings();
};
class LeAudioOffloadOutputAudioProvider : public LeAudioOffloadAudioProvider {
diff --git a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
index 858fa38..789e8a1 100644
--- a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
+++ b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
@@ -33,6 +33,11 @@
using aidl::android::hardware::audio::common::SinkMetadata;
using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::hardware::bluetooth::audio::A2dpConfiguration;
+using aidl::android::hardware::bluetooth::audio::A2dpConfigurationHint;
+using aidl::android::hardware::bluetooth::audio::A2dpRemoteCapabilities;
+using aidl::android::hardware::bluetooth::audio::A2dpStatus;
+using aidl::android::hardware::bluetooth::audio::A2dpStreamConfiguration;
using aidl::android::hardware::bluetooth::audio::AacCapabilities;
using aidl::android::hardware::bluetooth::audio::AacConfiguration;
using aidl::android::hardware::bluetooth::audio::AptxAdaptiveLeCapabilities;
@@ -41,12 +46,19 @@
using aidl::android::hardware::bluetooth::audio::AptxConfiguration;
using aidl::android::hardware::bluetooth::audio::AudioCapabilities;
using aidl::android::hardware::bluetooth::audio::AudioConfiguration;
+using aidl::android::hardware::bluetooth::audio::AudioContext;
using aidl::android::hardware::bluetooth::audio::BnBluetoothAudioPort;
using aidl::android::hardware::bluetooth::audio::BroadcastCapability;
using aidl::android::hardware::bluetooth::audio::ChannelMode;
using aidl::android::hardware::bluetooth::audio::CodecCapabilities;
using aidl::android::hardware::bluetooth::audio::CodecConfiguration;
+using aidl::android::hardware::bluetooth::audio::CodecId;
+using aidl::android::hardware::bluetooth::audio::CodecInfo;
+using aidl::android::hardware::bluetooth::audio::CodecParameters;
+using aidl::android::hardware::bluetooth::audio::CodecSpecificCapabilitiesLtv;
+using aidl::android::hardware::bluetooth::audio::CodecSpecificConfigurationLtv;
using aidl::android::hardware::bluetooth::audio::CodecType;
+using aidl::android::hardware::bluetooth::audio::HfpConfiguration;
using aidl::android::hardware::bluetooth::audio::IBluetoothAudioPort;
using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider;
using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProviderFactory;
@@ -55,11 +67,13 @@
using aidl::android::hardware::bluetooth::audio::Lc3Configuration;
using aidl::android::hardware::bluetooth::audio::LdacCapabilities;
using aidl::android::hardware::bluetooth::audio::LdacConfiguration;
+using aidl::android::hardware::bluetooth::audio::LeAudioAseConfiguration;
using aidl::android::hardware::bluetooth::audio::LeAudioBroadcastConfiguration;
using aidl::android::hardware::bluetooth::audio::
LeAudioCodecCapabilitiesSetting;
using aidl::android::hardware::bluetooth::audio::LeAudioCodecConfiguration;
using aidl::android::hardware::bluetooth::audio::LeAudioConfiguration;
+using aidl::android::hardware::bluetooth::audio::MetadataLtv;
using aidl::android::hardware::bluetooth::audio::OpusCapabilities;
using aidl::android::hardware::bluetooth::audio::OpusConfiguration;
using aidl::android::hardware::bluetooth::audio::PcmConfiguration;
@@ -83,6 +97,21 @@
using DataMQ = AidlMessageQueue<MqDataType, MqDataMode>;
using DataMQDesc = MQDescriptor<MqDataType, MqDataMode>;
+using LeAudioAseConfigurationSetting =
+ IBluetoothAudioProvider::LeAudioAseConfigurationSetting;
+using AseDirectionRequirement = IBluetoothAudioProvider::
+ LeAudioConfigurationRequirement::AseDirectionRequirement;
+using AseDirectionConfiguration = IBluetoothAudioProvider::
+ LeAudioAseConfigurationSetting::AseDirectionConfiguration;
+using AseQosDirectionRequirement = IBluetoothAudioProvider::
+ LeAudioAseQosConfigurationRequirement::AseQosDirectionRequirement;
+using LeAudioAseQosConfiguration =
+ IBluetoothAudioProvider::LeAudioAseQosConfiguration;
+using LeAudioDeviceCapabilities =
+ IBluetoothAudioProvider::LeAudioDeviceCapabilities;
+using LeAudioConfigurationRequirement =
+ IBluetoothAudioProvider::LeAudioConfigurationRequirement;
+
// Constants
static constexpr int32_t a2dp_sample_rates[] = {0, 44100, 48000, 88200, 96000};
@@ -90,6 +119,23 @@
static constexpr ChannelMode a2dp_channel_modes[] = {
ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
static std::vector<LatencyMode> latency_modes = {LatencyMode::FREE};
+
+enum class BluetoothAudioHalVersion : int32_t {
+ VERSION_UNAVAILABLE = 0,
+ VERSION_2_0,
+ VERSION_2_1,
+ VERSION_AIDL_V1,
+ VERSION_AIDL_V2,
+ VERSION_AIDL_V3,
+ VERSION_AIDL_V4,
+};
+
+// Some valid configs for HFP PCM configuration (software sessions)
+static constexpr int32_t hfp_sample_rates_[] = {8000, 16000, 32000};
+static constexpr int8_t hfp_bits_per_samples_[] = {16};
+static constexpr ChannelMode hfp_channel_modes_[] = {ChannelMode::MONO};
+static constexpr int32_t hfp_data_interval_us_[] = {7500};
+
// Helpers
template <typename T>
@@ -181,6 +227,12 @@
virtual void TearDown() override { provider_factory_ = nullptr; }
+ void GetProviderInfoHelper(const SessionType& session_type) {
+ temp_provider_info_ = std::nullopt;
+ auto aidl_reval =
+ provider_factory_->getProviderInfo(session_type, &temp_provider_info_);
+ }
+
void GetProviderCapabilitiesHelper(const SessionType& session_type) {
temp_provider_capabilities_.clear();
auto aidl_retval = provider_factory_->getProviderCapabilities(
@@ -195,7 +247,8 @@
case SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
case SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH:
- case SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH: {
+ case SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH:
+ case SessionType::HFP_SOFTWARE_ENCODING_DATAPATH: {
// All software paths are mandatory and must have exact 1
// "PcmParameters"
ASSERT_EQ(temp_provider_capabilities_.size(), 1);
@@ -256,7 +309,8 @@
AudioCapabilities::leAudioCapabilities);
}
} break;
- case SessionType::A2DP_SOFTWARE_DECODING_DATAPATH: {
+ case SessionType::A2DP_SOFTWARE_DECODING_DATAPATH:
+ case SessionType::HFP_SOFTWARE_DECODING_DATAPATH: {
if (!temp_provider_capabilities_.empty()) {
ASSERT_EQ(temp_provider_capabilities_.size(), 1);
ASSERT_EQ(temp_provider_capabilities_[0].getTag(),
@@ -296,7 +350,10 @@
LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
session_type ==
SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
- session_type == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
+ session_type == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH ||
+ session_type == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH ||
+ session_type == SessionType::HFP_SOFTWARE_DECODING_DATAPATH ||
+ session_type == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
ASSERT_EQ(audio_provider_, nullptr);
}
}
@@ -555,6 +612,8 @@
std::shared_ptr<IBluetoothAudioProvider> audio_provider_;
std::shared_ptr<IBluetoothAudioPort> audio_port_;
std::vector<AudioCapabilities> temp_provider_capabilities_;
+ std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
+ temp_provider_info_;
// temp storage saves the specified codec capability by
// GetOffloadCodecCapabilityHelper()
@@ -574,6 +633,37 @@
SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
};
+
+ static constexpr SessionType kAndroidVSessionType[] = {
+ SessionType::HFP_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::HFP_SOFTWARE_DECODING_DATAPATH,
+ };
+
+ BluetoothAudioHalVersion GetProviderFactoryInterfaceVersion() {
+ int32_t aidl_version = 0;
+ if (provider_factory_ == nullptr) {
+ return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
+ }
+
+ auto aidl_retval = provider_factory_->getInterfaceVersion(&aidl_version);
+ if (!aidl_retval.isOk()) {
+ return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
+ }
+ switch (aidl_version) {
+ case 1:
+ return BluetoothAudioHalVersion::VERSION_AIDL_V1;
+ case 2:
+ return BluetoothAudioHalVersion::VERSION_AIDL_V2;
+ case 3:
+ return BluetoothAudioHalVersion::VERSION_AIDL_V3;
+ case 4:
+ return BluetoothAudioHalVersion::VERSION_AIDL_V4;
+ default:
+ return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
+ }
+
+ return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
+ }
};
/**
@@ -595,6 +685,802 @@
EXPECT_TRUE(temp_provider_capabilities_.empty() ||
audio_provider_ != nullptr);
}
+ if (GetProviderFactoryInterfaceVersion() >=
+ BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+ for (auto session_type : kAndroidVSessionType) {
+ GetProviderCapabilitiesHelper(session_type);
+ OpenProviderHelper(session_type);
+ EXPECT_TRUE(temp_provider_capabilities_.empty() ||
+ audio_provider_ != nullptr);
+ }
+ }
+}
+
+/**
+ * Test that getProviderInfo, when implemented,
+ * returns empty information for session types for
+ * software data paths.
+ */
+TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_invalidSessionTypes) {
+ static constexpr SessionType kInvalidSessionTypes[]{
+ SessionType::UNKNOWN,
+ SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
+ SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
+ };
+
+ for (auto session_type : kInvalidSessionTypes) {
+ std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
+ std::nullopt;
+ auto aidl_retval =
+ provider_factory_->getProviderInfo(session_type, &provider_info);
+ if (!aidl_retval.isOk()) {
+ continue;
+ }
+
+ // If getProviderInfo is supported, the provider info
+ // must be empty for software session types.
+ ASSERT_FALSE(provider_info.has_value());
+ }
+}
+
+/**
+ * Test that getProviderInfo, when implemented,
+ * returns valid information for session types for
+ * a2dp hardware data paths.
+ */
+TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_a2dpSessionTypes) {
+ static constexpr SessionType kA2dpSessionTypes[]{
+ SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ };
+
+ for (auto session_type : kA2dpSessionTypes) {
+ std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
+ std::nullopt;
+ auto aidl_retval =
+ provider_factory_->getProviderInfo(session_type, &provider_info);
+ if (!aidl_retval.isOk() || !provider_info.has_value()) {
+ continue;
+ }
+
+ for (auto const& codec_info : provider_info->codecInfos) {
+ // The codec id must not be core.
+ ASSERT_NE(codec_info.id.getTag(), CodecId::core);
+ // The codec info must contain the information
+ // for a2dp transport.
+ ASSERT_EQ(codec_info.transport.getTag(), CodecInfo::Transport::a2dp);
+ }
+ }
+}
+
+/**
+ * Test that getProviderInfo, when implemented,
+ * returns valid information for session types for
+ * le audio hardware data paths.
+ */
+TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_leAudioSessionTypes) {
+ static constexpr SessionType kLeAudioSessionTypes[]{
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ };
+
+ for (auto session_type : kLeAudioSessionTypes) {
+ std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
+ std::nullopt;
+ auto aidl_retval =
+ provider_factory_->getProviderInfo(session_type, &provider_info);
+ if (!aidl_retval.isOk() || !provider_info.has_value()) {
+ continue;
+ }
+
+ for (auto const& codec_info : provider_info->codecInfos) {
+ // The codec id must not be a2dp.
+ ASSERT_NE(codec_info.id.getTag(), CodecId::a2dp);
+ // The codec info must contain the information
+ // for le audio transport.
+ ASSERT_EQ(codec_info.transport.getTag(), CodecInfo::Transport::leAudio);
+ }
+ }
+}
+
+class BluetoothAudioProviderAidl : public BluetoothAudioProviderFactoryAidl {
+ protected:
+ std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
+ a2dp_encoding_provider_info_{};
+ std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
+ a2dp_decoding_provider_info_{};
+ std::shared_ptr<IBluetoothAudioProvider> a2dp_encoding_provider_{nullptr};
+ std::shared_ptr<IBluetoothAudioProvider> a2dp_decoding_provider_{nullptr};
+
+ public:
+ void SetUp() override {
+ BluetoothAudioProviderFactoryAidl::SetUp();
+ audio_port_ = ndk::SharedRefBase::make<BluetoothAudioPort>();
+
+ (void)provider_factory_->getProviderInfo(
+ SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ &a2dp_encoding_provider_info_);
+
+ (void)provider_factory_->getProviderInfo(
+ SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ &a2dp_decoding_provider_info_);
+
+ (void)provider_factory_->openProvider(
+ SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ &a2dp_encoding_provider_);
+
+ (void)provider_factory_->openProvider(
+ SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ &a2dp_decoding_provider_);
+ }
+};
+
+/**
+ * Calling parseA2dpConfiguration on a session of a different type than
+ * A2DP_HARDWARE_OFFLOAD_(ENCODING|DECODING)_DATAPATH must fail.
+ */
+TEST_P(BluetoothAudioProviderAidl, parseA2dpConfiguration_invalidSessionType) {
+ static constexpr SessionType kInvalidSessionTypes[] = {
+ SessionType::UNKNOWN,
+ SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
+ };
+
+ for (auto session_type : kInvalidSessionTypes) {
+ // Open a BluetoothAudioProvider instance of the selected session type.
+ // Skip validation if the provider cannot be opened.
+ std::shared_ptr<IBluetoothAudioProvider> provider{nullptr};
+ (void)provider_factory_->openProvider(session_type, &provider);
+ if (provider == nullptr) {
+ continue;
+ }
+
+ // parseA2dpConfiguration must fail without returning an A2dpStatus.
+ CodecId codec_id(CodecId::A2dp::SBC);
+ CodecParameters codec_parameters;
+ A2dpStatus a2dp_status = A2dpStatus::OK;
+ auto aidl_retval = provider->parseA2dpConfiguration(
+ codec_id, std::vector<uint8_t>{}, &codec_parameters, &a2dp_status);
+ EXPECT_FALSE(aidl_retval.isOk());
+ }
+}
+
+/**
+ * Calling parseA2dpConfiguration with an unknown codec must fail
+ * with the A2dpStatus code INVALID_CODEC_TYPE or NOT_SUPPORTED_CODEC_TYPE.
+ */
+TEST_P(BluetoothAudioProviderAidl,
+ parseA2dpConfiguration_unsupportedCodecType) {
+ CodecId unsupported_core_id(CodecId::Core::CVSD);
+ CodecId unsupported_vendor_id(
+ CodecId::Vendor(0xFCB1, 0x42)); // Google Codec #42
+
+ for (auto& provider : {a2dp_encoding_provider_, a2dp_decoding_provider_}) {
+ if (provider == nullptr) {
+ continue;
+ }
+
+ CodecParameters codec_parameters;
+ A2dpStatus a2dp_status = A2dpStatus::OK;
+ ::ndk::ScopedAStatus aidl_retval;
+
+ // Test with two invalid codec identifiers: vendor or core.
+ aidl_retval = provider->parseA2dpConfiguration(
+ unsupported_core_id, std::vector<uint8_t>{}, &codec_parameters,
+ &a2dp_status);
+ EXPECT_TRUE(!aidl_retval.isOk() ||
+ a2dp_status == A2dpStatus::NOT_SUPPORTED_CODEC_TYPE);
+
+ aidl_retval = provider->parseA2dpConfiguration(
+ unsupported_vendor_id, std::vector<uint8_t>{}, &codec_parameters,
+ &a2dp_status);
+ EXPECT_TRUE(!aidl_retval.isOk() ||
+ a2dp_status == A2dpStatus::NOT_SUPPORTED_CODEC_TYPE);
+ }
+}
+
+/**
+ * Calling parseA2dpConfiguration with a known codec and invalid configuration
+ * must fail with an A2dpStatus code different from INVALID_CODEC_TYPE or
+ * NOT_SUPPORTED_CODEC_TYPE.
+ */
+TEST_P(BluetoothAudioProviderAidl,
+ parseA2dpConfiguration_invalidConfiguration) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ CodecParameters codec_parameters;
+ A2dpStatus a2dp_status = A2dpStatus::OK;
+ ::ndk::ScopedAStatus aidl_retval;
+
+ // Test with the first available codec in the provider info for testing.
+ // The test runs with an empty parameters array, anything more specific
+ // would need understanding the codec.
+ aidl_retval = provider->parseA2dpConfiguration(
+ provider_info->codecInfos[0].id, std::vector<uint8_t>{},
+ &codec_parameters, &a2dp_status);
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(a2dp_status != A2dpStatus::OK &&
+ a2dp_status != A2dpStatus::NOT_SUPPORTED_CODEC_TYPE &&
+ a2dp_status != A2dpStatus::INVALID_CODEC_TYPE);
+ }
+}
+
+/**
+ * Calling parseA2dpConfiguration with a known codec and valid parameters
+ * must return with A2dpStatus OK.
+ */
+TEST_P(BluetoothAudioProviderAidl, parseA2dpConfiguration_valid) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ CodecParameters codec_parameters;
+ A2dpStatus a2dp_status = A2dpStatus::OK;
+ ::ndk::ScopedAStatus aidl_retval;
+
+ // Test with the first available codec in the provider info for testing.
+ // To get a valid configuration (the capabilities array in the provider
+ // info is not a selection), getA2dpConfiguration is used with the
+ // selected codec parameters as input.
+ auto const& codec_info = provider_info->codecInfos[0];
+ auto transport = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
+ transport.capabilities);
+ std::optional<A2dpConfiguration> configuration;
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{remote_capabilities},
+ A2dpConfigurationHint(), &configuration);
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+
+ aidl_retval = provider->parseA2dpConfiguration(
+ configuration->id, configuration->configuration, &codec_parameters,
+ &a2dp_status);
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(a2dp_status == A2dpStatus::OK);
+ EXPECT_EQ(codec_parameters, configuration->parameters);
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration on a session of a different type than
+ * A2DP_HARDWARE_OFFLOAD_(ENCODING|DECODING)_DATAPATH must fail.
+ */
+TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_invalidSessionType) {
+ static constexpr SessionType kInvalidSessionTypes[] = {
+ SessionType::UNKNOWN,
+ SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
+ };
+
+ for (auto session_type : kInvalidSessionTypes) {
+ // Open a BluetoothAudioProvider instance of the selected session type.
+ // Skip validation if the provider cannot be opened.
+ std::shared_ptr<IBluetoothAudioProvider> provider{nullptr};
+ auto aidl_retval = provider_factory_->openProvider(session_type, &provider);
+ if (provider == nullptr) {
+ continue;
+ }
+
+ // getA2dpConfiguration must fail without returning a configuration.
+ std::optional<A2dpConfiguration> configuration;
+ aidl_retval =
+ provider->getA2dpConfiguration(std::vector<A2dpRemoteCapabilities>{},
+ A2dpConfigurationHint(), &configuration);
+ EXPECT_FALSE(aidl_retval.isOk());
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration with empty or unknown remote capabilities
+ * must return an empty configuration.
+ */
+TEST_P(BluetoothAudioProviderAidl,
+ getA2dpConfiguration_unknownRemoteCapabilities) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ std::optional<A2dpConfiguration> configuration;
+ ::ndk::ScopedAStatus aidl_retval;
+
+ // Test with empty remote capabilities.
+ aidl_retval =
+ provider->getA2dpConfiguration(std::vector<A2dpRemoteCapabilities>{},
+ A2dpConfigurationHint(), &configuration);
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_FALSE(configuration.has_value());
+
+ // Test with unknown remote capabilities.
+ A2dpRemoteCapabilities unknown_core_remote_capabilities(
+ /*seid*/ 0, CodecId::Core::CVSD, std::vector<uint8_t>{1, 2, 3});
+ A2dpRemoteCapabilities unknown_vendor_remote_capabilities(
+ /*seid*/ 1,
+ /* Google Codec #42 */ CodecId::Vendor(0xFCB1, 0x42),
+ std::vector<uint8_t>{1, 2, 3});
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{
+ unknown_core_remote_capabilities,
+ unknown_vendor_remote_capabilities,
+ },
+ A2dpConfigurationHint(), &configuration);
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_FALSE(configuration.has_value());
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration with invalid remote capabilities
+ * must return an empty configuration.
+ */
+TEST_P(BluetoothAudioProviderAidl,
+ getA2dpConfiguration_invalidRemoteCapabilities) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ std::optional<A2dpConfiguration> configuration;
+ ::ndk::ScopedAStatus aidl_retval;
+
+ // Use the first available codec in the provider info for testing.
+ // The capabilities are modified to make them invalid.
+ auto const& codec_info = provider_info->codecInfos[0];
+ auto transport = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ std::vector<uint8_t> invalid_capabilities = transport.capabilities;
+ invalid_capabilities.push_back(0x42); // adding bytes should be invalid.
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{
+ A2dpRemoteCapabilities(/*seid*/ 0, codec_info.id,
+ std::vector<uint8_t>()),
+ A2dpRemoteCapabilities(/*seid*/ 1, codec_info.id,
+ invalid_capabilities),
+ },
+ A2dpConfigurationHint(), &configuration);
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_FALSE(configuration.has_value());
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration with valid remote capabilities
+ * must return a valid configuration. The selected parameters must
+ * be contained in the original capabilities. The returned configuration
+ * must match the returned parameters. The returned SEID must match the
+ * input SEID.
+ */
+TEST_P(BluetoothAudioProviderAidl,
+ getA2dpConfiguration_validRemoteCapabilities) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ // Test with all available codecs in the provider info.
+ for (auto const& codec_info : provider_info->codecInfos) {
+ auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ std::optional<A2dpConfiguration> configuration{};
+ ::ndk::ScopedAStatus aidl_retval;
+
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{
+ A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
+ a2dp_info.capabilities),
+ },
+ A2dpConfigurationHint(), &configuration);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+
+ // Returned configuration must have the same codec id
+ // as the remote capability.
+ EXPECT_EQ(configuration->id, codec_info.id);
+
+ // Returned configuration must have the same SEID
+ // as the remote capability.
+ EXPECT_EQ(configuration->remoteSeid, 42);
+
+ // Returned codec parameters must be in the range of input
+ // parameters.
+ EXPECT_NE(
+ std::find(a2dp_info.channelMode.begin(), a2dp_info.channelMode.end(),
+ configuration->parameters.channelMode),
+ a2dp_info.channelMode.end());
+ EXPECT_NE(std::find(a2dp_info.samplingFrequencyHz.begin(),
+ a2dp_info.samplingFrequencyHz.end(),
+ configuration->parameters.samplingFrequencyHz),
+ a2dp_info.samplingFrequencyHz.end());
+ EXPECT_NE(std::find(a2dp_info.bitdepth.begin(), a2dp_info.bitdepth.end(),
+ configuration->parameters.bitdepth),
+ a2dp_info.bitdepth.end());
+ EXPECT_EQ(a2dp_info.lossless, configuration->parameters.lossless);
+ EXPECT_TRUE(configuration->parameters.minBitrate <=
+ configuration->parameters.maxBitrate);
+
+ // Returned configuration must be parsable by parseA2dpParameters
+ // and match the codec parameters.
+ CodecParameters codec_parameters;
+ A2dpStatus a2dp_status = A2dpStatus::OK;
+ aidl_retval = provider->parseA2dpConfiguration(
+ configuration->id, configuration->configuration, &codec_parameters,
+ &a2dp_status);
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(a2dp_status == A2dpStatus::OK);
+ EXPECT_EQ(codec_parameters, configuration->parameters);
+ }
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration with valid remote capabilities
+ * with various hinted codec ids.
+ */
+TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintCodecId) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ // Build the remote capabilities with all supported codecs.
+ std::vector<A2dpRemoteCapabilities> remote_capabilities;
+ for (size_t n = 0; n < provider_info->codecInfos.size(); n++) {
+ auto const& codec_info = provider_info->codecInfos[n];
+ auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ remote_capabilities.push_back(A2dpRemoteCapabilities(
+ /*seid*/ n, codec_info.id, a2dp_info.capabilities));
+ }
+
+ // Test with all supported codec identifiers,
+ for (auto const& codec_info : provider_info->codecInfos) {
+ std::optional<A2dpConfiguration> configuration{};
+ ::ndk::ScopedAStatus aidl_retval;
+
+ A2dpConfigurationHint hint;
+ hint.codecId = codec_info.id;
+
+ aidl_retval = provider->getA2dpConfiguration(remote_capabilities, hint,
+ &configuration);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+ EXPECT_EQ(configuration->id, codec_info.id);
+ }
+
+ // Test with unknown codec identifiers: either core or vendor.
+ for (auto& codec_id :
+ {CodecId(CodecId::Core::CVSD),
+ CodecId(CodecId::Vendor(0xFCB1, 0x42)) /*Google Codec #42*/}) {
+ std::optional<A2dpConfiguration> configuration{};
+ ::ndk::ScopedAStatus aidl_retval;
+
+ A2dpConfigurationHint hint;
+ hint.codecId = codec_id;
+
+ aidl_retval = provider->getA2dpConfiguration(remote_capabilities, hint,
+ &configuration);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+ EXPECT_NE(configuration->id, codec_id);
+ }
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration with valid remote capabilities
+ * with various hinted channel modes.
+ */
+TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintChannelMode) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ // Test with all available codecs in the provider info.
+ for (auto const& codec_info : provider_info->codecInfos) {
+ auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ std::optional<A2dpConfiguration> configuration{};
+ ::ndk::ScopedAStatus aidl_retval;
+
+ for (auto& channel_mode :
+ {ChannelMode::STEREO, ChannelMode::MONO, ChannelMode::DUALMONO}) {
+ // Add the hint for the channel mode.
+ A2dpConfigurationHint hint;
+ auto& codec_parameters = hint.codecParameters.emplace();
+ codec_parameters.channelMode = channel_mode;
+
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{
+ A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
+ a2dp_info.capabilities),
+ },
+ hint, &configuration);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+
+ // The hint must be ignored if the channel mode is not supported
+ // by the codec, and applied otherwise.
+ ASSERT_EQ(configuration->parameters.channelMode == channel_mode,
+ std::find(a2dp_info.channelMode.begin(),
+ a2dp_info.channelMode.end(),
+ channel_mode) != a2dp_info.channelMode.end());
+ }
+ }
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration with valid remote capabilities
+ * with various hinted sampling frequencies.
+ */
+TEST_P(BluetoothAudioProviderAidl,
+ getA2dpConfiguration_hintSamplingFrequencyHz) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ // Test with all available codecs in the provider info.
+ for (auto const& codec_info : provider_info->codecInfos) {
+ auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ std::optional<A2dpConfiguration> configuration{};
+ ::ndk::ScopedAStatus aidl_retval;
+
+ for (auto& sampling_frequency_hz : {
+ 0,
+ 1,
+ 8000,
+ 16000,
+ 24000,
+ 32000,
+ 44100,
+ 48000,
+ 88200,
+ 96000,
+ 176400,
+ 192000,
+ }) {
+ // Add the hint for the sampling frequency.
+ A2dpConfigurationHint hint;
+ auto& codec_parameters = hint.codecParameters.emplace();
+ codec_parameters.samplingFrequencyHz = sampling_frequency_hz;
+
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{
+ A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
+ a2dp_info.capabilities),
+ },
+ hint, &configuration);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+
+ // The hint must be ignored if the sampling frequency is not supported
+ // by the codec, and applied otherwise.
+ ASSERT_EQ(configuration->parameters.samplingFrequencyHz ==
+ sampling_frequency_hz,
+ std::find(a2dp_info.samplingFrequencyHz.begin(),
+ a2dp_info.samplingFrequencyHz.end(),
+ sampling_frequency_hz) !=
+ a2dp_info.samplingFrequencyHz.end());
+ }
+ }
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration with valid remote capabilities
+ * with various hinted sampling bit-depths.
+ */
+TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintBitdepth) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ // Test with all available codecs in the provider info.
+ for (auto const& codec_info : provider_info->codecInfos) {
+ auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ std::optional<A2dpConfiguration> configuration{};
+ ::ndk::ScopedAStatus aidl_retval;
+
+ for (auto& bitdepth : {0, 1, 16, 24, 32}) {
+ // Add the hint for the bit depth.
+ A2dpConfigurationHint hint;
+ auto& codec_parameters = hint.codecParameters.emplace();
+ codec_parameters.bitdepth = bitdepth;
+
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{
+ A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
+ a2dp_info.capabilities),
+ },
+ hint, &configuration);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+
+ // The hint must be ignored if the bitdepth is not supported
+ // by the codec, and applied otherwise.
+ ASSERT_EQ(
+ configuration->parameters.bitdepth == bitdepth,
+ std::find(a2dp_info.bitdepth.begin(), a2dp_info.bitdepth.end(),
+ bitdepth) != a2dp_info.bitdepth.end());
+ }
+ }
+ }
+}
+
+/**
+ * Calling startSession with an unknown codec id must fail.
+ */
+TEST_P(BluetoothAudioProviderAidl, startSession_unknownCodecId) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ for (auto& codec_id :
+ {CodecId(CodecId::Core::CVSD),
+ CodecId(CodecId::Vendor(0xFCB1, 0x42) /*Google Codec #42*/)}) {
+ A2dpStreamConfiguration a2dp_config;
+ DataMQDesc data_mq_desc;
+
+ a2dp_config.codecId = codec_id;
+ a2dp_config.configuration = std::vector<uint8_t>{1, 2, 3};
+
+ auto aidl_retval =
+ provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
+ std::vector<LatencyMode>{}, &data_mq_desc);
+
+ EXPECT_FALSE(aidl_retval.isOk());
+ }
+ }
+}
+
+/**
+ * Calling startSession with a known codec and a valid configuration
+ * must succeed.
+ */
+TEST_P(BluetoothAudioProviderAidl, startSession_valid) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ // Use the first available codec in the provider info for testing.
+ // To get a valid configuration (the capabilities array in the provider
+ // info is not a selection), getA2dpConfiguration is used with the
+ // selected codec parameters as input.
+ auto const& codec_info = provider_info->codecInfos[0];
+ auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ ::ndk::ScopedAStatus aidl_retval;
+ A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
+ a2dp_info.capabilities);
+ std::optional<A2dpConfiguration> configuration;
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{remote_capabilities},
+ A2dpConfigurationHint(), &configuration);
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+
+ // Build the stream configuration.
+ A2dpStreamConfiguration a2dp_config;
+ DataMQDesc data_mq_desc;
+
+ a2dp_config.codecId = codec_info.id;
+ a2dp_config.configuration = configuration->configuration;
+
+ aidl_retval =
+ provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
+ std::vector<LatencyMode>{}, &data_mq_desc);
+
+ EXPECT_TRUE(aidl_retval.isOk());
+ }
+}
+
+/**
+ * Calling startSession with a known codec but an invalid configuration
+ * must fail.
+ */
+TEST_P(BluetoothAudioProviderAidl, startSession_invalidConfiguration) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ // Use the first available codec in the provider info for testing.
+ // To get a valid configuration (the capabilities array in the provider
+ // info is not a selection), getA2dpConfiguration is used with the
+ // selected codec parameters as input.
+ ::ndk::ScopedAStatus aidl_retval;
+ auto const& codec_info = provider_info->codecInfos[0];
+ auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
+ a2dp_info.capabilities);
+ std::optional<A2dpConfiguration> configuration;
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{remote_capabilities},
+ A2dpConfigurationHint(), &configuration);
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+
+ // Build the stream configuration but edit the configuration bytes
+ // to make it invalid.
+ A2dpStreamConfiguration a2dp_config;
+ DataMQDesc data_mq_desc;
+
+ a2dp_config.codecId = codec_info.id;
+ a2dp_config.configuration = configuration->configuration;
+ a2dp_config.configuration.push_back(42);
+
+ aidl_retval =
+ provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
+ std::vector<LatencyMode>{}, &data_mq_desc);
+
+ EXPECT_FALSE(aidl_retval.isOk());
+ }
}
/**
@@ -625,8 +1511,8 @@
/**
* Test whether each provider of type
- * SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
- * different PCM config
+ * SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH can be started and stopped
+ * with different PCM config
*/
TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl,
StartAndEndA2dpEncodingSoftwareSessionWithPossiblePcmConfig) {
@@ -656,6 +1542,145 @@
}
/**
+ * openProvider HFP_SOFTWARE_ENCODING_DATAPATH
+ */
+class BluetoothAudioProviderHfpSoftwareEncodingAidl
+ : public BluetoothAudioProviderFactoryAidl {
+ public:
+ virtual void SetUp() override {
+ BluetoothAudioProviderFactoryAidl::SetUp();
+ if (GetProviderFactoryInterfaceVersion() <
+ BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+ GTEST_SKIP();
+ }
+ GetProviderCapabilitiesHelper(SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
+ OpenProviderHelper(SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
+ ASSERT_NE(audio_provider_, nullptr);
+ }
+
+ virtual void TearDown() override {
+ audio_port_ = nullptr;
+ audio_provider_ = nullptr;
+ BluetoothAudioProviderFactoryAidl::TearDown();
+ }
+
+ bool OpenSession(int32_t sample_rate, int8_t bits_per_sample,
+ ChannelMode channel_mode, int32_t data_interval_us) {
+ PcmConfiguration pcm_config{
+ .sampleRateHz = sample_rate,
+ .channelMode = channel_mode,
+ .bitsPerSample = bits_per_sample,
+ .dataIntervalUs = data_interval_us,
+ };
+ // Checking against provider capability from getProviderCapabilities
+ // For HFP software, it's
+ // BluetoothAudioCodecs::GetSoftwarePcmCapabilities();
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(pcm_config), latency_modes, &mq_desc);
+ DataMQ data_mq(mq_desc);
+
+ if (!aidl_retval.isOk()) return false;
+ if (!data_mq.isValid()) return false;
+ return true;
+ }
+};
+
+/**
+ * Test whether we can open a provider of type
+ */
+TEST_P(BluetoothAudioProviderHfpSoftwareEncodingAidl,
+ OpenHfpSoftwareEncodingProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::HFP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
+ * different PCM config
+ */
+TEST_P(BluetoothAudioProviderHfpSoftwareEncodingAidl,
+ StartAndEndHfpEncodingSoftwareSessionWithPossiblePcmConfig) {
+ for (auto sample_rate : hfp_sample_rates_) {
+ for (auto bits_per_sample : hfp_bits_per_samples_) {
+ for (auto channel_mode : hfp_channel_modes_) {
+ for (auto data_interval_us : hfp_data_interval_us_) {
+ EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample, channel_mode,
+ data_interval_us));
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+ }
+ }
+ }
+}
+
+/**
+ * openProvider HFP_SOFTWARE_DECODING_DATAPATH
+ */
+class BluetoothAudioProviderHfpSoftwareDecodingAidl
+ : public BluetoothAudioProviderFactoryAidl {
+ public:
+ virtual void SetUp() override {
+ BluetoothAudioProviderFactoryAidl::SetUp();
+ if (GetProviderFactoryInterfaceVersion() <
+ BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+ GTEST_SKIP();
+ }
+ GetProviderCapabilitiesHelper(SessionType::HFP_SOFTWARE_DECODING_DATAPATH);
+ OpenProviderHelper(SessionType::HFP_SOFTWARE_DECODING_DATAPATH);
+ ASSERT_NE(audio_provider_, nullptr);
+ }
+
+ virtual void TearDown() override {
+ audio_port_ = nullptr;
+ audio_provider_ = nullptr;
+ BluetoothAudioProviderFactoryAidl::TearDown();
+ }
+
+ bool OpenSession(int32_t sample_rate, int8_t bits_per_sample,
+ ChannelMode channel_mode, int32_t data_interval_us) {
+ PcmConfiguration pcm_config{
+ .sampleRateHz = sample_rate,
+ .channelMode = channel_mode,
+ .bitsPerSample = bits_per_sample,
+ .dataIntervalUs = data_interval_us,
+ };
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(pcm_config), latency_modes, &mq_desc);
+ DataMQ data_mq(mq_desc);
+
+ if (!aidl_retval.isOk()) return false;
+ if (!data_mq.isValid()) return false;
+ return true;
+ }
+};
+
+/**
+ * Test whether we can open a provider of type
+ */
+TEST_P(BluetoothAudioProviderHfpSoftwareDecodingAidl,
+ OpenHfpSoftwareDecodingProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::HFP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
+ * different PCM config
+ */
+TEST_P(BluetoothAudioProviderHfpSoftwareDecodingAidl,
+ StartAndEndHfpDecodingSoftwareSessionWithPossiblePcmConfig) {
+ for (auto sample_rate : hfp_sample_rates_) {
+ for (auto bits_per_sample : hfp_bits_per_samples_) {
+ for (auto channel_mode : hfp_channel_modes_) {
+ for (auto data_interval_us : hfp_data_interval_us_) {
+ EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample, channel_mode,
+ data_interval_us));
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+ }
+ }
+ }
+}
+
+/**
* openProvider A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH
*/
class BluetoothAudioProviderA2dpEncodingHardwareAidl
@@ -687,13 +1712,13 @@
/**
* Test whether each provider of type
- * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
- * SBC hardware encoding config
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
+ * with SBC hardware encoding config
*/
TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
StartAndEndA2dpSbcEncodingHardwareSession) {
if (!IsOffloadSupported()) {
- return;
+ GTEST_SKIP();
}
CodecConfiguration codec_config = {
@@ -717,13 +1742,13 @@
/**
* Test whether each provider of type
- * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
- * AAC hardware encoding config
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
+ * with AAC hardware encoding config
*/
TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
StartAndEndA2dpAacEncodingHardwareSession) {
if (!IsOffloadSupported()) {
- return;
+ GTEST_SKIP();
}
CodecConfiguration codec_config = {
@@ -747,13 +1772,13 @@
/**
* Test whether each provider of type
- * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
- * LDAC hardware encoding config
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
+ * with LDAC hardware encoding config
*/
TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
StartAndEndA2dpLdacEncodingHardwareSession) {
if (!IsOffloadSupported()) {
- return;
+ GTEST_SKIP();
}
CodecConfiguration codec_config = {
@@ -777,13 +1802,13 @@
/**
* Test whether each provider of type
- * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
- * Opus hardware encoding config
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
+ * with Opus hardware encoding config
*/
TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
StartAndEndA2dpOpusEncodingHardwareSession) {
if (!IsOffloadSupported()) {
- return;
+ GTEST_SKIP();
}
CodecConfiguration codec_config = {
@@ -807,13 +1832,13 @@
/**
* Test whether each provider of type
- * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
- * AptX hardware encoding config
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
+ * with AptX hardware encoding config
*/
TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
StartAndEndA2dpAptxEncodingHardwareSession) {
if (!IsOffloadSupported()) {
- return;
+ GTEST_SKIP();
}
for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
@@ -843,13 +1868,13 @@
/**
* Test whether each provider of type
- * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
- * an invalid codec config
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped
+ * with an invalid codec config
*/
TEST_P(BluetoothAudioProviderA2dpEncodingHardwareAidl,
StartAndEndA2dpEncodingHardwareSessionInvalidCodecConfig) {
if (!IsOffloadSupported()) {
- return;
+ GTEST_SKIP();
}
ASSERT_NE(audio_provider_, nullptr);
@@ -908,6 +1933,66 @@
}
/**
+ * openProvider HFP_HARDWARE_OFFLOAD_DATAPATH
+ */
+class BluetoothAudioProviderHfpHardwareAidl
+ : public BluetoothAudioProviderFactoryAidl {
+ public:
+ virtual void SetUp() override {
+ BluetoothAudioProviderFactoryAidl::SetUp();
+ if (GetProviderFactoryInterfaceVersion() <
+ BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+ GTEST_SKIP();
+ }
+ OpenProviderHelper(SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH);
+ // Can open or empty capability
+ ASSERT_TRUE(temp_provider_capabilities_.empty() ||
+ audio_provider_ != nullptr);
+ }
+
+ virtual void TearDown() override {
+ audio_port_ = nullptr;
+ audio_provider_ = nullptr;
+ BluetoothAudioProviderFactoryAidl::TearDown();
+ }
+
+ bool OpenSession(CodecId codec_id, int connection_handle, bool nrec,
+ bool controller_codec) {
+ // Check if can open session with a Hfp configuration
+ HfpConfiguration hfp_configuration{
+ .codecId = codec_id,
+ .connectionHandle = connection_handle,
+ .nrec = nrec,
+ .controllerCodec = controller_codec,
+ };
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(hfp_configuration), latency_modes,
+ &mq_desc);
+
+ // Only check if aidl is ok to start session.
+ return aidl_retval.isOk();
+ }
+};
+
+/**
+ * Test whether we can open a provider of type
+ */
+TEST_P(BluetoothAudioProviderHfpHardwareAidl, OpenHfpHardwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::HFP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
+ * different HFP config
+ */
+TEST_P(BluetoothAudioProviderHfpHardwareAidl,
+ StartAndEndHfpHardwareSessionWithPossiblePcmConfig) {
+ // Try to open with a sample configuration
+ EXPECT_TRUE(OpenSession(CodecId::Core::CVSD, 6, false, true));
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+}
+
+/**
* openProvider HEARING_AID_SOFTWARE_ENCODING_DATAPATH
*/
class BluetoothAudioProviderHearingAidSoftwareAidl
@@ -1128,6 +2213,8 @@
BluetoothAudioProviderFactoryAidl::SetUp();
GetProviderCapabilitiesHelper(
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+ GetProviderInfoHelper(
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
OpenProviderHelper(
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
ASSERT_TRUE(temp_provider_capabilities_.empty() ||
@@ -1154,6 +2241,99 @@
return false;
}
+ bool IsOffloadOutputProviderInfoSupported() {
+ if (!temp_provider_info_.has_value()) return false;
+ if (temp_provider_info_.value().codecInfos.empty()) return false;
+ // Check if all codec info is of LeAudio type
+ for (auto& codec_info : temp_provider_info_.value().codecInfos) {
+ if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
+ return false;
+ }
+ return true;
+ }
+
+ std::vector<Lc3Configuration> GetUnicastLc3SupportedListFromProviderInfo() {
+ std::vector<Lc3Configuration> le_audio_codec_configs;
+ for (auto& codec_info : temp_provider_info_.value().codecInfos) {
+ // Only gets LC3 codec information
+ if (codec_info.id != CodecId::Core::LC3) continue;
+ // Combine those parameters into one list of Lc3Configuration
+ auto& transport =
+ codec_info.transport.get<CodecInfo::Transport::Tag::leAudio>();
+ for (int32_t samplingFrequencyHz : transport.samplingFrequencyHz) {
+ for (int32_t frameDurationUs : transport.frameDurationUs) {
+ for (int32_t octetsPerFrame : transport.bitdepth) {
+ Lc3Configuration lc3_config = {
+ .samplingFrequencyHz = samplingFrequencyHz,
+ .frameDurationUs = frameDurationUs,
+ .octetsPerFrame = octetsPerFrame,
+ };
+ le_audio_codec_configs.push_back(lc3_config);
+ }
+ }
+ }
+ }
+
+ return le_audio_codec_configs;
+ }
+
+ AudioContext GetAudioContext(int32_t bitmask) {
+ AudioContext media_audio_context;
+ media_audio_context.bitmask = bitmask;
+ return media_audio_context;
+ }
+
+ LeAudioDeviceCapabilities GetDefaultRemoteCapability() {
+ // Create a capability
+ LeAudioDeviceCapabilities capability;
+
+ capability.codecId = CodecId::Core::LC3;
+
+ auto pref_context_metadata = MetadataLtv::PreferredAudioContexts();
+ pref_context_metadata.values = GetAudioContext(AudioContext::MEDIA);
+ capability.metadata = {pref_context_metadata};
+
+ auto sampling_rate =
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies();
+ sampling_rate.bitmask =
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ8000;
+ auto frame_duration =
+ CodecSpecificCapabilitiesLtv::SupportedFrameDurations();
+ frame_duration.bitmask =
+ CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US7500;
+ auto octets = CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame();
+ octets.min = 0;
+ octets.max = 60;
+ auto frames = CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU();
+ frames.value = 2;
+ capability.codecSpecificCapabilities = {sampling_rate, frame_duration,
+ octets, frames};
+ return capability;
+ }
+
+ LeAudioConfigurationRequirement GetDefaultRequirement(
+ bool is_source_requriement) {
+ // Create a requirements
+ LeAudioConfigurationRequirement requirement;
+ requirement.audioContext = GetAudioContext(AudioContext::MEDIA);
+
+ auto direction_ase_requriement = AseDirectionRequirement();
+ direction_ase_requriement.aseConfiguration.codecId = CodecId::Core::LC3;
+ direction_ase_requriement.aseConfiguration.targetLatency =
+ LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY;
+
+ // Mismatch sampling frequency
+ direction_ase_requriement.aseConfiguration.codecConfiguration = {
+ CodecSpecificConfigurationLtv::SamplingFrequency::HZ11025,
+ CodecSpecificConfigurationLtv::FrameDuration::US7500,
+ };
+ if (is_source_requriement)
+ requirement.sourceAseRequirement = {direction_ase_requriement};
+ else
+ requirement.sinkAseRequirement = {direction_ase_requriement};
+ return requirement;
+ }
+
std::vector<Lc3Configuration> GetUnicastLc3SupportedList(bool decoding,
bool supported) {
std::vector<Lc3Configuration> le_audio_codec_configs;
@@ -1271,6 +2451,14 @@
}
LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
+ std::vector<int32_t> all_context_bitmasks = {
+ AudioContext::UNSPECIFIED, AudioContext::CONVERSATIONAL,
+ AudioContext::MEDIA, AudioContext::GAME,
+ AudioContext::INSTRUCTIONAL, AudioContext::VOICE_ASSISTANTS,
+ AudioContext::LIVE_AUDIO, AudioContext::SOUND_EFFECTS,
+ AudioContext::NOTIFICATIONS, AudioContext::RINGTONE_ALERTS,
+ AudioContext::ALERTS, AudioContext::EMERGENCY_ALARM,
+ };
};
/**
@@ -1284,12 +2472,161 @@
/**
* Test whether each provider of type
* SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * stopped with Unicast hardware encoding config taken from provider info
+ */
+TEST_P(
+ BluetoothAudioProviderLeAudioOutputHardwareAidl,
+ StartAndEndLeAudioOutputSessionWithPossibleUnicastConfigFromProviderInfo) {
+ if (GetProviderFactoryInterfaceVersion() <
+ BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+ GTEST_SKIP();
+ }
+ if (!IsOffloadOutputProviderInfoSupported()) {
+ GTEST_SKIP();
+ }
+
+ auto lc3_codec_configs = GetUnicastLc3SupportedListFromProviderInfo();
+ LeAudioConfiguration le_audio_config = {
+ .codecType = CodecType::LC3,
+ .peerDelayUs = 0,
+ };
+
+ for (auto& lc3_config : lc3_codec_configs) {
+ le_audio_config.leAudioCodecConfig
+ .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(le_audio_config), latency_modes,
+ &mq_desc);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+}
+
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
+ GetEmptyAseConfigurationEmptyCapability) {
+ if (GetProviderFactoryInterfaceVersion() <
+ BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+ GTEST_SKIP();
+ }
+ std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
+ std::vector<LeAudioConfigurationRequirement> empty_requirement;
+ std::vector<LeAudioAseConfigurationSetting> configurations;
+
+ // Check empty capability for source direction
+ auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+ std::nullopt, empty_capability, empty_requirement, &configurations);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configurations.empty());
+
+ // Check empty capability for sink direction
+ aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+ empty_capability, std::nullopt, empty_requirement, &configurations);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configurations.empty());
+}
+
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
+ GetEmptyAseConfigurationMismatchedRequirement) {
+ if (GetProviderFactoryInterfaceVersion() <
+ BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+ GTEST_SKIP();
+ }
+ std::vector<std::optional<LeAudioDeviceCapabilities>> capabilities = {
+ GetDefaultRemoteCapability()};
+
+ // Check empty capability for source direction
+ std::vector<LeAudioAseConfigurationSetting> configurations;
+ std::vector<LeAudioConfigurationRequirement> source_requirements = {
+ GetDefaultRequirement(true)};
+ auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+ std::nullopt, capabilities, source_requirements, &configurations);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configurations.empty());
+
+ // Check empty capability for sink direction
+ std::vector<LeAudioConfigurationRequirement> sink_requirements = {
+ GetDefaultRequirement(false)};
+ aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+ capabilities, std::nullopt, source_requirements, &configurations);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configurations.empty());
+}
+
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl, GetQoSConfiguration) {
+ if (GetProviderFactoryInterfaceVersion() <
+ BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+ GTEST_SKIP();
+ }
+ IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement requirement;
+ std::vector<IBluetoothAudioProvider::LeAudioAseQosConfiguration>
+ QoSConfigurations;
+ for (auto bitmask : all_context_bitmasks) {
+ requirement.audioContext = GetAudioContext(bitmask);
+ IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
+ auto aidl_retval =
+ audio_provider_->getLeAudioAseQosConfiguration(requirement, &result);
+ ASSERT_TRUE(aidl_retval.isOk());
+ if (result.sinkQosConfiguration.has_value())
+ QoSConfigurations.push_back(result.sinkQosConfiguration.value());
+ if (result.sourceQosConfiguration.has_value())
+ QoSConfigurations.push_back(result.sourceQosConfiguration.value());
+ }
+ // QoS Configurations should not be empty, as we searched for all contexts
+ ASSERT_FALSE(QoSConfigurations.empty());
+}
+
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
+ GetDataPathConfiguration) {
+ if (GetProviderFactoryInterfaceVersion() <
+ BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+ GTEST_SKIP();
+ }
+ IBluetoothAudioProvider::StreamConfig sink_requirement;
+ IBluetoothAudioProvider::StreamConfig source_requirement;
+ std::vector<IBluetoothAudioProvider::LeAudioDataPathConfiguration>
+ DataPathConfigurations;
+ bool is_supported = false;
+
+ for (auto bitmask : all_context_bitmasks) {
+ sink_requirement.audioContext = GetAudioContext(bitmask);
+ source_requirement.audioContext = GetAudioContext(bitmask);
+ IBluetoothAudioProvider::LeAudioDataPathConfigurationPair result;
+ auto aidl_retval = audio_provider_->getLeAudioAseDatapathConfiguration(
+ sink_requirement, source_requirement, &result);
+ if (!aidl_retval.isOk()) {
+ // If not OK, then it could be not supported, as it is an optional feature
+ ASSERT_EQ(aidl_retval.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
+ } else {
+ is_supported = true;
+ if (result.inputConfig.has_value())
+ DataPathConfigurations.push_back(result.inputConfig.value());
+ if (result.inputConfig.has_value())
+ DataPathConfigurations.push_back(result.inputConfig.value());
+ }
+ }
+
+ if (is_supported) {
+ // Datapath Configurations should not be empty, as we searched for all
+ // contexts
+ ASSERT_FALSE(DataPathConfigurations.empty());
+ }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
* stopped with Unicast hardware encoding config
*/
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
StartAndEndLeAudioOutputSessionWithPossibleUnicastConfig) {
if (!IsOffloadOutputSupported()) {
- return;
+ GTEST_SKIP();
}
auto lc3_codec_configs =
@@ -1322,7 +2659,7 @@
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
DISABLED_StartAndEndLeAudioOutputSessionWithInvalidAudioConfiguration) {
if (!IsOffloadOutputSupported()) {
- return;
+ GTEST_SKIP();
}
auto lc3_codec_configs =
@@ -1360,7 +2697,7 @@
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
StartAndEndLeAudioOutputSessionWithAptxAdaptiveLeUnicastConfig) {
if (!IsOffloadOutputSupported()) {
- return;
+ GTEST_SKIP();
}
for (auto codec_type :
{CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
@@ -1397,7 +2734,7 @@
BluetoothAudioProviderLeAudioOutputHardwareAidl,
BluetoothAudioProviderLeAudioOutputHardwareAidl_StartAndEndLeAudioOutputSessionWithInvalidAptxAdaptiveLeAudioConfiguration) {
if (!IsOffloadOutputSupported()) {
- return;
+ GTEST_SKIP();
}
for (auto codec_type :
@@ -1437,6 +2774,8 @@
BluetoothAudioProviderFactoryAidl::SetUp();
GetProviderCapabilitiesHelper(
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
+ GetProviderInfoHelper(
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
OpenProviderHelper(
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
ASSERT_TRUE(temp_provider_capabilities_.empty() ||
@@ -1466,7 +2805,7 @@
/**
* Test whether each provider of type
- * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
* stopped
*/
TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
@@ -1474,13 +2813,44 @@
/**
* Test whether each provider of type
- * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
+ * stopped with Unicast hardware encoding config taken from provider info
+ */
+TEST_P(
+ BluetoothAudioProviderLeAudioInputHardwareAidl,
+ StartAndEndLeAudioInputSessionWithPossibleUnicastConfigFromProviderInfo) {
+ if (!IsOffloadOutputProviderInfoSupported()) {
+ GTEST_SKIP();
+ }
+
+ auto lc3_codec_configs = GetUnicastLc3SupportedListFromProviderInfo();
+ LeAudioConfiguration le_audio_config = {
+ .codecType = CodecType::LC3,
+ .peerDelayUs = 0,
+ };
+
+ for (auto& lc3_config : lc3_codec_configs) {
+ le_audio_config.leAudioCodecConfig
+ .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(le_audio_config), latency_modes,
+ &mq_desc);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
* stopped with Unicast hardware encoding config
*/
TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
StartAndEndLeAudioInputSessionWithPossibleUnicastConfig) {
if (!IsOffloadInputSupported()) {
- return;
+ GTEST_SKIP();
}
auto lc3_codec_configs =
@@ -1505,7 +2875,7 @@
/**
* Test whether each provider of type
- * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
* stopped with Unicast hardware encoding config
*
* Disabled since offload codec checking is not ready
@@ -1513,7 +2883,7 @@
TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
DISABLED_StartAndEndLeAudioInputSessionWithInvalidAudioConfiguration) {
if (!IsOffloadInputSupported()) {
- return;
+ GTEST_SKIP();
}
auto lc3_codec_configs =
@@ -1571,16 +2941,16 @@
/**
* Test whether each provider of type
- * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
- * stopped
+ * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started
+ * and stopped
*/
TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
OpenLeAudioOutputSoftwareProvider) {}
/**
* Test whether each provider of type
- * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
- * stopped with different PCM config
+ * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started
+ * and stopped with different PCM config
*/
TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
@@ -1623,6 +2993,8 @@
BluetoothAudioProviderFactoryAidl::SetUp();
GetProviderCapabilitiesHelper(
SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+ GetProviderInfoHelper(
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
OpenProviderHelper(
SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
ASSERT_TRUE(temp_provider_capabilities_.empty() ||
@@ -1649,6 +3021,42 @@
return false;
}
+ bool IsBroadcastOffloadProviderInfoSupported() {
+ if (!temp_provider_info_.has_value()) return false;
+ if (temp_provider_info_.value().codecInfos.empty()) return false;
+ // Check if all codec info is of LeAudio type
+ for (auto& codec_info : temp_provider_info_.value().codecInfos) {
+ if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
+ return false;
+ }
+ return true;
+ }
+
+ std::vector<Lc3Configuration> GetBroadcastLc3SupportedListFromProviderInfo() {
+ std::vector<Lc3Configuration> le_audio_codec_configs;
+ for (auto& codec_info : temp_provider_info_.value().codecInfos) {
+ // Only gets LC3 codec information
+ if (codec_info.id != CodecId::Core::LC3) continue;
+ // Combine those parameters into one list of Lc3Configuration
+ auto& transport =
+ codec_info.transport.get<CodecInfo::Transport::Tag::leAudio>();
+ for (int32_t samplingFrequencyHz : transport.samplingFrequencyHz) {
+ for (int32_t frameDurationUs : transport.frameDurationUs) {
+ for (int32_t octetsPerFrame : transport.bitdepth) {
+ Lc3Configuration lc3_config = {
+ .samplingFrequencyHz = samplingFrequencyHz,
+ .frameDurationUs = frameDurationUs,
+ .octetsPerFrame = octetsPerFrame,
+ };
+ le_audio_codec_configs.push_back(lc3_config);
+ }
+ }
+ }
+ }
+
+ return le_audio_codec_configs;
+ }
+
std::vector<Lc3Configuration> GetBroadcastLc3SupportedList(bool supported) {
std::vector<Lc3Configuration> le_audio_codec_configs;
if (!supported) {
@@ -1710,6 +3118,68 @@
/**
* Test whether each provider of type
* SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
+ * started and stopped with broadcast hardware encoding config taken from
+ * provider info
+ */
+TEST_P(
+ BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
+ StartAndEndLeAudioBroadcastSessionWithPossibleUnicastConfigFromProviderInfo) {
+ if (GetProviderFactoryInterfaceVersion() <
+ BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+ GTEST_SKIP();
+ }
+ if (!IsBroadcastOffloadProviderInfoSupported()) {
+ return;
+ }
+
+ auto lc3_codec_configs = GetBroadcastLc3SupportedListFromProviderInfo();
+ LeAudioBroadcastConfiguration le_audio_broadcast_config = {
+ .codecType = CodecType::LC3,
+ .streamMap = {},
+ };
+
+ for (auto& lc3_config : lc3_codec_configs) {
+ le_audio_broadcast_config.streamMap.resize(1);
+ le_audio_broadcast_config.streamMap[0]
+ .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
+ lc3_config);
+ le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
+ le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
+ le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
+
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(le_audio_broadcast_config),
+ latency_modes, &mq_desc);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+}
+
+TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
+ GetEmptyBroadcastConfigurationEmptyCapability) {
+ if (GetProviderFactoryInterfaceVersion() <
+ BluetoothAudioHalVersion::VERSION_AIDL_V4) {
+ GTEST_SKIP();
+ }
+ std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
+ IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement
+ empty_requirement;
+
+ IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting* configuration =
+ new IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting();
+
+ // Check empty capability for source direction
+ auto aidl_retval = audio_provider_->getLeAudioBroadcastConfiguration(
+ empty_capability, empty_requirement, configuration);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
* started and stopped with broadcast hardware encoding config
*/
TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
@@ -1807,8 +3277,8 @@
/**
* Test whether each provider of type
- * SessionType::A2DP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
- * different PCM config
+ * SessionType::A2DP_SOFTWARE_DECODING_DATAPATH can be started and stopped
+ * with different PCM config
*/
TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl,
StartAndEndA2dpDecodingSoftwareSessionWithPossiblePcmConfig) {
@@ -1869,13 +3339,13 @@
/**
* Test whether each provider of type
- * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
- * SBC hardware encoding config
+ * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
+ * with SBC hardware encoding config
*/
TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
StartAndEndA2dpSbcDecodingHardwareSession) {
if (!IsOffloadSupported()) {
- return;
+ GTEST_SKIP();
}
CodecConfiguration codec_config = {
@@ -1899,13 +3369,13 @@
/**
* Test whether each provider of type
- * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
- * AAC hardware encoding config
+ * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
+ * with AAC hardware encoding config
*/
TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
StartAndEndA2dpAacDecodingHardwareSession) {
if (!IsOffloadSupported()) {
- return;
+ GTEST_SKIP();
}
CodecConfiguration codec_config = {
@@ -1929,13 +3399,13 @@
/**
* Test whether each provider of type
- * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
- * LDAC hardware encoding config
+ * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
+ * with LDAC hardware encoding config
*/
TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
StartAndEndA2dpLdacDecodingHardwareSession) {
if (!IsOffloadSupported()) {
- return;
+ GTEST_SKIP();
}
CodecConfiguration codec_config = {
@@ -1959,13 +3429,13 @@
/**
* Test whether each provider of type
- * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
- * Opus hardware encoding config
+ * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
+ * with Opus hardware encoding config
*/
TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
StartAndEndA2dpOpusDecodingHardwareSession) {
if (!IsOffloadSupported()) {
- return;
+ GTEST_SKIP();
}
CodecConfiguration codec_config = {
@@ -1989,13 +3459,13 @@
/**
* Test whether each provider of type
- * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
- * AptX hardware encoding config
+ * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
+ * with AptX hardware encoding config
*/
TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
StartAndEndA2dpAptxDecodingHardwareSession) {
if (!IsOffloadSupported()) {
- return;
+ GTEST_SKIP();
}
for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
@@ -2025,13 +3495,13 @@
/**
* Test whether each provider of type
- * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped with
- * an invalid codec config
+ * SessionType::A2DP_HARDWARE_DECODING_DATAPATH can be started and stopped
+ * with an invalid codec config
*/
TEST_P(BluetoothAudioProviderA2dpDecodingHardwareAidl,
StartAndEndA2dpDecodingHardwareSessionInvalidCodecConfig) {
if (!IsOffloadSupported()) {
- return;
+ GTEST_SKIP();
}
ASSERT_NE(audio_provider_, nullptr);
@@ -2096,6 +3566,12 @@
IBluetoothAudioProviderFactory::descriptor)),
android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothAudioProviderAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothAudioProviderFactory::descriptor)),
+ android::PrintInstanceNameToString);
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
BluetoothAudioProviderA2dpEncodingSoftwareAidl);
INSTANTIATE_TEST_SUITE_P(PerInstance,
@@ -2184,6 +3660,29 @@
IBluetoothAudioProviderFactory::descriptor)),
android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderHfpHardwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderHfpHardwareAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothAudioProviderFactory::descriptor)),
+ android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderHfpSoftwareDecodingAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderHfpSoftwareDecodingAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothAudioProviderFactory::descriptor)),
+ android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderHfpSoftwareEncodingAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderHfpSoftwareEncodingAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothAudioProviderFactory::descriptor)),
+ android::PrintInstanceNameToString);
+
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
ABinderProcess_setThreadPoolMaxThreadCount(1);
diff --git a/bluetooth/audio/flags/Android.bp b/bluetooth/audio/flags/Android.bp
new file mode 100644
index 0000000..c3c8cf5
--- /dev/null
+++ b/bluetooth/audio/flags/Android.bp
@@ -0,0 +1,13 @@
+aconfig_declarations {
+ name: "btaudiohal_flags",
+ package: "com.android.btaudio.hal.flags",
+ container: "system",
+ srcs: ["btaudiohal.aconfig"],
+}
+
+cc_aconfig_library {
+ name: "btaudiohal_flags_c_lib",
+ aconfig_declarations: "btaudiohal_flags",
+ vendor: true,
+ host_supported: true,
+}
diff --git a/bluetooth/audio/flags/btaudiohal.aconfig b/bluetooth/audio/flags/btaudiohal.aconfig
new file mode 100644
index 0000000..4c1500a
--- /dev/null
+++ b/bluetooth/audio/flags/btaudiohal.aconfig
@@ -0,0 +1,9 @@
+package: "com.android.btaudio.hal.flags"
+container: "system"
+
+flag {
+ name: "dsa_lea"
+ namespace: "pixel_bluetooth"
+ description: "Flag for DSA Over LEA"
+ bug: "270987427"
+}
diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp
index 75081d6..c0817f5 100644
--- a/bluetooth/audio/utils/Android.bp
+++ b/bluetooth/audio/utils/Android.bp
@@ -42,6 +42,7 @@
"aidl_session/BluetoothAudioSession.cpp",
"aidl_session/HidlToAidlMiddleware.cpp",
"aidl_session/BluetoothLeAudioCodecsProvider.cpp",
+ "aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp",
],
export_include_dirs: ["aidl_session/"],
header_libs: [
@@ -61,9 +62,23 @@
"liblog",
"libhidlbase",
"libxml2",
+ "libflatbuffers-cpp",
+ "server_configurable_flags",
+ ],
+ static_libs: [
+ "btaudiohal_flags_c_lib",
],
generated_sources: ["le_audio_codec_capabilities"],
- generated_headers: ["le_audio_codec_capabilities"],
+ generated_headers: [
+ "le_audio_codec_capabilities",
+ "AIDLLeAudioSetConfigSchemas_h",
+ ],
+ required: [
+ "aidl_audio_set_configurations_bfbs",
+ "aidl_audio_set_configurations_json",
+ "aidl_audio_set_scenarios_bfbs",
+ "aidl_audio_set_scenarios_json",
+ ],
}
cc_test {
@@ -78,7 +93,7 @@
shared_libs: [
"libbase",
"libbinder_ndk",
- "android.hardware.bluetooth.audio-V3-ndk",
+ "android.hardware.bluetooth.audio-V4-ndk",
"libxml2",
],
test_suites: [
@@ -98,3 +113,81 @@
api_dir: "le_audio_codec_capabilities/schema",
root_elements: ["leAudioOffloadSetting"],
}
+
+genrule {
+ name: "AIDLLeAudioSetConfigSchemas_h",
+ tools: [
+ "flatc",
+ ],
+ cmd: "$(location flatc) -I hardware/interfaces/bluetooth/audio/utils/ -o $(genDir) --cpp $(in) ",
+ srcs: [
+ "le_audio_configuration_set/audio_set_configurations.fbs",
+ "le_audio_configuration_set/audio_set_scenarios.fbs",
+ ],
+ out: [
+ "audio_set_configurations_generated.h",
+ "audio_set_scenarios_generated.h",
+ ],
+}
+
+// Binary generation
+genrule {
+ name: "AIDLLeAudioSetScenariosSchema_bfbs",
+ tools: [
+ "flatc",
+ ],
+ cmd: "$(location flatc) -I hardware/interfaces/bluetooth/audio/utils/ -b --schema -o $(genDir) $(in) ",
+ srcs: [
+ "le_audio_configuration_set/audio_set_scenarios.fbs",
+ ],
+ out: [
+ "audio_set_scenarios.bfbs",
+ ],
+}
+
+genrule {
+ name: "AIDLLeAudioSetConfigsSchema_bfbs",
+ tools: [
+ "flatc",
+ ],
+ cmd: "$(location flatc) -I hardware/interfaces/bluetooth/audio/utils/ -b --schema -o $(genDir) $(in) ",
+ srcs: [
+ "le_audio_configuration_set/audio_set_configurations.fbs",
+ ],
+ out: [
+ "audio_set_configurations.bfbs",
+ ],
+}
+
+// Add to prebuilt etc
+prebuilt_etc {
+ name: "aidl_audio_set_scenarios_bfbs",
+ src: ":AIDLLeAudioSetScenariosSchema_bfbs",
+ filename: "aidl_audio_set_scenarios.bfbs",
+ sub_dir: "aidl/le_audio",
+ vendor: true,
+}
+
+prebuilt_etc {
+ name: "aidl_audio_set_scenarios_json",
+ src: "le_audio_configuration_set/audio_set_scenarios.json",
+ filename: "aidl_audio_set_scenarios.json",
+ sub_dir: "aidl/le_audio",
+ vendor: true,
+}
+
+prebuilt_etc {
+ name: "aidl_audio_set_configurations_bfbs",
+ src: ":AIDLLeAudioSetConfigsSchema_bfbs",
+ filename: "aidl_audio_set_configurations.bfbs",
+ sub_dir: "aidl/le_audio",
+ vendor: true,
+}
+
+prebuilt_etc {
+ name: "aidl_audio_set_configurations_json",
+ src: "le_audio_configuration_set/audio_set_configurations.json",
+ filename: "aidl_audio_set_configurations.json",
+ sub_dir: "aidl/le_audio",
+ vendor: true,
+}
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
index b4cba49..d37825a 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
@@ -32,6 +32,7 @@
#include <aidl/android/hardware/bluetooth/audio/SbcChannelMode.h>
#include <android-base/logging.h>
+#include "BluetoothLeAudioAseConfigurationSettingProvider.h"
#include "BluetoothLeAudioCodecsProvider.h"
namespace aidl {
@@ -41,7 +42,7 @@
namespace audio {
static const PcmCapabilities kDefaultSoftwarePcmCapabilities = {
- .sampleRateHz = {16000, 24000, 32000, 44100, 48000, 88200, 96000},
+ .sampleRateHz = {8000, 16000, 24000, 32000, 44100, 48000, 88200, 96000},
.channelMode = {ChannelMode::MONO, ChannelMode::STEREO},
.bitsPerSample = {16, 24, 32},
.dataIntervalUs = {},
@@ -97,6 +98,8 @@
{.codecType = CodecType::OPUS, .capabilities = {}}};
std::vector<LeAudioCodecCapabilitiesSetting> kDefaultOffloadLeAudioCapabilities;
+std::unordered_map<SessionType, std::vector<CodecInfo>>
+ kDefaultOffloadLeAudioCodecInfoMap;
template <class T>
bool BluetoothAudioCodecs::ContainedInVector(
@@ -411,6 +414,37 @@
return kDefaultOffloadLeAudioCapabilities;
}
+std::vector<CodecInfo> BluetoothAudioCodecs::GetLeAudioOffloadCodecInfo(
+ const SessionType& session_type) {
+ if (session_type !=
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+ session_type !=
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH &&
+ session_type !=
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+ return std::vector<CodecInfo>();
+ }
+
+ if (kDefaultOffloadLeAudioCodecInfoMap.empty()) {
+ auto le_audio_offload_setting =
+ BluetoothLeAudioCodecsProvider::ParseFromLeAudioOffloadSettingFile();
+ kDefaultOffloadLeAudioCodecInfoMap =
+ BluetoothLeAudioCodecsProvider::GetLeAudioCodecInfo(
+ le_audio_offload_setting);
+ }
+ auto codec_info_map_iter =
+ kDefaultOffloadLeAudioCodecInfoMap.find(session_type);
+ if (codec_info_map_iter == kDefaultOffloadLeAudioCodecInfoMap.end())
+ return std::vector<CodecInfo>();
+ return codec_info_map_iter->second;
+}
+
+std::vector<LeAudioAseConfigurationSetting>
+BluetoothAudioCodecs::GetLeAudioAseConfigurationSettings() {
+ return AudioSetConfigurationProviderJson::
+ GetLeAudioAseConfigurationSettings();
+}
+
} // namespace audio
} // namespace bluetooth
} // namespace hardware
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h
index e3d657b..057b9a7 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h
@@ -18,6 +18,8 @@
#include <aidl/android/hardware/bluetooth/audio/CodecCapabilities.h>
#include <aidl/android/hardware/bluetooth/audio/CodecConfiguration.h>
+#include <aidl/android/hardware/bluetooth/audio/CodecInfo.h>
+#include <aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.h>
#include <aidl/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.h>
#include <aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.h>
#include <aidl/android/hardware/bluetooth/audio/OpusConfiguration.h>
@@ -33,6 +35,9 @@
namespace bluetooth {
namespace audio {
+using LeAudioAseConfigurationSetting =
+ IBluetoothAudioProvider::LeAudioAseConfigurationSetting;
+
class BluetoothAudioCodecs {
public:
static std::vector<PcmCapabilities> GetSoftwarePcmCapabilities();
@@ -46,6 +51,11 @@
static std::vector<LeAudioCodecCapabilitiesSetting>
GetLeAudioOffloadCodecCapabilities(const SessionType& session_type);
+ static std::vector<CodecInfo> GetLeAudioOffloadCodecInfo(
+ const SessionType& session_type);
+
+ static std::vector<LeAudioAseConfigurationSetting>
+ GetLeAudioAseConfigurationSettings();
private:
template <typename T>
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
index e5cf53c..67ba93c 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
@@ -20,6 +20,7 @@
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <android/binder_manager.h>
+#include <com_android_btaudio_hal_flags.h>
#include <hardware/audio.h>
#include "BluetoothAudioSession.h"
@@ -36,6 +37,14 @@
static constexpr int kWritePollMs = 1; // polled non-blocking interval
static constexpr int kReadPollMs = 1; // polled non-blocking interval
+static std::string toString(const std::vector<LatencyMode>& latencies) {
+ std::stringstream latencyModesStr;
+ for (LatencyMode mode : latencies) {
+ latencyModesStr << " " << toString(mode);
+ }
+ return latencyModesStr.str();
+}
+
BluetoothAudioSession::BluetoothAudioSession(const SessionType& session_type)
: session_type_(session_type), stack_iface_(nullptr), data_mq_(nullptr) {}
@@ -65,6 +74,7 @@
stack_iface_ = stack_iface;
latency_modes_ = latency_modes;
LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+ << " - All LatencyModes=" << toString(latency_modes)
<< ", AudioConfiguration=" << audio_config.toString();
ReportSessionStatus();
}
@@ -95,6 +105,8 @@
case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH:
return AudioConfiguration(CodecConfiguration{});
+ case SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH:
+ return AudioConfiguration(HfpConfiguration{});
case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
return AudioConfiguration(LeAudioConfiguration{});
@@ -154,6 +166,7 @@
session_type_ ==
SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
+ session_type_ == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH ||
(data_mq_ != nullptr && data_mq_->isValid()));
return stack_iface_ != nullptr && is_mq_valid && audio_config_ != nullptr;
}
@@ -275,6 +288,8 @@
bool is_software_session =
(session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
session_type_ == SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH ||
+ session_type_ == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH ||
+ session_type_ == SessionType::HFP_SOFTWARE_DECODING_DATAPATH ||
session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH ||
session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
session_type_ ==
@@ -283,6 +298,8 @@
bool is_offload_a2dp_session =
(session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
+ bool is_offload_hfp_session =
+ session_type_ == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH;
bool is_offload_le_audio_unicast_session =
(session_type_ ==
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
@@ -297,7 +314,11 @@
audio_config_tag == AudioConfiguration::pcmConfig);
bool is_a2dp_offload_audio_config =
(is_offload_a2dp_session &&
- audio_config_tag == AudioConfiguration::a2dpConfig);
+ (audio_config_tag == AudioConfiguration::a2dp ||
+ audio_config_tag == AudioConfiguration::a2dpConfig));
+ bool is_hfp_offload_audio_config =
+ (is_offload_hfp_session &&
+ audio_config_tag == AudioConfiguration::hfpConfig);
bool is_le_audio_offload_unicast_audio_config =
(is_offload_le_audio_unicast_session &&
audio_config_tag == AudioConfiguration::leAudioConfig);
@@ -305,6 +326,7 @@
(is_offload_le_audio_broadcast_session &&
audio_config_tag == AudioConfiguration::leAudioBroadcastConfig);
if (!is_software_audio_config && !is_a2dp_offload_audio_config &&
+ !is_hfp_offload_audio_config &&
!is_le_audio_offload_unicast_audio_config &&
!is_le_audio_offload_broadcast_audio_config) {
return false;
@@ -439,6 +461,9 @@
}
void BluetoothAudioSession::ReportLowLatencyModeAllowedChanged(bool allowed) {
+ if (session_type_ != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+ return;
+ }
std::lock_guard<std::recursive_mutex> guard(mutex_);
low_latency_allowed_ = allowed;
// TODO(b/294498919): Remove this after there is API to update latency mode
@@ -475,14 +500,12 @@
<< " has NO session";
return false;
}
- bool retval = false;
-
if (!stack_iface_->getPresentationPosition(&presentation_position).isOk()) {
LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
<< toString(session_type_) << " failed";
return false;
}
- return retval;
+ return true;
}
void BluetoothAudioSession::UpdateSourceMetadata(
@@ -589,31 +612,46 @@
return std::vector<LatencyMode>();
}
- std::vector<LatencyMode> supported_latency_modes;
- if (session_type_ ==
- SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
- for (LatencyMode mode : latency_modes_) {
- if (mode == LatencyMode::LOW_LATENCY) {
- // LOW_LATENCY is not supported for LE_HARDWARE_OFFLOAD_ENC sessions
- continue;
+ if (com::android::btaudio::hal::flags::dsa_lea()) {
+ std::vector<LatencyMode> supported_latency_modes;
+ if (session_type_ ==
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+ for (LatencyMode mode : latency_modes_) {
+ if (mode == LatencyMode::LOW_LATENCY) {
+ // LOW_LATENCY is not supported for LE_HARDWARE_OFFLOAD_ENC sessions
+ continue;
+ }
+ supported_latency_modes.push_back(mode);
}
- supported_latency_modes.push_back(mode);
+ } else {
+ for (LatencyMode mode : latency_modes_) {
+ if (!low_latency_allowed_ && mode == LatencyMode::LOW_LATENCY) {
+ // ignore LOW_LATENCY mode if Bluetooth stack doesn't allow
+ continue;
+ }
+ if (mode == LatencyMode::DYNAMIC_SPATIAL_AUDIO_SOFTWARE ||
+ mode == LatencyMode::DYNAMIC_SPATIAL_AUDIO_HARDWARE) {
+ // DSA_SW and DSA_HW only supported for LE_HARDWARE_OFFLOAD_ENC
+ // sessions
+ continue;
+ }
+ supported_latency_modes.push_back(mode);
+ }
}
- } else {
- for (LatencyMode mode : latency_modes_) {
- if (!low_latency_allowed_ && mode == LatencyMode::LOW_LATENCY) {
- // ignore LOW_LATENCY mode if Bluetooth stack doesn't allow
- continue;
- }
- if (mode == LatencyMode::DYNAMIC_SPATIAL_AUDIO_SOFTWARE ||
- mode == LatencyMode::DYNAMIC_SPATIAL_AUDIO_HARDWARE) {
- // DSA_SW and DSA_HW only supported for LE_HARDWARE_OFFLOAD_ENC sessions
- continue;
- }
- supported_latency_modes.push_back(mode);
- }
+ LOG(DEBUG) << __func__ << " - Supported LatencyMode="
+ << toString(supported_latency_modes);
+ return supported_latency_modes;
}
- return supported_latency_modes;
+
+ if (low_latency_allowed_) return latency_modes_;
+ std::vector<LatencyMode> modes;
+ for (LatencyMode mode : latency_modes_) {
+ if (mode == LatencyMode::LOW_LATENCY)
+ // ignore those low latency mode if Bluetooth stack doesn't allow
+ continue;
+ modes.push_back(mode);
+ }
+ return modes;
}
void BluetoothAudioSession::SetLatencyMode(const LatencyMode& latency_mode) {
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h
index 7ae0353..5263222 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h
@@ -84,6 +84,8 @@
case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH:
return AudioConfiguration(CodecConfiguration{});
+ case SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH:
+ return AudioConfiguration(HfpConfiguration{});
case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
return AudioConfiguration(LeAudioConfiguration{});
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp
new file mode 100644
index 0000000..5429a8f
--- /dev/null
+++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp
@@ -0,0 +1,760 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define STREAM_TO_UINT8(u8, p) \
+ { \
+ (u8) = (uint8_t)(*(p)); \
+ (p) += 1; \
+ }
+#define STREAM_TO_UINT16(u16, p) \
+ { \
+ (u16) = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); \
+ (p) += 2; \
+ }
+#define STREAM_TO_UINT32(u32, p) \
+ { \
+ (u32) = (((uint32_t)(*(p))) + ((((uint32_t)(*((p) + 1)))) << 8) + \
+ ((((uint32_t)(*((p) + 2)))) << 16) + \
+ ((((uint32_t)(*((p) + 3)))) << 24)); \
+ (p) += 4; \
+ }
+
+#define LOG_TAG "BTAudioAseConfigAidl"
+
+#include "BluetoothLeAudioAseConfigurationSettingProvider.h"
+
+#include <aidl/android/hardware/bluetooth/audio/AudioConfiguration.h>
+#include <aidl/android/hardware/bluetooth/audio/AudioContext.h>
+#include <aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.h>
+#include <aidl/android/hardware/bluetooth/audio/CodecId.h>
+#include <aidl/android/hardware/bluetooth/audio/CodecSpecificCapabilitiesLtv.h>
+#include <aidl/android/hardware/bluetooth/audio/CodecSpecificConfigurationLtv.h>
+#include <aidl/android/hardware/bluetooth/audio/ConfigurationFlags.h>
+#include <aidl/android/hardware/bluetooth/audio/LeAudioAseConfiguration.h>
+#include <aidl/android/hardware/bluetooth/audio/Phy.h>
+#include <android-base/logging.h>
+
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+/* Internal structure definition */
+std::map<std::string,
+ std::tuple<std::vector<std::optional<AseDirectionConfiguration>>,
+ std::vector<std::optional<AseDirectionConfiguration>>,
+ ConfigurationFlags>>
+ configurations_;
+
+std::vector<LeAudioAseConfigurationSetting> ase_configuration_settings_;
+
+constexpr uint8_t kIsoDataPathHci = 0x00;
+constexpr uint8_t kIsoDataPathPlatformDefault = 0x01;
+constexpr uint8_t kIsoDataPathDisabled = 0xFF;
+
+constexpr uint8_t kLeAudioDirectionSink = 0x01;
+constexpr uint8_t kLeAudioDirectionSource = 0x02;
+constexpr uint8_t kLeAudioDirectionBoth =
+ kLeAudioDirectionSink | kLeAudioDirectionSource;
+
+/* Sampling Frequencies */
+constexpr uint8_t kLeAudioSamplingFreq8000Hz = 0x01;
+constexpr uint8_t kLeAudioSamplingFreq11025Hz = 0x02;
+constexpr uint8_t kLeAudioSamplingFreq16000Hz = 0x03;
+constexpr uint8_t kLeAudioSamplingFreq22050Hz = 0x04;
+constexpr uint8_t kLeAudioSamplingFreq24000Hz = 0x05;
+constexpr uint8_t kLeAudioSamplingFreq32000Hz = 0x06;
+constexpr uint8_t kLeAudioSamplingFreq44100Hz = 0x07;
+constexpr uint8_t kLeAudioSamplingFreq48000Hz = 0x08;
+constexpr uint8_t kLeAudioSamplingFreq88200Hz = 0x09;
+constexpr uint8_t kLeAudioSamplingFreq96000Hz = 0x0A;
+constexpr uint8_t kLeAudioSamplingFreq176400Hz = 0x0B;
+constexpr uint8_t kLeAudioSamplingFreq192000Hz = 0x0C;
+constexpr uint8_t kLeAudioSamplingFreq384000Hz = 0x0D;
+
+/* Frame Durations */
+constexpr uint8_t kLeAudioCodecFrameDur7500us = 0x00;
+constexpr uint8_t kLeAudioCodecFrameDur10000us = 0x01;
+
+/* Audio Allocations */
+constexpr uint32_t kLeAudioLocationNotAllowed = 0x00000000;
+constexpr uint32_t kLeAudioLocationFrontLeft = 0x00000001;
+constexpr uint32_t kLeAudioLocationFrontRight = 0x00000002;
+constexpr uint32_t kLeAudioLocationFrontCenter = 0x00000004;
+constexpr uint32_t kLeAudioLocationLowFreqEffects1 = 0x00000008;
+constexpr uint32_t kLeAudioLocationBackLeft = 0x00000010;
+constexpr uint32_t kLeAudioLocationBackRight = 0x00000020;
+constexpr uint32_t kLeAudioLocationFrontLeftOfCenter = 0x00000040;
+constexpr uint32_t kLeAudioLocationFrontRightOfCenter = 0x00000080;
+constexpr uint32_t kLeAudioLocationBackCenter = 0x00000100;
+constexpr uint32_t kLeAudioLocationLowFreqEffects2 = 0x00000200;
+constexpr uint32_t kLeAudioLocationSideLeft = 0x00000400;
+constexpr uint32_t kLeAudioLocationSideRight = 0x00000800;
+constexpr uint32_t kLeAudioLocationTopFrontLeft = 0x00001000;
+constexpr uint32_t kLeAudioLocationTopFrontRight = 0x00002000;
+constexpr uint32_t kLeAudioLocationTopFrontCenter = 0x00004000;
+constexpr uint32_t kLeAudioLocationTopCenter = 0x00008000;
+constexpr uint32_t kLeAudioLocationTopBackLeft = 0x00010000;
+constexpr uint32_t kLeAudioLocationTopBackRight = 0x00020000;
+constexpr uint32_t kLeAudioLocationTopSideLeft = 0x00040000;
+constexpr uint32_t kLeAudioLocationTopSideRight = 0x00080000;
+constexpr uint32_t kLeAudioLocationTopBackCenter = 0x00100000;
+constexpr uint32_t kLeAudioLocationBottomFrontCenter = 0x00200000;
+constexpr uint32_t kLeAudioLocationBottomFrontLeft = 0x00400000;
+constexpr uint32_t kLeAudioLocationBottomFrontRight = 0x00800000;
+constexpr uint32_t kLeAudioLocationFrontLeftWide = 0x01000000;
+constexpr uint32_t kLeAudioLocationFrontRightWide = 0x02000000;
+constexpr uint32_t kLeAudioLocationLeftSurround = 0x04000000;
+constexpr uint32_t kLeAudioLocationRightSurround = 0x08000000;
+
+constexpr uint32_t kLeAudioLocationAnyLeft =
+ kLeAudioLocationFrontLeft | kLeAudioLocationBackLeft |
+ kLeAudioLocationFrontLeftOfCenter | kLeAudioLocationSideLeft |
+ kLeAudioLocationTopFrontLeft | kLeAudioLocationTopBackLeft |
+ kLeAudioLocationTopSideLeft | kLeAudioLocationBottomFrontLeft |
+ kLeAudioLocationFrontLeftWide | kLeAudioLocationLeftSurround;
+
+constexpr uint32_t kLeAudioLocationAnyRight =
+ kLeAudioLocationFrontRight | kLeAudioLocationBackRight |
+ kLeAudioLocationFrontRightOfCenter | kLeAudioLocationSideRight |
+ kLeAudioLocationTopFrontRight | kLeAudioLocationTopBackRight |
+ kLeAudioLocationTopSideRight | kLeAudioLocationBottomFrontRight |
+ kLeAudioLocationFrontRightWide | kLeAudioLocationRightSurround;
+
+constexpr uint32_t kLeAudioLocationStereo =
+ kLeAudioLocationFrontLeft | kLeAudioLocationFrontRight;
+
+/* Octets Per Frame */
+constexpr uint16_t kLeAudioCodecFrameLen30 = 30;
+constexpr uint16_t kLeAudioCodecFrameLen40 = 40;
+constexpr uint16_t kLeAudioCodecFrameLen60 = 60;
+constexpr uint16_t kLeAudioCodecFrameLen80 = 80;
+constexpr uint16_t kLeAudioCodecFrameLen100 = 100;
+constexpr uint16_t kLeAudioCodecFrameLen120 = 120;
+
+/* Helper map for matching various sampling frequency notations */
+const std::map<uint8_t, CodecSpecificConfigurationLtv::SamplingFrequency>
+ sampling_freq_map = {
+ {kLeAudioSamplingFreq8000Hz,
+ CodecSpecificConfigurationLtv::SamplingFrequency::HZ8000},
+ {kLeAudioSamplingFreq16000Hz,
+ CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000},
+ {kLeAudioSamplingFreq24000Hz,
+ CodecSpecificConfigurationLtv::SamplingFrequency::HZ24000},
+ {kLeAudioSamplingFreq32000Hz,
+ CodecSpecificConfigurationLtv::SamplingFrequency::HZ32000},
+ {kLeAudioSamplingFreq44100Hz,
+ CodecSpecificConfigurationLtv::SamplingFrequency::HZ44100},
+ {kLeAudioSamplingFreq48000Hz,
+ CodecSpecificConfigurationLtv::SamplingFrequency::HZ48000}};
+
+/* Helper map for matching various frame durations notations */
+const std::map<uint8_t, CodecSpecificConfigurationLtv::FrameDuration>
+ frame_duration_map = {
+ {kLeAudioCodecFrameDur7500us,
+ CodecSpecificConfigurationLtv::FrameDuration::US7500},
+ {kLeAudioCodecFrameDur10000us,
+ CodecSpecificConfigurationLtv::FrameDuration::US10000}};
+
+/* Helper map for matching various audio channel allocation notations */
+std::map<uint32_t, uint32_t> audio_channel_allocation_map = {
+ {kLeAudioLocationNotAllowed,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::NOT_ALLOWED},
+ {kLeAudioLocationFrontLeft,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT},
+ {kLeAudioLocationFrontRight,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT},
+ {kLeAudioLocationFrontCenter,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_CENTER},
+ {kLeAudioLocationLowFreqEffects1,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::
+ LOW_FREQUENCY_EFFECTS_1},
+ {kLeAudioLocationBackLeft,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::BACK_LEFT},
+ {kLeAudioLocationBackRight,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::BACK_RIGHT},
+ {kLeAudioLocationFrontLeftOfCenter,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::
+ FRONT_LEFT_OF_CENTER},
+ {kLeAudioLocationFrontRightOfCenter,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::
+ FRONT_RIGHT_OF_CENTER},
+ {kLeAudioLocationBackCenter,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::BACK_CENTER},
+ {kLeAudioLocationLowFreqEffects2,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::
+ LOW_FREQUENCY_EFFECTS_2},
+ {kLeAudioLocationSideLeft,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::SIDE_LEFT},
+ {kLeAudioLocationSideRight,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::SIDE_RIGHT},
+ {kLeAudioLocationTopFrontLeft,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_FRONT_LEFT},
+ {kLeAudioLocationTopFrontRight,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_FRONT_RIGHT},
+ {kLeAudioLocationTopFrontCenter,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_FRONT_CENTER},
+ {kLeAudioLocationTopCenter,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_CENTER},
+ {kLeAudioLocationTopBackLeft,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_BACK_LEFT},
+ {kLeAudioLocationTopBackRight,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_BACK_RIGHT},
+ {kLeAudioLocationTopSideLeft,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_SIDE_LEFT},
+ {kLeAudioLocationTopSideRight,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_SIDE_RIGHT},
+ {kLeAudioLocationTopBackCenter,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_BACK_CENTER},
+ {kLeAudioLocationBottomFrontCenter,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::
+ BOTTOM_FRONT_CENTER},
+ {kLeAudioLocationBottomFrontLeft,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::BOTTOM_FRONT_LEFT},
+ {kLeAudioLocationBottomFrontRight,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::BOTTOM_FRONT_RIGHT},
+ {kLeAudioLocationFrontLeftWide,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT_WIDE},
+ {kLeAudioLocationFrontRightWide,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT_WIDE},
+ {kLeAudioLocationLeftSurround,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::LEFT_SURROUND},
+ {kLeAudioLocationRightSurround,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::RIGHT_SURROUND},
+};
+
+static const std::vector<
+ std::pair<const char* /*schema*/, const char* /*content*/>>
+ kLeAudioSetConfigs = {{"/vendor/etc/aidl/le_audio/"
+ "aidl_audio_set_configurations.bfbs",
+ "/vendor/etc/aidl/le_audio/"
+ "aidl_audio_set_configurations.json"}};
+static const std::vector<
+ std::pair<const char* /*schema*/, const char* /*content*/>>
+ kLeAudioSetScenarios = {{"/vendor/etc/aidl/le_audio/"
+ "aidl_audio_set_scenarios.bfbs",
+ "/vendor/etc/aidl/le_audio/"
+ "aidl_audio_set_scenarios.json"}};
+
+/* Implementation */
+
+std::vector<LeAudioAseConfigurationSetting>
+AudioSetConfigurationProviderJson::GetLeAudioAseConfigurationSettings() {
+ AudioSetConfigurationProviderJson::LoadAudioSetConfigurationProviderJson();
+ return ase_configuration_settings_;
+}
+
+void AudioSetConfigurationProviderJson::
+ LoadAudioSetConfigurationProviderJson() {
+ if (configurations_.empty() || ase_configuration_settings_.empty()) {
+ ase_configuration_settings_.clear();
+ configurations_.clear();
+ auto loaded = LoadContent(kLeAudioSetConfigs, kLeAudioSetScenarios,
+ CodecLocation::HOST);
+ if (!loaded)
+ LOG(ERROR) << ": Unable to load le audio set configuration files.";
+ } else
+ LOG(INFO) << ": Reusing loaded le audio set configuration";
+}
+
+const le_audio::CodecSpecificConfiguration*
+AudioSetConfigurationProviderJson::LookupCodecSpecificParam(
+ const flatbuffers::Vector<flatbuffers::Offset<
+ le_audio::CodecSpecificConfiguration>>* flat_codec_specific_params,
+ le_audio::CodecSpecificLtvGenericTypes type) {
+ auto it = std::find_if(
+ flat_codec_specific_params->cbegin(), flat_codec_specific_params->cend(),
+ [&type](const auto& csc) { return (csc->type() == type); });
+ return (it != flat_codec_specific_params->cend()) ? *it : nullptr;
+}
+
+void AudioSetConfigurationProviderJson::populateAudioChannelAllocation(
+ CodecSpecificConfigurationLtv::AudioChannelAllocation&
+ audio_channel_allocation,
+ uint32_t audio_location) {
+ audio_channel_allocation.bitmask = 0;
+ for (auto [allocation, bitmask] : audio_channel_allocation_map) {
+ if (audio_location & allocation)
+ audio_channel_allocation.bitmask |= bitmask;
+ }
+}
+
+void AudioSetConfigurationProviderJson::populateConfigurationData(
+ LeAudioAseConfiguration& ase,
+ const flatbuffers::Vector<
+ flatbuffers::Offset<le_audio::CodecSpecificConfiguration>>*
+ flat_codec_specific_params) {
+ uint8_t sampling_frequency = 0;
+ uint8_t frame_duration = 0;
+ uint32_t audio_channel_allocation = 0;
+ uint16_t octets_per_codec_frame = 0;
+ uint8_t codec_frames_blocks_per_sdu = 0;
+
+ auto param = LookupCodecSpecificParam(
+ flat_codec_specific_params,
+ le_audio::CodecSpecificLtvGenericTypes_SUPPORTED_SAMPLING_FREQUENCY);
+ if (param) {
+ auto ptr = param->compound_value()->value()->data();
+ STREAM_TO_UINT8(sampling_frequency, ptr);
+ }
+
+ param = LookupCodecSpecificParam(
+ flat_codec_specific_params,
+ le_audio::CodecSpecificLtvGenericTypes_SUPPORTED_FRAME_DURATION);
+ if (param) {
+ auto ptr = param->compound_value()->value()->data();
+ STREAM_TO_UINT8(frame_duration, ptr);
+ }
+
+ param = LookupCodecSpecificParam(
+ flat_codec_specific_params,
+ le_audio::
+ CodecSpecificLtvGenericTypes_SUPPORTED_AUDIO_CHANNEL_ALLOCATION);
+ if (param) {
+ auto ptr = param->compound_value()->value()->data();
+ STREAM_TO_UINT32(audio_channel_allocation, ptr);
+ }
+
+ param = LookupCodecSpecificParam(
+ flat_codec_specific_params,
+ le_audio::CodecSpecificLtvGenericTypes_SUPPORTED_OCTETS_PER_CODEC_FRAME);
+ if (param) {
+ auto ptr = param->compound_value()->value()->data();
+ STREAM_TO_UINT16(octets_per_codec_frame, ptr);
+ }
+
+ param = LookupCodecSpecificParam(
+ flat_codec_specific_params,
+ le_audio::
+ CodecSpecificLtvGenericTypes_SUPPORTED_CODEC_FRAME_BLOCKS_PER_SDU);
+ if (param) {
+ auto ptr = param->compound_value()->value()->data();
+ STREAM_TO_UINT8(codec_frames_blocks_per_sdu, ptr);
+ }
+
+ // Make the correct value
+ ase.codecConfiguration = std::vector<CodecSpecificConfigurationLtv>();
+
+ auto sampling_freq_it = sampling_freq_map.find(sampling_frequency);
+ if (sampling_freq_it != sampling_freq_map.end())
+ ase.codecConfiguration.push_back(sampling_freq_it->second);
+ auto frame_duration_it = frame_duration_map.find(frame_duration);
+ if (frame_duration_it != frame_duration_map.end())
+ ase.codecConfiguration.push_back(frame_duration_it->second);
+
+ CodecSpecificConfigurationLtv::AudioChannelAllocation channel_allocation;
+ populateAudioChannelAllocation(channel_allocation, audio_channel_allocation);
+ ase.codecConfiguration.push_back(channel_allocation);
+
+ auto octet_structure = CodecSpecificConfigurationLtv::OctetsPerCodecFrame();
+ octet_structure.value = octets_per_codec_frame;
+ ase.codecConfiguration.push_back(octet_structure);
+
+ auto frame_sdu_structure =
+ CodecSpecificConfigurationLtv::CodecFrameBlocksPerSDU();
+ frame_sdu_structure.value = codec_frames_blocks_per_sdu;
+ ase.codecConfiguration.push_back(frame_sdu_structure);
+ // TODO: Channel count
+}
+
+void AudioSetConfigurationProviderJson::populateAseConfiguration(
+ LeAudioAseConfiguration& ase,
+ const le_audio::AudioSetSubConfiguration* flat_subconfig,
+ const le_audio::QosConfiguration* qos_cfg) {
+ // Target latency
+ switch (qos_cfg->target_latency()) {
+ case le_audio::AudioSetConfigurationTargetLatency::
+ AudioSetConfigurationTargetLatency_BALANCED_RELIABILITY:
+ ase.targetLatency =
+ LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY;
+ break;
+ case le_audio::AudioSetConfigurationTargetLatency::
+ AudioSetConfigurationTargetLatency_HIGH_RELIABILITY:
+ ase.targetLatency =
+ LeAudioAseConfiguration::TargetLatency::HIGHER_RELIABILITY;
+ break;
+ case le_audio::AudioSetConfigurationTargetLatency::
+ AudioSetConfigurationTargetLatency_LOW:
+ ase.targetLatency = LeAudioAseConfiguration::TargetLatency::LOWER;
+ break;
+ default:
+ ase.targetLatency = LeAudioAseConfiguration::TargetLatency::UNDEFINED;
+ break;
+ };
+
+ ase.targetPhy = Phy::TWO_M;
+ // Making CodecId
+ if (flat_subconfig->codec_id()->coding_format() ==
+ (uint8_t)CodecId::Core::LC3) {
+ ase.codecId = CodecId::Core::LC3;
+ } else {
+ auto vendorC = CodecId::Vendor();
+ vendorC.codecId = flat_subconfig->codec_id()->vendor_codec_id();
+ vendorC.id = flat_subconfig->codec_id()->vendor_company_id();
+ ase.codecId = vendorC;
+ }
+ // Codec configuration data
+ populateConfigurationData(ase, flat_subconfig->codec_configuration());
+}
+
+void AudioSetConfigurationProviderJson::populateAseQosConfiguration(
+ LeAudioAseQosConfiguration& qos,
+ const le_audio::QosConfiguration* qos_cfg) {
+ qos.maxTransportLatencyMs = qos_cfg->max_transport_latency();
+ qos.retransmissionNum = qos_cfg->retransmission_number();
+}
+
+// Parse into AseDirectionConfiguration
+AseDirectionConfiguration
+AudioSetConfigurationProviderJson::SetConfigurationFromFlatSubconfig(
+ const le_audio::AudioSetSubConfiguration* flat_subconfig,
+ const le_audio::QosConfiguration* qos_cfg, CodecLocation location) {
+ AseDirectionConfiguration direction_conf;
+
+ LeAudioAseConfiguration ase;
+ LeAudioAseQosConfiguration qos;
+ LeAudioDataPathConfiguration path;
+
+ // Translate into LeAudioAseConfiguration
+ populateAseConfiguration(ase, flat_subconfig, qos_cfg);
+
+ // Translate into LeAudioAseQosConfiguration
+ populateAseQosConfiguration(qos, qos_cfg);
+
+ // Translate location to data path id
+ switch (location) {
+ case CodecLocation::ADSP:
+ path.isoDataPathConfiguration.isTransparent = true;
+ path.dataPathId = kIsoDataPathPlatformDefault;
+ break;
+ case CodecLocation::HOST:
+ path.isoDataPathConfiguration.isTransparent = true;
+ path.dataPathId = kIsoDataPathHci;
+ break;
+ case CodecLocation::CONTROLLER:
+ path.isoDataPathConfiguration.isTransparent = false;
+ path.dataPathId = kIsoDataPathPlatformDefault;
+ break;
+ }
+
+ direction_conf.aseConfiguration = ase;
+ direction_conf.qosConfiguration = qos;
+ direction_conf.dataPathConfiguration = path;
+
+ return direction_conf;
+}
+
+// Parse into AseDirectionConfiguration and the ConfigurationFlags
+// and put them in the given list.
+void AudioSetConfigurationProviderJson::processSubconfig(
+ const le_audio::AudioSetSubConfiguration* subconfig,
+ const le_audio::QosConfiguration* qos_cfg,
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ directionAseConfiguration,
+ CodecLocation location) {
+ directionAseConfiguration.push_back(
+ SetConfigurationFromFlatSubconfig(subconfig, qos_cfg, location));
+}
+
+void AudioSetConfigurationProviderJson::PopulateAseConfigurationFromFlat(
+ const le_audio::AudioSetConfiguration* flat_cfg,
+ std::vector<const le_audio::CodecConfiguration*>* codec_cfgs,
+ std::vector<const le_audio::QosConfiguration*>* qos_cfgs,
+ CodecLocation location,
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ sourceAseConfiguration,
+ std::vector<std::optional<AseDirectionConfiguration>>& sinkAseConfiguration,
+ ConfigurationFlags& /*configurationFlags*/) {
+ if (flat_cfg == nullptr) {
+ LOG(ERROR) << "flat_cfg cannot be null";
+ return;
+ }
+ std::string codec_config_key = flat_cfg->codec_config_name()->str();
+ auto* qos_config_key_array = flat_cfg->qos_config_name();
+
+ constexpr std::string_view default_qos = "QoS_Config_Balanced_Reliability";
+
+ std::string qos_sink_key(default_qos);
+ std::string qos_source_key(default_qos);
+
+ /* We expect maximum two QoS settings. First for Sink and second for Source
+ */
+ if (qos_config_key_array->size() > 0) {
+ qos_sink_key = qos_config_key_array->Get(0)->str();
+ if (qos_config_key_array->size() > 1) {
+ qos_source_key = qos_config_key_array->Get(1)->str();
+ } else {
+ qos_source_key = qos_sink_key;
+ }
+ }
+
+ LOG(INFO) << "Audio set config " << flat_cfg->name()->c_str()
+ << ": codec config " << codec_config_key.c_str() << ", qos_sink "
+ << qos_sink_key.c_str() << ", qos_source "
+ << qos_source_key.c_str();
+
+ // Find the first qos config that match the name
+ const le_audio::QosConfiguration* qos_sink_cfg = nullptr;
+ for (auto i = qos_cfgs->begin(); i != qos_cfgs->end(); ++i) {
+ if ((*i)->name()->str() == qos_sink_key) {
+ qos_sink_cfg = *i;
+ break;
+ }
+ }
+
+ const le_audio::QosConfiguration* qos_source_cfg = nullptr;
+ for (auto i = qos_cfgs->begin(); i != qos_cfgs->end(); ++i) {
+ if ((*i)->name()->str() == qos_source_key) {
+ qos_source_cfg = *i;
+ break;
+ }
+ }
+
+ // First codec_cfg with the same name
+ const le_audio::CodecConfiguration* codec_cfg = nullptr;
+ for (auto i = codec_cfgs->begin(); i != codec_cfgs->end(); ++i) {
+ if ((*i)->name()->str() == codec_config_key) {
+ codec_cfg = *i;
+ break;
+ }
+ }
+
+ // Process each subconfig and put it into the correct list
+ if (codec_cfg != nullptr && codec_cfg->subconfigurations()) {
+ /* Load subconfigurations */
+ for (auto subconfig : *codec_cfg->subconfigurations()) {
+ if (subconfig->direction() == kLeAudioDirectionSink) {
+ processSubconfig(subconfig, qos_sink_cfg, sinkAseConfiguration,
+ location);
+ } else {
+ processSubconfig(subconfig, qos_source_cfg, sourceAseConfiguration,
+ location);
+ }
+ }
+ } else {
+ if (codec_cfg == nullptr) {
+ LOG(ERROR) << "No codec config matching key " << codec_config_key.c_str()
+ << " found";
+ } else {
+ LOG(ERROR) << "Configuration '" << flat_cfg->name()->c_str()
+ << "' has no valid subconfigurations.";
+ }
+ }
+
+ // TODO: Populate information for ConfigurationFlags
+}
+
+bool AudioSetConfigurationProviderJson::LoadConfigurationsFromFiles(
+ const char* schema_file, const char* content_file, CodecLocation location) {
+ flatbuffers::Parser configurations_parser_;
+ std::string configurations_schema_binary_content;
+ bool ok = flatbuffers::LoadFile(schema_file, true,
+ &configurations_schema_binary_content);
+ LOG(INFO) << __func__ << ": Loading file " << schema_file;
+ if (!ok) return ok;
+
+ /* Load the binary schema */
+ ok = configurations_parser_.Deserialize(
+ (uint8_t*)configurations_schema_binary_content.c_str(),
+ configurations_schema_binary_content.length());
+ if (!ok) return ok;
+
+ /* Load the content from JSON */
+ std::string configurations_json_content;
+ LOG(INFO) << __func__ << ": Loading file " << content_file;
+ ok = flatbuffers::LoadFile(content_file, false, &configurations_json_content);
+ if (!ok) return ok;
+
+ /* Parse */
+ LOG(INFO) << __func__ << ": Parse JSON content";
+ ok = configurations_parser_.Parse(configurations_json_content.c_str());
+ if (!ok) return ok;
+
+ /* Import from flatbuffers */
+ LOG(INFO) << __func__ << ": Build flat buffer structure";
+ auto configurations_root = le_audio::GetAudioSetConfigurations(
+ configurations_parser_.builder_.GetBufferPointer());
+ if (!configurations_root) return false;
+
+ auto flat_qos_configs = configurations_root->qos_configurations();
+ if ((flat_qos_configs == nullptr) || (flat_qos_configs->size() == 0))
+ return false;
+
+ LOG(DEBUG) << ": Updating " << flat_qos_configs->size()
+ << " qos config entries.";
+ std::vector<const le_audio::QosConfiguration*> qos_cfgs;
+ for (auto const& flat_qos_cfg : *flat_qos_configs) {
+ qos_cfgs.push_back(flat_qos_cfg);
+ }
+
+ auto flat_codec_configs = configurations_root->codec_configurations();
+ if ((flat_codec_configs == nullptr) || (flat_codec_configs->size() == 0))
+ return false;
+
+ LOG(DEBUG) << ": Updating " << flat_codec_configs->size()
+ << " codec config entries.";
+ std::vector<const le_audio::CodecConfiguration*> codec_cfgs;
+ for (auto const& flat_codec_cfg : *flat_codec_configs) {
+ codec_cfgs.push_back(flat_codec_cfg);
+ }
+
+ auto flat_configs = configurations_root->configurations();
+ if ((flat_configs == nullptr) || (flat_configs->size() == 0)) return false;
+
+ LOG(DEBUG) << ": Updating " << flat_configs->size() << " config entries.";
+ for (auto const& flat_cfg : *flat_configs) {
+ // Create 3 vector to use
+ std::vector<std::optional<AseDirectionConfiguration>>
+ sourceAseConfiguration;
+ std::vector<std::optional<AseDirectionConfiguration>> sinkAseConfiguration;
+ ConfigurationFlags configurationFlags;
+ PopulateAseConfigurationFromFlat(flat_cfg, &codec_cfgs, &qos_cfgs, location,
+ sourceAseConfiguration,
+ sinkAseConfiguration, configurationFlags);
+ if (sourceAseConfiguration.empty() && sinkAseConfiguration.empty())
+ continue;
+ configurations_[flat_cfg->name()->str()] = std::make_tuple(
+ sourceAseConfiguration, sinkAseConfiguration, configurationFlags);
+ }
+
+ return true;
+}
+
+bool AudioSetConfigurationProviderJson::LoadScenariosFromFiles(
+ const char* schema_file, const char* content_file) {
+ flatbuffers::Parser scenarios_parser_;
+ std::string scenarios_schema_binary_content;
+ bool ok = flatbuffers::LoadFile(schema_file, true,
+ &scenarios_schema_binary_content);
+ LOG(INFO) << __func__ << ": Loading file " << schema_file;
+ if (!ok) return ok;
+
+ /* Load the binary schema */
+ ok = scenarios_parser_.Deserialize(
+ (uint8_t*)scenarios_schema_binary_content.c_str(),
+ scenarios_schema_binary_content.length());
+ if (!ok) return ok;
+
+ /* Load the content from JSON */
+ LOG(INFO) << __func__ << ": Loading file " << content_file;
+ std::string scenarios_json_content;
+ ok = flatbuffers::LoadFile(content_file, false, &scenarios_json_content);
+ if (!ok) return ok;
+
+ /* Parse */
+ LOG(INFO) << __func__ << ": Parse json content";
+ ok = scenarios_parser_.Parse(scenarios_json_content.c_str());
+ if (!ok) return ok;
+
+ /* Import from flatbuffers */
+ LOG(INFO) << __func__ << ": Build flat buffer structure";
+ auto scenarios_root = le_audio::GetAudioSetScenarios(
+ scenarios_parser_.builder_.GetBufferPointer());
+ if (!scenarios_root) return false;
+
+ auto flat_scenarios = scenarios_root->scenarios();
+ if ((flat_scenarios == nullptr) || (flat_scenarios->size() == 0))
+ return false;
+
+ LOG(INFO) << __func__ << ": Turn flat buffer into structure";
+ AudioContext media_context = AudioContext();
+ media_context.bitmask =
+ (AudioContext::ALERTS | AudioContext::INSTRUCTIONAL |
+ AudioContext::NOTIFICATIONS | AudioContext::EMERGENCY_ALARM |
+ AudioContext::UNSPECIFIED | AudioContext::MEDIA);
+
+ AudioContext conversational_context = AudioContext();
+ conversational_context.bitmask =
+ (AudioContext::RINGTONE_ALERTS | AudioContext::CONVERSATIONAL);
+
+ AudioContext live_context = AudioContext();
+ live_context.bitmask = AudioContext::LIVE_AUDIO;
+
+ AudioContext game_context = AudioContext();
+ game_context.bitmask = AudioContext::GAME;
+
+ AudioContext voice_assistants_context = AudioContext();
+ voice_assistants_context.bitmask = AudioContext::VOICE_ASSISTANTS;
+
+ LOG(DEBUG) << "Updating " << flat_scenarios->size() << " scenarios.";
+ for (auto const& scenario : *flat_scenarios) {
+ LOG(DEBUG) << "Scenario " << scenario->name()->c_str()
+ << " configs: " << scenario->configurations()->size();
+
+ if (!scenario->configurations()) continue;
+ std::string scenario_name = scenario->name()->c_str();
+ AudioContext context;
+ if (scenario_name == "Media")
+ context = AudioContext(media_context);
+ else if (scenario_name == "Conversational")
+ context = AudioContext(conversational_context);
+ else if (scenario_name == "Live")
+ context = AudioContext(live_context);
+ else if (scenario_name == "Game")
+ context = AudioContext(game_context);
+ else if (scenario_name == "VoiceAssistants")
+ context = AudioContext(voice_assistants_context);
+
+ for (auto it = scenario->configurations()->begin();
+ it != scenario->configurations()->end(); ++it) {
+ auto config_name = it->str();
+ auto configuration = configurations_.find(config_name);
+ if (configuration == configurations_.end()) continue;
+ LOG(DEBUG) << "Getting configuration with name: " << config_name;
+ auto [source, sink, flags] = configuration->second;
+ // Each configuration will create a LeAudioAseConfigurationSetting
+ // with the same {context, packing}
+ // and different data
+ LeAudioAseConfigurationSetting setting;
+ setting.audioContext = context;
+ // TODO: Packing
+ setting.sourceAseConfiguration = source;
+ setting.sinkAseConfiguration = sink;
+ setting.flags = flags;
+ // Add to list of setting
+ LOG(DEBUG) << "Pushing configuration to list: " << config_name;
+ ase_configuration_settings_.push_back(setting);
+ }
+ }
+
+ return true;
+}
+
+bool AudioSetConfigurationProviderJson::LoadContent(
+ std::vector<std::pair<const char* /*schema*/, const char* /*content*/>>
+ config_files,
+ std::vector<std::pair<const char* /*schema*/, const char* /*content*/>>
+ scenario_files,
+ CodecLocation location) {
+ for (auto [schema, content] : config_files) {
+ if (!LoadConfigurationsFromFiles(schema, content, location)) return false;
+ }
+
+ for (auto [schema, content] : scenario_files) {
+ if (!LoadScenariosFromFiles(schema, content)) return false;
+ }
+ return true;
+}
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.h b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.h
new file mode 100644
index 0000000..ce91fca
--- /dev/null
+++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.h
@@ -0,0 +1,125 @@
+
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.h>
+
+#include <map>
+#include <mutex>
+#include <optional>
+#include <string>
+#include <string_view>
+#include <tuple>
+
+#include "audio_set_configurations_generated.h"
+#include "audio_set_scenarios_generated.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+using LeAudioAseConfigurationSetting =
+ IBluetoothAudioProvider::LeAudioAseConfigurationSetting;
+using AseDirectionConfiguration = IBluetoothAudioProvider::
+ LeAudioAseConfigurationSetting::AseDirectionConfiguration;
+using LeAudioAseQosConfiguration =
+ IBluetoothAudioProvider::LeAudioAseQosConfiguration;
+using LeAudioDataPathConfiguration =
+ IBluetoothAudioProvider::LeAudioDataPathConfiguration;
+
+enum class CodecLocation {
+ HOST,
+ ADSP,
+ CONTROLLER,
+};
+
+class AudioSetConfigurationProviderJson {
+ public:
+ static std::vector<LeAudioAseConfigurationSetting>
+ GetLeAudioAseConfigurationSettings();
+
+ private:
+ static void LoadAudioSetConfigurationProviderJson();
+
+ static const le_audio::CodecSpecificConfiguration* LookupCodecSpecificParam(
+ const flatbuffers::Vector<flatbuffers::Offset<
+ le_audio::CodecSpecificConfiguration>>* flat_codec_specific_params,
+ le_audio::CodecSpecificLtvGenericTypes type);
+
+ static void populateAudioChannelAllocation(
+ CodecSpecificConfigurationLtv::AudioChannelAllocation&
+ audio_channel_allocation,
+ uint32_t audio_location);
+
+ static void populateConfigurationData(
+ LeAudioAseConfiguration& ase,
+ const flatbuffers::Vector<
+ flatbuffers::Offset<le_audio::CodecSpecificConfiguration>>*
+ flat_codec_specific_params);
+
+ static void populateAseConfiguration(
+ LeAudioAseConfiguration& ase,
+ const le_audio::AudioSetSubConfiguration* flat_subconfig,
+ const le_audio::QosConfiguration* qos_cfg);
+
+ static void populateAseQosConfiguration(
+ LeAudioAseQosConfiguration& qos,
+ const le_audio::QosConfiguration* qos_cfg);
+
+ static AseDirectionConfiguration SetConfigurationFromFlatSubconfig(
+ const le_audio::AudioSetSubConfiguration* flat_subconfig,
+ const le_audio::QosConfiguration* qos_cfg, CodecLocation location);
+
+ static void processSubconfig(
+ const le_audio::AudioSetSubConfiguration* subconfig,
+ const le_audio::QosConfiguration* qos_cfg,
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ directionAseConfiguration,
+ CodecLocation location);
+
+ static void PopulateAseConfigurationFromFlat(
+ const le_audio::AudioSetConfiguration* flat_cfg,
+ std::vector<const le_audio::CodecConfiguration*>* codec_cfgs,
+ std::vector<const le_audio::QosConfiguration*>* qos_cfgs,
+ CodecLocation location,
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ sourceAseConfiguration,
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ sinkAseConfiguration,
+ ConfigurationFlags& configurationFlags);
+
+ static bool LoadConfigurationsFromFiles(const char* schema_file,
+ const char* content_file,
+ CodecLocation location);
+
+ static bool LoadScenariosFromFiles(const char* schema_file,
+ const char* content_file);
+
+ static bool LoadContent(
+ std::vector<std::pair<const char* /*schema*/, const char* /*content*/>>
+ config_files,
+ std::vector<std::pair<const char* /*schema*/, const char* /*content*/>>
+ scenario_files,
+ CodecLocation location);
+};
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp
index 26da5fb..473777c 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp
@@ -14,6 +14,11 @@
* limitations under the License.
*/
+#include <set>
+
+#include "aidl/android/hardware/bluetooth/audio/ChannelMode.h"
+#include "aidl/android/hardware/bluetooth/audio/CodecId.h"
+#include "aidl_android_hardware_bluetooth_audio_setting_enums.h"
#define LOG_TAG "BTAudioCodecsProviderAidl"
#include "BluetoothLeAudioCodecsProvider.h"
@@ -38,9 +43,6 @@
std::optional<setting::LeAudioOffloadSetting>
BluetoothLeAudioCodecsProvider::ParseFromLeAudioOffloadSettingFile() {
- if (!leAudioCodecCapabilities.empty() || isInvalidFileContent) {
- return std::nullopt;
- }
auto le_audio_offload_setting =
setting::readLeAudioOffloadSetting(kLeAudioCodecCapabilitiesFile);
if (!le_audio_offload_setting.has_value()) {
@@ -50,6 +52,131 @@
return le_audio_offload_setting;
}
+std::unordered_map<SessionType, std::vector<CodecInfo>>
+BluetoothLeAudioCodecsProvider::GetLeAudioCodecInfo(
+ const std::optional<setting::LeAudioOffloadSetting>&
+ le_audio_offload_setting) {
+ // Load from previous storage if present
+ if (!session_codecs_map_.empty()) return session_codecs_map_;
+
+ isInvalidFileContent = true;
+ if (!le_audio_offload_setting.has_value()) return {};
+
+ // Load scenario, configuration, codec configuration and strategy
+ LoadConfigurationToMap(le_audio_offload_setting);
+ if (supported_scenarios_.empty() || configuration_map_.empty() ||
+ codec_configuration_map_.empty() || strategy_configuration_map_.empty())
+ return {};
+
+ // Map each configuration into a CodecInfo
+ std::unordered_map<std::string, CodecInfo> config_codec_info_map_;
+
+ for (auto& p : configuration_map_) {
+ // Initialize new CodecInfo for the config
+ auto config_name = p.first;
+
+ // Getting informations from codecConfig and strategyConfig
+ const auto codec_config_name = p.second.getCodecConfiguration();
+ const auto strategy_config_name = p.second.getStrategyConfiguration();
+ const auto codec_configuration_map_iter =
+ codec_configuration_map_.find(codec_config_name);
+ if (codec_configuration_map_iter == codec_configuration_map_.end())
+ continue;
+ const auto strategy_configuration_map_iter =
+ strategy_configuration_map_.find(strategy_config_name);
+ if (strategy_configuration_map_iter == strategy_configuration_map_.end())
+ continue;
+
+ if (config_codec_info_map_.count(config_name) == 0)
+ config_codec_info_map_[config_name] = CodecInfo();
+
+ const auto& codec_config = codec_configuration_map_iter->second;
+ const auto codec = codec_config.getCodec();
+ const auto& strategy_config = strategy_configuration_map_iter->second;
+ const auto strategy_config_channel_count =
+ strategy_config.getChannelCount();
+
+ // Initiate information
+ auto& codec_info = config_codec_info_map_[config_name];
+ switch (codec) {
+ case setting::CodecType::LC3:
+ codec_info.name = "LC3";
+ codec_info.id = CodecId::Core::LC3;
+ break;
+ default:
+ codec_info.name = "UNDEFINE";
+ codec_info.id = CodecId::Vendor();
+ break;
+ }
+ codec_info.transport =
+ CodecInfo::Transport::make<CodecInfo::Transport::Tag::leAudio>();
+
+ // Mapping codec configuration information
+ auto& transport =
+ codec_info.transport.get<CodecInfo::Transport::Tag::leAudio>();
+ transport.samplingFrequencyHz.push_back(
+ codec_config.getSamplingFrequency());
+ // Mapping octetsPerCodecFrame to bitdepth for easier comparison.
+ transport.bitdepth.push_back(codec_config.getOctetsPerCodecFrame());
+ transport.frameDurationUs.push_back(codec_config.getFrameDurationUs());
+ switch (strategy_config.getAudioLocation()) {
+ case setting::AudioLocation::MONO:
+ if (strategy_config_channel_count == 1)
+ transport.channelMode.push_back(ChannelMode::MONO);
+ else
+ transport.channelMode.push_back(ChannelMode::DUALMONO);
+ break;
+ case setting::AudioLocation::STEREO:
+ transport.channelMode.push_back(ChannelMode::STEREO);
+ break;
+ default:
+ transport.channelMode.push_back(ChannelMode::UNKNOWN);
+ break;
+ }
+ }
+
+ // Goes through every scenario, deduplicate configuration, skip the invalid
+ // config references (e.g. the "invalid" entries in the xml file).
+ std::set<std::string> encoding_config, decoding_config, broadcast_config;
+ for (auto& s : supported_scenarios_) {
+ if (s.hasEncode() && config_codec_info_map_.count(s.getEncode())) {
+ encoding_config.insert(s.getEncode());
+ }
+ if (s.hasDecode() && config_codec_info_map_.count(s.getDecode())) {
+ decoding_config.insert(s.getDecode());
+ }
+ if (s.hasBroadcast() && config_codec_info_map_.count(s.getBroadcast())) {
+ broadcast_config.insert(s.getBroadcast());
+ }
+ }
+
+ // Split by session types and add results
+ const auto encoding_path =
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
+ const auto decoding_path =
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH;
+ const auto broadcast_path =
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
+ session_codecs_map_ =
+ std::unordered_map<SessionType, std::vector<CodecInfo>>();
+ session_codecs_map_[encoding_path] = std::vector<CodecInfo>();
+ session_codecs_map_[decoding_path] = std::vector<CodecInfo>();
+ session_codecs_map_[broadcast_path] = std::vector<CodecInfo>();
+ session_codecs_map_[encoding_path].reserve(encoding_config.size());
+ session_codecs_map_[decoding_path].reserve(decoding_config.size());
+ session_codecs_map_[broadcast_path].reserve(broadcast_config.size());
+ for (auto& c : encoding_config)
+ session_codecs_map_[encoding_path].push_back(config_codec_info_map_[c]);
+ for (auto& c : decoding_config)
+ session_codecs_map_[decoding_path].push_back(config_codec_info_map_[c]);
+ for (auto& c : broadcast_config)
+ session_codecs_map_[broadcast_path].push_back(config_codec_info_map_[c]);
+
+ isInvalidFileContent = session_codecs_map_.empty();
+
+ return session_codecs_map_;
+}
+
std::vector<LeAudioCodecCapabilitiesSetting>
BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities(
const std::optional<setting::LeAudioOffloadSetting>&
@@ -58,6 +185,8 @@
return leAudioCodecCapabilities;
}
+ isInvalidFileContent = true;
+
if (!le_audio_offload_setting.has_value()) {
LOG(ERROR)
<< __func__
@@ -65,40 +194,13 @@
return {};
}
- ClearLeAudioCodecCapabilities();
- isInvalidFileContent = true;
-
- std::vector<setting::Scenario> supported_scenarios =
- GetScenarios(le_audio_offload_setting);
- if (supported_scenarios.empty()) {
- LOG(ERROR) << __func__ << ": No scenarios in "
- << kLeAudioCodecCapabilitiesFile;
+ LoadConfigurationToMap(le_audio_offload_setting);
+ if (supported_scenarios_.empty() || configuration_map_.empty() ||
+ codec_configuration_map_.empty() || strategy_configuration_map_.empty())
return {};
- }
-
- UpdateConfigurationsToMap(le_audio_offload_setting);
- if (configuration_map_.empty()) {
- LOG(ERROR) << __func__ << ": No configurations in "
- << kLeAudioCodecCapabilitiesFile;
- return {};
- }
-
- UpdateCodecConfigurationsToMap(le_audio_offload_setting);
- if (codec_configuration_map_.empty()) {
- LOG(ERROR) << __func__ << ": No codec configurations in "
- << kLeAudioCodecCapabilitiesFile;
- return {};
- }
-
- UpdateStrategyConfigurationsToMap(le_audio_offload_setting);
- if (strategy_configuration_map_.empty()) {
- LOG(ERROR) << __func__ << ": No strategy configurations in "
- << kLeAudioCodecCapabilitiesFile;
- return {};
- }
leAudioCodecCapabilities =
- ComposeLeAudioCodecCapabilities(supported_scenarios);
+ ComposeLeAudioCodecCapabilities(supported_scenarios_);
isInvalidFileContent = leAudioCodecCapabilities.empty();
return leAudioCodecCapabilities;
@@ -109,6 +211,8 @@
configuration_map_.clear();
codec_configuration_map_.clear();
strategy_configuration_map_.clear();
+ session_codecs_map_.clear();
+ supported_scenarios_.clear();
}
std::vector<setting::Scenario> BluetoothLeAudioCodecsProvider::GetScenarios(
@@ -191,6 +295,40 @@
}
}
+void BluetoothLeAudioCodecsProvider::LoadConfigurationToMap(
+ const std::optional<setting::LeAudioOffloadSetting>&
+ le_audio_offload_setting) {
+ ClearLeAudioCodecCapabilities();
+
+ supported_scenarios_ = GetScenarios(le_audio_offload_setting);
+ if (supported_scenarios_.empty()) {
+ LOG(ERROR) << __func__ << ": No scenarios in "
+ << kLeAudioCodecCapabilitiesFile;
+ return;
+ }
+
+ UpdateConfigurationsToMap(le_audio_offload_setting);
+ if (configuration_map_.empty()) {
+ LOG(ERROR) << __func__ << ": No configurations in "
+ << kLeAudioCodecCapabilitiesFile;
+ return;
+ }
+
+ UpdateCodecConfigurationsToMap(le_audio_offload_setting);
+ if (codec_configuration_map_.empty()) {
+ LOG(ERROR) << __func__ << ": No codec configurations in "
+ << kLeAudioCodecCapabilitiesFile;
+ return;
+ }
+
+ UpdateStrategyConfigurationsToMap(le_audio_offload_setting);
+ if (strategy_configuration_map_.empty()) {
+ LOG(ERROR) << __func__ << ": No strategy configurations in "
+ << kLeAudioCodecCapabilitiesFile;
+ return;
+ }
+}
+
std::vector<LeAudioCodecCapabilitiesSetting>
BluetoothLeAudioCodecsProvider::ComposeLeAudioCodecCapabilities(
const std::vector<setting::Scenario>& supported_scenarios) {
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h
index 654e70c..5bf67e2 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h
@@ -22,6 +22,8 @@
#include <unordered_map>
#include <vector>
+#include "aidl/android/hardware/bluetooth/audio/CodecInfo.h"
+#include "aidl/android/hardware/bluetooth/audio/SessionType.h"
#include "aidl_android_hardware_bluetooth_audio_setting.h"
namespace aidl {
@@ -39,14 +41,20 @@
const std::optional<setting::LeAudioOffloadSetting>&
le_audio_offload_setting);
static void ClearLeAudioCodecCapabilities();
+ static std::unordered_map<SessionType, std::vector<CodecInfo>>
+ GetLeAudioCodecInfo(const std::optional<setting::LeAudioOffloadSetting>&
+ le_audio_offload_setting);
private:
+ static inline std::vector<setting::Scenario> supported_scenarios_;
static inline std::unordered_map<std::string, setting::Configuration>
configuration_map_;
static inline std::unordered_map<std::string, setting::CodecConfiguration>
codec_configuration_map_;
static inline std::unordered_map<std::string, setting::StrategyConfiguration>
strategy_configuration_map_;
+ static inline std::unordered_map<SessionType, std::vector<CodecInfo>>
+ session_codecs_map_;
static std::vector<setting::Scenario> GetScenarios(
const std::optional<setting::LeAudioOffloadSetting>&
@@ -60,6 +68,9 @@
static void UpdateStrategyConfigurationsToMap(
const std::optional<setting::LeAudioOffloadSetting>&
le_audio_offload_setting);
+ static void LoadConfigurationToMap(
+ const std::optional<setting::LeAudioOffloadSetting>&
+ le_audio_offload_setting);
static std::vector<LeAudioCodecCapabilitiesSetting>
ComposeLeAudioCodecCapabilities(
diff --git a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp
index 3d92ee7..fd12a6e 100644
--- a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp
+++ b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp
@@ -467,6 +467,8 @@
hidl_audio_config.codecConfig(to_hidl_codec_config_2_0(
audio_config.get<AudioConfiguration::a2dpConfig>()));
break;
+ case AudioConfiguration::a2dp:
+ break;
case AudioConfiguration::leAudioConfig:
hidl_audio_config.leAudioCodecConfig(to_hidl_leaudio_config_2_1(
audio_config.get<AudioConfiguration::leAudioConfig>()));
@@ -475,6 +477,8 @@
hidl_audio_config.leAudioCodecConfig(to_hidl_leaudio_broadcast_config_2_1(
audio_config.get<AudioConfiguration::leAudioBroadcastConfig>()));
break;
+ default:
+ LOG(FATAL) << __func__ << ": unexpected AudioConfiguration";
}
return hidl_audio_config;
}
diff --git a/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.fbs b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.fbs
new file mode 100644
index 0000000..bde467d
--- /dev/null
+++ b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.fbs
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2022 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.
+ *
+ */
+namespace aidl.android.hardware.bluetooth.audio.le_audio;
+enum CodecSpecificLtvGenericTypes : byte {
+ SUPPORTED_SAMPLING_FREQUENCY = 0x01,
+ SUPPORTED_FRAME_DURATION = 0x02,
+ SUPPORTED_AUDIO_CHANNEL_ALLOCATION = 0x03,
+ SUPPORTED_OCTETS_PER_CODEC_FRAME = 0x04,
+ SUPPORTED_CODEC_FRAME_BLOCKS_PER_SDU = 0x05,
+}
+/// Note: Holds either a single value (when `value_width == 0`) or multiple
+/// values if `value.length()` is no-remainder divisible by the non-zero
+/// `value_width`.
+/// Note: Consider extending it with `flags` field, to hold additional info like
+/// IsBitfield, IsRange, etc. if we need these type-specific validations.
+table CompoundValue {
+ value: [ubyte] (required);
+ value_width: ubyte = 0;
+}
+table CodecSpecificConfiguration {
+ name: string;
+ type: ubyte (key);
+ compound_value: CompoundValue;
+}
+struct CodecId {
+ coding_format: ubyte;
+ vendor_company_id : ushort;
+ vendor_codec_id : ushort;
+}
+enum AudioSetConfigurationStrategy : byte {
+ MONO_ONE_CIS_PER_DEVICE = 0x00,
+ STEREO_TWO_CISES_PER_DEVICE = 0x01,
+ STEREO_ONE_CIS_PER_DEVICE = 0x02,
+}
+enum AudioSetConfigurationDirection : byte {
+ SINK = 0x01,
+ SOURCE = 0x02,
+}
+enum AudioSetConfigurationTargetLatency : byte {
+ LOW = 0x01,
+ BALANCED_RELIABILITY = 0x02,
+ HIGH_RELIABILITY = 0x03,
+}
+table AudioSetSubConfiguration {
+ device_cnt: ubyte;
+ ase_cnt: ubyte;
+ direction: AudioSetConfigurationDirection = SINK;
+ configuration_strategy: AudioSetConfigurationStrategy;
+ codec_id : CodecId (required);
+ codec_configuration: [CodecSpecificConfiguration] (required);
+}
+table CodecConfiguration {
+ name: string (key, required);
+ subconfigurations: [AudioSetSubConfiguration] (required);
+}
+table QosConfiguration {
+ name: string (key, required);
+ target_latency: AudioSetConfigurationTargetLatency = BALANCED_RELIABILITY;
+ retransmission_number: ubyte;
+ max_transport_latency : ushort;
+}
+/// Each set configration can contain multiple logical subconfigurations, which
+/// all must be configurable with the current set of audio devices. For example,
+/// one can define multiple output stream configurations with different
+/// qualities, or assign different configurations to each stream direction.
+table AudioSetConfiguration {
+ name: string (key, required);
+ codec_config_name: string (required);
+ qos_config_name: [string] (required);
+}
+table AudioSetConfigurations {
+ _comments_: [string];
+ configurations: [AudioSetConfiguration] (required);
+ codec_configurations: [CodecConfiguration] (required);
+ qos_configurations: [QosConfiguration] (required);
+}
+root_type AudioSetConfigurations;
diff --git a/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.json b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.json
new file mode 100644
index 0000000..404a48a
--- /dev/null
+++ b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.json
@@ -0,0 +1,11382 @@
+{
+ "_comments_": [
+ " == Audio Set Configurations == ",
+ " Contains: ",
+ " 1. configurations : ",
+ " Maps configuration name with codec and qos config to be used",
+ " 2. codec_configurations : ",
+ " Array of codec specific configurations",
+ " 3. qos_configurations : ",
+ " Array of QoS specific configurations",
+ " QoS configuration values are as per BAP spec 1.0",
+ " Example values which can be used as 'codec_configuration.type'",
+ " Codec Configuration parameter types:",
+ " SUPPORTED_SAMPLING_FREQUENCY = 1",
+ " SUPPORTED_FRAME_DURATION = 2",
+ " SUPPORTED_AUDIO_CHANNEL_ALLOCATION = 3",
+ " SUPPORTED_OCTETS_PER_CODEC_FRAME = 4",
+ " SUPPORTED_CODEC_FRAME_BLOCKS_PER_SDU = 5",
+ " Example values which can be used as 'codec_configuration.compound_value'",
+ " Codec Coding formats:",
+ " LC3 = 6",
+ " ASE Configuration strategies:",
+ " MONO_ONE_CIS_PER_DEVICE = 0",
+ " STEREO_TWO_CISES_PER_DEVICE = 1",
+ " STEREO_ONE_CIS_PER_DEVICE = 2",
+ " Sampling Frequencies: ",
+ " 8000Hz = 1",
+ " 11025Hz = 2",
+ " 16000Hz = 3",
+ " 22050Hz = 4",
+ " 24000Hz = 5",
+ " 32000Hz = 6",
+ " 44100Hz = 7",
+ " 48000Hz = 8",
+ " 88200Hz = 9",
+ " 96000Hz = 10",
+ " 176400Hz = 11",
+ " 192000Hz = 12",
+ " 384000Hz = 13",
+ " Frame Durations:",
+ " 7500us = 0",
+ " 10000us = 1"
+ ],
+ "configurations": [
+ {
+ "name": "DualDev_OneChanStereoSnk_16_1_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_16_1_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_16_1_1",
+ "codec_config_name": "DualDev_OneChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_16_1_2",
+ "codec_config_name": "DualDev_OneChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_16_2_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_16_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_16_2_1",
+ "codec_config_name": "DualDev_OneChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_16_2_2",
+ "codec_config_name": "DualDev_OneChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_16_1_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_16_1_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_16_1_1",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_16_1_2",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_16_2_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_16_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_16_2_1",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_16_2_2",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_16_1_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_16_1_Balanced_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_16_1_1",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_16_1_2",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_16_2_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_16_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_16_2_1",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_16_2_2",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_32_1_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_32_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_32_1_1",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_32_1",
+ "qos_config_name": [
+ "QoS_Config_32_1_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_32_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_32_2_1",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_16_1_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_16_1_1",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_16_1_2",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanMonoSnk_16_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanMonoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_16_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_16_2_1",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_16_2_2",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1_1",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1_2",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_2",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_1",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_2",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_1",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2_1",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2_2",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_1",
+ "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_1",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_2",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_1",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_2",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_1",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_2",
+ "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_1",
+ "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_2",
+ "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_1",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_2",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_1",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_2",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_1",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_2",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_1",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_2",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_1",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSrc_16_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanStereoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_48_4_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSrc_48_4",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_48_3_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSrc_48_3",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_48_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSrc_48_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_48_1_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSrc_48_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_32_1_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSrc_32_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_24_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSrc_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_24_1_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSrc_24_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_16_1_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_2",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_1",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_2",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_24_1_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_24_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_24_1_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_24_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_24_1_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_24_2_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_24_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_24_2_2",
+ "codec_config_name": "DualDev_OneChanStereoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_24_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_24_2_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_24_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_24_2_2",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_24_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_24_2_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_24_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_24_2_2",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_24_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_24_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_24_2_2",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_24_2_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_1",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2_1",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_32_2_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_32_1_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_32_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_32_1_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_32_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_32_2_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_32_1_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_32_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2_1",
+ "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_1",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_1",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_1",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_32_2_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_High_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_1",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_2",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_3_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_3",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_3_High_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_3",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_3_2",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_3",
+ "qos_config_name": [
+ "QoS_Config_48_3_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_2_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_2_High_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_2",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_2_2",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_2",
+ "qos_config_name": [
+ "QoS_Config_48_2_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_1_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_1_High_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_1",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_1_2",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_1",
+ "qos_config_name": [
+ "QoS_Config_48_1_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_4_High_Reliability",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_4_1",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_4_2",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_3_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_3",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_3_High_Reliability",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_3",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_3_2",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_3",
+ "qos_config_name": [
+ "QoS_Config_48_3_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_2_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_2_High_Reliability",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_2",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_2_2",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_2",
+ "qos_config_name": [
+ "QoS_Config_48_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_1_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_1_High_Reliability",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_1",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_1_2",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_1",
+ "qos_config_name": [
+ "QoS_Config_48_1_2"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_High_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_1",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_1"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_2",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_2"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_3_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_3",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_3_High_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_3",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_3_2",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_3",
+ "qos_config_name": [
+ "QoS_Config_48_3_2"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_2_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_2_High_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_2",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_2_2",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_2",
+ "qos_config_name": [
+ "QoS_Config_48_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_1_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_1_High_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_1",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_1_2",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_1",
+ "qos_config_name": [
+ "QoS_Config_48_1_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_4_High_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_4_1",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_4_2",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_3_High_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_48_3",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_3_2",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_48_3",
+ "qos_config_name": [
+ "QoS_Config_48_3_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_2_High_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_48_2",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_2_2",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_48_2",
+ "qos_config_name": [
+ "QoS_Config_48_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_1_High_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_48_1",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_1_2",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_48_1",
+ "qos_config_name": [
+ "QoS_Config_48_1_2"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60octs_Low_Latency_1",
+ "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60octs_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60oct_R3_L22_1",
+ "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60octs_1",
+ "qos_config_name": [
+ "VND_QoS_Config_R3_L22"
+ ]
+ },
+ {
+ "name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_High_Reliability_1",
+ "codec_config_name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_1",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_R15_L70_1",
+ "codec_config_name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_1",
+ "qos_config_name": [
+ "VND_QoS_Config_R15_L70"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_High_Reliability_1",
+ "codec_config_name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_1",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_R15_L70_1",
+ "codec_config_name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_1",
+ "qos_config_name": [
+ "VND_QoS_Config_R15_L70"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_High_Reliability_1",
+ "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_1",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_R15_L70_1",
+ "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_1",
+ "qos_config_name": [
+ "VND_QoS_Config_R15_L70"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_High_Reliability_1",
+ "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_1",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_R5_L12_1",
+ "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_1",
+ "qos_config_name": [
+ "VND_QoS_Config_R5_L12"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_32_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_24_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_16_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_32_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_24_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_16_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_1_OneChanMonoSrc_24_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_1_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_4_1_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_4_1_OneChanMonoSrc_24_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_4_1_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_4_1_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_4_1_OneChanMonoSrc_24_2_1_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_4_1_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_Balanced_Reliability_1",
+ "codec_config_name": "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_R11_L40_1",
+ "codec_config_name": "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_1",
+ "qos_config_name": [
+ "VND_QoS_Config_R11_L40"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_R5_L12_TwoChanStereoSrc_16khz_30octs_R3_L12_1",
+ "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_TwoChanStereoSrc_16khz_30octs_1",
+ "qos_config_name": [
+ "VND_QoS_Config_R5_L12",
+ "VND_QoS_Config_R3_L12"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_TwoChanStereoSrc_16khz_30octs_Balanced_Reliability_1",
+ "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_TwoChanStereoSrc_16khz_30octs_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ }
+ ],
+ "codec_configurations": [
+ {
+ "name": "DualDev_OneChanStereoSnk_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_24_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_32_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_32_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanMonoSnk_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 4,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 4,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_48_4",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_48_3",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 90,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_48_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 100,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_48_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 75,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_32_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_24_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_24_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 45,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_3",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 90,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 100,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 75,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_4",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_3",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 90,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 100,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 75,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_3",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 90,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 100,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 75,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_4",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_3",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 90,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 100,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 75,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 100,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 100,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 100,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 75,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_24_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 4,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 4,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 4,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_24_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_24_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 75,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 75,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 100,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 100,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 100,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60octs_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_TwoChanStereoSrc_16khz_30octs_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 75,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_24_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_24_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 45,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_24_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_24_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 45,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_24_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_24_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 45,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_24_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 4,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_32_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_32_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "qos_configurations": [
+ {
+ "name": "QoS_Config_16_1_1",
+ "retransmission_number": 2,
+ "max_transport_latency": 8
+ },
+ {
+ "name": "QoS_Config_16_1_2",
+ "retransmission_number": 13,
+ "max_transport_latency": 75
+ },
+ {
+ "name": "QoS_Config_16_2_1",
+ "retransmission_number": 2,
+ "max_transport_latency": 10
+ },
+ {
+ "name": "QoS_Config_16_2_2",
+ "retransmission_number": 13,
+ "max_transport_latency": 95
+ },
+ {
+ "name": "QoS_Config_24_1_1",
+ "retransmission_number": 2,
+ "max_transport_latency": 8
+ },
+ {
+ "name": "QoS_Config_24_1_2",
+ "retransmission_number": 13,
+ "max_transport_latency": 75
+ },
+ {
+ "name": "QoS_Config_24_2_1",
+ "retransmission_number": 2,
+ "max_transport_latency": 10
+ },
+ {
+ "name": "QoS_Config_24_2_2",
+ "retransmission_number": 13,
+ "max_transport_latency": 95
+ },
+ {
+ "name": "QoS_Config_32_1_1",
+ "retransmission_number": 2,
+ "max_transport_latency": 8
+ },
+ {
+ "name": "QoS_Config_32_1_2",
+ "retransmission_number": 13,
+ "max_transport_latency": 75
+ },
+ {
+ "name": "QoS_Config_32_2_1",
+ "retransmission_number": 2,
+ "max_transport_latency": 10
+ },
+ {
+ "name": "QoS_Config_32_2_2",
+ "retransmission_number": 13,
+ "max_transport_latency": 95
+ },
+ {
+ "name": "QoS_Config_48_1_2",
+ "retransmission_number": 13,
+ "max_transport_latency": 75
+ },
+ {
+ "name": "QoS_Config_48_2_2",
+ "retransmission_number": 13,
+ "max_transport_latency": 95
+ },
+ {
+ "name": "QoS_Config_48_3_2",
+ "retransmission_number": 13,
+ "max_transport_latency": 75
+ },
+ {
+ "name": "QoS_Config_48_4_1",
+ "retransmission_number": 5,
+ "max_transport_latency": 20
+ },
+ {
+ "name": "QoS_Config_48_4_2",
+ "retransmission_number": 13,
+ "max_transport_latency": 100
+ },
+ {
+ "name": "VND_QoS_Config_R3_L22",
+ "retransmission_number": 3,
+ "max_transport_latency": 22
+ },
+ {
+ "name": "VND_QoS_Config_R15_L70",
+ "retransmission_number": 15,
+ "max_transport_latency": 70
+ },
+ {
+ "name": "VND_QoS_Config_R5_L12",
+ "retransmission_number": 5,
+ "max_transport_latency": 12
+ },
+ {
+ "name": "VND_QoS_Config_R11_L40",
+ "retransmission_number": 11,
+ "max_transport_latency": 40
+ },
+ {
+ "name": "VND_QoS_Config_R3_L12",
+ "retransmission_number": 3,
+ "max_transport_latency": 12
+ },
+ {
+ "name": "QoS_Config_Low_Latency",
+ "target_latency": "LOW",
+ "retransmission_number": 0,
+ "max_transport_latency": 0
+ },
+ {
+ "name": "QoS_Config_Balanced_Reliability",
+ "target_latency": "BALANCED_RELIABILITY",
+ "retransmission_number": 0,
+ "max_transport_latency": 0
+ },
+ {
+ "name": "QoS_Config_High_Reliability",
+ "target_latency": "HIGH_RELIABILITY",
+ "retransmission_number": 0,
+ "max_transport_latency": 0
+ }
+
+ ]
+}
diff --git a/bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.fbs b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.fbs
new file mode 100644
index 0000000..e898bdc
--- /dev/null
+++ b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.fbs
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2022 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.
+ *
+ */
+namespace aidl.android.hardware.bluetooth.audio.le_audio;
+/// Scenario represents the use case such as "Media", "Conversation", etc.
+/// Each scenario can list any number of codec configurations by their names in
+/// the order of preference. That means if the first entry does not meet all
+/// the current requirements (such as peer device capabilities etc.) next
+/// configurations are being checked.
+///
+/// The referenced codec configurations are defined by the
+/// audio_set_configurations.fbs schema and loaded from a different source file.
+/// Multiple scenarios can reference same codec configurations.
+table AudioSetScenario {
+ _comments_: [string];
+ name: string (key, required);
+ configurations: [string] (required);
+}
+table AudioSetScenarios {
+ _comments_: [string];
+ scenarios: [AudioSetScenario] (required);
+}
+root_type AudioSetScenarios;
diff --git a/bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.json b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.json
new file mode 100644
index 0000000..a28c6cd
--- /dev/null
+++ b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.json
@@ -0,0 +1,304 @@
+{
+ "_comments_": [
+ "== Audio Set Scenarios ==",
+ " Each defined scenario references externally defined audio set",
+ " configurations, listed in the order of priority."
+ ],
+ "scenarios": [
+ {
+ "name": "Conversational",
+ "configurations": [
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_1",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_1",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_2",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_1",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_2",
+ "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2_1",
+ "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2_1",
+ "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1_1",
+ "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2_1",
+ "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_1",
+ "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_1",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_1",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_1",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_2",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_1",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_2",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_1",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_1",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_1",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_1",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_1",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_1",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_1",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_1",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_1",
+ "DualDev_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "SingleDev_OneChanStereoSrc_16_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_48_4_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_48_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_48_3_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_48_1_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_32_1_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_24_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_24_1_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_16_1_Balanced_Reliability",
+ "VND_SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32khz_Server_Prefered_1",
+ "VND_SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32khz_60oct_R3_L22_1",
+ "DualDev_OneChanMonoSnk_16_2_Balanced_Reliability",
+ "SingleDev_OneChanStereoSnk_16_2_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_16_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSnk_16_2_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Media",
+ "configurations": [
+ "DualDev_OneChanStereoSnk_48_4_High_Reliability",
+ "DualDev_OneChanStereoSnk_48_4_2",
+ "DualDev_OneChanStereoSnk_48_2_High_Reliability",
+ "DualDev_OneChanStereoSnk_48_2_2",
+ "DualDev_OneChanStereoSnk_48_3_High_Reliability",
+ "DualDev_OneChanStereoSnk_48_3_2",
+ "DualDev_OneChanStereoSnk_48_1_High_Reliability",
+ "DualDev_OneChanStereoSnk_48_1_2",
+ "DualDev_OneChanStereoSnk_24_2_Balanced_Reliability",
+ "DualDev_OneChanStereoSnk_24_2_2",
+ "DualDev_OneChanStereoSnk_16_2_Balanced_Reliability",
+ "DualDev_OneChanStereoSnk_16_2_2",
+ "DualDev_OneChanStereoSnk_16_1_Balanced_Reliability",
+ "DualDev_OneChanStereoSnk_16_1_2",
+ "SingleDev_OneChanStereoSnk_48_4_High_Reliability",
+ "SingleDev_OneChanStereoSnk_48_4_2",
+ "SingleDev_OneChanStereoSnk_48_2_High_Reliability",
+ "SingleDev_OneChanStereoSnk_48_2_2",
+ "SingleDev_OneChanStereoSnk_48_3_High_Reliability",
+ "SingleDev_OneChanStereoSnk_48_3_2",
+ "SingleDev_OneChanStereoSnk_48_1_High_Reliability",
+ "SingleDev_OneChanStereoSnk_48_1_2",
+ "SingleDev_OneChanStereoSnk_24_2_Balanced_Reliability",
+ "SingleDev_OneChanStereoSnk_24_2_2",
+ "SingleDev_OneChanStereoSnk_16_2_Balanced_Reliability",
+ "SingleDev_OneChanStereoSnk_16_2_2",
+ "SingleDev_OneChanStereoSnk_16_1_Balanced_Reliability",
+ "SingleDev_OneChanStereoSnk_16_1_2",
+ "SingleDev_TwoChanStereoSnk_48_4_High_Reliability",
+ "SingleDev_TwoChanStereoSnk_48_4_2",
+ "SingleDev_TwoChanStereoSnk_48_4_High_Reliability",
+ "SingleDev_TwoChanStereoSnk_48_4_2",
+ "SingleDev_TwoChanStereoSnk_48_2_High_Reliability",
+ "SingleDev_TwoChanStereoSnk_48_2_2",
+ "SingleDev_TwoChanStereoSnk_48_3_High_Reliability",
+ "SingleDev_TwoChanStereoSnk_48_3_2",
+ "SingleDev_TwoChanStereoSnk_48_1_High_Reliability",
+ "SingleDev_TwoChanStereoSnk_48_1_2",
+ "SingleDev_TwoChanStereoSnk_24_2_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_24_2_2",
+ "SingleDev_TwoChanStereoSnk_16_2_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_16_2_2",
+ "SingleDev_TwoChanStereoSnk_16_1_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_16_1_2",
+ "SingleDev_OneChanMonoSnk_48_4_High_Reliability",
+ "SingleDev_OneChanMonoSnk_48_4_2",
+ "SingleDev_OneChanMonoSnk_48_2_High_Reliability",
+ "SingleDev_OneChanMonoSnk_48_2_2",
+ "SingleDev_OneChanMonoSnk_48_3_High_Reliability",
+ "SingleDev_OneChanMonoSnk_48_3_2",
+ "SingleDev_OneChanMonoSnk_48_1_High_Reliability",
+ "SingleDev_OneChanMonoSnk_48_1_2",
+ "SingleDev_OneChanMonoSnk_32_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSnk_32_2_2",
+ "SingleDev_OneChanMonoSnk_32_1_Balanced_Reliability",
+ "SingleDev_OneChanMonoSnk_32_1_2",
+ "SingleDev_OneChanMonoSnk_24_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSnk_24_2_2",
+ "SingleDev_OneChanMonoSnk_16_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSnk_16_2_2",
+ "SingleDev_OneChanMonoSnk_16_1_Balanced_Reliability",
+ "SingleDev_OneChanMonoSnk_16_1_2",
+ "VND_DualDev_OneChanStereoSnk_48khz_100octs_High_Reliability_1",
+ "VND_DualDev_OneChanStereoSnk_48khz_100octs_R15_L70_1",
+ "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_High_Reliability_1",
+ "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_R15_L70_1",
+ "VND_SingleDev_OneChanStereoSnk_48khz_100octs_High_Reliability_1",
+ "VND_SingleDev_OneChanStereoSnk_48khz_100octs_R15_L70_1",
+ "DualDev_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "SingleDev_OneChanStereoSrc_16_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_16_2_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Game",
+ "configurations": [
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_TwoChanStereoSrc_16khz_30octs_Balanced_Reliability_1",
+ "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_R5_L12_TwoChanStereoSrc_16khz_30octs_R3_L12_1",
+ "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_High_Reliability_1",
+ "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_R5_L12_1",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "DualDev_OneChanStereoSnk_48_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_48_3_Low_Latency",
+ "DualDev_OneChanStereoSnk_48_1_Low_Latency",
+ "DualDev_OneChanStereoSnk_32_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_32_1_Low_Latency",
+ "DualDev_OneChanStereoSnk_24_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_24_1_Low_Latency",
+ "DualDev_OneChanStereoSnk_16_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_16_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_48_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_48_3_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_48_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_32_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_32_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_24_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_24_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_16_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_16_1_Low_Latency",
+ "SingleDev_OneChanStereoSnk_48_2_Low_Latency",
+ "SingleDev_OneChanStereoSnk_48_3_Low_Latency",
+ "SingleDev_OneChanStereoSnk_48_1_Low_Latency",
+ "SingleDev_OneChanStereoSnk_32_2_Low_Latency",
+ "SingleDev_OneChanStereoSnk_32_1_Low_Latency",
+ "SingleDev_OneChanStereoSnk_24_2_Low_Latency",
+ "SingleDev_OneChanStereoSnk_24_1_Low_Latency",
+ "SingleDev_OneChanStereoSnk_16_2_Low_Latency",
+ "SingleDev_OneChanStereoSnk_16_1_Low_Latency"
+ ]
+ },
+ {
+ "name": "VoiceAssistants",
+ "configurations": [
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_1",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_1",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_1",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2_Balanced_Reliability",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_1",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_1",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_1",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_1",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_1",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_1",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_1",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_1",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_1",
+ "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_16_2_Balanced_Reliability",
+ "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_24_2_Balanced_Reliability",
+ "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_32_2_Balanced_Reliability",
+ "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability",
+ "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability",
+ "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_16_2_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_24_2_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_32_2_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability",
+ "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Live",
+ "configurations": [
+ "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_Balanced_Reliability_1",
+ "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_R11_L40_1",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_1",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_1",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_1",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2_Balanced_Reliability",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_1",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_1",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_1",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_1",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_1",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_1",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_1",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_1",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_1",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_1",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_1",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_1",
+ "SingleDev_OneChanMonoSrc_48_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_48_1_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_32_1_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_16_1_Balanced_Reliability"
+ ]
+ }
+ ]
+}
diff --git a/bluetooth/finder/aidl/Android.bp b/bluetooth/finder/aidl/Android.bp
new file mode 100644
index 0000000..25c1287
--- /dev/null
+++ b/bluetooth/finder/aidl/Android.bp
@@ -0,0 +1,41 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+aidl_interface {
+ name: "android.hardware.bluetooth.finder",
+ vendor_available: true,
+ srcs: ["android/hardware/bluetooth/finder/*.aidl"],
+ stability: "vintf",
+
+ backend: {
+ ndk: {
+ enabled: true,
+ },
+ java: {
+ enabled: true,
+ sdk_version: "module_current",
+ min_sdk_version: "30",
+ apex_available: [
+ "com.android.tethering",
+ ],
+ lint: {
+ baseline_filename: "lint-baseline.xml",
+ },
+ },
+ },
+}
diff --git a/bluetooth/finder/aidl/aidl_api/android.hardware.bluetooth.finder/current/android/hardware/bluetooth/finder/Eid.aidl b/bluetooth/finder/aidl/aidl_api/android.hardware.bluetooth.finder/current/android/hardware/bluetooth/finder/Eid.aidl
new file mode 100644
index 0000000..42461c5
--- /dev/null
+++ b/bluetooth/finder/aidl/aidl_api/android.hardware.bluetooth.finder/current/android/hardware/bluetooth/finder/Eid.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.finder;
+@VintfStability
+parcelable Eid {
+ byte[20] bytes;
+}
diff --git a/bluetooth/finder/aidl/aidl_api/android.hardware.bluetooth.finder/current/android/hardware/bluetooth/finder/IBluetoothFinder.aidl b/bluetooth/finder/aidl/aidl_api/android.hardware.bluetooth.finder/current/android/hardware/bluetooth/finder/IBluetoothFinder.aidl
new file mode 100644
index 0000000..4bc9041
--- /dev/null
+++ b/bluetooth/finder/aidl/aidl_api/android.hardware.bluetooth.finder/current/android/hardware/bluetooth/finder/IBluetoothFinder.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.finder;
+@VintfStability
+interface IBluetoothFinder {
+ void sendEids(in android.hardware.bluetooth.finder.Eid[] eids);
+ void setPoweredOffFinderMode(in boolean enable);
+ boolean getPoweredOffFinderMode();
+}
diff --git a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp b/bluetooth/finder/aidl/android/hardware/bluetooth/finder/Eid.aidl
similarity index 62%
copy from health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
copy to bluetooth/finder/aidl/android/hardware/bluetooth/finder/Eid.aidl
index aba6cc3..0de306f 100644
--- a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
+++ b/bluetooth/finder/aidl/android/hardware/bluetooth/finder/Eid.aidl
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -13,12 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "include/StorageHealthDefault.h"
-void get_storage_info(std::vector<struct StorageInfo>&) {
- // Use defaults.
-}
+package android.hardware.bluetooth.finder;
-void get_disk_stats(std::vector<struct DiskStats>&) {
- // Use defaults
+/**
+ * Find My Device network ephemeral identifier
+ */
+@VintfStability
+parcelable Eid {
+ byte[20] bytes;
}
diff --git a/bluetooth/finder/aidl/android/hardware/bluetooth/finder/IBluetoothFinder.aidl b/bluetooth/finder/aidl/android/hardware/bluetooth/finder/IBluetoothFinder.aidl
new file mode 100644
index 0000000..a374c2a
--- /dev/null
+++ b/bluetooth/finder/aidl/android/hardware/bluetooth/finder/IBluetoothFinder.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.finder;
+
+import android.hardware.bluetooth.finder.Eid;
+
+@VintfStability
+interface IBluetoothFinder {
+ /**
+ * API to set Find My Device network EIDs to the Bluetooth Controller
+ *
+ * @param eids array of 20 bytes EID to the Bluetooth
+ * controller
+ */
+ void sendEids(in Eid[] eids);
+
+ /**
+ * API to enable the powered-off finder feature, which allows the Bluetooth controller to send
+ * beacons after the device is powered off.
+ *
+ * @param enable true to enable; false to disable
+ */
+ void setPoweredOffFinderMode(in boolean enable);
+
+ /**
+ * API for retrieving feature enablement status
+ *
+ * @return the value last set by setPoweredOffFinderMode, false if setPoweredOffFinderMode was
+ * never been invoked since boot.
+ */
+ boolean getPoweredOffFinderMode();
+}
diff --git a/bluetooth/finder/aidl/default/Android.bp b/bluetooth/finder/aidl/default/Android.bp
new file mode 100644
index 0000000..b364ae1
--- /dev/null
+++ b/bluetooth/finder/aidl/default/Android.bp
@@ -0,0 +1,42 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_binary {
+ name: "android.hardware.bluetooth.finder-service.default",
+ relative_install_path: "hw",
+ init_rc: ["bluetooth-finder-service-default.rc"],
+ vintf_fragments: [":manifest_android.hardware.bluetooth.finder-service.default.xml"],
+ vendor: true,
+ srcs: [
+ "BluetoothFinder.cpp",
+ "service.cpp",
+ ],
+ shared_libs: [
+ "android.hardware.bluetooth.finder-V1-ndk",
+ "libbase",
+ "libbinder_ndk",
+ "libhidlbase",
+ "libutils",
+ "liblog",
+ ],
+}
+
+filegroup {
+ name: "manifest_android.hardware.bluetooth.finder-service.default.xml",
+ srcs: ["bluetooth-finder-service-default.xml"],
+}
diff --git a/bluetooth/finder/aidl/default/BluetoothFinder.cpp b/bluetooth/finder/aidl/default/BluetoothFinder.cpp
new file mode 100644
index 0000000..236a1f8
--- /dev/null
+++ b/bluetooth/finder/aidl/default/BluetoothFinder.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BluetoothFinder.h"
+
+namespace aidl::android::hardware::bluetooth::finder::impl {
+
+::ndk::ScopedAStatus BluetoothFinder::sendEids(const ::std::vector<Eid>& keys) {
+ keys_.insert(keys_.end(), keys.begin(), keys.end());
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus BluetoothFinder::setPoweredOffFinderMode(bool enable) {
+ pof_enabled_ = enable;
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus BluetoothFinder::getPoweredOffFinderMode(
+ bool* _aidl_return) {
+ *_aidl_return = pof_enabled_;
+ return ::ndk::ScopedAStatus::ok();
+}
+
+} // namespace aidl::android::hardware::bluetooth::finder::impl
diff --git a/bluetooth/finder/aidl/default/BluetoothFinder.h b/bluetooth/finder/aidl/default/BluetoothFinder.h
new file mode 100644
index 0000000..16110f6
--- /dev/null
+++ b/bluetooth/finder/aidl/default/BluetoothFinder.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/bluetooth/finder/BnBluetoothFinder.h>
+
+#include <vector>
+
+namespace aidl::android::hardware::bluetooth::finder::impl {
+
+using ::aidl::android::hardware::bluetooth::finder::BnBluetoothFinder;
+using ::aidl::android::hardware::bluetooth::finder::Eid;
+
+class BluetoothFinder : public BnBluetoothFinder {
+ public:
+ BluetoothFinder() = default;
+
+ ::ndk::ScopedAStatus sendEids(const ::std::vector<Eid>& keys) override;
+ ::ndk::ScopedAStatus setPoweredOffFinderMode(bool enable) override;
+ ::ndk::ScopedAStatus getPoweredOffFinderMode(bool* _aidl_return) override;
+
+ private:
+ bool pof_enabled_;
+ std::vector<Eid> keys_;
+};
+
+} // namespace aidl::android::hardware::bluetooth::finder::impl
diff --git a/bluetooth/finder/aidl/default/bluetooth-finder-service-default.rc b/bluetooth/finder/aidl/default/bluetooth-finder-service-default.rc
new file mode 100644
index 0000000..64bbf09
--- /dev/null
+++ b/bluetooth/finder/aidl/default/bluetooth-finder-service-default.rc
@@ -0,0 +1,6 @@
+service vendor.bluetooth.finder-default /vendor/bin/hw/android.hardware.bluetooth.finder-service.default
+ class hal
+ capabilities BLOCK_SUSPEND NET_ADMIN SYS_NICE
+ user bluetooth
+ group bluetooth
+ task_profiles ServicePerformance
diff --git a/bluetooth/finder/aidl/default/bluetooth-finder-service-default.xml b/bluetooth/finder/aidl/default/bluetooth-finder-service-default.xml
new file mode 100644
index 0000000..be7c00d
--- /dev/null
+++ b/bluetooth/finder/aidl/default/bluetooth-finder-service-default.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.bluetooth.finder</name>
+ <version>1</version>
+ <fqname>IBluetoothFinder/default</fqname>
+ </hal>
+</manifest>
diff --git a/bluetooth/finder/aidl/default/service.cpp b/bluetooth/finder/aidl/default/service.cpp
new file mode 100644
index 0000000..fe8904b
--- /dev/null
+++ b/bluetooth/finder/aidl/default/service.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "aidl.android.hardware.bluetooth.finder.default"
+
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <utils/Log.h>
+
+#include "BluetoothFinder.h"
+
+using ::aidl::android::hardware::bluetooth::finder::impl::BluetoothFinder;
+
+int main(int /* argc */, char** /* argv */) {
+ ALOGI("Bluetooth Finder HAL registering");
+ if (!ABinderProcess_setThreadPoolMaxThreadCount(0)) {
+ ALOGE("failed to set thread pool max thread count");
+ return 1;
+ }
+
+ std::shared_ptr<BluetoothFinder> service =
+ ndk::SharedRefBase::make<BluetoothFinder>();
+ std::string instance =
+ std::string() + BluetoothFinder::descriptor + "/default";
+ if (AServiceManager_isDeclared(instance.c_str())) {
+ auto result =
+ AServiceManager_addService(service->asBinder().get(), instance.c_str());
+ if (result != STATUS_OK) {
+ ALOGE("Could not register as a service!");
+ }
+ } else {
+ ALOGE("Could not register as a service because it's not declared.");
+ }
+ // Keep running
+ ABinderProcess_joinThreadPool();
+ return 0;
+}
diff --git a/bluetooth/finder/aidl/lint-baseline.xml b/bluetooth/finder/aidl/lint-baseline.xml
new file mode 100644
index 0000000..e0570f6
--- /dev/null
+++ b/bluetooth/finder/aidl/lint-baseline.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.4.0-alpha01" type="baseline" client="" dependencies="true" name="" variant="all" version="8.4.0-alpha01">
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 33 (current min is 30): `android.os.Parcel#writeFixedArray`"
+ errorLine1=" _aidl_parcel.writeFixedArray(bytes, _aidl_flag, 20);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/soong/.intermediates/hardware/interfaces/bluetooth/finder/aidl/android.hardware.bluetooth.finder-V1-java-source/gen/android/hardware/bluetooth/finder/Eid.java"
+ line="28"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 33 (current min is 30): `android.os.Parcel#createFixedArray`"
+ errorLine1=" bytes = _aidl_parcel.createFixedArray(byte[].class, 20);"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="out/soong/.intermediates/hardware/interfaces/bluetooth/finder/aidl/android.hardware.bluetooth.finder-V1-java-source/gen/android/hardware/bluetooth/finder/Eid.java"
+ line="41"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/soong/.intermediates/hardware/interfaces/bluetooth/finder/aidl/android.hardware.bluetooth.finder-V1-java-source/gen/android/hardware/bluetooth/finder/IBluetoothFinder.java"
+ line="67"
+ column="12"/>
+ </issue>
+
+</issues>
diff --git a/bluetooth/finder/aidl/vts/Android.bp b/bluetooth/finder/aidl/vts/Android.bp
new file mode 100644
index 0000000..6b0285e
--- /dev/null
+++ b/bluetooth/finder/aidl/vts/Android.bp
@@ -0,0 +1,41 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+ name: "VtsHalBluetoothFinderTargetTest",
+ defaults: [
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: ["VtsHalBluetoothFinderTargetTest.cpp"],
+ shared_libs: [
+ "libbase",
+ "libcutils",
+ "libbinder_ndk",
+ "liblog",
+ "libutils",
+ ],
+ static_libs: [
+ "android.hardware.bluetooth.finder-V1-ndk",
+ "libbluetooth-types",
+ ],
+ test_config: "VtsHalBluetoothFinderTargetTest.xml",
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
diff --git a/bluetooth/finder/aidl/vts/VtsHalBluetoothFinderTargetTest.cpp b/bluetooth/finder/aidl/vts/VtsHalBluetoothFinderTargetTest.cpp
new file mode 100644
index 0000000..fee9e242
--- /dev/null
+++ b/bluetooth/finder/aidl/vts/VtsHalBluetoothFinderTargetTest.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/bluetooth/finder/IBluetoothFinder.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <binder/IServiceManager.h>
+#include <utils/Log.h>
+
+#include <array>
+#include <vector>
+
+using ::aidl::android::hardware::bluetooth::finder::Eid;
+using ::aidl::android::hardware::bluetooth::finder::IBluetoothFinder;
+using ::ndk::ScopedAStatus;
+
+class BluetoothFinderTest : public ::testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ ALOGI("SetUp Finder Test");
+ bluetooth_finder = IBluetoothFinder::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+ ASSERT_NE(bluetooth_finder, nullptr);
+ }
+
+ virtual void TearDown() override {
+ ALOGI("TearDown Finder Test");
+ bluetooth_finder = nullptr;
+ ASSERT_EQ(bluetooth_finder, nullptr);
+ }
+
+ ScopedAStatus sendEids(uint8_t num);
+ ScopedAStatus setPoweredOffFinderMode(bool enable);
+ ScopedAStatus getPoweredOffFinderMode(bool* status);
+
+ private:
+ std::shared_ptr<IBluetoothFinder> bluetooth_finder;
+};
+
+ScopedAStatus BluetoothFinderTest::sendEids(uint8_t numKeys) {
+ std::vector<Eid> keys(numKeys);
+ for (uint_t i = 0; i < numKeys; i++) {
+ std::array<uint8_t, 20> key;
+ key.fill(i + 1);
+ keys[i].bytes = key;
+ }
+ return bluetooth_finder->sendEids(keys);
+}
+
+ScopedAStatus BluetoothFinderTest::setPoweredOffFinderMode(bool enable) {
+ return bluetooth_finder->setPoweredOffFinderMode(enable);
+}
+
+ScopedAStatus BluetoothFinderTest::getPoweredOffFinderMode(bool* status) {
+ return bluetooth_finder->getPoweredOffFinderMode(status);
+}
+
+TEST_P(BluetoothFinderTest, PropertyIsSet) {
+ ASSERT_EQ(
+ android::base::GetProperty("ro.bluetooth.finder.supported", "false"),
+ "true");
+}
+
+TEST_P(BluetoothFinderTest, SendEidsSingle) {
+ ScopedAStatus status = sendEids(1);
+ ASSERT_TRUE(status.isOk());
+}
+
+TEST_P(BluetoothFinderTest, Send255Eids) {
+ ScopedAStatus status = sendEids(255);
+ ASSERT_TRUE(status.isOk());
+}
+
+TEST_P(BluetoothFinderTest, setAndGetPoweredOffFinderModeEnable) {
+ ScopedAStatus status = setPoweredOffFinderMode(true);
+ ASSERT_TRUE(status.isOk());
+ bool pof_status;
+ status = getPoweredOffFinderMode(&pof_status);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_TRUE(pof_status);
+}
+
+TEST_P(BluetoothFinderTest, setAndGetPoweredOffFinderModeDisable) {
+ ScopedAStatus status = setPoweredOffFinderMode(false);
+ ASSERT_TRUE(status.isOk());
+ bool pof_status;
+ status = getPoweredOffFinderMode(&pof_status);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_TRUE(!pof_status);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothFinderTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothFinderTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothFinder::descriptor)),
+ android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_startThreadPool();
+ int status = RUN_ALL_TESTS();
+ ALOGI("Test result = %d", status);
+ return status;
+}
diff --git a/bluetooth/finder/aidl/vts/VtsHalBluetoothFinderTargetTest.xml b/bluetooth/finder/aidl/vts/VtsHalBluetoothFinderTargetTest.xml
new file mode 100644
index 0000000..46053dd
--- /dev/null
+++ b/bluetooth/finder/aidl/vts/VtsHalBluetoothFinderTargetTest.xml
@@ -0,0 +1,33 @@
+<!--
+ Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<configuration description="Runs VtsHalBluetoothFinderTargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalBluetoothFinderTargetTest->/data/local/tmp/VtsHalBluetoothFinderTargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalBluetoothFinderTargetTest" />
+ </test>
+</configuration>
diff --git a/bluetooth/lmp_event/aidl/Android.bp b/bluetooth/lmp_event/aidl/Android.bp
new file mode 100644
index 0000000..6c2f278
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/Android.bp
@@ -0,0 +1,33 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+aidl_interface {
+ name: "android.hardware.bluetooth.lmp_event",
+ vendor_available: true,
+ host_supported: true,
+ srcs: ["android/hardware/bluetooth/lmp_event/*.aidl"],
+ stability: "vintf",
+ backend: {
+ java: {
+ enabled: true,
+ platform_apis: true,
+ },
+ cpp: {
+ enabled: true,
+ },
+ ndk: {
+ enabled: true,
+ min_sdk_version: "33",
+ },
+ rust: {
+ enabled: true,
+ min_sdk_version: "33",
+ },
+ },
+}
diff --git a/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/AddressType.aidl b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/AddressType.aidl
new file mode 100644
index 0000000..0f239e8
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/AddressType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.lmp_event;
+@Backing(type="byte") @VintfStability
+enum AddressType {
+ PUBLIC = 0x00,
+ RANDOM = 0x01,
+}
diff --git a/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/Direction.aidl b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/Direction.aidl
new file mode 100644
index 0000000..6f807cc
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/Direction.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.lmp_event;
+@Backing(type="byte") @VintfStability
+enum Direction {
+ TX = 0x00,
+ RX = 0x01,
+}
diff --git a/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/IBluetoothLmpEvent.aidl b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/IBluetoothLmpEvent.aidl
new file mode 100644
index 0000000..3431010
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/IBluetoothLmpEvent.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.lmp_event;
+@VintfStability
+interface IBluetoothLmpEvent {
+ void registerForLmpEvents(in android.hardware.bluetooth.lmp_event.IBluetoothLmpEventCallback callback, in android.hardware.bluetooth.lmp_event.AddressType addressType, in byte[6] address, in android.hardware.bluetooth.lmp_event.LmpEventId[] lmpEventIds);
+ void unregisterLmpEvents(in android.hardware.bluetooth.lmp_event.AddressType addressType, in byte[6] address);
+}
diff --git a/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/IBluetoothLmpEventCallback.aidl b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/IBluetoothLmpEventCallback.aidl
new file mode 100644
index 0000000..fc6758c
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/IBluetoothLmpEventCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.lmp_event;
+@VintfStability
+interface IBluetoothLmpEventCallback {
+ void onEventGenerated(in android.hardware.bluetooth.lmp_event.Timestamp timestamp, in android.hardware.bluetooth.lmp_event.AddressType addressType, in byte[6] address, in android.hardware.bluetooth.lmp_event.Direction direction, in android.hardware.bluetooth.lmp_event.LmpEventId lmpEventId, in char connEventCounter);
+ void onRegistered(in boolean status);
+}
diff --git a/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/LmpEventId.aidl b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/LmpEventId.aidl
new file mode 100644
index 0000000..4ee95d1
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/LmpEventId.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.lmp_event;
+@Backing(type="byte") @VintfStability
+enum LmpEventId {
+ CONNECT_IND = 0x00,
+ LL_PHY_UPDATE_IND = 0x01,
+}
diff --git a/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/Timestamp.aidl b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/Timestamp.aidl
new file mode 100644
index 0000000..5ef32ba
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/Timestamp.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.lmp_event;
+@VintfStability
+parcelable Timestamp {
+ long systemTimeUs;
+ long bluetoothTimeUs;
+}
diff --git a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/AddressType.aidl
similarity index 68%
copy from health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
copy to bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/AddressType.aidl
index aba6cc3..6bfc7c7 100644
--- a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
+++ b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/AddressType.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,12 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "include/StorageHealthDefault.h"
-void get_storage_info(std::vector<struct StorageInfo>&) {
- // Use defaults.
-}
+package android.hardware.bluetooth.lmp_event;
-void get_disk_stats(std::vector<struct DiskStats>&) {
- // Use defaults
+/**
+ * Type of Address
+ */
+@VintfStability
+@Backing(type="byte")
+enum AddressType {
+ PUBLIC = 0x00,
+ RANDOM = 0x01,
}
diff --git a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/Direction.aidl
similarity index 68%
copy from health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
copy to bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/Direction.aidl
index aba6cc3..884c2bb 100644
--- a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
+++ b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/Direction.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,12 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "include/StorageHealthDefault.h"
-void get_storage_info(std::vector<struct StorageInfo>&) {
- // Use defaults.
-}
+package android.hardware.bluetooth.lmp_event;
-void get_disk_stats(std::vector<struct DiskStats>&) {
- // Use defaults
+/**
+ * Direction of the LMP event
+ */
+@VintfStability
+@Backing(type="byte")
+enum Direction {
+ TX = 0x00,
+ RX = 0x01,
}
diff --git a/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/IBluetoothLmpEvent.aidl b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/IBluetoothLmpEvent.aidl
new file mode 100644
index 0000000..3828af6
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/IBluetoothLmpEvent.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.lmp_event;
+
+import android.hardware.bluetooth.lmp_event.IBluetoothLmpEventCallback;
+import android.hardware.bluetooth.lmp_event.AddressType;
+import android.hardware.bluetooth.lmp_event.LmpEventId;
+
+@VintfStability
+interface IBluetoothLmpEvent {
+ /**
+ * API to monitor specific LMP event timestamp for given Bluetooth device.
+ *
+ * @param callback An instance of the |IBluetoothLmpEventCallback| AIDL interface object.
+ * @param addressType Type of bluetooth address.
+ * @param address Bluetooth address to monitor.
+ * @param lmpEventIds LMP events to monitor.
+ */
+ void registerForLmpEvents(in IBluetoothLmpEventCallback callback,
+ in AddressType addressType,
+ in byte[6] address,
+ in LmpEventId[] lmpEventIds);
+
+ /**
+ * API to stop monitoring a given Bluetooth device.
+ *
+ * @param addressType Type of Bluetooth address.
+ * @param address Bluetooth device to stop monitoring.
+ */
+ void unregisterLmpEvents(in AddressType addressType, in byte[6] address);
+}
diff --git a/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/IBluetoothLmpEventCallback.aidl b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/IBluetoothLmpEventCallback.aidl
new file mode 100644
index 0000000..3295ef0
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/IBluetoothLmpEventCallback.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.lmp_event;
+
+import android.hardware.bluetooth.lmp_event.Direction;
+import android.hardware.bluetooth.lmp_event.AddressType;
+import android.hardware.bluetooth.lmp_event.LmpEventId;
+import android.hardware.bluetooth.lmp_event.Timestamp;
+
+@VintfStability
+interface IBluetoothLmpEventCallback {
+ /**
+ * Callback when monitored LMP event invoked.
+ *
+ * @param timestamp Timestamp when the LMP event invoked
+ * @param addressType Type of Bluetooth address.
+ * @param address Remote bluetooth address that invoke LMP event
+ * @param direction Direction of the invoked LMP event
+ * @param lmpEventId LMP event id that bluetooth chip invoked
+ * @param connEventCounter counter incremented by one for each new connection event
+ */
+ void onEventGenerated(in Timestamp timestamp,
+ in AddressType addressType,
+ in byte[6] address,
+ in Direction direction,
+ in LmpEventId lmpEventId,
+ in char connEventCounter);
+
+ /**
+ * Callback when registration done.
+ */
+ void onRegistered(in boolean status);
+}
diff --git a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/LmpEventId.aidl
similarity index 61%
copy from health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
copy to bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/LmpEventId.aidl
index aba6cc3..3584b0c 100644
--- a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
+++ b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/LmpEventId.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,12 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "include/StorageHealthDefault.h"
-void get_storage_info(std::vector<struct StorageInfo>&) {
- // Use defaults.
-}
+package android.hardware.bluetooth.lmp_event;
-void get_disk_stats(std::vector<struct DiskStats>&) {
- // Use defaults
+/**
+ * LMP event id to be monitored
+ * CONNECT_IND indicator for initiating connection
+ * LL_PHY_UPDATE_IND indicator for PHY update
+ */
+@VintfStability
+@Backing(type="byte")
+enum LmpEventId {
+ CONNECT_IND = 0x00,
+ LL_PHY_UPDATE_IND = 0x01,
}
diff --git a/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/Timestamp.aidl b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/Timestamp.aidl
new file mode 100644
index 0000000..e3c991d
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/Timestamp.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.lmp_event;
+
+/**
+ * Generic structure to return the timestamp
+ */
+@VintfStability
+parcelable Timestamp {
+ /**
+ * Timestamp in microsecond since system boot.
+ * if systemTimeUs is set to 0, its value is to be ignored
+ */
+ long systemTimeUs;
+ /**
+ * Timestamp in microsecond since Bluetooth controller power up.
+ */
+ long bluetoothTimeUs;
+}
diff --git a/bluetooth/lmp_event/aidl/default/Android.bp b/bluetooth/lmp_event/aidl/default/Android.bp
new file mode 100644
index 0000000..f8ca5e6
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/default/Android.bp
@@ -0,0 +1,28 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+rust_binary {
+ name: "android.hardware.bluetooth.lmp_event-service.default",
+ relative_install_path: "hw",
+ init_rc: ["lmp_event-default.rc"],
+ vintf_fragments: [":manifest_android.hardware.bluetooth.lmp_event-service.default.xml"],
+ vendor: true,
+ rustlibs: [
+ "liblogger",
+ "liblog_rust",
+ "libbinder_rs",
+ "android.hardware.bluetooth.lmp_event-V1-rust",
+ ],
+ srcs: [ "src/main.rs" ],
+}
+
+filegroup {
+ name: "manifest_android.hardware.bluetooth.lmp_event-service.default.xml",
+ srcs: [ "lmp_event-default.xml" ],
+}
diff --git a/bluetooth/lmp_event/aidl/default/lmp_event-default.rc b/bluetooth/lmp_event/aidl/default/lmp_event-default.rc
new file mode 100644
index 0000000..845e04d
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/default/lmp_event-default.rc
@@ -0,0 +1,6 @@
+service vendor.bluetooth.lmp_event-default /vendor/bin/hw/android.hardware.bluetooth.lmp_event-service.default
+ class hal
+ capabilities BLOCK_SUSPEND NET_ADMIN SYS_NICE
+ user bluetooth
+ group bluetooth
+ task_profiles HighPerformance
diff --git a/bluetooth/lmp_event/aidl/default/lmp_event-default.xml b/bluetooth/lmp_event/aidl/default/lmp_event-default.xml
new file mode 100644
index 0000000..24d93f8
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/default/lmp_event-default.xml
@@ -0,0 +1,10 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.bluetooth.lmp_event</name>
+ <version>1</version>
+ <interface>
+ <name>IBluetoothLmpEvent</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/bluetooth/lmp_event/aidl/default/src/lmp_event.rs b/bluetooth/lmp_event/aidl/default/src/lmp_event.rs
new file mode 100644
index 0000000..f016c3f
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/default/src/lmp_event.rs
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//! Implements LMP Event AIDL Interface.
+
+use android_hardware_bluetooth_lmp_event::aidl::android::hardware::bluetooth::lmp_event::{
+ Direction::Direction, AddressType::AddressType, IBluetoothLmpEvent::IBluetoothLmpEvent,
+ IBluetoothLmpEventCallback::IBluetoothLmpEventCallback, LmpEventId::LmpEventId,
+ Timestamp::Timestamp,
+};
+
+use binder::{Interface, Result, Strong};
+
+use log::info;
+use std::thread;
+use std::time;
+
+
+pub struct LmpEvent;
+
+impl LmpEvent {
+ pub fn new() -> Self {
+ Self
+ }
+}
+
+impl Interface for LmpEvent {}
+
+impl IBluetoothLmpEvent for LmpEvent {
+ fn registerForLmpEvents(&self,
+ callback: &Strong<dyn IBluetoothLmpEventCallback>,
+ address_type: AddressType,
+ address: &[u8; 6],
+ lmp_event_ids: &[LmpEventId]
+ ) -> Result<()> {
+ info!("registerForLmpEvents");
+
+ let cb = callback.clone();
+ let addr_type = address_type;
+ let addr = address.clone();
+ let lmp_event = lmp_event_ids.to_vec();
+
+ let thread_handle = thread::spawn(move || {
+ let ts = Timestamp {
+ bluetoothTimeUs: 1000000,
+ systemTimeUs: 2000000,
+ };
+
+ info!("sleep for 1000 ms");
+ thread::sleep(time::Duration::from_millis(1000));
+
+ info!("callback event");
+ cb.onEventGenerated(&ts, addr_type, &addr, Direction::RX, lmp_event[0], 1)
+ .expect("onEventGenerated failed");
+ });
+
+ info!("callback register");
+ callback.onRegistered(true)?;
+
+ thread_handle.join().expect("join failed");
+ Ok(())
+ }
+ fn unregisterLmpEvents(&self, _address_type: AddressType, _address: &[u8; 6]) -> Result<()> {
+ info!("unregisterLmpEvents");
+
+ Ok(())
+ }
+}
diff --git a/bluetooth/lmp_event/aidl/default/src/main.rs b/bluetooth/lmp_event/aidl/default/src/main.rs
new file mode 100644
index 0000000..b24164e
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/default/src/main.rs
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//! Implements LMP Event Example Service.
+
+
+use android_hardware_bluetooth_lmp_event::aidl::android::hardware::bluetooth::lmp_event::IBluetoothLmpEvent::{
+ IBluetoothLmpEvent, BnBluetoothLmpEvent
+};
+
+use binder::BinderFeatures;
+use log::{info, LevelFilter};
+
+mod lmp_event;
+
+const LOG_TAG: &str = "lmp_event_service_example";
+
+fn main() {
+ info!("{LOG_TAG}: starting service");
+ let logger_success = logger::init(
+ logger::Config::default().with_tag_on_device(LOG_TAG).with_max_level(LevelFilter::Trace)
+ );
+ if !logger_success {
+ panic!("{LOG_TAG}: Failed to start logger");
+ }
+
+ binder::ProcessState::set_thread_pool_max_thread_count(0);
+
+ let lmp_event_service = lmp_event::LmpEvent::new();
+ let lmp_event_service_binder = BnBluetoothLmpEvent::new_binder(lmp_event_service, BinderFeatures::default());
+
+ let descriptor = format!("{}/default", lmp_event::LmpEvent::get_descriptor());
+ if binder::is_declared(&descriptor).expect("Failed to check if declared") {
+ binder::add_service(&descriptor, lmp_event_service_binder.as_binder()).expect("Failed to register service");
+ } else {
+ info!("{LOG_TAG}: Failed to register service. Not declared.");
+ }
+ binder::ProcessState::join_thread_pool()
+}
diff --git a/bluetooth/lmp_event/aidl/vts/Android.bp b/bluetooth/lmp_event/aidl/vts/Android.bp
new file mode 100644
index 0000000..b89351e
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/vts/Android.bp
@@ -0,0 +1,20 @@
+cc_test {
+ name: "VtsHalLmpEventTargetTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: ["VtsHalLmpEventTargetTest.cpp"],
+ shared_libs: [
+ "libbinder",
+ "libbinder_ndk"
+ ],
+ static_libs: [
+ "android.hardware.bluetooth.lmp_event-V1-ndk",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ]
+}
+
diff --git a/bluetooth/lmp_event/aidl/vts/VtsHalLmpEventTargetTest.cpp b/bluetooth/lmp_event/aidl/vts/VtsHalLmpEventTargetTest.cpp
new file mode 100644
index 0000000..c49f60b
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/vts/VtsHalLmpEventTargetTest.cpp
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the std::shared_ptrecific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "lmp_event_hal_test"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+
+#include <aidl/android/hardware/bluetooth/lmp_event/BnBluetoothLmpEvent.h>
+#include <aidl/android/hardware/bluetooth/lmp_event/BnBluetoothLmpEventCallback.h>
+#include <aidl/android/hardware/bluetooth/lmp_event/Direction.h>
+#include <aidl/android/hardware/bluetooth/lmp_event/AddressType.h>
+#include <aidl/android/hardware/bluetooth/lmp_event/LmpEventId.h>
+#include <aidl/android/hardware/bluetooth/lmp_event/Timestamp.h>
+
+#include <android/binder_auto_utils.h>
+#include <android/binder_manager.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <log/log.h>
+
+#include <chrono>
+#include <condition_variable>
+#include <cinttypes>
+#include <thread>
+
+using ::aidl::android::hardware::bluetooth::lmp_event::BnBluetoothLmpEventCallback;
+using ::aidl::android::hardware::bluetooth::lmp_event::IBluetoothLmpEvent;
+using ::aidl::android::hardware::bluetooth::lmp_event::IBluetoothLmpEventCallback;
+using ::aidl::android::hardware::bluetooth::lmp_event::Direction;
+using ::aidl::android::hardware::bluetooth::lmp_event::AddressType;
+using ::aidl::android::hardware::bluetooth::lmp_event::LmpEventId;
+using ::aidl::android::hardware::bluetooth::lmp_event::Timestamp;
+
+using ::android::ProcessState;
+using ::ndk::SpAIBinder;
+
+namespace {
+ static constexpr std::chrono::milliseconds kEventTimeoutMs(10000);
+}
+
+class BluetoothLmpEventTest : public testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ ALOGI("%s", __func__);
+
+ ibt_lmp_event_ = IBluetoothLmpEvent::fromBinder(SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+ ASSERT_NE(ibt_lmp_event_, nullptr);
+
+ ibt_lmp_event_cb_ = ndk::SharedRefBase::make<BluetoothLmpEventCallback>(*this);
+ ASSERT_NE(ibt_lmp_event_cb_, nullptr);
+ }
+
+ virtual void TearDown() override {
+ ALOGI("%s", __func__);
+ ibt_lmp_event_->unregisterLmpEvents(address_type, address);
+
+ ibt_lmp_event_cb_ = nullptr;
+ }
+
+ class BluetoothLmpEventCallback : public BnBluetoothLmpEventCallback {
+ public:
+ BluetoothLmpEventTest& parent_;
+ BluetoothLmpEventCallback(BluetoothLmpEventTest& parent)
+ : parent_(parent) {}
+ ~BluetoothLmpEventCallback() = default;
+
+ ::ndk::ScopedAStatus onEventGenerated(const Timestamp& timestamp, AddressType address_type,
+ const std::array<uint8_t, 6>& address, Direction direction,
+ LmpEventId lmp_event_id, char16_t conn_event_counter) override {
+ for (auto t: address) {
+ ALOGD("%s: 0x%02x", __func__, t);
+ }
+ if (direction == Direction::TX) {
+ ALOGD("%s: Transmitting", __func__);
+ } else if (direction == Direction::RX) {
+ ALOGD("%s: Receiving", __func__);
+ }
+ if (address_type == AddressType::PUBLIC) {
+ ALOGD("%s: Public address", __func__);
+ } else if (address_type == AddressType::RANDOM) {
+ ALOGD("%s: Random address", __func__);
+ }
+ if (lmp_event_id == LmpEventId::CONNECT_IND) {
+ ALOGD("%s: initiating connection", __func__);
+ } else if (lmp_event_id == LmpEventId::LL_PHY_UPDATE_IND) {
+ ALOGD("%s: PHY update indication", __func__);
+ }
+
+ ALOGD("%s: time: %" PRId64 "counter value: %x", __func__, timestamp.bluetoothTimeUs, conn_event_counter);
+
+ parent_.event_recv = true;
+ parent_.notify();
+
+ return ::ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onRegistered(bool status) override {
+ ALOGD("%s: status: %d", __func__, status);
+ parent_.status_recv = status;
+ parent_.notify();
+ return ::ndk::ScopedAStatus::ok();
+ }
+ };
+
+ inline void notify() {
+ std::unique_lock<std::mutex> lock(lmp_event_mtx);
+ lmp_event_cv.notify_one();
+ }
+
+ inline void wait(bool is_register_event) {
+ std::unique_lock<std::mutex> lock(lmp_event_mtx);
+
+
+ if (is_register_event) {
+ lmp_event_cv.wait(lock, [&]() { return status_recv == true; });
+ } else {
+ lmp_event_cv.wait_for(lock, kEventTimeoutMs,
+ [&](){ return event_recv == true; });
+ }
+
+ }
+
+ std::shared_ptr<IBluetoothLmpEvent> ibt_lmp_event_;
+ std::shared_ptr<IBluetoothLmpEventCallback> ibt_lmp_event_cb_;
+
+ AddressType address_type;
+ std::array<uint8_t, 6> address;
+
+ std::atomic<bool> event_recv;
+ bool status_recv;
+
+ std::mutex lmp_event_mtx;
+ std::condition_variable lmp_event_cv;
+};
+
+TEST_P(BluetoothLmpEventTest, RegisterAndReceive) {
+ address = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
+ address_type = AddressType::RANDOM;
+ std::vector<LmpEventId> lmp_event_ids{LmpEventId::CONNECT_IND, LmpEventId::LL_PHY_UPDATE_IND};
+
+ ibt_lmp_event_->registerForLmpEvents(ibt_lmp_event_cb_, address_type, address, lmp_event_ids);
+ wait(true);
+ EXPECT_EQ(true, status_recv);
+
+ /* Wait for event generated here */
+ wait(false);
+ EXPECT_EQ(true, event_recv);
+
+ ibt_lmp_event_->unregisterLmpEvents(address_type, address);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothLmpEventTest);
+INSTANTIATE_TEST_SUITE_P(BluetoothLmpEvent, BluetoothLmpEventTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IBluetoothLmpEvent::descriptor)),
+ android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ProcessState::self()->setThreadPoolMaxThreadCount(1);
+ ProcessState::self()->startThreadPool();
+ return RUN_ALL_TESTS();
+}
+
diff --git a/bluetooth/ranging/OWNERS b/bluetooth/ranging/OWNERS
new file mode 100644
index 0000000..3d95624
--- /dev/null
+++ b/bluetooth/ranging/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 27441
+
+include platform/packages/modules/Bluetooth:/OWNERS
+
+chienyuanhuang@google.com
diff --git a/bluetooth/ranging/aidl/Android.bp b/bluetooth/ranging/aidl/Android.bp
new file mode 100644
index 0000000..9e53ef6
--- /dev/null
+++ b/bluetooth/ranging/aidl/Android.bp
@@ -0,0 +1,39 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+aidl_interface {
+ name: "android.hardware.bluetooth.ranging",
+ vendor_available: true,
+ host_supported: true,
+ srcs: ["android/hardware/bluetooth/ranging/*.aidl"],
+ stability: "vintf",
+ backend: {
+ ndk: {
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.btservices",
+ ],
+ min_sdk_version: "33",
+ },
+ },
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/AddressType.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/AddressType.aidl
new file mode 100644
index 0000000..fc417f0
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/AddressType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@Backing(type="int") @VintfStability
+enum AddressType {
+ PUBLIC = 0x00,
+ RANDOM = 0x01,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/BluetoothChannelSoundingParameters.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/BluetoothChannelSoundingParameters.aidl
new file mode 100644
index 0000000..e8fefbe
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/BluetoothChannelSoundingParameters.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@VintfStability
+parcelable BluetoothChannelSoundingParameters {
+ android.hardware.bluetooth.ranging.SessionType sessionType;
+ int aclHandle;
+ int l2capCid;
+ int realTimeProcedureDataAttHandle;
+ android.hardware.bluetooth.ranging.Role role;
+ boolean localSupportsSoundingPhaseBasedRanging;
+ boolean remoteSupportsSoundingPhaseBaseRanging;
+ android.hardware.bluetooth.ranging.Config config;
+ android.hardware.bluetooth.ranging.DeviceAddress address;
+ @nullable android.hardware.bluetooth.ranging.VendorSpecificData[] vendorSpecificData;
+ android.hardware.bluetooth.ranging.LocationType locationType;
+ android.hardware.bluetooth.ranging.SightType sightType;
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl
new file mode 100644
index 0000000..8fc77ae
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@VintfStability
+parcelable ChannelSoudingRawData {
+ int procedureCounter;
+ int[] frequencyCompensation;
+ boolean aborted;
+ android.hardware.bluetooth.ranging.ChannelSoundingSingleSideData initiatorData;
+ android.hardware.bluetooth.ranging.ChannelSoundingSingleSideData reflectorData;
+ byte[] stepChannels;
+ @nullable int[] toaTodInitiator;
+ @nullable int[] todToaReflector;
+ android.hardware.bluetooth.ranging.ModeType[] stepMode;
+ byte numAntennaPaths;
+ long timestampMs;
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl
new file mode 100644
index 0000000..172ac5e
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@VintfStability
+parcelable ChannelSoundingSingleSideData {
+ @nullable android.hardware.bluetooth.ranging.StepTonePct[] stepTonePcts;
+ @nullable byte[] packetQuality;
+ @nullable byte[] packetRssiDbm;
+ @nullable android.hardware.bluetooth.ranging.Nadm[] packetNadm;
+ @nullable int[] measuredFreqOffset;
+ @nullable android.hardware.bluetooth.ranging.ComplexNumber[] packetPct1;
+ @nullable android.hardware.bluetooth.ranging.ComplexNumber[] packetPct2;
+ byte referencePowerDbm;
+ @nullable byte[] vendorSpecificCsSingleSidedata;
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ComplexNumber.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ComplexNumber.aidl
new file mode 100644
index 0000000..4d5ac21
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ComplexNumber.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@VintfStability
+parcelable ComplexNumber {
+ double real;
+ double imaginary;
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Config.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Config.aidl
new file mode 100644
index 0000000..c9ac991
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Config.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@VintfStability
+parcelable Config {
+ android.hardware.bluetooth.ranging.ModeType modeType;
+ android.hardware.bluetooth.ranging.SubModeType subModeType;
+ android.hardware.bluetooth.ranging.RttType rttType;
+ byte[10] channelMap;
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/CsSecurityLevel.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/CsSecurityLevel.aidl
new file mode 100644
index 0000000..6a31547
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/CsSecurityLevel.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@Backing(type="int") @VintfStability
+enum CsSecurityLevel {
+ NOT_SUPPORTED = 0x00,
+ ONE = 0x01,
+ TWO = 0x02,
+ THREE = 0x03,
+ FOUR = 0x04,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/DeviceAddress.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/DeviceAddress.aidl
new file mode 100644
index 0000000..69cad5d
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/DeviceAddress.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@VintfStability
+parcelable DeviceAddress {
+ android.hardware.bluetooth.ranging.AddressType addressType;
+ byte[6] address;
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/IBluetoothChannelSounding.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/IBluetoothChannelSounding.aidl
new file mode 100644
index 0000000..004a482
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/IBluetoothChannelSounding.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@VintfStability
+interface IBluetoothChannelSounding {
+ @nullable android.hardware.bluetooth.ranging.VendorSpecificData[] getVendorSpecificData();
+ @nullable android.hardware.bluetooth.ranging.SessionType[] getSupportedSessionTypes();
+ android.hardware.bluetooth.ranging.CsSecurityLevel getMaxSupportedCsSecurityLevel();
+ @nullable android.hardware.bluetooth.ranging.IBluetoothChannelSoundingSession openSession(in android.hardware.bluetooth.ranging.BluetoothChannelSoundingParameters params, in android.hardware.bluetooth.ranging.IBluetoothChannelSoundingSessionCallback callback);
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSession.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSession.aidl
new file mode 100644
index 0000000..9f691b4
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSession.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@VintfStability
+interface IBluetoothChannelSoundingSession {
+ @nullable android.hardware.bluetooth.ranging.VendorSpecificData[] getVendorSpecificReplies();
+ android.hardware.bluetooth.ranging.ResultType[] getSupportedResultTypes();
+ boolean isAbortedProcedureRequired();
+ void writeRawData(in android.hardware.bluetooth.ranging.ChannelSoudingRawData rawData);
+ void close(android.hardware.bluetooth.ranging.Reason reason);
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSessionCallback.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSessionCallback.aidl
new file mode 100644
index 0000000..d6622de
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSessionCallback.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@VintfStability
+interface IBluetoothChannelSoundingSessionCallback {
+ void onOpened(android.hardware.bluetooth.ranging.Reason reason);
+ void onOpenFailed(android.hardware.bluetooth.ranging.Reason reason);
+ void onResult(in android.hardware.bluetooth.ranging.RangingResult result);
+ void onClose(android.hardware.bluetooth.ranging.Reason reason);
+ void onCloseFailed(android.hardware.bluetooth.ranging.Reason reason);
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/LocationType.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/LocationType.aidl
new file mode 100644
index 0000000..d95af26
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/LocationType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@Backing(type="byte") @VintfStability
+enum LocationType {
+ UNKNOWN = 0x00,
+ INDOOR = 0x01,
+ OUTDOOR = 0x02,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ModeType.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ModeType.aidl
new file mode 100644
index 0000000..1e8ae91
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ModeType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@Backing(type="byte") @VintfStability
+enum ModeType {
+ ZERO = 0x00,
+ ONE = 0x01,
+ TWO = 0x02,
+ THREE = 0x03,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Nadm.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Nadm.aidl
new file mode 100644
index 0000000..a0aa47b
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Nadm.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@Backing(type="byte") @VintfStability
+enum Nadm {
+ ATTACK_IS_EXTREMELY_UNLIKELY = 0x00,
+ ATTACK_IS_VERY_UNLIKELY = 0x01,
+ ATTACK_IS_UNLIKELY = 0x02,
+ ATTACK_IS_POSSIBLE = 0x03,
+ ATTACK_IS_LIKELY = 0x04,
+ ATTACK_IS_VERY_LIKELY = 0x05,
+ ATTACK_IS_EXTREMELY_LIKELY = 0x06,
+ UNKNOWN = 0xFFu8,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/RangingResult.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/RangingResult.aidl
new file mode 100644
index 0000000..d092b80
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/RangingResult.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@VintfStability
+parcelable RangingResult {
+ double resultMeters;
+ double errorMeters;
+ double azimuthDegrees;
+ double errorAzimuthDegrees;
+ double altitudeDegrees;
+ double errorAltitudeDegrees;
+ double delaySpreadMeters;
+ byte confidenceLevel;
+ android.hardware.bluetooth.ranging.Nadm detectedAttackLevel;
+ double velocityMetersPerSecond;
+ @nullable byte[] vendorSpecificCsRangingResultsData;
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Reason.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Reason.aidl
new file mode 100644
index 0000000..ddd44fe
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Reason.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@Backing(type="int") @VintfStability
+enum Reason {
+ LOCAL_STACK_REQUEST,
+ HAL_INITIATED,
+ HARDWARE_INITIATED,
+ ERROR_INVALID_PARAMETER,
+ ERROR_UNKNOWN,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ResultType.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ResultType.aidl
new file mode 100644
index 0000000..b3e098c
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ResultType.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@Backing(type="int") @VintfStability
+enum ResultType {
+ RESULT_METERS = 0x00,
+ ERROR_METERS = 0x01,
+ AZIMUTH_DEGREES = 0x02,
+ ERROR_AZIMUTH_DEGREES = 0x03,
+ ALTITUDE_DEGREES = 0x04,
+ ERROR_ALTITUDE_DEGREES = 0x05,
+ DELAY_SPREAD_METERS = 0x06,
+ CONFIDENCE_LEVEL = 0x07,
+ SECURITY_LEVEL = 0x08,
+ VELOCITY = 0x09,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Role.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Role.aidl
new file mode 100644
index 0000000..61ee1aa
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Role.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@Backing(type="int") @VintfStability
+enum Role {
+ INITIATOR = 0,
+ REFLECTOR = 1,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/RttType.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/RttType.aidl
new file mode 100644
index 0000000..e662c07
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/RttType.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@Backing(type="int") @VintfStability
+enum RttType {
+ AA_COARSE = 0x00,
+ WITH_32_BIT_SOUNDING_SEQUENCE = 0x01,
+ WITH_96_BIT_SOUNDING_SEQUENCE = 0x02,
+ WITH_32_BIT_RANDOM_SEQUENCE = 0x03,
+ WITH_64_BIT_RANDOM_SEQUENCE = 0x04,
+ WITH_96_BIT_RANDOM_SEQUENCE = 0x05,
+ WITH_128_BIT_RANDOM_SEQUENCE = 0x06,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/SessionType.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/SessionType.aidl
new file mode 100644
index 0000000..d43022f
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/SessionType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@Backing(type="int") @VintfStability
+enum SessionType {
+ SOFTWARE_STACK_DATA_PARSING = 0,
+ HARDWARE_OFFLOAD_DATA_PARSING = 1,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/SightType.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/SightType.aidl
new file mode 100644
index 0000000..6e96ba4
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/SightType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@Backing(type="byte") @VintfStability
+enum SightType {
+ UNKNOWN = 0x00,
+ LINE_OF_SIGHT = 0x01,
+ NON_LINE_OF_SIGHT = 0x02,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/StepTonePct.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/StepTonePct.aidl
new file mode 100644
index 0000000..4125748
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/StepTonePct.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@VintfStability
+parcelable StepTonePct {
+ List<android.hardware.bluetooth.ranging.ComplexNumber> tonePcts;
+ byte[] toneQualityIndicator;
+ byte toneExtensionAntennaIndex;
+ const int TONE_QUALITY_GOOD = 0;
+ const int TONE_QUALITY_MEDIUM = 1;
+ const int TONE_QUALITY_LOW = 2;
+ const int TONE_QUALITY_UNAVAILABLE = 3;
+ const int EXTENSION_SLOT_NONE = 0;
+ const int EXTENSION_SLOT_TONE_NOT_EXPECTED_TO_BE_PRESENT = 1;
+ const int EXTENSION_SLOT_TONE_EXPECTED_TO_BE_PRESENT = 2;
+ const int EXTENSION_SLOT_SHIFT_AMOUNT = 4;
+ const byte TONE_EXTENSION_ANTENNA_1 = 0x0;
+ const byte TONE_EXTENSION_ANTENNA_2 = 0x1;
+ const byte TONE_EXTENSION_ANTENNA_3 = 0x2;
+ const byte TONE_EXTENSION_ANTENNA_4 = 0x3;
+ const byte TONE_EXTENSION_UNUSED = 0xFFu8;
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/SubModeType.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/SubModeType.aidl
new file mode 100644
index 0000000..b72a97d
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/SubModeType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@Backing(type="byte") @VintfStability
+enum SubModeType {
+ ONE = 0x01,
+ TWO = 0x02,
+ THREE = 0x03,
+ UNUSED = 0xffu8,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/VendorSpecificData.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/VendorSpecificData.aidl
new file mode 100644
index 0000000..13bf696
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/VendorSpecificData.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.bluetooth.ranging;
+@VintfStability
+parcelable VendorSpecificData {
+ byte[16] characteristicUuid;
+ byte[] opaqueValue;
+}
diff --git a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/AddressType.aidl
similarity index 61%
copy from health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
copy to bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/AddressType.aidl
index aba6cc3..499d42f 100644
--- a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/AddressType.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,12 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "include/StorageHealthDefault.h"
-void get_storage_info(std::vector<struct StorageInfo>&) {
- // Use defaults.
-}
+package android.hardware.bluetooth.ranging;
-void get_disk_stats(std::vector<struct DiskStats>&) {
- // Use defaults
+/**
+ * Same as the BLE address type, except anonymous isn't supported for ranging.
+ */
+@VintfStability
+@Backing(type="int")
+enum AddressType {
+ PUBLIC = 0x00,
+ /* Still may be fixed on the device and is not randomized on boot */
+ RANDOM = 0x01,
}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/BluetoothChannelSoundingParameters.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/BluetoothChannelSoundingParameters.aidl
new file mode 100644
index 0000000..0cda847
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/BluetoothChannelSoundingParameters.aidl
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+import android.hardware.bluetooth.ranging.Config;
+import android.hardware.bluetooth.ranging.DeviceAddress;
+import android.hardware.bluetooth.ranging.LocationType;
+import android.hardware.bluetooth.ranging.Role;
+import android.hardware.bluetooth.ranging.SessionType;
+import android.hardware.bluetooth.ranging.SightType;
+import android.hardware.bluetooth.ranging.VendorSpecificData;
+
+/**
+ * Parameters for IBluetoothChannelSoundingSession.openSession().
+ */
+@VintfStability
+parcelable BluetoothChannelSoundingParameters {
+ SessionType sessionType;
+ /**
+ * Acl handle of the connection.
+ */
+ int aclHandle;
+ /**
+ * L2CAP Cid, needed in case of EATT which may use dynamic channel for GATT.
+ */
+ int l2capCid;
+ /**
+ * ATT handle of the Real-time Procedure Data.
+ */
+ int realTimeProcedureDataAttHandle;
+ /**
+ * Role of the local device.
+ */
+ Role role;
+ /**
+ * If sounding phase-based ranging is supported by the local device.
+ */
+ boolean localSupportsSoundingPhaseBasedRanging;
+ /**
+ * If sounding phase-based ranging is supported by the remote device.
+ */
+ boolean remoteSupportsSoundingPhaseBaseRanging;
+ /**
+ * CS conifg used for procedure enable.
+ */
+ Config config;
+ /**
+ * Device address of the remote device.
+ */
+ DeviceAddress address;
+ /**
+ * Vendor-specific data get from remote GATT Server
+ */
+ @nullable VendorSpecificData[] vendorSpecificData;
+ /**
+ * Specifies the preferred location type of the use case (indoor, outdoor, unknown), this is
+ * used by the HAL to choose the corresponding ranging algorithm if it supports multiple
+ * algorithms
+ */
+ LocationType locationType;
+ /**
+ * Specifies the preferred sight type of the use case (line-of-sight, non-line-of-sight,
+ * unknown), this is used by the HAL to choose the corresponding ranging algorithm if it
+ * supports multiple algorithms
+ */
+ SightType sightType;
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl
new file mode 100644
index 0000000..78ce4f4
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+import android.hardware.bluetooth.ranging.ChannelSoundingSingleSideData;
+import android.hardware.bluetooth.ranging.ModeType;
+
+/**
+ * Raw ranging data of Channel Sounding.
+ * See Channel Sounding CR_PR 3.1.10 and Channel Sounding HCI Updates CR_PR 3.1.23 for details.
+ *
+ * Specification: https://www.bluetooth.com/specifications/specs/channel-sounding-cr-pr/
+ */
+@VintfStability
+parcelable ChannelSoudingRawData {
+ /**
+ * Procedure counter of the CS procedure.
+ */
+ int procedureCounter;
+ /**
+ * Frequency Compensation indicates fractional frequency
+ * offset (FFO) value of initiator, in 0.01ppm
+ */
+ int[] frequencyCompensation;
+ /**
+ * Indicate if the procedure aborted.
+ */
+ boolean aborted;
+ /**
+ * Common data for both initator and reflector sided.
+ */
+ ChannelSoundingSingleSideData initiatorData;
+ ChannelSoundingSingleSideData reflectorData;
+ /**
+ * The channel indices of every step in a CS procedure (in time order).
+ */
+ byte[] stepChannels;
+ /**
+ * Toa_tod_initator from mode-1 or mode-3 steps in a CS procedure (in time order).
+ * Time of flight = 0.5 * (toa_tod_initiator - tod_toa_reflector).
+ */
+ @nullable int[] toaTodInitiator;
+ /**
+ * Tod_toa_reflector from mode-1 or mode-3 steps in a CS procedure (in time order).
+ * Time of flight = 0.5 * (toa_tod_initiator - tod_toa_reflector).
+ */
+ @nullable int[] todToaReflector;
+ /**
+ * CS mode (0, 1, 2, 3) of each CS step.
+ */
+ ModeType[] stepMode;
+ /**
+ * Number of antenna paths (1 to 4) reported in the CS procedure.
+ */
+ byte numAntennaPaths;
+ /**
+ * Timestamp when the procedure is created. Using epoch time in ms (e.g., 1697673127175).
+ */
+ long timestampMs;
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl
new file mode 100644
index 0000000..9c4b472
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+import android.hardware.bluetooth.ranging.ComplexNumber;
+import android.hardware.bluetooth.ranging.Nadm;
+import android.hardware.bluetooth.ranging.StepTonePct;
+
+/**
+ * Raw ranging data of Channel Sounding from either Initator or Reflector.
+ * See Channel Sounding CR_PR 3.1.10 and Channel Sounding HCI Updates CR_PR 3.1.23 for details.
+ *
+ * Specification: https://www.bluetooth.com/specifications/specs/channel-sounding-cr-pr/
+ */
+@VintfStability
+parcelable ChannelSoundingSingleSideData {
+ /**
+ * PCT (complex value) measured from mode-2 or mode-3 steps in a CS procedure (in time order).
+ */
+ @nullable StepTonePct[] stepTonePcts;
+ /**
+ * Packet Quality from mode-1 or mode-3 steps in a CS procedures (in time order).
+ */
+ @nullable byte[] packetQuality;
+ /**
+ * Packet RSSI (-127 to 20) of mode-0, mode-1, or mode-3 step data, in dBm.
+ */
+ @nullable byte[] packetRssiDbm;
+ /**
+ * Packet NADM of mode-1 or mode-3 step data for attack detection.
+ */
+ @nullable Nadm[] packetNadm;
+ /**
+ * Measured Frequency Offset from mode 0, relative to the remote device, in 0.01ppm
+ */
+ @nullable int[] measuredFreqOffset;
+ /**
+ * Packet_PCT1 or packet_PCT2 of mode-1 or mode-3, if sounding sequence is used and sounding
+ * phase-based ranging is supported.
+ */
+ @nullable ComplexNumber[] packetPct1;
+ @nullable ComplexNumber[] packetPct2;
+ /**
+ * Reference power level (-127 to 20) of the signal in the procedure, in dBm.
+ */
+ byte referencePowerDbm;
+ /**
+ * Parameter for vendors to place vendor-specific raw ranging data.
+ */
+ @nullable byte[] vendorSpecificCsSingleSidedata;
+}
diff --git a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ComplexNumber.aidl
similarity index 68%
copy from health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
copy to bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ComplexNumber.aidl
index aba6cc3..5253d9f 100644
--- a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ComplexNumber.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,12 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "include/StorageHealthDefault.h"
-void get_storage_info(std::vector<struct StorageInfo>&) {
- // Use defaults.
-}
+package android.hardware.bluetooth.ranging;
-void get_disk_stats(std::vector<struct DiskStats>&) {
- // Use defaults
+@VintfStability
+parcelable ComplexNumber {
+ double real;
+ double imaginary;
}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Config.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Config.aidl
new file mode 100644
index 0000000..85ae4c1
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Config.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+import android.hardware.bluetooth.ranging.ModeType;
+import android.hardware.bluetooth.ranging.RttType;
+import android.hardware.bluetooth.ranging.SubModeType;
+
+@VintfStability
+parcelable Config {
+ /**
+ * Main_Mode_Type of the CS conifg
+ */
+ ModeType modeType;
+ /**
+ * Sub_Mode_Type of the CS conifg
+ */
+ SubModeType subModeType;
+ /**
+ * RTT_Type of the CS conifg
+ */
+ RttType rttType;
+ /**
+ * Channel_Map of the CS conifg, this parameter contains 80 1-bit fields. The nth such field
+ * (in the range 0 to 78) contains the value for the CS channel index n.
+ *
+ * Channel n is enabled for CS procedure = 1
+ * Channel n is disabled for CS procedure = 0
+ */
+ byte[10] channelMap;
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/CsSecurityLevel.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/CsSecurityLevel.aidl
new file mode 100644
index 0000000..3fd4424
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/CsSecurityLevel.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+@VintfStability
+@Backing(type="int")
+enum CsSecurityLevel {
+ /**
+ * Ranging algorithm is not implemented.
+ */
+ NOT_SUPPORTED = 0x00,
+ /**
+ * Either CS tone or CS RTT.
+ */
+ ONE = 0x01,
+ /**
+ * 150 ns CS RTT accuracy and CS tones.
+ */
+ TWO = 0x02,
+ /**
+ * 10 ns CS RTT accuracy and CS tones.
+ */
+ THREE = 0x03,
+ /**
+ * Level 3 with the addition of CS RTT sounding sequence or random sequence
+ * payloads, and support of the Normalized Attack Detector Metric requirements.
+ */
+ FOUR = 0x04,
+}
diff --git a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/DeviceAddress.aidl
similarity index 65%
copy from health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
copy to bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/DeviceAddress.aidl
index aba6cc3..c847c30 100644
--- a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/DeviceAddress.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,12 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "include/StorageHealthDefault.h"
-void get_storage_info(std::vector<struct StorageInfo>&) {
- // Use defaults.
-}
+package android.hardware.bluetooth.ranging;
-void get_disk_stats(std::vector<struct DiskStats>&) {
- // Use defaults
+import android.hardware.bluetooth.ranging.AddressType;
+
+/**
+ * Bluetooth address with address type
+ */
+@VintfStability
+parcelable DeviceAddress {
+ AddressType addressType;
+ byte[6] address;
}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSounding.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSounding.aidl
new file mode 100644
index 0000000..45ec79f
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSounding.aidl
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+import android.hardware.bluetooth.ranging.BluetoothChannelSoundingParameters;
+import android.hardware.bluetooth.ranging.CsSecurityLevel;
+import android.hardware.bluetooth.ranging.IBluetoothChannelSoundingSession;
+import android.hardware.bluetooth.ranging.IBluetoothChannelSoundingSessionCallback;
+import android.hardware.bluetooth.ranging.Nadm;
+import android.hardware.bluetooth.ranging.SessionType;
+import android.hardware.bluetooth.ranging.VendorSpecificData;
+
+/**
+ * The interface for the Bluetooth stack to get vendor specifc data and open session
+ * for channel sounding.
+ */
+@VintfStability
+interface IBluetoothChannelSounding {
+ /**
+ * API to get vendor-specific data, the Bluetooth stack will provision the GATT server with
+ * these vendor-specific UUIDs and data.
+ *
+ * @return an array of vendor specifc data
+ */
+ @nullable VendorSpecificData[] getVendorSpecificData();
+
+ /**
+ * API to get supported session types of the HAL
+ *
+ * @return an array of supported session types
+ */
+ @nullable SessionType[] getSupportedSessionTypes();
+
+ /**
+ * API to get max supported security level (0 to 4) of CS for ranging algorithms.
+ *
+ * See: https://bluetooth.com/specifications/specs/channel-sounding-cr-pr/
+ *
+ * @return CsSecurityLevel that indicates max supported security level of CS for ranging
+ * algorithms.
+ */
+ CsSecurityLevel getMaxSupportedCsSecurityLevel();
+
+ /**
+ * API to open session for channel sounding and register the corresponeding callback
+ *
+ * @return an instance of IBluetoothChannelSoundingSession
+ */
+ @nullable IBluetoothChannelSoundingSession openSession(
+ in BluetoothChannelSoundingParameters params,
+ in IBluetoothChannelSoundingSessionCallback callback);
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSession.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSession.aidl
new file mode 100644
index 0000000..97b147e
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSession.aidl
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+import android.hardware.bluetooth.ranging.ChannelSoudingRawData;
+import android.hardware.bluetooth.ranging.Reason;
+import android.hardware.bluetooth.ranging.ResultType;
+import android.hardware.bluetooth.ranging.VendorSpecificData;
+
+/**
+ * Session of Channel Sounding get from IBluetoothChannelSounding.openSession().
+ * Used by the Bluetooth stack to get preferred config from HAL and provide raw ranging data to
+ * the HAL.
+ */
+@VintfStability
+interface IBluetoothChannelSoundingSession {
+ /**
+ * API to get vendor-specifc replies
+ *
+ * @return an array of vendor-specifc data
+ */
+ @nullable VendorSpecificData[] getVendorSpecificReplies();
+
+ /**
+ * API to obtain supported result types. The Bluetooth stack should use this function to check
+ * for supported result types and ignore unsupported types in the RangingResult.
+ *
+ * @return an array of vendor-specifc data
+ */
+ ResultType[] getSupportedResultTypes();
+
+ /**
+ * Indicate whether the HAL would like to receive raw data of abort procedures.
+ * If this function returns true, the Bluetooth stack should pass the data to the HAL using
+ * the writeRawData() function, even if the CS procedure is aborted.
+ *
+ * @return true if the HAL would like to receive raw data of abort procedures.
+ */
+ boolean isAbortedProcedureRequired();
+
+ /**
+ * API to provide raw ranging data to the HAL. The HAL converts this data into meaningful
+ * ranging results using a proprietary algorithm and then calls back to the Bluetooth stack via
+ * IBluetoothChannelSoundingSessionCallback.onResult().
+ */
+ void writeRawData(in ChannelSoudingRawData rawData);
+
+ /**
+ * Close the current session. Object is no longer useful after this method.
+ */
+ void close(Reason reason);
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSessionCallback.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSessionCallback.aidl
new file mode 100644
index 0000000..6901305
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSessionCallback.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+import android.hardware.bluetooth.ranging.RangingResult;
+import android.hardware.bluetooth.ranging.Reason;
+
+/**
+ * The callback from the HAL to the stack.
+ * Register by IBluetoothChannelSoundingSession.openSession().
+ */
+@VintfStability
+interface IBluetoothChannelSoundingSessionCallback {
+ /**
+ * Invoked when IBluetoothChannelSounding.openSession() is successful.
+ */
+ void onOpened(Reason reason);
+ /**
+ * Invoked when IBluetoothChannelSounding.openSession() fails.
+ */
+ void onOpenFailed(Reason reason);
+ /**
+ * Invoked when HAL get raning result.
+ */
+ void onResult(in RangingResult result);
+ /**
+ * Invoked when IBluetoothChannelSoundingSession.close() is successful.
+ */
+ void onClose(Reason reason);
+ /**
+ * Invoked when IBluetoothChannelSoundingSession.close() fails.
+ */
+ void onCloseFailed(Reason reason);
+}
diff --git a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/LocationType.aidl
similarity index 68%
copy from health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
copy to bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/LocationType.aidl
index aba6cc3..bccf291 100644
--- a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/LocationType.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,12 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "include/StorageHealthDefault.h"
-void get_storage_info(std::vector<struct StorageInfo>&) {
- // Use defaults.
-}
+package android.hardware.bluetooth.ranging;
-void get_disk_stats(std::vector<struct DiskStats>&) {
- // Use defaults
+@VintfStability
+@Backing(type="byte")
+enum LocationType {
+ UNKNOWN = 0x00,
+ INDOOR = 0x01,
+ OUTDOOR = 0x02,
}
diff --git a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ModeType.aidl
similarity index 68%
copy from health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
copy to bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ModeType.aidl
index aba6cc3..3a727aa 100644
--- a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ModeType.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,12 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "include/StorageHealthDefault.h"
-void get_storage_info(std::vector<struct StorageInfo>&) {
- // Use defaults.
-}
+package android.hardware.bluetooth.ranging;
-void get_disk_stats(std::vector<struct DiskStats>&) {
- // Use defaults
+@VintfStability
+@Backing(type="byte")
+enum ModeType {
+ ZERO = 0x00,
+ ONE = 0x01,
+ TWO = 0x02,
+ THREE = 0x03,
}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Nadm.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Nadm.aidl
new file mode 100644
index 0000000..74cf731
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Nadm.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+/**
+ * Normalized Attack Detector Metric.
+ * See Channel Sounding CR_PR, 3.13.24 for details.
+ *
+ * Specification: https://www.bluetooth.com/specifications/specs/channel-sounding-cr-pr/
+ */
+@VintfStability
+@Backing(type="byte")
+enum Nadm {
+ ATTACK_IS_EXTREMELY_UNLIKELY = 0x00,
+ ATTACK_IS_VERY_UNLIKELY = 0x01,
+ ATTACK_IS_UNLIKELY = 0x02,
+ ATTACK_IS_POSSIBLE = 0x03,
+ ATTACK_IS_LIKELY = 0x04,
+ ATTACK_IS_VERY_LIKELY = 0x05,
+ ATTACK_IS_EXTREMELY_LIKELY = 0x06,
+ /* If a device is unable to determine a NADM value, then it shall report a NADM value of Unknown
+ */
+ UNKNOWN = 0xFFu8,
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/RangingResult.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/RangingResult.aidl
new file mode 100644
index 0000000..65907dd
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/RangingResult.aidl
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+import android.hardware.bluetooth.ranging.Nadm;
+
+/**
+ * Generic structure to return the ranging result
+ */
+@VintfStability
+parcelable RangingResult {
+ /**
+ * Estimated distance in meters.
+ */
+ double resultMeters;
+ /**
+ * Potential distance estimate error (plus or minus) in meters, always positive.
+ */
+ double errorMeters;
+ /**
+ * Azimuth Angle measurement in degrees.
+ *
+ * Azimuth of remote device in horizontal coordinate system, this measured from azimuth north
+ * and increasing eastward. When the remote device in azimuth north, this angle is 0, when the
+ * remote device in azimuth south, this angle is 180.
+ *
+ * See: <a href="https://en.wikipedia.org/wiki/Horizontal_coordinate_system">Horizontal
+ * coordinate system</a>for the details
+ *
+ * On an Android device, azimuth north is defined as the angle perpendicular away from the
+ * back of the device when holding it in portrait mode upright.
+ *
+ * The Azimuth north is defined as the direction in which the top edge of the device is
+ * facing when it is placed flat.
+ *
+ */
+ double azimuthDegrees;
+ /**
+ * Estimated error (plus or minus) of azimuth angle measurement in degrees, always positive.
+ */
+ double errorAzimuthDegrees;
+ /**
+ * Altitude Angle measurement in degrees.
+ *
+ * Altitude of remote device in horizontal coordinate system, this is the angle between the
+ * remote device and the top edge of local device. When local device is placed flat, the angle
+ * of the zenith is 90, the angle of the nadir is -90.
+ *
+ * See: https://en.wikipedia.org/wiki/Horizontal_coordinate_system
+ */
+ double altitudeDegrees;
+ /**
+ * Estimated error (plus or minus) of altitude angle measurement in degrees, always positive.
+ */
+ double errorAltitudeDegrees;
+ /**
+ * Estimated delay spread in meters of the measured channel. This is a measure of multipath
+ * richness of the channel.
+ */
+ double delaySpreadMeters;
+ /**
+ * A normalized value from 0 (low confidence) to 100 (high confidence) representing the
+ * confidence of estimated distance.
+ */
+ byte confidenceLevel;
+ /**
+ * A value representing the chance of being attacked for the measurement.
+ */
+ Nadm detectedAttackLevel;
+ /**
+ * Estimated velocity, in the direction of line between two devices, of the moving object in
+ * meters/sec.
+ */
+ double velocityMetersPerSecond;
+ /**
+ * Parameter for vendors to place vendor-specific ranging results data.
+ */
+ @nullable byte[] vendorSpecificCsRangingResultsData;
+}
diff --git a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Reason.aidl
similarity index 67%
copy from health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
copy to bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Reason.aidl
index aba6cc3..4f587de 100644
--- a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Reason.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,12 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "include/StorageHealthDefault.h"
-void get_storage_info(std::vector<struct StorageInfo>&) {
- // Use defaults.
-}
+package android.hardware.bluetooth.ranging;
-void get_disk_stats(std::vector<struct DiskStats>&) {
- // Use defaults
+@VintfStability
+@Backing(type="int")
+enum Reason {
+ LOCAL_STACK_REQUEST,
+ HAL_INITIATED,
+ HARDWARE_INITIATED,
+ ERROR_INVALID_PARAMETER,
+ ERROR_UNKNOWN,
}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ResultType.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ResultType.aidl
new file mode 100644
index 0000000..561b7dd
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ResultType.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+@VintfStability
+@Backing(type="int")
+enum ResultType {
+ RESULT_METERS = 0x00,
+ ERROR_METERS = 0x01,
+ AZIMUTH_DEGREES = 0x02,
+ ERROR_AZIMUTH_DEGREES = 0x03,
+ ALTITUDE_DEGREES = 0x04,
+ ERROR_ALTITUDE_DEGREES = 0x05,
+ DELAY_SPREAD_METERS = 0x06,
+ CONFIDENCE_LEVEL = 0x07,
+ SECURITY_LEVEL = 0x08,
+ VELOCITY = 0x09,
+}
diff --git a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Role.aidl
similarity index 68%
copy from health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
copy to bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Role.aidl
index aba6cc3..b531935 100644
--- a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Role.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,12 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "include/StorageHealthDefault.h"
-void get_storage_info(std::vector<struct StorageInfo>&) {
- // Use defaults.
-}
+package android.hardware.bluetooth.ranging;
-void get_disk_stats(std::vector<struct DiskStats>&) {
- // Use defaults
+@VintfStability
+@Backing(type="int")
+enum Role {
+ INITIATOR = 0,
+ REFLECTOR = 1,
}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/RttType.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/RttType.aidl
new file mode 100644
index 0000000..6e163c9
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/RttType.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+@VintfStability
+@Backing(type="int")
+enum RttType {
+ AA_COARSE = 0x00,
+ WITH_32_BIT_SOUNDING_SEQUENCE = 0x01,
+ WITH_96_BIT_SOUNDING_SEQUENCE = 0x02,
+ WITH_32_BIT_RANDOM_SEQUENCE = 0x03,
+ WITH_64_BIT_RANDOM_SEQUENCE = 0x04,
+ WITH_96_BIT_RANDOM_SEQUENCE = 0x05,
+ WITH_128_BIT_RANDOM_SEQUENCE = 0x06,
+}
diff --git a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/SessionType.aidl
similarity index 61%
copy from health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
copy to bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/SessionType.aidl
index aba6cc3..4f0d529 100644
--- a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/SessionType.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,12 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "include/StorageHealthDefault.h"
-void get_storage_info(std::vector<struct StorageInfo>&) {
- // Use defaults.
-}
+package android.hardware.bluetooth.ranging;
-void get_disk_stats(std::vector<struct DiskStats>&) {
- // Use defaults
+@VintfStability
+@Backing(type="int")
+enum SessionType {
+ /**
+ * Stack parses raw data and passes it to the HAL
+ */
+ SOFTWARE_STACK_DATA_PARSING = 0,
+ /**
+ * Offloader parses raw data
+ */
+ HARDWARE_OFFLOAD_DATA_PARSING = 1
}
diff --git a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/SightType.aidl
similarity index 68%
rename from health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
rename to bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/SightType.aidl
index aba6cc3..14106e0 100644
--- a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/SightType.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,12 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "include/StorageHealthDefault.h"
-void get_storage_info(std::vector<struct StorageInfo>&) {
- // Use defaults.
-}
+package android.hardware.bluetooth.ranging;
-void get_disk_stats(std::vector<struct DiskStats>&) {
- // Use defaults
+@VintfStability
+@Backing(type="byte")
+enum SightType {
+ UNKNOWN = 0x00,
+ LINE_OF_SIGHT = 0x01,
+ NON_LINE_OF_SIGHT = 0x02,
}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/StepTonePct.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/StepTonePct.aidl
new file mode 100644
index 0000000..4650861
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/StepTonePct.aidl
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+import android.hardware.bluetooth.ranging.ComplexNumber;
+
+/**
+ * Tone PCT data with quality indicator from a mode-2 or mode-3 step.
+ */
+@VintfStability
+parcelable StepTonePct {
+ /**
+ * PCT measured from mode-2 or mode-3 steps
+ * (in ascending order of antenna position with tone extension data at the end).
+ */
+ List<ComplexNumber> tonePcts;
+ const int TONE_QUALITY_GOOD = 0;
+ const int TONE_QUALITY_MEDIUM = 1;
+ const int TONE_QUALITY_LOW = 2;
+ const int TONE_QUALITY_UNAVAILABLE = 3;
+ const int EXTENSION_SLOT_NONE = 0;
+ const int EXTENSION_SLOT_TONE_NOT_EXPECTED_TO_BE_PRESENT = 1;
+ const int EXTENSION_SLOT_TONE_EXPECTED_TO_BE_PRESENT = 2;
+ /**
+ * Shift amount for extension slot (bits 4 to 7).
+ */
+ const int EXTENSION_SLOT_SHIFT_AMOUNT = 4;
+ /**
+ * Tone_Quality_Indicator defined in the LE CS Subevent Result event
+ *
+ * Bits 0 to 3:
+ * 0x0 = Tone quality is good
+ * 0x1 = Tone quality is medium
+ * 0x2 = Tone quality is low
+ * 0x3 = Tone quality is unavailable
+ *
+ * Bits 4 to 7:
+ * 0x0 = Not tone extension slot
+ * 0x1 = Tone extension slot; tone not expected to be present
+ * 0x2 = Tone extension slot; tone expected to be present
+ *
+ * See: https://bluetooth.com/specifications/specs/channel-sounding-cr-pr/
+ */
+ byte[] toneQualityIndicator;
+
+ const byte TONE_EXTENSION_ANTENNA_1 = 0x0;
+ const byte TONE_EXTENSION_ANTENNA_2 = 0x1;
+ const byte TONE_EXTENSION_ANTENNA_3 = 0x2;
+ const byte TONE_EXTENSION_ANTENNA_4 = 0x3;
+ const byte TONE_EXTENSION_UNUSED = 0xFFu8;
+ /**
+ * Tone Extension Antenna Index indicates the Antenna position used in tone extension slot
+ *
+ * 0x00 = A1
+ * 0x01 = A2
+ * 0x02 = A3
+ * 0x03 = A4
+ * 0xFF = Tone extension not used
+ */
+ byte toneExtensionAntennaIndex;
+}
diff --git a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/SubModeType.aidl
similarity index 68%
copy from health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
copy to bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/SubModeType.aidl
index aba6cc3..b775002 100644
--- a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/SubModeType.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,12 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "include/StorageHealthDefault.h"
-void get_storage_info(std::vector<struct StorageInfo>&) {
- // Use defaults.
-}
+package android.hardware.bluetooth.ranging;
-void get_disk_stats(std::vector<struct DiskStats>&) {
- // Use defaults
+@VintfStability
+@Backing(type="byte")
+enum SubModeType {
+ ONE = 0x01,
+ TWO = 0x02,
+ THREE = 0x03,
+ UNUSED = 0xffu8,
}
diff --git a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/VendorSpecificData.aidl
similarity index 68%
copy from health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
copy to bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/VendorSpecificData.aidl
index aba6cc3..a8c9a2a 100644
--- a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/VendorSpecificData.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,12 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "include/StorageHealthDefault.h"
-void get_storage_info(std::vector<struct StorageInfo>&) {
- // Use defaults.
-}
+package android.hardware.bluetooth.ranging;
-void get_disk_stats(std::vector<struct DiskStats>&) {
- // Use defaults
+/**
+ * Vendor specific data for GATT.
+ */
+@VintfStability
+parcelable VendorSpecificData {
+ byte[16] characteristicUuid;
+ byte[] opaqueValue;
}
diff --git a/bluetooth/ranging/aidl/default/Android.bp b/bluetooth/ranging/aidl/default/Android.bp
new file mode 100644
index 0000000..5072a43
--- /dev/null
+++ b/bluetooth/ranging/aidl/default/Android.bp
@@ -0,0 +1,29 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_binary {
+ name: "android.hardware.bluetooth.ranging-service.default",
+ relative_install_path: "hw",
+ init_rc: ["bluetooth-ranging-service-default.rc"],
+ vintf_fragments: [":manifest_android.hardware.bluetooth.ranging-service.default.xml"],
+ vendor: true,
+ srcs: [
+ "BluetoothChannelSounding.cpp",
+ "BluetoothChannelSoundingSession.cpp",
+ "service.cpp",
+ ],
+ shared_libs: [
+ "android.hardware.bluetooth.ranging-V1-ndk",
+ "libbase",
+ "libbinder_ndk",
+ "libhidlbase",
+ "libutils",
+ "liblog",
+ ],
+}
+
+filegroup {
+ name: "manifest_android.hardware.bluetooth.ranging-service.default.xml",
+ srcs: ["bluetooth-ranging-service-default.xml"],
+}
diff --git a/bluetooth/ranging/aidl/default/BluetoothChannelSounding.cpp b/bluetooth/ranging/aidl/default/BluetoothChannelSounding.cpp
new file mode 100644
index 0000000..3807d4f
--- /dev/null
+++ b/bluetooth/ranging/aidl/default/BluetoothChannelSounding.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BluetoothChannelSounding.h"
+
+#include "BluetoothChannelSoundingSession.h"
+
+namespace aidl::android::hardware::bluetooth::ranging::impl {
+
+BluetoothChannelSounding::BluetoothChannelSounding() {}
+BluetoothChannelSounding::~BluetoothChannelSounding() {}
+
+ndk::ScopedAStatus BluetoothChannelSounding::getVendorSpecificData(
+ std::optional<
+ std::vector<std::optional<VendorSpecificData>>>* /*_aidl_return*/) {
+ return ::ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus BluetoothChannelSounding::getSupportedSessionTypes(
+ std::optional<std::vector<SessionType>>* _aidl_return) {
+ std::vector<SessionType> supported_session_types = {};
+ *_aidl_return = supported_session_types;
+ return ::ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus BluetoothChannelSounding::getMaxSupportedCsSecurityLevel(
+ CsSecurityLevel* _aidl_return) {
+ CsSecurityLevel security_level = CsSecurityLevel::NOT_SUPPORTED;
+ *_aidl_return = security_level;
+ return ::ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus BluetoothChannelSounding::openSession(
+ const BluetoothChannelSoundingParameters& /*in_params*/,
+ const std::shared_ptr<IBluetoothChannelSoundingSessionCallback>&
+ in_callback,
+ std::shared_ptr<IBluetoothChannelSoundingSession>* _aidl_return) {
+ if (in_callback == nullptr) {
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "Invalid nullptr callback");
+ }
+ std::shared_ptr<BluetoothChannelSoundingSession> session = nullptr;
+ session = ndk::SharedRefBase::make<BluetoothChannelSoundingSession>(
+ in_callback, Reason::LOCAL_STACK_REQUEST);
+ *_aidl_return = session;
+ return ::ndk::ScopedAStatus::ok();
+}
+} // namespace aidl::android::hardware::bluetooth::ranging::impl
diff --git a/bluetooth/ranging/aidl/default/BluetoothChannelSounding.h b/bluetooth/ranging/aidl/default/BluetoothChannelSounding.h
new file mode 100644
index 0000000..d6b5c03
--- /dev/null
+++ b/bluetooth/ranging/aidl/default/BluetoothChannelSounding.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/bluetooth/ranging/BnBluetoothChannelSounding.h>
+
+#include <vector>
+
+namespace aidl::android::hardware::bluetooth::ranging::impl {
+
+using ::aidl::android::hardware::bluetooth::ranging::
+ BluetoothChannelSoundingParameters;
+using ::aidl::android::hardware::bluetooth::ranging::BnBluetoothChannelSounding;
+using ::aidl::android::hardware::bluetooth::ranging::CsSecurityLevel;
+using ::aidl::android::hardware::bluetooth::ranging::
+ IBluetoothChannelSoundingSession;
+using ::aidl::android::hardware::bluetooth::ranging::
+ IBluetoothChannelSoundingSessionCallback;
+using ::aidl::android::hardware::bluetooth::ranging::SessionType;
+using ::aidl::android::hardware::bluetooth::ranging::VendorSpecificData;
+
+class BluetoothChannelSounding : public BnBluetoothChannelSounding {
+ public:
+ BluetoothChannelSounding();
+ ~BluetoothChannelSounding(); // Add the destructor declaration
+ ndk::ScopedAStatus getVendorSpecificData(
+ std::optional<std::vector<std::optional<VendorSpecificData>>>*
+ _aidl_return) override;
+ ndk::ScopedAStatus getSupportedSessionTypes(
+ std::optional<std::vector<SessionType>>* _aidl_return) override;
+ ndk::ScopedAStatus getMaxSupportedCsSecurityLevel(
+ CsSecurityLevel* _aidl_return) override;
+ ndk::ScopedAStatus openSession(
+ const BluetoothChannelSoundingParameters& in_params,
+ const std::shared_ptr<IBluetoothChannelSoundingSessionCallback>&
+ in_callback,
+ std::shared_ptr<IBluetoothChannelSoundingSession>* _aidl_return) override;
+};
+
+} // namespace aidl::android::hardware::bluetooth::ranging::impl
diff --git a/bluetooth/ranging/aidl/default/BluetoothChannelSoundingSession.cpp b/bluetooth/ranging/aidl/default/BluetoothChannelSoundingSession.cpp
new file mode 100644
index 0000000..6c58a07
--- /dev/null
+++ b/bluetooth/ranging/aidl/default/BluetoothChannelSoundingSession.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BluetoothChannelSoundingSession.h"
+
+namespace aidl::android::hardware::bluetooth::ranging::impl {
+
+BluetoothChannelSoundingSession::BluetoothChannelSoundingSession(
+ std::shared_ptr<IBluetoothChannelSoundingSessionCallback> callback,
+ Reason reason) {
+ callback_ = callback;
+ callback_->onOpened(reason);
+}
+
+ndk::ScopedAStatus BluetoothChannelSoundingSession::getVendorSpecificReplies(
+ std::optional<
+ std::vector<std::optional<VendorSpecificData>>>* /*_aidl_return*/) {
+ return ::ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus BluetoothChannelSoundingSession::getSupportedResultTypes(
+ std::vector<ResultType>* _aidl_return) {
+ std::vector<ResultType> supported_result_types = {ResultType::RESULT_METERS};
+ *_aidl_return = supported_result_types;
+ return ::ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus BluetoothChannelSoundingSession::isAbortedProcedureRequired(
+ bool* _aidl_return) {
+ *_aidl_return = false;
+ return ::ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus BluetoothChannelSoundingSession::writeRawData(
+ const ChannelSoudingRawData& /*in_rawData*/) {
+ RangingResult ranging_result;
+ ranging_result.resultMeters = 0.0;
+ callback_->onResult(ranging_result);
+ return ::ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus BluetoothChannelSoundingSession::close(Reason in_reason) {
+ callback_->onClose(in_reason);
+ return ::ndk::ScopedAStatus::ok();
+}
+} // namespace aidl::android::hardware::bluetooth::ranging::impl
diff --git a/bluetooth/ranging/aidl/default/BluetoothChannelSoundingSession.h b/bluetooth/ranging/aidl/default/BluetoothChannelSoundingSession.h
new file mode 100644
index 0000000..6703f7f
--- /dev/null
+++ b/bluetooth/ranging/aidl/default/BluetoothChannelSoundingSession.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/bluetooth/ranging/BnBluetoothChannelSoundingSession.h>
+#include <aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSessionCallback.h>
+
+#include <vector>
+
+namespace aidl::android::hardware::bluetooth::ranging::impl {
+
+using ::aidl::android::hardware::bluetooth::ranging::ChannelSoudingRawData;
+using ::aidl::android::hardware::bluetooth::ranging::Reason;
+using ::aidl::android::hardware::bluetooth::ranging::ResultType;
+using ::aidl::android::hardware::bluetooth::ranging::VendorSpecificData;
+
+class BluetoothChannelSoundingSession
+ : public BnBluetoothChannelSoundingSession {
+ public:
+ BluetoothChannelSoundingSession(
+ std::shared_ptr<IBluetoothChannelSoundingSessionCallback> callback,
+ Reason reason);
+
+ ndk::ScopedAStatus getVendorSpecificReplies(
+ std::optional<std::vector<std::optional<VendorSpecificData>>>*
+ _aidl_return) override;
+ ndk::ScopedAStatus getSupportedResultTypes(
+ std::vector<ResultType>* _aidl_return) override;
+ ndk::ScopedAStatus isAbortedProcedureRequired(bool* _aidl_return) override;
+ ndk::ScopedAStatus writeRawData(
+ const ChannelSoudingRawData& in_rawData) override;
+ ndk::ScopedAStatus close(Reason in_reason) override;
+
+ private:
+ std::shared_ptr<IBluetoothChannelSoundingSessionCallback> callback_;
+};
+
+} // namespace aidl::android::hardware::bluetooth::ranging::impl
diff --git a/bluetooth/ranging/aidl/default/bluetooth-ranging-service-default.rc b/bluetooth/ranging/aidl/default/bluetooth-ranging-service-default.rc
new file mode 100644
index 0000000..fabb409
--- /dev/null
+++ b/bluetooth/ranging/aidl/default/bluetooth-ranging-service-default.rc
@@ -0,0 +1,6 @@
+service vendor.bluetooth.ranging-default /vendor/bin/hw/android.hardware.bluetooth.ranging-service.default
+ class hal
+ capabilities BLOCK_SUSPEND NET_ADMIN SYS_NICE
+ user bluetooth
+ group bluetooth
+ task_profiles HighPerformance
diff --git a/bluetooth/ranging/aidl/default/bluetooth-ranging-service-default.xml b/bluetooth/ranging/aidl/default/bluetooth-ranging-service-default.xml
new file mode 100644
index 0000000..fe3613d
--- /dev/null
+++ b/bluetooth/ranging/aidl/default/bluetooth-ranging-service-default.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.bluetooth.ranging</name>
+ <version>1</version>
+ <fqname>IBluetoothChannelSounding/default</fqname>
+ </hal>
+</manifest>
diff --git a/bluetooth/ranging/aidl/default/service.cpp b/bluetooth/ranging/aidl/default/service.cpp
new file mode 100644
index 0000000..35a3f55
--- /dev/null
+++ b/bluetooth/ranging/aidl/default/service.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "aidl.android.hardware.bluetooth.ranging.service.default"
+
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <utils/Log.h>
+
+#include "BluetoothChannelSounding.h"
+#include "BluetoothChannelSoundingSession.h"
+
+using ::aidl::android::hardware::bluetooth::ranging::impl::
+ BluetoothChannelSounding;
+
+int main(int /* argc */, char** /* argv */) {
+ ALOGI("Bluetooth Ranging HAL registering");
+ if (!ABinderProcess_setThreadPoolMaxThreadCount(0)) {
+ ALOGE("Failed to set thread pool max thread count");
+ return 1;
+ }
+
+ std::shared_ptr<BluetoothChannelSounding> service =
+ ndk::SharedRefBase::make<BluetoothChannelSounding>();
+ std::string instance =
+ std::string() + BluetoothChannelSounding::descriptor + "/default";
+ if (AServiceManager_isDeclared(instance.c_str())) {
+ auto result =
+ AServiceManager_addService(service->asBinder().get(), instance.c_str());
+ if (result != STATUS_OK) {
+ ALOGE("Could not register as a service!");
+ }
+ } else {
+ ALOGE("Could not register as a service because it's not declared.");
+ }
+ // Keep running
+ ABinderProcess_joinThreadPool();
+ return 0;
+}
diff --git a/bluetooth/ranging/aidl/vts/Android.bp b/bluetooth/ranging/aidl/vts/Android.bp
new file mode 100644
index 0000000..ead9992
--- /dev/null
+++ b/bluetooth/ranging/aidl/vts/Android.bp
@@ -0,0 +1,27 @@
+package {
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+ name: "VtsHalBluetoothRangingTargetTest",
+ defaults: [
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: ["VtsHalBluetoothRangingTargetTest.cpp"],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "libcutils",
+ "liblog",
+ "libutils",
+ ],
+ static_libs: [
+ "android.hardware.bluetooth.ranging-V1-ndk",
+ "libbluetooth-types",
+ ],
+ test_config: "VtsHalBluetoothRangingTargetTest.xml",
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
diff --git a/bluetooth/ranging/aidl/vts/VtsHalBluetoothRangingTargetTest.cpp b/bluetooth/ranging/aidl/vts/VtsHalBluetoothRangingTargetTest.cpp
new file mode 100644
index 0000000..702df95
--- /dev/null
+++ b/bluetooth/ranging/aidl/vts/VtsHalBluetoothRangingTargetTest.cpp
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/bluetooth/ranging/BnBluetoothChannelSoundingSessionCallback.h>
+#include <aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSounding.h>
+#include <aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSessionCallback.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <binder/IServiceManager.h>
+#include <utils/Log.h>
+
+using aidl::android::hardware::bluetooth::ranging::
+ BluetoothChannelSoundingParameters;
+using aidl::android::hardware::bluetooth::ranging::
+ BnBluetoothChannelSoundingSessionCallback;
+using aidl::android::hardware::bluetooth::ranging::ChannelSoudingRawData;
+using aidl::android::hardware::bluetooth::ranging::CsSecurityLevel;
+using aidl::android::hardware::bluetooth::ranging::IBluetoothChannelSounding;
+using aidl::android::hardware::bluetooth::ranging::
+ IBluetoothChannelSoundingSession;
+using aidl::android::hardware::bluetooth::ranging::
+ IBluetoothChannelSoundingSessionCallback;
+using aidl::android::hardware::bluetooth::ranging::RangingResult;
+using aidl::android::hardware::bluetooth::ranging::Reason;
+using aidl::android::hardware::bluetooth::ranging::ResultType;
+using aidl::android::hardware::bluetooth::ranging::SessionType;
+using aidl::android::hardware::bluetooth::ranging::VendorSpecificData;
+using ndk::ScopedAStatus;
+
+class BluetoothChannelSoundingSessionCallback
+ : public BnBluetoothChannelSoundingSessionCallback {
+ public:
+ ScopedAStatus onOpened(Reason reason) override;
+ ScopedAStatus onOpenFailed(Reason reason) override;
+ ScopedAStatus onResult(const RangingResult& in_result) override;
+ ScopedAStatus onClose(Reason reason) override;
+ ScopedAStatus onCloseFailed(Reason reason) override;
+};
+
+ScopedAStatus BluetoothChannelSoundingSessionCallback::onOpened(
+ Reason /*reason*/) {
+ return ::ndk::ScopedAStatus::ok();
+}
+ScopedAStatus BluetoothChannelSoundingSessionCallback::onOpenFailed(
+ Reason /*reason*/) {
+ return ::ndk::ScopedAStatus::ok();
+}
+ScopedAStatus BluetoothChannelSoundingSessionCallback::onResult(
+ const RangingResult& /*in_result*/) {
+ return ::ndk::ScopedAStatus::ok();
+}
+ScopedAStatus BluetoothChannelSoundingSessionCallback::onClose(
+ Reason /*reason*/) {
+ return ::ndk::ScopedAStatus::ok();
+}
+ScopedAStatus BluetoothChannelSoundingSessionCallback::onCloseFailed(
+ Reason /*reason*/) {
+ return ::ndk::ScopedAStatus::ok();
+}
+
+class BluetoothRangingTest : public ::testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ ALOGI("SetUp Ranging Test");
+ bluetooth_channel_sounding_ = IBluetoothChannelSounding::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+ ASSERT_NE(bluetooth_channel_sounding_, nullptr);
+ }
+
+ virtual void TearDown() override {
+ ALOGI("TearDown Ranging Test");
+ bluetooth_channel_sounding_ = nullptr;
+ ASSERT_EQ(bluetooth_channel_sounding_, nullptr);
+ }
+
+ ScopedAStatus getVendorSpecificData(
+ std::optional<std::vector<std::optional<VendorSpecificData>>>*
+ _aidl_return);
+ ScopedAStatus getSupportedSessionTypes(
+ std::optional<std::vector<SessionType>>* _aidl_return);
+ ScopedAStatus getMaxSupportedCsSecurityLevel(CsSecurityLevel* _aidl_return);
+ ScopedAStatus openSession(
+ const BluetoothChannelSoundingParameters& in_params,
+ const std::shared_ptr<IBluetoothChannelSoundingSessionCallback>&
+ in_callback,
+ std::shared_ptr<IBluetoothChannelSoundingSession>* _aidl_return);
+
+ ScopedAStatus initBluetoothChannelSoundingSession(
+ std::shared_ptr<IBluetoothChannelSoundingSession>* session) {
+ BluetoothChannelSoundingParameters params;
+ std::shared_ptr<BluetoothChannelSoundingSessionCallback> callback = nullptr;
+ callback =
+ ndk::SharedRefBase::make<BluetoothChannelSoundingSessionCallback>();
+ ScopedAStatus status = openSession(params, callback, session);
+ return status;
+ }
+
+ private:
+ std::shared_ptr<IBluetoothChannelSounding> bluetooth_channel_sounding_;
+};
+
+ScopedAStatus BluetoothRangingTest::getVendorSpecificData(
+ std::optional<std::vector<std::optional<VendorSpecificData>>>*
+ _aidl_return) {
+ return bluetooth_channel_sounding_->getVendorSpecificData(_aidl_return);
+}
+ScopedAStatus BluetoothRangingTest::getSupportedSessionTypes(
+ std::optional<std::vector<SessionType>>* _aidl_return) {
+ return bluetooth_channel_sounding_->getSupportedSessionTypes(_aidl_return);
+}
+
+ScopedAStatus BluetoothRangingTest::getMaxSupportedCsSecurityLevel(
+ CsSecurityLevel* _aidl_return) {
+ return bluetooth_channel_sounding_->getMaxSupportedCsSecurityLevel(
+ _aidl_return);
+}
+ScopedAStatus BluetoothRangingTest::openSession(
+ const BluetoothChannelSoundingParameters& in_params,
+ const std::shared_ptr<IBluetoothChannelSoundingSessionCallback>&
+ in_callback,
+ std::shared_ptr<IBluetoothChannelSoundingSession>* _aidl_return) {
+ return bluetooth_channel_sounding_->openSession(in_params, in_callback,
+ _aidl_return);
+}
+
+TEST_P(BluetoothRangingTest, SetupAndTearDown) {}
+
+TEST_P(BluetoothRangingTest, GetVendorSpecificData) {
+ std::optional<std::vector<std::optional<VendorSpecificData>>>
+ vendor_specific_data;
+ ScopedAStatus status = getVendorSpecificData(&vendor_specific_data);
+ ASSERT_TRUE(status.isOk());
+}
+
+TEST_P(BluetoothRangingTest, GetSupportedSessionTypes) {
+ std::optional<std::vector<SessionType>> supported_session_types;
+ ScopedAStatus status = getSupportedSessionTypes(&supported_session_types);
+ ASSERT_TRUE(status.isOk());
+}
+
+TEST_P(BluetoothRangingTest, GetMaxSupportedCsSecurityLevel) {
+ CsSecurityLevel security_level;
+ ScopedAStatus status = getMaxSupportedCsSecurityLevel(&security_level);
+ ASSERT_TRUE(status.isOk());
+}
+
+TEST_P(BluetoothRangingTest, OpenSession) {
+ BluetoothChannelSoundingParameters params;
+ std::shared_ptr<BluetoothChannelSoundingSessionCallback> callback = nullptr;
+ callback =
+ ndk::SharedRefBase::make<BluetoothChannelSoundingSessionCallback>();
+ std::shared_ptr<IBluetoothChannelSoundingSession> session;
+ ScopedAStatus status = openSession(params, callback, &session);
+ ASSERT_TRUE(status.isOk());
+}
+
+TEST_P(BluetoothRangingTest, GetVendorSpecificReplies) {
+ std::shared_ptr<IBluetoothChannelSoundingSession> session;
+ auto status = initBluetoothChannelSoundingSession(&session);
+ ASSERT_TRUE(status.isOk());
+ if (session != nullptr) {
+ std::optional<std::vector<std::optional<VendorSpecificData>>>
+ vendor_specific_data;
+ status = session->getVendorSpecificReplies(&vendor_specific_data);
+ ASSERT_TRUE(status.isOk());
+ }
+}
+
+TEST_P(BluetoothRangingTest, GetSupportedResultTypes) {
+ std::shared_ptr<IBluetoothChannelSoundingSession> session;
+ auto status = initBluetoothChannelSoundingSession(&session);
+ ASSERT_TRUE(status.isOk());
+ if (session != nullptr) {
+ std::vector<ResultType> supported_result_types;
+ status = session->getSupportedResultTypes(&supported_result_types);
+ ASSERT_TRUE(status.isOk());
+ }
+}
+
+TEST_P(BluetoothRangingTest, IsAbortedProcedureRequired) {
+ std::shared_ptr<IBluetoothChannelSoundingSession> session;
+ auto status = initBluetoothChannelSoundingSession(&session);
+ ASSERT_TRUE(status.isOk());
+ if (session != nullptr) {
+ bool is_abort_procedure_required = true;
+ status = session->isAbortedProcedureRequired(&is_abort_procedure_required);
+ ASSERT_TRUE(status.isOk());
+ }
+}
+
+TEST_P(BluetoothRangingTest, WriteRawData) {
+ std::shared_ptr<IBluetoothChannelSoundingSession> session;
+ auto status = initBluetoothChannelSoundingSession(&session);
+ ASSERT_TRUE(status.isOk());
+ if (session != nullptr) {
+ ChannelSoudingRawData raw_data;
+ status = session->writeRawData(raw_data);
+ ASSERT_TRUE(status.isOk());
+ }
+}
+
+TEST_P(BluetoothRangingTest, CloseSession) {
+ std::shared_ptr<IBluetoothChannelSoundingSession> session;
+ auto status = initBluetoothChannelSoundingSession(&session);
+ ASSERT_TRUE(status.isOk());
+ if (session != nullptr) {
+ status = session->close(Reason::LOCAL_STACK_REQUEST);
+ ASSERT_TRUE(status.isOk());
+ }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothRangingTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothRangingTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothChannelSounding::descriptor)),
+ android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_startThreadPool();
+ int status = RUN_ALL_TESTS();
+ ALOGI("Test result = %d", status);
+ return status;
+}
\ No newline at end of file
diff --git a/bluetooth/ranging/aidl/vts/VtsHalBluetoothRangingTargetTest.xml b/bluetooth/ranging/aidl/vts/VtsHalBluetoothRangingTargetTest.xml
new file mode 100644
index 0000000..624b77e
--- /dev/null
+++ b/bluetooth/ranging/aidl/vts/VtsHalBluetoothRangingTargetTest.xml
@@ -0,0 +1,33 @@
+<!--
+ Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<configuration description="Runs VtsHalBluetoothRangingTargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalBluetoothRangingTargetTest->/data/local/tmp/VtsHalBluetoothRangingTargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalBluetoothRangingTargetTest" />
+ </test>
+</configuration>
diff --git a/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp b/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp
index cac3dd0..dec1f17 100644
--- a/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp
+++ b/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp
@@ -52,10 +52,9 @@
using ::android::hardware::broadcastradio::V1_0::Result;
using ::android::hardware::broadcastradio::V1_0::vts::RadioClassFromString;
-#define RETURN_IF_SKIPPED \
- if (skipped) { \
- std::cout << "[ SKIPPED ] This device class is not supported. " << std::endl; \
- return; \
+#define RETURN_IF_SKIPPED \
+ if (skipped) { \
+ GTEST_SKIP() << "This device class is not supported."; \
}
// The main test class for Broadcast Radio HIDL HAL.
@@ -734,4 +733,4 @@
testing::Combine(testing::ValuesIn(android::hardware::getAllHalInstanceNames(
IBroadcastRadioFactory::descriptor)),
::testing::Values("AM_FM", "SAT", "DT")),
- android::hardware::PrintInstanceTupleNameToString<>);
\ No newline at end of file
+ android::hardware::PrintInstanceTupleNameToString<>);
diff --git a/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp b/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp
index caf6cbd..b54e9d8 100644
--- a/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp
+++ b/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp
@@ -73,10 +73,6 @@
ProgramType::AM, ProgramType::FM, ProgramType::AM_HD, ProgramType::FM_HD,
ProgramType::DAB, ProgramType::DRMO, ProgramType::SXM};
-static void printSkipped(std::string msg) {
- std::cout << "[ SKIPPED ] " << msg << std::endl;
-}
-
struct TunerCallbackMock : public ITunerCallback {
TunerCallbackMock() { EXPECT_CALL(*this, hardwareFailure()).Times(0); }
@@ -106,7 +102,6 @@
bool getProgramList(std::function<void(const hidl_vec<ProgramInfo>& list)> cb);
Class radioClass;
- bool skipped = false;
sp<IBroadcastRadio> mRadioModule;
sp<ITuner> mTuner;
@@ -137,9 +132,7 @@
ASSERT_TRUE(onConnect.waitForCall(kConnectModuleTimeout));
if (connectResult == Result::INVALID_ARGUMENTS) {
- printSkipped("This device class is not supported.");
- skipped = true;
- return;
+ GTEST_SKIP() << "This device class is not supported.";
}
ASSERT_EQ(connectResult, Result::OK);
ASSERT_NE(nullptr, mRadioModule.get());
@@ -285,8 +278,6 @@
* might fail.
*/
TEST_P(BroadcastRadioHalTest, OpenTunerTwice) {
- if (skipped) return;
-
ASSERT_TRUE(openTuner());
auto secondTuner = mTuner;
@@ -306,7 +297,6 @@
* - getProgramInformation_1_1 returns the same selector as returned in tuneComplete_1_1 call.
*/
TEST_P(BroadcastRadioHalTest, TuneFromProgramList) {
- if (skipped) return;
ASSERT_TRUE(openTuner());
ProgramInfo firstProgram;
@@ -320,8 +310,7 @@
} while (nextBand());
if (HasFailure()) return;
if (!foundAny) {
- printSkipped("Program list is empty.");
- return;
+ GTEST_SKIP() << "Program list is empty.";
}
ProgramInfo infoCb;
@@ -356,7 +345,6 @@
* identifier for program types other than VENDORn.
*/
TEST_P(BroadcastRadioHalTest, TuneFailsForPrimaryVendor) {
- if (skipped) return;
ASSERT_TRUE(openTuner());
for (auto ptype : kStandardProgramTypes) {
@@ -377,7 +365,6 @@
* - tuneByProgramSelector fails with INVALID_ARGUMENT when unknown program type is passed.
*/
TEST_P(BroadcastRadioHalTest, TuneFailsForUnknownProgram) {
- if (skipped) return;
ASSERT_TRUE(openTuner());
// Program type is 1-based, so 0 will be always invalid.
@@ -393,7 +380,6 @@
* - cancelAnnouncement succeeds either when there is an announcement or there is none.
*/
TEST_P(BroadcastRadioHalTest, CancelAnnouncement) {
- if (skipped) return;
ASSERT_TRUE(openTuner());
auto hidlResult = mTuner->cancelAnnouncement();
@@ -407,8 +393,6 @@
* - getImage call handles argument 0 gracefully.
*/
TEST_P(BroadcastRadioHalTest, GetNoImage) {
- if (skipped) return;
-
size_t len = 0;
auto hidlResult =
mRadioModule->getImage(0, [&](hidl_vec<uint8_t> rawImage) { len = rawImage.size(); });
@@ -425,7 +409,6 @@
* - images are available for getImage call.
*/
TEST_P(BroadcastRadioHalTest, OobImagesOnly) {
- if (skipped) return;
ASSERT_TRUE(openTuner());
std::vector<int> imageIds;
@@ -446,8 +429,7 @@
} while (nextBand());
if (imageIds.size() == 0) {
- printSkipped("No images found");
- return;
+ GTEST_SKIP() << "No images found";
}
for (auto id : imageIds) {
@@ -469,7 +451,6 @@
* - setAnalogForced results either with INVALID_STATE, or isAnalogForced replying the same.
*/
TEST_P(BroadcastRadioHalTest, AnalogForcedSwitch) {
- if (skipped) return;
ASSERT_TRUE(openTuner());
bool forced;
@@ -584,7 +565,6 @@
* - values of ProgramIdentifier match their definitions at IdentifierType.
*/
TEST_P(BroadcastRadioHalTest, VerifyIdentifiersFormat) {
- if (skipped) return;
ASSERT_TRUE(openTuner());
do {
diff --git a/broadcastradio/TEST_MAPPING b/broadcastradio/TEST_MAPPING
new file mode 100644
index 0000000..2604fb3
--- /dev/null
+++ b/broadcastradio/TEST_MAPPING
@@ -0,0 +1,18 @@
+{
+ "presubmit": [
+ {
+ "name": "broadcastradio_utils_aidl_test"
+ },
+ {
+ "name": "DefaultBroadcastRadioHalTestCase"
+ },
+ {
+ "name": "android.hardware.broadcastradio@common-utils-tests"
+ }
+ ],
+ "auto-presubmit": [
+ {
+ "name": "VtsHalBroadcastradioAidlTargetTest"
+ }
+ ]
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/Metadata.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/Metadata.aidl
index 0ce967f..f1800dc 100644
--- a/broadcastradio/aidl/android/hardware/broadcastradio/Metadata.aidl
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/Metadata.aidl
@@ -86,7 +86,7 @@
/**
* DAB ensemble name abbreviated (string).
*
- * <p>Note: The string must be up to 8 characters long.
+ * <p>Note: The string should be <= 8 characters.
*
* <p>Note: If the short variant is present, the long ({@link Metadata#dabEnsembleName})
* one must be present as well.
@@ -101,7 +101,7 @@
/**
* DAB service name abbreviated (string)
*
- * <p>Note: The string must be up to 8 characters long.
+ * <p>Note: The string should be <= 8 characters.
*/
String dabServiceNameShort;
@@ -113,7 +113,7 @@
/**
* DAB component name abbreviated (string)
*
- * <p>Note: The string must be up to 8 characters long.
+ * <p>Note: The string should be <= 8 characters.
*/
String dabComponentNameShort;
@@ -161,7 +161,7 @@
/**
* HD short station name or HD universal short station name
*
- * <p>It can be up to 12 characters (see SY_IDD_1020s for more info).
+ * <p>It can be <= 12 characters (see SY_IDD_1020s for more info).
*/
String hdStationNameShort;
diff --git a/broadcastradio/aidl/default/Android.bp b/broadcastradio/aidl/default/Android.bp
index 743365a..d7bb751 100644
--- a/broadcastradio/aidl/default/Android.bp
+++ b/broadcastradio/aidl/default/Android.bp
@@ -26,11 +26,11 @@
cc_defaults {
name: "BroadcastRadioHalDefaults",
static_libs: [
+ "android.hardware.broadcastradio-V2-ndk",
"android.hardware.broadcastradio@common-utils-aidl-lib-V2",
"android.hardware.broadcastradio@common-utils-lib",
],
shared_libs: [
- "android.hardware.broadcastradio-V2-ndk",
"libbase",
"libbinder_ndk",
"liblog",
diff --git a/broadcastradio/aidl/default/BroadcastRadio.cpp b/broadcastradio/aidl/default/BroadcastRadio.cpp
index 63073d7..4d6d81d 100644
--- a/broadcastradio/aidl/default/BroadcastRadio.cpp
+++ b/broadcastradio/aidl/default/BroadcastRadio.cpp
@@ -48,6 +48,8 @@
inline constexpr std::chrono::seconds kListDelayTimeS = 1s;
// clang-format off
+const AmFmBandRange kFmFullBandRange = {65000, 108000, 10, 0};
+const AmFmBandRange kAmFullBandRange = {150, 30000, 1, 0};
const AmFmRegionConfig kDefaultAmFmConfig = {
{
{87500, 108000, 100, 100}, // FM
@@ -64,12 +66,7 @@
prop.maker = "Android";
prop.product = virtualRadio.getName();
- prop.supportedIdentifierTypes = vector<IdentifierType>({
- IdentifierType::AMFM_FREQUENCY_KHZ,
- IdentifierType::RDS_PI,
- IdentifierType::HD_STATION_ID_EXT,
- IdentifierType::DAB_SID_EXT,
- });
+ prop.supportedIdentifierTypes = virtualRadio.getSupportedIdentifierTypes();
prop.vendorInfo = vector<VendorKeyValue>({
{"com.android.sample", "sample"},
});
@@ -77,14 +74,71 @@
return prop;
}
+bool isDigitalProgramAllowed(const ProgramSelector& sel, bool forceAnalogFm, bool forceAnalogAm) {
+ if (sel.primaryId.type != IdentifierType::HD_STATION_ID_EXT) {
+ return true;
+ }
+ int32_t freq = static_cast<int32_t>(utils::getAmFmFrequency(sel));
+ bool isFm = freq >= kFmFullBandRange.lowerBound && freq <= kFmFullBandRange.upperBound;
+ return isFm ? !forceAnalogFm : !forceAnalogAm;
+}
+
+/**
+ * Checks whether a program selector is in the current band.
+ *
+ * <p>For an AM/FM program, this method checks whether it is in the current AM/FM band. For a
+ * program selector is also an HD program, it is also checked whether HD radio is enabled in the
+ * current AM/FM band. For a non-AM/FM program, the method will returns {@code true} directly.
+ * @param sel Program selector to be checked
+ * @param currentAmFmBandRange the current AM/FM band
+ * @param forceAnalogFm whether FM band is forced to be analog
+ * @param forceAnalogAm whether AM band is forced to be analog
+ * @return whether the program selector is in the current band if it is an AM/FM (including HD)
+ * selector, {@code true} otherwise
+ */
+bool isProgramInBand(const ProgramSelector& sel,
+ const std::optional<AmFmBandRange>& currentAmFmBandRange, bool forceAnalogFm,
+ bool forceAnalogAm) {
+ if (!utils::hasAmFmFrequency(sel)) {
+ return true;
+ }
+ if (!currentAmFmBandRange.has_value()) {
+ return false;
+ }
+ int32_t freq = static_cast<int32_t>(utils::getAmFmFrequency(sel));
+ if (freq < currentAmFmBandRange->lowerBound || freq > currentAmFmBandRange->upperBound) {
+ return false;
+ }
+ return isDigitalProgramAllowed(sel, forceAnalogFm, forceAnalogAm);
+}
+
// Makes ProgramInfo that does not point to any particular program
ProgramInfo makeSampleProgramInfo(const ProgramSelector& selector) {
ProgramInfo info = {};
info.selector = selector;
- info.logicallyTunedTo =
- utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ,
- utils::getId(selector, IdentifierType::AMFM_FREQUENCY_KHZ));
- info.physicallyTunedTo = info.logicallyTunedTo;
+ switch (info.selector.primaryId.type) {
+ case IdentifierType::AMFM_FREQUENCY_KHZ:
+ info.logicallyTunedTo = utils::makeIdentifier(
+ IdentifierType::AMFM_FREQUENCY_KHZ,
+ utils::getId(selector, IdentifierType::AMFM_FREQUENCY_KHZ));
+ info.physicallyTunedTo = info.logicallyTunedTo;
+ break;
+ case IdentifierType::HD_STATION_ID_EXT:
+ info.logicallyTunedTo = utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ,
+ utils::getAmFmFrequency(info.selector));
+ info.physicallyTunedTo = info.logicallyTunedTo;
+ break;
+ case IdentifierType::DAB_SID_EXT:
+ info.logicallyTunedTo = info.selector.primaryId;
+ info.physicallyTunedTo = utils::makeIdentifier(
+ IdentifierType::DAB_FREQUENCY_KHZ,
+ utils::getId(selector, IdentifierType::DAB_FREQUENCY_KHZ));
+ break;
+ default:
+ info.logicallyTunedTo = info.selector.primaryId;
+ info.physicallyTunedTo = info.logicallyTunedTo;
+ break;
+ }
return info;
}
@@ -112,6 +166,7 @@
} else {
mCurrentProgram = sel;
}
+ adjustAmFmRangeLocked();
}
}
@@ -124,8 +179,8 @@
if (full) {
*returnConfigs = {};
returnConfigs->ranges = vector<AmFmBandRange>({
- {65000, 108000, 10, 0}, // FM
- {150, 30000, 1, 0}, // AM
+ kFmFullBandRange,
+ kAmFullBandRange,
});
returnConfigs->fmDeemphasis =
AmFmRegionConfig::DEEMPHASIS_D50 | AmFmRegionConfig::DEEMPHASIS_D75;
@@ -171,14 +226,27 @@
VirtualProgram virtualProgram = {};
ProgramInfo programInfo;
- if (mVirtualRadio.getProgram(sel, &virtualProgram)) {
+ bool isProgramAllowed =
+ isDigitalProgramAllowed(sel, isConfigFlagSetLocked(ConfigFlag::FORCE_ANALOG_FM),
+ isConfigFlagSetLocked(ConfigFlag::FORCE_ANALOG_AM));
+ if (isProgramAllowed && mVirtualRadio.getProgram(sel, &virtualProgram)) {
mCurrentProgram = virtualProgram.selector;
programInfo = virtualProgram;
} else {
- mCurrentProgram = sel;
+ if (!isProgramAllowed) {
+ mCurrentProgram = utils::makeSelectorAmfm(utils::getAmFmFrequency(sel));
+ } else {
+ mCurrentProgram = sel;
+ }
programInfo = makeSampleProgramInfo(sel);
}
- mIsTuneCompleted = true;
+ programInfo.infoFlags |= ProgramInfo::FLAG_SIGNAL_ACQUISITION;
+ if (programInfo.selector.primaryId.type != IdentifierType::HD_STATION_ID_EXT) {
+ mIsTuneCompleted = true;
+ }
+ if (adjustAmFmRangeLocked()) {
+ startProgramListUpdatesLocked({});
+ }
return programInfo;
}
@@ -206,6 +274,32 @@
return ScopedAStatus::ok();
}
+void BroadcastRadio::handleProgramInfoUpdateRadioCallback(
+ ProgramInfo programInfo, const std::shared_ptr<ITunerCallback>& callback) {
+ callback->onCurrentProgramInfoChanged(programInfo);
+ if (programInfo.selector.primaryId.type != IdentifierType::HD_STATION_ID_EXT) {
+ return;
+ }
+ ProgramSelector sel = programInfo.selector;
+ auto cancelTask = [sel, callback]() { callback->onTuneFailed(Result::CANCELED, sel); };
+ programInfo.infoFlags |= ProgramInfo::FLAG_HD_SIS_ACQUISITION;
+ auto sisAcquiredTask = [this, callback, programInfo, cancelTask]() {
+ callback->onCurrentProgramInfoChanged(programInfo);
+ auto audioAcquiredTask = [this, callback, programInfo]() {
+ ProgramInfo hdProgramInfoWithAudio = programInfo;
+ hdProgramInfoWithAudio.infoFlags |= ProgramInfo::FLAG_HD_AUDIO_ACQUISITION;
+ callback->onCurrentProgramInfoChanged(hdProgramInfoWithAudio);
+ lock_guard<mutex> lk(mMutex);
+ mIsTuneCompleted = true;
+ };
+ lock_guard<mutex> lk(mMutex);
+ mTuningThread->schedule(audioAcquiredTask, cancelTask, kTuneDelayTimeMs);
+ };
+
+ lock_guard<mutex> lk(mMutex);
+ mTuningThread->schedule(sisAcquiredTask, cancelTask, kTuneDelayTimeMs);
+}
+
ScopedAStatus BroadcastRadio::tune(const ProgramSelector& program) {
LOG(DEBUG) << __func__ << ": tune to " << program.toString() << "...";
@@ -238,7 +332,7 @@
lock_guard<mutex> lk(mMutex);
programInfo = tuneInternalLocked(program);
}
- callback->onCurrentProgramInfoChanged(programInfo);
+ handleProgramInfoUpdateRadioCallback(programInfo, callback);
};
auto cancelTask = [program, callback]() { callback->onTuneFailed(Result::CANCELED, program); };
mTuningThread->schedule(task, cancelTask, kTuneDelayTimeMs);
@@ -246,6 +340,122 @@
return ScopedAStatus::ok();
}
+bool BroadcastRadio::findNextLocked(const ProgramSelector& current, bool directionUp,
+ bool skipSubChannel, VirtualProgram* nextProgram) const {
+ if (mProgramList.empty()) {
+ return false;
+ }
+ // The list is not sorted here since it has already stored in VirtualRadio.
+ bool hasAmFmFrequency = utils::hasAmFmFrequency(current);
+ bool hasDabSId = utils::hasId(current, IdentifierType::DAB_SID_EXT);
+ uint32_t currentChannel =
+ hasAmFmFrequency ? utils::getAmFmFrequency(current) : utils::getDabSId(current);
+ auto found =
+ std::lower_bound(mProgramList.begin(), mProgramList.end(), VirtualProgram({current}));
+ if (directionUp) {
+ if (found < mProgramList.end() - 1) {
+ // When seeking up, tuner will jump to the first selector which is main program service
+ // greater than and of the same band as the current program selector in the program
+ // list (if not exist, jump to the first selector in the same band) for skipping
+ // sub-channels case or AM/FM without HD radio enabled case. Otherwise, the tuner will
+ // jump to the first selector which is greater than and of the same band as the current
+ // program selector.
+ if (utils::tunesTo(current, found->selector)) found++;
+ if (skipSubChannel) {
+ if (hasAmFmFrequency || hasDabSId) {
+ auto firstFound = found;
+ while ((hasAmFmFrequency &&
+ utils::getAmFmFrequency(found->selector) == currentChannel) ||
+ (hasDabSId && utils::getDabSId(found->selector) == currentChannel)) {
+ if (found < mProgramList.end() - 1) {
+ found++;
+ } else {
+ found = mProgramList.begin();
+ }
+ if (found == firstFound) {
+ // Only one main channel exists in the program list, the tuner cannot
+ // skip sub-channel to the next program selector.
+ return false;
+ }
+ }
+ }
+ }
+ } else {
+ // If the selector of current program is no less than all selectors of the same band or
+ // not found in the program list, seeking up should wrap the tuner to the first program
+ // selector of the same band in the program list.
+ found = mProgramList.begin();
+ }
+ } else {
+ if (found > mProgramList.begin() && found != mProgramList.end()) {
+ // When seeking down, tuner will jump to the first selector which is main program
+ // service less than and of the same band as the current program selector in the
+ // program list (if not exist, jump to the last main program service selector of the
+ // same band) for skipping sub-channels case or AM/FM without HD radio enabled case.
+ // Otherwise, the tuner will jump to the first selector less than and of the same band
+ // as the current program selector.
+ found--;
+ if ((hasAmFmFrequency && utils::hasAmFmFrequency(found->selector)) ||
+ (hasDabSId && utils::hasId(found->selector, IdentifierType::DAB_SID_EXT))) {
+ uint32_t nextChannel = hasAmFmFrequency ? utils::getAmFmFrequency(found->selector)
+ : utils::getDabSId(found->selector);
+ if (nextChannel != currentChannel) {
+ jumpToFirstSubChannelLocked(found);
+ } else if (skipSubChannel) {
+ jumpToFirstSubChannelLocked(found);
+ auto firstFound = found;
+ if (found > mProgramList.begin()) {
+ found--;
+ } else {
+ found = mProgramList.end() - 1;
+ }
+ jumpToFirstSubChannelLocked(found);
+ if (found == firstFound) {
+ // Only one main channel exists in the program list, the tuner cannot skip
+ // sub-channel to the next program selector.
+ return false;
+ }
+ }
+ }
+ } else {
+ // If the selector of current program is no greater than all selectors of the same band
+ // or not found in the program list, seeking down should wrap the tuner to the last
+ // selector of the same band in the program list. If the last program selector in the
+ // program list is sub-channel and skipping sub-channels is needed, the tuner will jump
+ // to the last main program service of the same band in the program list.
+ found = mProgramList.end() - 1;
+ jumpToFirstSubChannelLocked(found);
+ }
+ }
+ *nextProgram = *found;
+ return true;
+}
+
+void BroadcastRadio::jumpToFirstSubChannelLocked(vector<VirtualProgram>::const_iterator& it) const {
+ if (it == mProgramList.begin()) {
+ return;
+ }
+ bool hasAmFmFrequency = utils::hasAmFmFrequency(it->selector);
+ bool hasDabSId = utils::hasId(it->selector, IdentifierType::DAB_SID_EXT);
+ if (hasAmFmFrequency || hasDabSId) {
+ uint32_t currentChannel = hasAmFmFrequency ? utils::getAmFmFrequency(it->selector)
+ : utils::getDabSId(it->selector);
+ it--;
+ while (it != mProgramList.begin()) {
+ if (hasAmFmFrequency && utils::hasAmFmFrequency(it->selector) &&
+ utils::getAmFmFrequency(it->selector) == currentChannel) {
+ it--;
+ } else if (hasDabSId && utils::hasId(it->selector, IdentifierType::DAB_SID_EXT) &&
+ utils::getDabSId(it->selector) == currentChannel) {
+ it--;
+ } else {
+ break;
+ }
+ }
+ it++;
+ }
+}
+
ScopedAStatus BroadcastRadio::seek(bool directionUp, bool skipSubChannel) {
LOG(DEBUG) << __func__ << ": seek " << (directionUp ? "up" : "down") << " with skipSubChannel? "
<< (skipSubChannel ? "yes" : "no") << "...";
@@ -259,11 +469,21 @@
cancelLocked();
+ auto filterCb = [this](const VirtualProgram& program) {
+ return isProgramInBand(program.selector, mCurrentAmFmBandRange,
+ isConfigFlagSetLocked(ConfigFlag::FORCE_ANALOG_FM),
+ isConfigFlagSetLocked(ConfigFlag::FORCE_ANALOG_AM));
+ };
const auto& list = mVirtualRadio.getProgramList();
+ mProgramList.clear();
+ std::copy_if(list.begin(), list.end(), std::back_inserter(mProgramList), filterCb);
std::shared_ptr<ITunerCallback> callback = mCallback;
auto cancelTask = [callback]() { callback->onTuneFailed(Result::CANCELED, {}); };
- if (list.empty()) {
- mIsTuneCompleted = false;
+
+ VirtualProgram nextProgram = {};
+ bool foundNext = findNextLocked(mCurrentProgram, directionUp, skipSubChannel, &nextProgram);
+ mIsTuneCompleted = false;
+ if (!foundNext) {
auto task = [callback]() {
LOG(DEBUG) << "seek: program list is empty, seek couldn't stop";
@@ -274,33 +494,13 @@
return ScopedAStatus::ok();
}
- // The list is not sorted here since it has already stored in VirtualRadio.
- // If the list is not sorted in advance, it should be sorted here.
- const auto& current = mCurrentProgram;
- auto found = std::lower_bound(list.begin(), list.end(), VirtualProgram({current}));
- if (directionUp) {
- if (found < list.end() - 1) {
- if (tunesTo(current, found->selector)) found++;
- } else {
- found = list.begin();
- }
- } else {
- if (found > list.begin() && found != list.end()) {
- found--;
- } else {
- found = list.end() - 1;
- }
- }
- const ProgramSelector tuneTo = found->selector;
-
- mIsTuneCompleted = false;
- auto task = [this, tuneTo, callback]() {
+ auto task = [this, nextProgram, callback]() {
ProgramInfo programInfo = {};
{
lock_guard<mutex> lk(mMutex);
- programInfo = tuneInternalLocked(tuneTo);
+ programInfo = tuneInternalLocked(nextProgram.selector);
}
- callback->onCurrentProgramInfoChanged(programInfo);
+ handleProgramInfoUpdateRadioCallback(programInfo, callback);
};
mTuningThread->schedule(task, cancelTask, kSeekDelayTimeMs);
@@ -319,31 +519,33 @@
cancelLocked();
- if (!utils::hasId(mCurrentProgram, IdentifierType::AMFM_FREQUENCY_KHZ)) {
+ int64_t stepTo;
+ if (utils::hasId(mCurrentProgram, IdentifierType::AMFM_FREQUENCY_KHZ)) {
+ stepTo = utils::getId(mCurrentProgram, IdentifierType::AMFM_FREQUENCY_KHZ);
+ } else if (mCurrentProgram.primaryId.type == IdentifierType::HD_STATION_ID_EXT) {
+ stepTo = utils::getHdFrequency(mCurrentProgram);
+ } else {
LOG(WARNING) << __func__ << ": can't step in anything else than AM/FM";
return ScopedAStatus::fromServiceSpecificErrorWithMessage(
resultToInt(Result::NOT_SUPPORTED), "cannot step in anything else than AM/FM");
}
- int64_t stepTo = utils::getId(mCurrentProgram, IdentifierType::AMFM_FREQUENCY_KHZ);
- std::optional<AmFmBandRange> range = getAmFmRangeLocked();
- if (!range) {
- LOG(ERROR) << __func__ << ": can't find current band or tune operation is in process";
+ if (!mCurrentAmFmBandRange.has_value()) {
+ LOG(ERROR) << __func__ << ": can't find current band";
return ScopedAStatus::fromServiceSpecificErrorWithMessage(
- resultToInt(Result::INTERNAL_ERROR),
- "can't find current band or tune operation is in process");
+ resultToInt(Result::INTERNAL_ERROR), "can't find current band");
}
if (directionUp) {
- stepTo += range->spacing;
+ stepTo += mCurrentAmFmBandRange->spacing;
} else {
- stepTo -= range->spacing;
+ stepTo -= mCurrentAmFmBandRange->spacing;
}
- if (stepTo > range->upperBound) {
- stepTo = range->lowerBound;
+ if (stepTo > mCurrentAmFmBandRange->upperBound) {
+ stepTo = mCurrentAmFmBandRange->lowerBound;
}
- if (stepTo < range->lowerBound) {
- stepTo = range->upperBound;
+ if (stepTo < mCurrentAmFmBandRange->lowerBound) {
+ stepTo = mCurrentAmFmBandRange->upperBound;
}
mIsTuneCompleted = false;
@@ -354,7 +556,7 @@
lock_guard<mutex> lk(mMutex);
programInfo = tuneInternalLocked(utils::makeSelectorAmfm(stepTo));
}
- callback->onCurrentProgramInfoChanged(programInfo);
+ handleProgramInfoUpdateRadioCallback(programInfo, callback);
};
auto cancelTask = [callback]() { callback->onTuneFailed(Result::CANCELED, {}); };
mTuningThread->schedule(task, cancelTask, kStepDelayTimeMs);
@@ -380,16 +582,14 @@
return ScopedAStatus::ok();
}
-ScopedAStatus BroadcastRadio::startProgramListUpdates(const ProgramFilter& filter) {
- LOG(DEBUG) << __func__ << ": requested program list updates, filter = " << filter.toString()
- << "...";
-
- auto filterCb = [&filter](const VirtualProgram& program) {
- return utils::satisfies(filter, program.selector);
+void BroadcastRadio::startProgramListUpdatesLocked(const ProgramFilter& filter) {
+ auto filterCb = [&filter, this](const VirtualProgram& program) {
+ return utils::satisfies(filter, program.selector) &&
+ isProgramInBand(program.selector, mCurrentAmFmBandRange,
+ isConfigFlagSetLocked(ConfigFlag::FORCE_ANALOG_FM),
+ isConfigFlagSetLocked(ConfigFlag::FORCE_ANALOG_AM));
};
- lock_guard<mutex> lk(mMutex);
-
cancelProgramListUpdateLocked();
const auto& list = mVirtualRadio.getProgramList();
@@ -415,6 +615,15 @@
callback->onProgramListUpdated(chunk);
};
mProgramListThread->schedule(task, kListDelayTimeS);
+}
+
+ScopedAStatus BroadcastRadio::startProgramListUpdates(const ProgramFilter& filter) {
+ LOG(DEBUG) << __func__ << ": requested program list updates, filter = " << filter.toString()
+ << "...";
+
+ lock_guard<mutex> lk(mMutex);
+
+ startProgramListUpdatesLocked(filter);
return ScopedAStatus::ok();
}
@@ -431,18 +640,28 @@
return ScopedAStatus::ok();
}
+bool BroadcastRadio::isConfigFlagSetLocked(ConfigFlag flag) const {
+ int flagBit = static_cast<int>(flag);
+ return ((mConfigFlagValues >> flagBit) & 1) == 1;
+}
+
ScopedAStatus BroadcastRadio::isConfigFlagSet(ConfigFlag flag, bool* returnIsSet) {
LOG(DEBUG) << __func__ << ": flag = " << toString(flag);
- int flagBit = static_cast<int>(flag);
+ if (flag == ConfigFlag::FORCE_ANALOG) {
+ flag = ConfigFlag::FORCE_ANALOG_FM;
+ }
lock_guard<mutex> lk(mMutex);
- *returnIsSet = ((mConfigFlagValues >> flagBit) & 1) == 1;
+ *returnIsSet = isConfigFlagSetLocked(flag);
return ScopedAStatus::ok();
}
ScopedAStatus BroadcastRadio::setConfigFlag(ConfigFlag flag, bool value) {
LOG(DEBUG) << __func__ << ": flag = " << toString(flag) << ", value = " << value;
+ if (flag == ConfigFlag::FORCE_ANALOG) {
+ flag = ConfigFlag::FORCE_ANALOG_FM;
+ }
int flagBitMask = 1 << (static_cast<int>(flag));
lock_guard<mutex> lk(mMutex);
if (value) {
@@ -450,6 +669,9 @@
} else {
mConfigFlagValues &= ~flagBitMask;
}
+ if (flag == ConfigFlag::FORCE_ANALOG_AM || flag == ConfigFlag::FORCE_ANALOG_FM) {
+ startProgramListUpdatesLocked({});
+ }
return ScopedAStatus::ok();
}
@@ -468,24 +690,25 @@
return ScopedAStatus::ok();
}
-std::optional<AmFmBandRange> BroadcastRadio::getAmFmRangeLocked() const {
- if (!mIsTuneCompleted) {
- LOG(WARNING) << __func__ << ": tune operation is in process";
- return {};
- }
- if (!utils::hasId(mCurrentProgram, IdentifierType::AMFM_FREQUENCY_KHZ)) {
+bool BroadcastRadio::adjustAmFmRangeLocked() {
+ bool hasBandBefore = mCurrentAmFmBandRange.has_value();
+ if (!utils::hasAmFmFrequency(mCurrentProgram)) {
LOG(WARNING) << __func__ << ": current program does not has AMFM_FREQUENCY_KHZ identifier";
- return {};
+ mCurrentAmFmBandRange.reset();
+ return hasBandBefore;
}
- int64_t freq = utils::getId(mCurrentProgram, IdentifierType::AMFM_FREQUENCY_KHZ);
+ int32_t freq = static_cast<int32_t>(utils::getAmFmFrequency(mCurrentProgram));
for (const auto& range : mAmFmConfig.ranges) {
if (range.lowerBound <= freq && range.upperBound >= freq) {
- return range;
+ bool isBandChanged = hasBandBefore ? *mCurrentAmFmBandRange != range : true;
+ mCurrentAmFmBandRange = range;
+ return isBandChanged;
}
}
- return {};
+ mCurrentAmFmBandRange.reset();
+ return !hasBandBefore;
}
ScopedAStatus BroadcastRadio::registerAnnouncementListener(
diff --git a/broadcastradio/aidl/default/BroadcastRadio.h b/broadcastradio/aidl/default/BroadcastRadio.h
index 0f818ce..60ea907 100644
--- a/broadcastradio/aidl/default/BroadcastRadio.h
+++ b/broadcastradio/aidl/default/BroadcastRadio.h
@@ -39,21 +39,25 @@
public:
explicit BroadcastRadio(const VirtualRadio& virtualRadio);
~BroadcastRadio();
- ndk::ScopedAStatus getAmFmRegionConfig(bool full, AmFmRegionConfig* returnConfigs) override;
+ ndk::ScopedAStatus getAmFmRegionConfig(bool full, AmFmRegionConfig* returnConfigs)
+ EXCLUDES(mMutex) override;
ndk::ScopedAStatus getDabRegionConfig(std::vector<DabTableEntry>* returnConfigs) override;
ndk::ScopedAStatus getImage(int32_t id, std::vector<uint8_t>* returnImage) override;
- ndk::ScopedAStatus getProperties(Properties* returnProperties) override;
+ ndk::ScopedAStatus getProperties(Properties* returnProperties) EXCLUDES(mMutex) override;
- ndk::ScopedAStatus setTunerCallback(const std::shared_ptr<ITunerCallback>& callback) override;
- ndk::ScopedAStatus unsetTunerCallback() override;
- ndk::ScopedAStatus tune(const ProgramSelector& program) override;
- ndk::ScopedAStatus seek(bool directionUp, bool skipSubChannel) override;
- ndk::ScopedAStatus step(bool directionUp) override;
- ndk::ScopedAStatus cancel() override;
- ndk::ScopedAStatus startProgramListUpdates(const ProgramFilter& filter) override;
- ndk::ScopedAStatus stopProgramListUpdates() override;
- ndk::ScopedAStatus isConfigFlagSet(ConfigFlag flag, bool* returnIsSet) override;
- ndk::ScopedAStatus setConfigFlag(ConfigFlag flag, bool in_value) override;
+ ndk::ScopedAStatus setTunerCallback(const std::shared_ptr<ITunerCallback>& callback)
+ EXCLUDES(mMutex) override;
+ ndk::ScopedAStatus unsetTunerCallback() EXCLUDES(mMutex) override;
+ ndk::ScopedAStatus tune(const ProgramSelector& program) EXCLUDES(mMutex) override;
+ ndk::ScopedAStatus seek(bool directionUp, bool skipSubChannel) EXCLUDES(mMutex) override;
+ ndk::ScopedAStatus step(bool directionUp) EXCLUDES(mMutex) override;
+ ndk::ScopedAStatus cancel() EXCLUDES(mMutex) override;
+ ndk::ScopedAStatus startProgramListUpdates(const ProgramFilter& filter)
+ EXCLUDES(mMutex) override;
+ ndk::ScopedAStatus stopProgramListUpdates() EXCLUDES(mMutex) override;
+ ndk::ScopedAStatus isConfigFlagSet(ConfigFlag flag, bool* returnIsSet)
+ EXCLUDES(mMutex) override;
+ ndk::ScopedAStatus setConfigFlag(ConfigFlag flag, bool in_value) EXCLUDES(mMutex) override;
ndk::ScopedAStatus setParameters(const std::vector<VendorKeyValue>& parameters,
std::vector<VendorKeyValue>* returnParameters) override;
ndk::ScopedAStatus getParameters(const std::vector<std::string>& keys,
@@ -62,7 +66,7 @@
const std::shared_ptr<IAnnouncementListener>& listener,
const std::vector<AnnouncementType>& enabled,
std::shared_ptr<ICloseHandle>* returnCloseHandle) override;
- binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+ binder_status_t dump(int fd, const char** args, uint32_t numArgs) EXCLUDES(mMutex) override;
private:
const VirtualRadio& mVirtualRadio;
@@ -75,15 +79,26 @@
bool mIsTuneCompleted GUARDED_BY(mMutex) = true;
Properties mProperties GUARDED_BY(mMutex);
ProgramSelector mCurrentProgram GUARDED_BY(mMutex) = {};
+ std::vector<VirtualProgram> mProgramList GUARDED_BY(mMutex) = {};
+ std::optional<AmFmBandRange> mCurrentAmFmBandRange GUARDED_BY(mMutex);
std::shared_ptr<ITunerCallback> mCallback GUARDED_BY(mMutex);
// Bitmap for all ConfigFlag values
int mConfigFlagValues GUARDED_BY(mMutex) = 0;
- std::optional<AmFmBandRange> getAmFmRangeLocked() const;
- void cancelLocked();
- ProgramInfo tuneInternalLocked(const ProgramSelector& sel);
- void cancelProgramListUpdateLocked();
+ bool adjustAmFmRangeLocked() REQUIRES(mMutex);
+ void cancelLocked() REQUIRES(mMutex);
+ ProgramInfo tuneInternalLocked(const ProgramSelector& sel) REQUIRES(mMutex);
+ void startProgramListUpdatesLocked(const ProgramFilter& filter) REQUIRES(mMutex);
+ void cancelProgramListUpdateLocked() REQUIRES(mMutex);
+ void handleProgramInfoUpdateRadioCallback(ProgramInfo programInfo,
+ const std::shared_ptr<ITunerCallback>& callback)
+ EXCLUDES(mMutex);
+ bool findNextLocked(const ProgramSelector& current, bool directionUp, bool skipSubChannel,
+ VirtualProgram* nextProgram) const REQUIRES(mMutex);
+ void jumpToFirstSubChannelLocked(std::vector<VirtualProgram>::const_iterator& it) const
+ REQUIRES(mMutex);
+ bool isConfigFlagSetLocked(ConfigFlag flag) const REQUIRES(mMutex);
binder_status_t cmdHelp(int fd) const;
binder_status_t cmdTune(int fd, const char** args, uint32_t numArgs);
@@ -93,7 +108,7 @@
binder_status_t cmdStartProgramListUpdates(int fd, const char** args, uint32_t numArgs);
binder_status_t cmdStopProgramListUpdates(int fd, uint32_t numArgs);
- binder_status_t dumpsys(int fd);
+ binder_status_t dumpsys(int fd) EXCLUDES(mMutex);
};
} // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/aidl/default/VirtualProgram.cpp b/broadcastradio/aidl/default/VirtualProgram.cpp
index 4fe6567..fab4a49 100644
--- a/broadcastradio/aidl/default/VirtualProgram.cpp
+++ b/broadcastradio/aidl/default/VirtualProgram.cpp
@@ -49,7 +49,12 @@
break;
case IdentifierType::HD_STATION_ID_EXT:
info.logicallyTunedTo = selectId(IdentifierType::HD_STATION_ID_EXT);
- info.physicallyTunedTo = selectId(IdentifierType::AMFM_FREQUENCY_KHZ);
+ if (utils::hasId(info.selector, IdentifierType::AMFM_FREQUENCY_KHZ)) {
+ info.physicallyTunedTo = selectId(IdentifierType::AMFM_FREQUENCY_KHZ);
+ } else {
+ info.physicallyTunedTo = utils::makeIdentifier(
+ IdentifierType::AMFM_FREQUENCY_KHZ, utils::getHdFrequency(info.selector));
+ }
break;
case IdentifierType::DAB_SID_EXT:
info.logicallyTunedTo = selectId(IdentifierType::DAB_SID_EXT);
@@ -88,13 +93,7 @@
}
bool operator<(const VirtualProgram& lhs, const VirtualProgram& rhs) {
- auto& l = lhs.selector;
- auto& r = rhs.selector;
-
- // Two programs with the same primaryId are considered the same.
- if (l.primaryId.type != r.primaryId.type) return l.primaryId.type < r.primaryId.type;
-
- return l.primaryId.value < r.primaryId.value;
+ return utils::ProgramSelectorComparator()(lhs.selector, rhs.selector);
}
} // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/aidl/default/VirtualRadio.cpp b/broadcastradio/aidl/default/VirtualRadio.cpp
index 86c5a96..d6e58cd 100644
--- a/broadcastradio/aidl/default/VirtualRadio.cpp
+++ b/broadcastradio/aidl/default/VirtualRadio.cpp
@@ -16,12 +16,15 @@
#include "VirtualRadio.h"
#include <broadcastradio-utils-aidl/Utils.h>
+#include <unordered_set>
namespace aidl::android::hardware::broadcastradio {
using ::aidl::android::hardware::broadcastradio::utils::makeSelectorAmfm;
using ::aidl::android::hardware::broadcastradio::utils::makeSelectorDab;
+using ::aidl::android::hardware::broadcastradio::utils::makeSelectorHd;
using ::std::string;
+using ::std::unordered_set;
using ::std::vector;
VirtualRadio::VirtualRadio(const string& name, const vector<VirtualProgram>& initialList)
@@ -38,15 +41,43 @@
}
bool VirtualRadio::getProgram(const ProgramSelector& selector, VirtualProgram* programOut) const {
- for (const auto& program : mPrograms) {
- if (utils::tunesTo(selector, program.selector)) {
- *programOut = program;
- return true;
+ for (auto it = mPrograms.begin(); it != mPrograms.end(); it++) {
+ if (!utils::tunesTo(selector, it->selector)) {
+ continue;
}
+ auto firstMatchIt = it;
+ if (utils::hasAmFmFrequency(it->selector)) {
+ uint32_t channelFreq = utils::getAmFmFrequency(it->selector);
+ it++;
+ while (it != mPrograms.end() && utils::hasAmFmFrequency(it->selector) &&
+ utils::getAmFmFrequency(it->selector) == channelFreq) {
+ if (it->selector == selector) {
+ *programOut = *it;
+ return true;
+ }
+ it++;
+ }
+ }
+ *programOut = *firstMatchIt;
+ return true;
}
return false;
}
+vector<IdentifierType> VirtualRadio::getSupportedIdentifierTypes() const {
+ unordered_set<IdentifierType> supportedIdentifierTypeSet;
+ for (const auto& program : mPrograms) {
+ IdentifierType type = program.selector.primaryId.type;
+ if (supportedIdentifierTypeSet.count(type)) {
+ continue;
+ }
+ supportedIdentifierTypeSet.insert(type);
+ }
+ vector<IdentifierType> supportedIdentifierTypes(supportedIdentifierTypeSet.begin(),
+ supportedIdentifierTypeSet.end());
+ return supportedIdentifierTypes;
+}
+
// get singleton of AMFM Virtual Radio
const VirtualRadio& VirtualRadio::getAmFmRadio() {
// clang-format off
@@ -56,15 +87,27 @@
{makeSelectorAmfm(/* frequency= */ 94900u), "Wild 94.9", "Drake ft. Rihanna",
"Too Good"},
{makeSelectorAmfm(/* frequency= */ 96500u), "KOIT", "Celine Dion", "All By Myself"},
- {makeSelectorAmfm(/* frequency= */ 97300u), "Alice@97.3", "Drops of Jupiter", "Train"},
- {makeSelectorAmfm(/* frequency= */ 99700u), "99.7 Now!", "The Chainsmokers", "Closer"},
{makeSelectorAmfm(/* frequency= */ 101300u), "101-3 KISS-FM", "Justin Timberlake",
"Rock Your Body"},
{makeSelectorAmfm(/* frequency= */ 103700u), "iHeart80s @ 103.7", "Michael Jackson",
"Billie Jean"},
{makeSelectorAmfm(/* frequency= */ 106100u), "106 KMEL", "Drake", "Marvins Room"},
- {makeSelectorAmfm(/* frequency= */ 700u), "700 AM", "Artist700", "Title700"},
- {makeSelectorAmfm(/* frequency= */ 1700u), "1700 AM", "Artist1700", "Title1700"},
+ {makeSelectorAmfm(/* frequency= */ 560u), "Talk Radio 560 KSFO", "Artist560", "Title560"},
+ {makeSelectorAmfm(/* frequency= */ 680u), "KNBR 680", "Artist680", "Title680"},
+ {makeSelectorAmfm(/* frequency= */ 97300u), "Alice@97.3", "Drops of Jupiter", "Train"},
+ {makeSelectorAmfm(/* frequency= */ 99700u), "99.7 Now!", "The Chainsmokers", "Closer"},
+ {makeSelectorHd(/* stationId= */ 0xA0000001u, /* subChannel= */ 0u, /* frequency= */ 97700u),
+ "K-LOVE", "ArtistHd0", "TitleHd0"},
+ {makeSelectorHd(/* stationId= */ 0xA0000001u, /* subChannel= */ 1u, /* frequency= */ 97700u),
+ "Air1", "ArtistHd1", "TitleHd1"},
+ {makeSelectorHd(/* stationId= */ 0xA0000001u, /* subChannel= */ 2u, /* frequency= */ 97700u),
+ "K-LOVE Classics", "ArtistHd2", "TitleHd2"},
+ {makeSelectorHd(/* stationId= */ 0xA0000001u, /* subChannel= */ 0u, /* frequency= */ 98500u),
+ "98.5-1 South Bay's Classic Rock", "ArtistHd0", "TitleHd0"},
+ {makeSelectorHd(/* stationId= */ 0xA0000001u, /* subChannel= */ 1u, /* frequency= */ 98500u),
+ "Highway 1 - Different", "ArtistHd1", "TitleHd1"},
+ {makeSelectorHd(/* stationId= */ 0xB0000001u, /* subChannel= */ 0u, /* frequency= */ 1170u),
+ "KLOK", "ArtistHd1", "TitleHd1"},
});
// clang-format on
return amFmRadioMock;
@@ -76,14 +119,24 @@
static VirtualRadio dabRadioMock(
"DAB radio mock",
{
- {makeSelectorDab(/* sidExt= */ 0xA000000001u, /* ensemble= */ 0x0001u,
+ {makeSelectorDab(/* sidExt= */ 0x0E10000C221u, /* ensemble= */ 0xCE15u,
/* freq= */ 225648u), "BBC Radio 1", "Khalid", "Talk"},
- {makeSelectorDab(/* sidExt= */ 0xB000000001u, /* ensemble= */ 0x1001u,
+ {makeSelectorDab(/* sidExt= */ 0x0E10000C222u, /* ensemble= */ 0xCE15u,
+ /* freq= */ 225648u), "BBC Radio 2", "Khalid", "Talk"},
+ {makeSelectorDab(/* sidExt= */ 0xE10000C224u, /* ensemble= */ 0xCE15u,
+ /* freq= */ 225648u), "BBC Radio 4", "ArtistBBC1", "TitleCountry1"},
+ {makeSelectorDab(/* sidExt= */ 0x1E10000C224u, /* ensemble= */ 0xCE15u,
+ /* freq= */ 225648u), "BBC Radio 4 LW", "ArtistBBC2", "TitleCountry2"},
+ {makeSelectorDab(/* sidExt= */ 0x0E10000C21Au, /* ensemble= */ 0xC181u,
/* freq= */ 222064u), "Classic FM", "Jean Sibelius", "Andante Festivo"},
- {makeSelectorDab(/* sidExt= */ 0xB000000002u, /* ensemble= */ 0x1002u,
- /* freq= */ 227360u), "Absolute Radio", "Coldplay", "Clocks"},
- {makeSelectorDab(/* sidExt= */ 0xB000000002u, /* ensemble= */ 0x1002u,
+ {makeSelectorDab(/* sidExt= */ 0x0E10000C1C0u, /* ensemble= */ 0xC181u,
+ /* freq= */ 223936u), "Absolute Radio", "Coldplay", "Clocks"},
+ {makeSelectorDab(/* sidExt= */ 0x0E10000C1C0u, /* ensemble= */ 0xC181u,
/* freq= */ 222064u), "Absolute Radio", "Coldplay", "Clocks"},
+ {makeSelectorDab(/* sidExt= */ 0x0E10000CCE7u, /* ensemble= */ 0xC19Du,
+ /* freq= */ 218640u), "Absolute Radio Country", "ArtistCountry1", "TitleCountry1"},
+ {makeSelectorDab(/* sidExt= */ 0x0E10000CCE7u, /* ensemble= */ 0xC1A0u,
+ /* freq= */ 218640u), "Absolute Radio Country", "ArtistCountry2", "TitleCountry2"},
});
// clang-format on
return dabRadioMock;
diff --git a/broadcastradio/aidl/default/VirtualRadio.h b/broadcastradio/aidl/default/VirtualRadio.h
index ae039c4..0d70aef 100644
--- a/broadcastradio/aidl/default/VirtualRadio.h
+++ b/broadcastradio/aidl/default/VirtualRadio.h
@@ -36,6 +36,7 @@
std::string getName() const;
const std::vector<VirtualProgram>& getProgramList() const;
bool getProgram(const ProgramSelector& selector, VirtualProgram* program) const;
+ std::vector<IdentifierType> getSupportedIdentifierTypes() const;
static const VirtualRadio& getAmFmRadio();
static const VirtualRadio& getDabRadio();
diff --git a/broadcastradio/aidl/default/test/Android.bp b/broadcastradio/aidl/default/test/Android.bp
new file mode 100644
index 0000000..a33fb70
--- /dev/null
+++ b/broadcastradio/aidl/default/test/Android.bp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+ default_team: "trendy_team_aaos_framework",
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+ name: "DefaultBroadcastRadioHalTestCase",
+ vendor: true,
+ srcs: ["*.cpp"],
+ static_libs: [
+ "DefaultBroadcastRadioHal",
+ "libgtest",
+ "libgmock",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "liblog",
+ "libutils",
+ ],
+ header_libs: [
+ "IVehicleHardware",
+ ],
+ defaults: [
+ "BroadcastRadioHalDefaults",
+ ],
+ test_suites: ["device-tests"],
+}
diff --git a/broadcastradio/aidl/default/test/DefaultBroadcastRadioHalTest.cpp b/broadcastradio/aidl/default/test/DefaultBroadcastRadioHalTest.cpp
new file mode 100644
index 0000000..78fcf27
--- /dev/null
+++ b/broadcastradio/aidl/default/test/DefaultBroadcastRadioHalTest.cpp
@@ -0,0 +1,517 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MockBroadcastRadioCallback.h"
+
+#include <BroadcastRadio.h>
+#include <VirtualRadio.h>
+#include <broadcastradio-utils-aidl/Utils.h>
+
+#include <android-base/logging.h>
+#include <gtest/gtest.h>
+
+namespace aidl::android::hardware::broadcastradio {
+
+namespace {
+using ::std::vector;
+
+constexpr uint32_t kAmFreq1 = 560u;
+constexpr uint32_t kAmFreq2 = 680u;
+constexpr uint32_t kAmHdFreq = 1170u;
+constexpr uint64_t kAmHdSid = 0xB0000001u;
+constexpr uint32_t kFmFreq1 = 94900u;
+constexpr uint64_t kFmHdSid1 = 0xA0000001u;
+constexpr uint64_t kFmHdSid2 = 0xA0000002u;
+constexpr uint32_t kFmHdFreq1 = 98500u;
+constexpr uint32_t kFmHdSubChannel0 = 0u;
+constexpr uint32_t kFmHdSubChannel1 = 1u;
+constexpr uint32_t kFmFreq2 = 99100u;
+constexpr uint32_t kFmHdFreq2 = 101100u;
+
+const ProgramSelector kAmSel1 = utils::makeSelectorAmfm(kAmFreq1);
+const ProgramSelector kAmSel2 = utils::makeSelectorAmfm(kAmFreq2);
+const ProgramSelector kAmHdSel = utils::makeSelectorHd(kAmHdSid, kFmHdSubChannel0, kAmHdFreq);
+const ProgramSelector kFmSel1 = utils::makeSelectorAmfm(kFmFreq1);
+const ProgramSelector kFmSel2 = utils::makeSelectorAmfm(kFmFreq2);
+const ProgramSelector kFmHdFreq1Sel1 =
+ utils::makeSelectorHd(kFmHdSid1, kFmHdSubChannel0, kFmHdFreq1);
+const ProgramSelector kFmHdFreq1Sel2 =
+ utils::makeSelectorHd(kFmHdSid1, kFmHdSubChannel1, kFmHdFreq1);
+const ProgramSelector kFmHdFreq2Sel1 =
+ utils::makeSelectorHd(kFmHdSid2, kFmHdSubChannel0, kFmHdFreq2);
+const ProgramSelector kFmHdFreq2Sel2 =
+ utils::makeSelectorHd(kFmHdSid2, kFmHdSubChannel1, kFmHdFreq2);
+
+const VirtualRadio& getAmFmMockTestRadio() {
+ static VirtualRadio amFmRadioMockTestRadio(
+ "AM/FM radio mock for test",
+ {
+ {kAmSel1, "ProgramAm1", "ArtistAm1", "TitleAm1"},
+ {kAmSel2, "ProgramAm2", "ArtistAm2", "TitleAm2"},
+ {kFmSel1, "ProgramFm1", "ArtistFm1", "TitleFm1"},
+ {kFmSel2, "ProgramFm2", "ArtistFm2", "TitleFm2"},
+ {kAmHdSel, "ProgramAmHd1", "ArtistAmHd1", "TitleAmHd1"},
+ {kFmHdFreq1Sel1, "ProgramFmHd1", "ArtistFmHd1", "TitleFmHd1"},
+ {kFmHdFreq1Sel2, "ProgramFmHd2", "ArtistFmHd2", "TitleFmHd2"},
+ {kFmHdFreq2Sel1, "ProgramFmHd3", "ArtistFmHd3", "TitleFmHd3"},
+ {kFmHdFreq2Sel2, "ProgramFmHd4", "ArtistFmHd4", "TitleFmHd4"},
+ });
+ return amFmRadioMockTestRadio;
+}
+
+int getSignalAcquisitionFlags(const ProgramInfo& info) {
+ return (info.infoFlags &
+ (ProgramInfo::FLAG_SIGNAL_ACQUISITION | ProgramInfo::FLAG_HD_SIS_ACQUISITION |
+ ProgramInfo::FLAG_HD_AUDIO_ACQUISITION)) >>
+ 6;
+}
+
+} // namespace
+
+class DefaultBroadcastRadioHalTest : public testing::Test {
+ public:
+ void SetUp() override {
+ ::android::base::SetDefaultTag("BcRadioAidlDef.test");
+ const VirtualRadio& amFmRadioMockTest = getAmFmMockTestRadio();
+ mBroadcastRadioHal = ::ndk::SharedRefBase::make<BroadcastRadio>(amFmRadioMockTest);
+ mTunerCallback = ndk::SharedRefBase::make<MockBroadcastRadioCallback>();
+ }
+
+ void TearDown() override {
+ mBroadcastRadioHal->unsetTunerCallback();
+ EXPECT_FALSE(mTunerCallback->isTunerFailed());
+ }
+
+ void verifyUpdatedProgramInfo(const ProgramSelector& sel) {
+ ASSERT_TRUE(mTunerCallback->waitOnCurrentProgramInfoChangedCallback());
+ ProgramInfo infoCb1 = mTunerCallback->getCurrentProgramInfo();
+ mTunerCallback->reset();
+ if (sel.primaryId.type == IdentifierType::HD_STATION_ID_EXT) {
+ EXPECT_TRUE(mTunerCallback->waitOnCurrentProgramInfoChangedCallback());
+ ProgramInfo infoCb2 = mTunerCallback->getCurrentProgramInfo();
+ mTunerCallback->reset();
+ EXPECT_TRUE(mTunerCallback->waitOnCurrentProgramInfoChangedCallback());
+ ProgramInfo infoCb3 = mTunerCallback->getCurrentProgramInfo();
+ mTunerCallback->reset();
+ EXPECT_EQ(infoCb1.selector, sel);
+ EXPECT_EQ(getSignalAcquisitionFlags(infoCb1), 0b001);
+ EXPECT_EQ(infoCb2.selector, sel);
+ EXPECT_EQ(getSignalAcquisitionFlags(infoCb2), 0b011);
+ EXPECT_EQ(infoCb3.selector, sel);
+ EXPECT_EQ(getSignalAcquisitionFlags(infoCb3), 0b111);
+ } else {
+ EXPECT_EQ(infoCb1.selector, sel);
+ }
+ }
+
+ bool getAmFmBandRange(utils::FrequencyBand band, AmFmBandRange* res) {
+ AmFmRegionConfig config;
+ auto halResult = mBroadcastRadioHal->getAmFmRegionConfig(/* full= */ false, &config);
+ if (!halResult.isOk()) {
+ return false;
+ }
+ for (const auto& range : config.ranges) {
+ if (utils::getBand(range.lowerBound) == band) {
+ *res = range;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ std::optional<utils::ProgramInfoSet> getProgramList() {
+ ProgramFilter emptyFilter = {};
+ return getProgramList(emptyFilter);
+ }
+
+ std::optional<utils::ProgramInfoSet> getProgramList(const ProgramFilter& filter) {
+ mTunerCallback->reset();
+
+ auto startResult = mBroadcastRadioHal->startProgramListUpdates(filter);
+
+ EXPECT_TRUE(startResult.isOk());
+
+ if (!startResult.isOk()) {
+ return std::nullopt;
+ }
+ EXPECT_TRUE(mTunerCallback->waitProgramReady());
+
+ auto stopResult = mBroadcastRadioHal->stopProgramListUpdates();
+
+ EXPECT_TRUE(stopResult.isOk());
+
+ return mTunerCallback->getProgramList();
+ }
+
+ void switchToFmBand() {
+ ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
+ mTunerCallback->reset();
+ ASSERT_TRUE(mBroadcastRadioHal->tune(kFmSel1).isOk());
+ verifyUpdatedProgramInfo(kFmSel1);
+ }
+
+ std::shared_ptr<BroadcastRadio> mBroadcastRadioHal;
+ std::shared_ptr<MockBroadcastRadioCallback> mTunerCallback;
+};
+
+TEST_F(DefaultBroadcastRadioHalTest, GetAmFmRegionConfig) {
+ AmFmRegionConfig config;
+
+ auto halResult = mBroadcastRadioHal->getAmFmRegionConfig(/* full= */ false, &config);
+
+ ASSERT_TRUE(halResult.isOk());
+ EXPECT_EQ(config.fmDeemphasis, AmFmRegionConfig::DEEMPHASIS_D50);
+ EXPECT_EQ(config.fmRds, AmFmRegionConfig::RDS);
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, GetAmFmRegionConfigWithFullBand) {
+ AmFmRegionConfig config;
+
+ auto halResult = mBroadcastRadioHal->getAmFmRegionConfig(/* full= */ true, &config);
+
+ ASSERT_TRUE(halResult.isOk());
+ EXPECT_EQ(config.fmDeemphasis,
+ AmFmRegionConfig::DEEMPHASIS_D50 | AmFmRegionConfig::DEEMPHASIS_D75);
+ EXPECT_EQ(config.fmRds, AmFmRegionConfig::RDS | AmFmRegionConfig::RBDS);
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, GetDabRegionConfig) {
+ vector<DabTableEntry> config;
+
+ auto halResult = mBroadcastRadioHal->getDabRegionConfig(&config);
+
+ ASSERT_TRUE(halResult.isOk());
+ ASSERT_FALSE(config.empty());
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, GetImage) {
+ vector<uint8_t> img;
+
+ auto halResult = mBroadcastRadioHal->getImage(BroadcastRadio::INVALID_IMAGE, &img);
+
+ ASSERT_TRUE(halResult.isOk());
+ ASSERT_TRUE(img.empty());
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, GetProperties) {
+ vector<VirtualProgram> mockPrograms = getAmFmMockTestRadio().getProgramList();
+ Properties prop;
+
+ auto halResult = mBroadcastRadioHal->getProperties(&prop);
+
+ ASSERT_TRUE(halResult.isOk());
+ ASSERT_FALSE(prop.supportedIdentifierTypes.empty());
+ std::unordered_set<IdentifierType> supportedTypeSet;
+ for (const auto& supportedType : prop.supportedIdentifierTypes) {
+ supportedTypeSet.insert(supportedType);
+ }
+ for (const auto& program : mockPrograms) {
+ EXPECT_NE(supportedTypeSet.find(program.selector.primaryId.type), supportedTypeSet.end());
+ }
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, SetTunerCallback) {
+ auto halResult = mBroadcastRadioHal->setTunerCallback(mTunerCallback);
+
+ ASSERT_TRUE(halResult.isOk());
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, SetTunerCallbackWithNull) {
+ auto halResult = mBroadcastRadioHal->setTunerCallback(nullptr);
+
+ ASSERT_EQ(halResult.getServiceSpecificError(), utils::resultToInt(Result::INVALID_ARGUMENTS));
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, UnsetTunerCallbackWithNull) {
+ ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
+
+ auto halResult = mBroadcastRadioHal->unsetTunerCallback();
+
+ ASSERT_TRUE(halResult.isOk());
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, TuneWithAmFmSelectorInProgramList) {
+ ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
+ mTunerCallback->reset();
+
+ auto halResult = mBroadcastRadioHal->tune(kFmSel1);
+
+ ASSERT_TRUE(halResult.isOk());
+ ASSERT_TRUE(mTunerCallback->waitOnCurrentProgramInfoChangedCallback());
+ ProgramInfo infoCb = mTunerCallback->getCurrentProgramInfo();
+ EXPECT_EQ(infoCb.selector, kFmSel1);
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, TuneWithHdSelectorInProgramList) {
+ ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
+ mTunerCallback->reset();
+
+ auto halResult = mBroadcastRadioHal->tune(kFmHdFreq1Sel2);
+
+ ASSERT_TRUE(halResult.isOk());
+ verifyUpdatedProgramInfo(kFmHdFreq1Sel2);
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, TuneWitFrequencyOfHdProgramInProgramList) {
+ ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
+ mTunerCallback->reset();
+
+ auto halResult = mBroadcastRadioHal->tune(
+ utils::makeSelectorAmfm(utils::getHdFrequency(kFmHdFreq1Sel1)));
+
+ ASSERT_TRUE(halResult.isOk());
+ verifyUpdatedProgramInfo(kFmHdFreq1Sel1);
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, TuneWithInvalidSelector) {
+ ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
+ ProgramSelector invalidSelector = {utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, 0),
+ {}};
+
+ auto halResult = mBroadcastRadioHal->tune(invalidSelector);
+
+ ASSERT_EQ(halResult.getServiceSpecificError(), utils::resultToInt(Result::INVALID_ARGUMENTS));
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, TuneWithoutTunerCallback) {
+ auto halResult = mBroadcastRadioHal->tune(kFmSel1);
+
+ ASSERT_EQ(halResult.getServiceSpecificError(), utils::resultToInt(Result::INVALID_STATE));
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, StepUp) {
+ AmFmBandRange fmRange;
+ ASSERT_TRUE(getAmFmBandRange(utils::FrequencyBand::FM, &fmRange));
+ ProgramSelector nextChannelSel =
+ utils::makeSelectorAmfm(kFmSel1.primaryId.value + fmRange.spacing);
+ ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
+ mTunerCallback->reset();
+ ASSERT_TRUE(mBroadcastRadioHal->tune(kFmSel1).isOk());
+ verifyUpdatedProgramInfo(kFmSel1);
+
+ auto halResult = mBroadcastRadioHal->step(/* in_directionUp= */ true);
+
+ ASSERT_TRUE(halResult.isOk());
+ verifyUpdatedProgramInfo(nextChannelSel);
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, StepUpFromUpperBound) {
+ AmFmBandRange fmRange;
+ ASSERT_TRUE(getAmFmBandRange(utils::FrequencyBand::FM, &fmRange));
+ ProgramSelector upperBoundSel = utils::makeSelectorAmfm(fmRange.upperBound);
+ ProgramSelector lowerBoundSel = utils::makeSelectorAmfm(fmRange.lowerBound);
+ ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
+ mTunerCallback->reset();
+ ASSERT_TRUE(mBroadcastRadioHal->tune(upperBoundSel).isOk());
+ verifyUpdatedProgramInfo(upperBoundSel);
+
+ auto halResult = mBroadcastRadioHal->step(/* in_directionUp= */ true);
+
+ ASSERT_TRUE(halResult.isOk());
+ verifyUpdatedProgramInfo(lowerBoundSel);
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, StepDown) {
+ AmFmBandRange fmRange;
+ ASSERT_TRUE(getAmFmBandRange(utils::FrequencyBand::FM, &fmRange));
+ ProgramSelector nextChannelSel =
+ utils::makeSelectorAmfm(kFmSel1.primaryId.value - fmRange.spacing);
+ ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
+ mTunerCallback->reset();
+ ASSERT_TRUE(mBroadcastRadioHal->tune(kFmSel1).isOk());
+ verifyUpdatedProgramInfo(kFmSel1);
+
+ auto halResult = mBroadcastRadioHal->step(/* directionUp= */ false);
+
+ ASSERT_TRUE(halResult.isOk());
+ verifyUpdatedProgramInfo(nextChannelSel);
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, StepDownFromLowerBound) {
+ AmFmBandRange fmRange;
+ ASSERT_TRUE(getAmFmBandRange(utils::FrequencyBand::FM, &fmRange));
+ ProgramSelector upperBoundSel = utils::makeSelectorAmfm(fmRange.upperBound);
+ ProgramSelector lowerBoundSel = utils::makeSelectorAmfm(fmRange.lowerBound);
+ ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
+ mTunerCallback->reset();
+ ASSERT_TRUE(mBroadcastRadioHal->tune(lowerBoundSel).isOk());
+ verifyUpdatedProgramInfo(lowerBoundSel);
+
+ auto halResult = mBroadcastRadioHal->step(/* directionUp= */ false);
+
+ ASSERT_TRUE(halResult.isOk());
+ verifyUpdatedProgramInfo(upperBoundSel);
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, StepWithoutTunerCallback) {
+ switchToFmBand();
+ mBroadcastRadioHal->unsetTunerCallback();
+
+ auto halResult = mBroadcastRadioHal->step(/* directionUp= */ false);
+
+ ASSERT_EQ(halResult.getServiceSpecificError(), utils::resultToInt(Result::INVALID_STATE));
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, SeekUpWithoutSkipSubchannel) {
+ ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
+ mTunerCallback->reset();
+ ASSERT_TRUE(mBroadcastRadioHal->tune(kFmHdFreq1Sel1).isOk());
+ verifyUpdatedProgramInfo(kFmHdFreq1Sel1);
+
+ auto halResult = mBroadcastRadioHal->seek(/* directionUp= */ true, /* skipSubChannel= */ false);
+
+ ASSERT_TRUE(halResult.isOk());
+ verifyUpdatedProgramInfo(kFmHdFreq1Sel2);
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, SeekUpWithSkipSubchannel) {
+ ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
+ mTunerCallback->reset();
+ ASSERT_TRUE(mBroadcastRadioHal->tune(kFmHdFreq1Sel1).isOk());
+ verifyUpdatedProgramInfo(kFmHdFreq1Sel1);
+
+ auto halResult = mBroadcastRadioHal->seek(/* directionUp= */ true, /* skipSubChannel= */ true);
+
+ ASSERT_TRUE(halResult.isOk());
+ verifyUpdatedProgramInfo(kFmSel2);
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, SeekUpFromLastProgramInProgramList) {
+ ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
+ mTunerCallback->reset();
+ ASSERT_TRUE(mBroadcastRadioHal->tune(kFmHdFreq2Sel1).isOk());
+ verifyUpdatedProgramInfo(kFmHdFreq2Sel1);
+
+ auto halResult = mBroadcastRadioHal->seek(/* directionUp= */ true, /* skipSubChannel= */ true);
+
+ ASSERT_TRUE(halResult.isOk());
+ verifyUpdatedProgramInfo(kFmSel1);
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, SeekDownWithoutSkipSubchannel) {
+ ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
+ mTunerCallback->reset();
+ ASSERT_TRUE(mBroadcastRadioHal->tune(kFmHdFreq1Sel2).isOk());
+ verifyUpdatedProgramInfo(kFmHdFreq1Sel2);
+
+ auto halResult =
+ mBroadcastRadioHal->seek(/* directionUp= */ false, /* skipSubChannel= */ false);
+
+ ASSERT_TRUE(halResult.isOk());
+ verifyUpdatedProgramInfo(kFmHdFreq1Sel1);
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, SeekDownWithSkipSubchannel) {
+ ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
+ mTunerCallback->reset();
+ ASSERT_TRUE(mBroadcastRadioHal->tune(kFmHdFreq1Sel2).isOk());
+ verifyUpdatedProgramInfo(kFmHdFreq1Sel2);
+
+ auto halResult = mBroadcastRadioHal->seek(/* directionUp= */ false, /* skipSubChannel= */ true);
+
+ ASSERT_TRUE(halResult.isOk());
+ verifyUpdatedProgramInfo(kFmSel1);
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, SeekDownWithFirstProgramInProgramList) {
+ switchToFmBand();
+
+ auto halResult = mBroadcastRadioHal->seek(/* directionUp= */ false, /* skipSubChannel= */ true);
+
+ ASSERT_TRUE(halResult.isOk());
+ verifyUpdatedProgramInfo(kFmHdFreq2Sel1);
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, SeekWithoutTunerCallback) {
+ switchToFmBand();
+ mBroadcastRadioHal->unsetTunerCallback();
+
+ auto halResult = mBroadcastRadioHal->seek(/* directionUp= */ false, /* skipSubChannel= */ true);
+
+ ASSERT_EQ(halResult.getServiceSpecificError(), utils::resultToInt(Result::INVALID_STATE));
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, Cancel) {
+ ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
+ mTunerCallback->reset();
+ ASSERT_TRUE(mBroadcastRadioHal->tune(kFmSel1).isOk());
+
+ auto halResult = mBroadcastRadioHal->cancel();
+
+ ASSERT_TRUE(halResult.isOk());
+ mTunerCallback->reset();
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, SetConfigFlag) {
+ ConfigFlag flag = ConfigFlag::FORCE_MONO;
+
+ auto setResult = mBroadcastRadioHal->setConfigFlag(flag, /* value= */ true);
+
+ ASSERT_TRUE(setResult.isOk());
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, GetConfigFlag) {
+ bool gotValue = false;
+ ConfigFlag flag = ConfigFlag::FORCE_MONO;
+ mBroadcastRadioHal->setConfigFlag(flag, /* value= */ true);
+
+ auto getResult = mBroadcastRadioHal->isConfigFlagSet(flag, &gotValue);
+
+ ASSERT_TRUE(getResult.isOk());
+ ASSERT_TRUE(gotValue);
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, StartProgramListUpdatesWithEmptyFilter) {
+ switchToFmBand();
+
+ auto programList = getProgramList();
+
+ ASSERT_TRUE(programList.has_value());
+ for (auto it = programList->begin(); it != programList->end(); it++) {
+ EXPECT_EQ(utils::getBand(utils::getAmFmFrequency(it->selector)), utils::FrequencyBand::FM);
+ }
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, StartProgramListUpdatesWithAmFmFilter) {
+ ProgramFilter amFmFilter = {.identifierTypes = {IdentifierType::AMFM_FREQUENCY_KHZ},
+ .identifiers = {},
+ .includeCategories = false,
+ .excludeModifications = false};
+ switchToFmBand();
+
+ auto programList = getProgramList(amFmFilter);
+
+ ASSERT_TRUE(programList.has_value());
+ for (auto it = programList->begin(); it != programList->end(); it++) {
+ EXPECT_TRUE(utils::hasId(it->selector, IdentifierType::AMFM_FREQUENCY_KHZ));
+ EXPECT_EQ(utils::getBand(utils::getAmFmFrequency(it->selector)), utils::FrequencyBand::FM);
+ }
+}
+
+TEST_F(DefaultBroadcastRadioHalTest, StartProgramListUpdatesWhenHdIsDisabled) {
+ switchToFmBand();
+ mBroadcastRadioHal->setConfigFlag(ConfigFlag::FORCE_ANALOG_FM, /* value= */ true);
+
+ auto programList = getProgramList();
+
+ ASSERT_TRUE(programList.has_value());
+ for (auto it = programList->begin(); it != programList->end(); it++) {
+ EXPECT_FALSE(utils::hasId(it->selector, IdentifierType::HD_STATION_ID_EXT));
+ EXPECT_EQ(utils::getBand(utils::getAmFmFrequency(it->selector)), utils::FrequencyBand::FM);
+ }
+}
+
+} // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/aidl/default/test/MockBroadcastRadioCallback.cpp b/broadcastradio/aidl/default/test/MockBroadcastRadioCallback.cpp
new file mode 100644
index 0000000..963f8bf
--- /dev/null
+++ b/broadcastradio/aidl/default/test/MockBroadcastRadioCallback.cpp
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+#include "MockBroadcastRadioCallback.h"
+
+#include <android-base/logging.h>
+
+namespace aidl::android::hardware::broadcastradio {
+
+namespace {
+using std::vector;
+}
+
+MockBroadcastRadioCallback::MockBroadcastRadioCallback() {
+ mAntennaConnectionState = true;
+}
+
+ScopedAStatus MockBroadcastRadioCallback::onTuneFailed(Result result,
+ const ProgramSelector& selector) {
+ LOG(DEBUG) << "onTuneFailed with result with " << selector.toString().c_str();
+ if (result != Result::CANCELED) {
+ std::lock_guard<std::mutex> lk(mLock);
+ tunerFailed = true;
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ScopedAStatus MockBroadcastRadioCallback::onCurrentProgramInfoChanged(const ProgramInfo& info) {
+ LOG(DEBUG) << "onCurrentProgramInfoChanged with " << info.toString().c_str();
+ {
+ std::lock_guard<std::mutex> lk(mLock);
+ mCurrentProgramInfo = info;
+ }
+
+ mOnCurrentProgramInfoChangedFlag.notify();
+ return ndk::ScopedAStatus::ok();
+}
+
+ScopedAStatus MockBroadcastRadioCallback::onProgramListUpdated(const ProgramListChunk& chunk) {
+ {
+ std::lock_guard<std::mutex> lk(mLock);
+ updateProgramList(chunk, &mProgramList);
+ }
+
+ if (chunk.complete) {
+ mOnProgramListReadyFlag.notify();
+ }
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ScopedAStatus MockBroadcastRadioCallback::onParametersUpdated(
+ [[maybe_unused]] const vector<VendorKeyValue>& parameters) {
+ return ndk::ScopedAStatus::ok();
+}
+
+ScopedAStatus MockBroadcastRadioCallback::onAntennaStateChange(bool connected) {
+ if (!connected) {
+ std::lock_guard<std::mutex> lk(mLock);
+ mAntennaConnectionState = false;
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ScopedAStatus MockBroadcastRadioCallback::onConfigFlagUpdated([[maybe_unused]] ConfigFlag in_flag,
+ [[maybe_unused]] bool in_value) {
+ return ndk::ScopedAStatus::ok();
+}
+
+bool MockBroadcastRadioCallback::waitOnCurrentProgramInfoChangedCallback() {
+ return mOnCurrentProgramInfoChangedFlag.wait();
+}
+
+bool MockBroadcastRadioCallback::waitProgramReady() {
+ return mOnProgramListReadyFlag.wait();
+}
+
+void MockBroadcastRadioCallback::reset() {
+ mOnCurrentProgramInfoChangedFlag.reset();
+ mOnProgramListReadyFlag.reset();
+}
+
+bool MockBroadcastRadioCallback::isTunerFailed() {
+ std::lock_guard<std::mutex> lk(mLock);
+ return tunerFailed;
+}
+
+ProgramInfo MockBroadcastRadioCallback::getCurrentProgramInfo() {
+ std::lock_guard<std::mutex> lk(mLock);
+ return mCurrentProgramInfo;
+}
+
+utils::ProgramInfoSet MockBroadcastRadioCallback::getProgramList() {
+ std::lock_guard<std::mutex> lk(mLock);
+ return mProgramList;
+}
+
+} // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/aidl/default/test/MockBroadcastRadioCallback.h b/broadcastradio/aidl/default/test/MockBroadcastRadioCallback.h
new file mode 100644
index 0000000..4415842
--- /dev/null
+++ b/broadcastradio/aidl/default/test/MockBroadcastRadioCallback.h
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/broadcastradio/BnTunerCallback.h>
+#include <aidl/android/hardware/broadcastradio/ConfigFlag.h>
+#include <aidl/android/hardware/broadcastradio/IBroadcastRadio.h>
+#include <aidl/android/hardware/broadcastradio/ProgramInfo.h>
+#include <aidl/android/hardware/broadcastradio/ProgramListChunk.h>
+#include <aidl/android/hardware/broadcastradio/ProgramSelector.h>
+#include <aidl/android/hardware/broadcastradio/Result.h>
+#include <aidl/android/hardware/broadcastradio/VendorKeyValue.h>
+
+#include <android-base/thread_annotations.h>
+
+#include <broadcastradio-utils-aidl/Utils.h>
+
+#include <condition_variable>
+
+namespace aidl::android::hardware::broadcastradio {
+
+namespace {
+using ::ndk::ScopedAStatus;
+
+} // namespace
+
+class MockBroadcastRadioCallback final : public BnTunerCallback {
+ public:
+ explicit MockBroadcastRadioCallback();
+ ScopedAStatus onTuneFailed(Result result, const ProgramSelector& selector) override;
+ ScopedAStatus onCurrentProgramInfoChanged(const ProgramInfo& info) override;
+ ScopedAStatus onProgramListUpdated(const ProgramListChunk& chunk) override;
+ ScopedAStatus onParametersUpdated(const std::vector<VendorKeyValue>& parameters) override;
+ ScopedAStatus onAntennaStateChange(bool connected) override;
+ ScopedAStatus onConfigFlagUpdated(ConfigFlag in_flag, bool in_value) override;
+
+ bool waitOnCurrentProgramInfoChangedCallback();
+ bool waitProgramReady();
+ bool isTunerFailed();
+ void reset();
+
+ ProgramInfo getCurrentProgramInfo();
+ utils::ProgramInfoSet getProgramList();
+
+ private:
+ class CallbackFlag final {
+ public:
+ CallbackFlag(int timeoutMs) { mTimeoutMs = timeoutMs; }
+ /**
+ * Notify that the callback is called.
+ */
+ void notify() {
+ std::unique_lock<std::mutex> lock(mMutex);
+ mCalled = true;
+ lock.unlock();
+ mCv.notify_all();
+ };
+
+ /**
+ * Wait for the timeout passed into the constructor.
+ */
+ bool wait() {
+ std::unique_lock<std::mutex> lock(mMutex);
+ return mCv.wait_for(lock, std::chrono::milliseconds(mTimeoutMs),
+ [this] { return mCalled; });
+ };
+
+ /**
+ * Reset the callback to not called.
+ */
+ void reset() {
+ std::unique_lock<std::mutex> lock(mMutex);
+ mCalled = false;
+ }
+
+ private:
+ std::mutex mMutex;
+ bool mCalled GUARDED_BY(mMutex) = false;
+ std::condition_variable mCv;
+ int mTimeoutMs;
+ };
+
+ std::mutex mLock;
+ bool mAntennaConnectionState GUARDED_BY(mLock);
+ bool tunerFailed GUARDED_BY(mLock) = false;
+ ProgramInfo mCurrentProgramInfo GUARDED_BY(mLock);
+ utils::ProgramInfoSet mProgramList GUARDED_BY(mLock);
+ CallbackFlag mOnCurrentProgramInfoChangedFlag = CallbackFlag(IBroadcastRadio::TUNER_TIMEOUT_MS);
+ CallbackFlag mOnProgramListReadyFlag = CallbackFlag(IBroadcastRadio::LIST_COMPLETE_TIMEOUT_MS);
+};
+
+} // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp b/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
index 72869cc..9633ebb 100644
--- a/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
+++ b/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
@@ -35,6 +35,7 @@
#include <broadcastradio-utils-aidl/UtilsV2.h>
#include <cutils/bitops.h>
#include <gmock/gmock.h>
+#include <gtest/gtest.h>
#include <chrono>
#include <condition_variable>
@@ -76,12 +77,6 @@
constexpr int32_t kAidlVersion1 = 1;
constexpr int32_t kAidlVersion2 = 2;
-void printSkipped(const std::string& msg) {
- const auto testInfo = testing::UnitTest::GetInstance()->current_test_info();
- LOG(INFO) << "[ SKIPPED ] " << testInfo->test_case_name() << "." << testInfo->name()
- << " with message: " << msg;
-}
-
bool isValidAmFmFreq(int64_t freq, int aidlVersion) {
ProgramIdentifier id = bcutils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, freq);
if (aidlVersion == kAidlVersion1) {
@@ -255,6 +250,16 @@
}
}
+ for (const auto& metadataItem : info.metadata) {
+ bool validMetadata = false;
+ if (mCallbackAidlVersion == kAidlVersion1) {
+ validMetadata = bcutils::isValidMetadata(metadataItem);
+ } else {
+ validMetadata = bcutils::isValidMetadataV2(metadataItem);
+ }
+ EXPECT_TRUE(validMetadata) << "Invalid metadata " << metadataItem.toString().c_str();
+ }
+
{
std::lock_guard<std::mutex> lk(mLock);
mCurrentProgramInfo = info;
@@ -385,7 +390,7 @@
auto startResult = mModule->startProgramListUpdates(filter);
if (startResult.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
- printSkipped("Program list not supported");
+ LOG(WARNING) << "Program list not supported";
return std::nullopt;
}
EXPECT_TRUE(startResult.isOk());
@@ -430,8 +435,7 @@
bool supported = getAmFmRegionConfig(/* full= */ false, &config);
if (!supported) {
- printSkipped("AM/FM not supported");
- return;
+ GTEST_SKIP() << "AM/FM not supported";
}
EXPECT_LE(popcountll(static_cast<unsigned long long>(config.fmDeemphasis)), 1);
@@ -459,8 +463,7 @@
bool supported = getAmFmRegionConfig(/* full= */ false, &config);
if (!supported) {
- printSkipped("AM/FM not supported");
- return;
+ GTEST_SKIP() << "AM/FM not supported";
}
EXPECT_GT(config.ranges.size(), 0u);
@@ -488,7 +491,7 @@
if (supported && supportsFM(config)) {
EXPECT_GE(popcountll(static_cast<unsigned long long>(config.fmDeemphasis)), 1);
} else {
- printSkipped("FM not supported");
+ GTEST_SKIP() << "FM not supported";
}
}
@@ -509,8 +512,7 @@
bool supported = getAmFmRegionConfig(/* full= */ true, &config);
if (!supported) {
- printSkipped("AM/FM not supported");
- return;
+ GTEST_SKIP() << "AM/FM not supported";
}
EXPECT_GT(config.ranges.size(), 0u);
@@ -536,8 +538,7 @@
auto halResult = mModule->getDabRegionConfig(&config);
if (halResult.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
- printSkipped("DAB not supported");
- return;
+ GTEST_SKIP() << "DAB not supported";
}
ASSERT_TRUE(halResult.isOk());
@@ -671,7 +672,7 @@
* - if it is supported, the method succeeds;
* - after a successful tune call, onCurrentProgramInfoChanged callback is
* invoked carrying a proper selector;
- * - program changes exactly to what was requested.
+ * - program changes to a program info with the program selector requested.
*/
TEST_P(BroadcastRadioHalTest, FmTune) {
LOG(DEBUG) << "FmTune Test";
@@ -702,6 +703,57 @@
}
/**
+ * Test tuning with HD selector.
+ *
+ * Verifies that:
+ * - if AM/FM HD selector is not supported, the method returns NOT_SUPPORTED;
+ * - if it is supported, the method succeeds;
+ * - after a successful tune call, onCurrentProgramInfoChanged callback is
+ * invoked carrying a proper selector;
+ * - program changes to a program info with the program selector requested.
+ */
+TEST_P(BroadcastRadioHalTest, HdTune) {
+ LOG(DEBUG) << "HdTune Test";
+ auto programList = getProgramList();
+ if (!programList) {
+ GTEST_SKIP() << "Empty station list, tune cannot be performed";
+ }
+ ProgramSelector hdSel = {};
+ ProgramIdentifier physicallyTunedToExpected = {};
+ bool hdStationPresent = false;
+ for (auto&& programInfo : *programList) {
+ if (programInfo.selector.primaryId.type != IdentifierType::HD_STATION_ID_EXT) {
+ continue;
+ }
+ hdSel = programInfo.selector;
+ hdStationPresent = true;
+ physicallyTunedToExpected = bcutils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ,
+ bcutils::getAmFmFrequency(hdSel));
+ break;
+ }
+ if (!hdStationPresent) {
+ GTEST_SKIP() << "No HD stations in the list, tune cannot be performed";
+ }
+
+ // try tuning
+ auto result = mModule->tune(hdSel);
+
+ // expect a failure if it's not supported
+ if (!bcutils::isSupported(mProperties, hdSel)) {
+ EXPECT_EQ(result.getServiceSpecificError(), resultToInt(Result::NOT_SUPPORTED));
+ return;
+ }
+ // expect a callback if it succeeds
+ EXPECT_TRUE(result.isOk());
+ EXPECT_TRUE(mCallback->waitOnCurrentProgramInfoChangedCallback());
+ ProgramInfo infoCb = mCallback->getCurrentProgramInfo();
+ LOG(DEBUG) << "Current program info: " << infoCb.toString();
+ // it should tune exactly to what was requested
+ EXPECT_EQ(infoCb.selector.primaryId, hdSel.primaryId);
+ EXPECT_EQ(infoCb.physicallyTunedTo, physicallyTunedToExpected);
+}
+
+/**
* Test tuning with DAB selector.
*
* Verifies that:
@@ -709,7 +761,7 @@
* - if it is supported, the method succeeds;
* - after a successful tune call, onCurrentProgramInfoChanged callback is
* invoked carrying a proper selector;
- * - program changes exactly to what was requested.
+ * - program changes to a program info with the program selector requested.
*/
TEST_P(BroadcastRadioHalTest, DabTune) {
LOG(DEBUG) << "DabTune Test";
@@ -718,8 +770,7 @@
auto halResult = mModule->getDabRegionConfig(&config);
if (halResult.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
- printSkipped("DAB not supported");
- return;
+ GTEST_SKIP() << "DAB not supported";
}
ASSERT_TRUE(halResult.isOk());
ASSERT_NE(config.size(), 0U);
@@ -727,8 +778,7 @@
auto programList = getProgramList();
if (!programList) {
- printSkipped("Empty DAB station list, tune cannot be performed");
- return;
+ GTEST_SKIP() << "Empty DAB station list, tune cannot be performed";
}
ProgramSelector sel = {};
@@ -758,8 +808,7 @@
}
if (!dabStationPresent) {
- printSkipped("No DAB stations in the list, tune cannot be performed");
- return;
+ GTEST_SKIP() << "No DAB stations in the list, tune cannot be performed";
}
// try tuning
@@ -791,7 +840,7 @@
* Verifies that:
* - the method succeeds;
* - the program info is changed within kTuneTimeoutMs;
- * - works both directions and with or without skipping sub-channel.
+ * - works both directions and with or without ing sub-channel.
*/
TEST_P(BroadcastRadioHalTest, Seek) {
LOG(DEBUG) << "Seek Test";
@@ -801,8 +850,7 @@
auto result = mModule->seek(/* in_directionUp= */ true, /* in_skipSubChannel= */ true);
if (result.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
- printSkipped("Seek not supported");
- return;
+ GTEST_SKIP() << "Seek not supported";
}
EXPECT_TRUE(result.isOk());
@@ -852,8 +900,7 @@
auto result = mModule->step(/* in_directionUp= */ true);
if (result.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
- printSkipped("Step not supported");
- return;
+ GTEST_SKIP() << "Step not supported";
}
EXPECT_TRUE(result.isOk());
EXPECT_TRUE(mCallback->waitOnCurrentProgramInfoChangedCallback());
@@ -904,8 +951,7 @@
auto result = mModule->seek(/* in_directionUp= */ true, /* in_skipSubChannel= */ true);
if (result.getServiceSpecificError() == notSupportedError) {
- printSkipped("Cancel is skipped because of seek not supported");
- return;
+ GTEST_SKIP() << "Cancel is skipped because of seek not supported";
}
EXPECT_TRUE(result.isOk());
@@ -1099,8 +1145,7 @@
std::optional<bcutils::ProgramInfoSet> completeList = getProgramList();
if (!completeList) {
- printSkipped("No program list available");
- return;
+ GTEST_SKIP() << "No program list available";
}
ProgramFilter amfmFilter = {};
@@ -1125,8 +1170,7 @@
}
if (expectedResultSize == 0) {
- printSkipped("No Am/FM programs available");
- return;
+ GTEST_SKIP() << "No Am/FM programs available";
}
std::optional<bcutils::ProgramInfoSet> amfmList = getProgramList(amfmFilter);
ASSERT_EQ(amfmList->size(), expectedResultSize) << "amfm filter result size is wrong";
@@ -1147,8 +1191,7 @@
std::optional<bcutils::ProgramInfoSet> completeList = getProgramList();
if (!completeList) {
- printSkipped("No program list available");
- return;
+ GTEST_SKIP() << "No program list available";
}
ProgramFilter dabFilter = {};
@@ -1172,8 +1215,7 @@
}
if (expectedResultSize == 0) {
- printSkipped("No DAB programs available");
- return;
+ GTEST_SKIP() << "No DAB programs available";
}
std::optional<bcutils::ProgramInfoSet> dabList = getProgramList(dabFilter);
ASSERT_EQ(dabList->size(), expectedResultSize) << "dab filter result size is wrong";
@@ -1192,8 +1234,7 @@
std::optional<bcutils::ProgramInfoSet> list = getProgramList();
if (!list) {
- printSkipped("No program list");
- return;
+ GTEST_SKIP() << "No program list";
}
for (const auto& program : *list) {
@@ -1244,8 +1285,7 @@
if (halResult.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
ASSERT_EQ(closeHandle.get(), nullptr);
- printSkipped("Announcements not supported");
- return;
+ GTEST_SKIP() << "Announcements not supported";
}
ASSERT_TRUE(halResult.isOk());
diff --git a/broadcastradio/common/tests/Android.bp b/broadcastradio/common/tests/Android.bp
index 0a6a3a2..1ea4e85 100644
--- a/broadcastradio/common/tests/Android.bp
+++ b/broadcastradio/common/tests/Android.bp
@@ -86,4 +86,7 @@
],
static_libs: ["android.hardware.broadcastradio@common-utils-lib"],
test_suites: ["general-tests"],
+ shared_libs: [
+ "libbase",
+ ],
}
diff --git a/broadcastradio/common/utils/WorkerThread.cpp b/broadcastradio/common/utils/WorkerThread.cpp
index 43fd04a..5c8e59c 100644
--- a/broadcastradio/common/utils/WorkerThread.cpp
+++ b/broadcastradio/common/utils/WorkerThread.cpp
@@ -69,8 +69,11 @@
}
void WorkerThread::threadLoop() {
- while (!mIsTerminating) {
+ while (true) {
unique_lock<mutex> lk(mMut);
+ if (mIsTerminating) {
+ return;
+ }
if (mTasks.empty()) {
mCond.wait(lk);
continue;
diff --git a/broadcastradio/common/utils/include/broadcastradio-utils/WorkerThread.h b/broadcastradio/common/utils/include/broadcastradio-utils/WorkerThread.h
index 457b57e..e381f5a 100644
--- a/broadcastradio/common/utils/include/broadcastradio-utils/WorkerThread.h
+++ b/broadcastradio/common/utils/include/broadcastradio-utils/WorkerThread.h
@@ -20,6 +20,8 @@
#include <queue>
#include <thread>
+#include <android-base/thread_annotations.h>
+
namespace android {
class WorkerThread {
@@ -40,11 +42,11 @@
};
friend bool operator<(const Task& lhs, const Task& rhs);
- std::atomic<bool> mIsTerminating;
std::mutex mMut;
- std::condition_variable mCond;
+ bool mIsTerminating GUARDED_BY(mMut);
+ std::condition_variable mCond GUARDED_BY(mMut);
std::thread mThread;
- std::priority_queue<Task> mTasks;
+ std::priority_queue<Task> mTasks GUARDED_BY(mMut);
void threadLoop();
};
diff --git a/broadcastradio/common/utilsaidl/Android.bp b/broadcastradio/common/utilsaidl/Android.bp
index 4ec635b..e3bdfdd 100644
--- a/broadcastradio/common/utilsaidl/Android.bp
+++ b/broadcastradio/common/utilsaidl/Android.bp
@@ -20,13 +20,14 @@
// all of the 'license_kinds' from "hardware_interfaces_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
+ default_team: "trendy_team_aaos_framework",
default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_library_static {
name: "android.hardware.broadcastradio@common-utils-aidl-lib",
defaults: [
- "VtsBroadcastRadioDefaults",
+ "BroadcastRadioUtilsDefaults",
],
shared_libs: [
"android.hardware.broadcastradio-V1-ndk",
@@ -36,7 +37,7 @@
cc_library_static {
name: "android.hardware.broadcastradio@common-utils-aidl-lib-V2",
defaults: [
- "VtsBroadcastRadioDefaults",
+ "BroadcastRadioUtilsDefaults",
],
srcs: [
"src/UtilsV2.cpp",
@@ -46,8 +47,23 @@
],
}
+cc_test {
+ name: "broadcastradio_utils_aidl_test",
+ defaults: [
+ "BroadcastRadioUtilsDefaults",
+ ],
+ srcs: [
+ "test/*.cpp",
+ ],
+ static_libs: [
+ "android.hardware.broadcastradio@common-utils-aidl-lib-V2",
+ "android.hardware.broadcastradio-V2-ndk",
+ ],
+ test_suites: ["general-tests"],
+}
+
cc_defaults {
- name: "VtsBroadcastRadioDefaults",
+ name: "BroadcastRadioUtilsDefaults",
vendor_available: true,
relative_install_path: "hw",
cflags: [
diff --git a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
index b6fb33f..25c96d0 100644
--- a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
+++ b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
@@ -139,9 +139,20 @@
ProgramSelector makeSelectorAmfm(uint32_t frequency);
ProgramSelector makeSelectorDab(uint64_t sidExt);
ProgramSelector makeSelectorDab(uint64_t sidExt, uint32_t ensemble, uint64_t freq);
+ProgramSelector makeSelectorHd(uint64_t stationId, uint64_t subChannel, uint64_t frequency);
bool satisfies(const ProgramFilter& filter, const ProgramSelector& sel);
+bool isValidMetadata(const Metadata& metadata);
+
+struct ProgramSelectorComparator {
+ bool operator()(const ProgramSelector& lhs, const ProgramSelector& rhs) const;
+};
+
+struct ProgramInfoComparator {
+ bool operator()(const ProgramInfo& lhs, const ProgramInfo& rhs) const;
+};
+
struct ProgramInfoHasher {
size_t operator()(const ProgramInfo& info) const;
};
@@ -158,6 +169,20 @@
ProgramIdentifier makeHdRadioStationName(const std::string& name);
+uint32_t getHdFrequency(const ProgramSelector& sel);
+
+int getHdSubchannel(const ProgramSelector& sel);
+
+uint32_t getDabSId(const ProgramSelector& sel);
+
+int getDabEccCode(const ProgramSelector& sel);
+
+int getDabSCIdS(const ProgramSelector& sel);
+
+bool hasAmFmFrequency(const ProgramSelector& sel);
+
+uint32_t getAmFmFrequency(const ProgramSelector& sel);
+
template <typename aidl_type>
inline std::string vectorToString(const std::vector<aidl_type>& in_values) {
return std::accumulate(std::begin(in_values), std::end(in_values), std::string{},
diff --git a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/UtilsV2.h b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/UtilsV2.h
index e411aa4..734758d 100644
--- a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/UtilsV2.h
+++ b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/UtilsV2.h
@@ -28,6 +28,7 @@
bool isValidV2(const ProgramIdentifier& id);
bool isValidV2(const ProgramSelector& sel);
+bool isValidMetadataV2(const Metadata& metadata);
std::optional<std::string> getMetadataStringV2(const ProgramInfo& info, const Metadata::Tag& tag);
} // namespace utils
diff --git a/broadcastradio/common/utilsaidl/src/Utils.cpp b/broadcastradio/common/utilsaidl/src/Utils.cpp
index 2875318..ddc5b8d 100644
--- a/broadcastradio/common/utilsaidl/src/Utils.cpp
+++ b/broadcastradio/common/utilsaidl/src/Utils.cpp
@@ -49,12 +49,6 @@
return getId(a, type) == getId(b, type);
}
-int getHdSubchannel(const ProgramSelector& sel) {
- int64_t hdSidExt = getId(sel, IdentifierType::HD_STATION_ID_EXT, /* defaultValue */ 0);
- hdSidExt >>= 32; // Station ID number
- return hdSidExt & 0xF; // HD Radio subchannel
-}
-
bool maybeGetId(const ProgramSelector& sel, const IdentifierType& type, int64_t* val) {
// iterate through primaryId and secondaryIds
for (auto it = begin(sel); it != end(sel); it++) {
@@ -132,8 +126,13 @@
case IdentifierType::AMFM_FREQUENCY_KHZ:
if (haveEqualIds(a, b, IdentifierType::HD_STATION_ID_EXT)) return true;
if (haveEqualIds(a, b, IdentifierType::RDS_PI)) return true;
- return getHdSubchannel(b) == 0 &&
- haveEqualIds(a, b, IdentifierType::AMFM_FREQUENCY_KHZ);
+ if (getHdSubchannel(b) != 0) { // supplemental program services
+ return false;
+ }
+ return haveEqualIds(a, b, IdentifierType::AMFM_FREQUENCY_KHZ) ||
+ (b.primaryId.type == IdentifierType::HD_STATION_ID_EXT &&
+ static_cast<uint32_t>(getId(a, IdentifierType::AMFM_FREQUENCY_KHZ)) ==
+ getAmFmFrequency(b));
case IdentifierType::DAB_SID_EXT:
if (!haveEqualIds(a, b, IdentifierType::DAB_SID_EXT)) {
return false;
@@ -316,6 +315,13 @@
return sel;
}
+ProgramSelector makeSelectorHd(uint64_t stationId, uint64_t subChannel, uint64_t frequency) {
+ ProgramSelector sel = {};
+ uint64_t sidExt = stationId | (subChannel << 32) | (frequency << 36);
+ sel.primaryId = makeIdentifier(IdentifierType::HD_STATION_ID_EXT, sidExt);
+ return sel;
+}
+
ProgramSelector makeSelectorDab(uint64_t sidExt, uint32_t ensemble, uint64_t freq) {
ProgramSelector sel = {};
sel.primaryId = makeIdentifier(IdentifierType::DAB_SID_EXT, sidExt);
@@ -349,6 +355,55 @@
return true;
}
+bool ProgramSelectorComparator::operator()(const ProgramSelector& lhs,
+ const ProgramSelector& rhs) const {
+ if ((utils::hasId(lhs, IdentifierType::AMFM_FREQUENCY_KHZ) ||
+ lhs.primaryId.type == IdentifierType::HD_STATION_ID_EXT) &&
+ (utils::hasId(rhs, IdentifierType::AMFM_FREQUENCY_KHZ) ||
+ rhs.primaryId.type == IdentifierType::HD_STATION_ID_EXT)) {
+ uint32_t freq1 = utils::getAmFmFrequency(lhs);
+ int subChannel1 = lhs.primaryId.type == IdentifierType::HD_STATION_ID_EXT
+ ? utils::getHdSubchannel(lhs)
+ : 0;
+ uint32_t freq2 = utils::getAmFmFrequency(rhs);
+ int subChannel2 = rhs.primaryId.type == IdentifierType::HD_STATION_ID_EXT
+ ? utils::getHdSubchannel(rhs)
+ : 0;
+ return freq1 < freq2 || (freq1 == freq2 && (lhs.primaryId.type < rhs.primaryId.type ||
+ subChannel1 < subChannel2));
+ }
+ if (lhs.primaryId.type == IdentifierType::DAB_SID_EXT &&
+ rhs.primaryId.type == IdentifierType::DAB_SID_EXT) {
+ uint64_t dabFreq1 = utils::getId(lhs, IdentifierType::DAB_FREQUENCY_KHZ);
+ uint64_t dabFreq2 = utils::getId(rhs, IdentifierType::DAB_FREQUENCY_KHZ);
+ if (dabFreq1 != dabFreq2) {
+ return dabFreq1 < dabFreq2;
+ }
+ uint32_t ecc1 = utils::getDabEccCode(lhs);
+ uint32_t ecc2 = utils::getDabEccCode(rhs);
+ if (ecc1 != ecc2) {
+ return ecc1 < ecc2;
+ }
+ uint64_t dabEnsemble1 = utils::getId(lhs, IdentifierType::DAB_ENSEMBLE);
+ uint64_t dabEnsemble2 = utils::getId(rhs, IdentifierType::DAB_ENSEMBLE);
+ if (dabEnsemble1 != dabEnsemble2) {
+ return dabEnsemble1 < dabEnsemble2;
+ }
+ uint32_t sId1 = utils::getDabSId(lhs);
+ uint32_t sId2 = utils::getDabSId(rhs);
+ return sId1 < sId2 || (sId1 == sId2 && utils::getDabSCIdS(lhs) < utils::getDabSCIdS(rhs));
+ }
+
+ if (lhs.primaryId.type != rhs.primaryId.type) {
+ return lhs.primaryId.type < rhs.primaryId.type;
+ }
+ return lhs.primaryId.value < rhs.primaryId.value;
+}
+
+bool ProgramInfoComparator::operator()(const ProgramInfo& lhs, const ProgramInfo& rhs) const {
+ return ProgramSelectorComparator()(lhs.selector, rhs.selector);
+}
+
size_t ProgramInfoHasher::operator()(const ProgramInfo& info) const {
const ProgramIdentifier& id = info.selector.primaryId;
@@ -387,9 +442,9 @@
}
std::optional<std::string> getMetadataString(const ProgramInfo& info, const Metadata::Tag& tag) {
- auto isRdsPs = [tag](const Metadata& item) { return item.getTag() == tag; };
+ auto hasMetadataType = [tag](const Metadata& item) { return item.getTag() == tag; };
- auto it = std::find_if(info.metadata.begin(), info.metadata.end(), isRdsPs);
+ auto it = std::find_if(info.metadata.begin(), info.metadata.end(), hasMetadataType);
if (it == info.metadata.end()) {
return std::nullopt;
}
@@ -483,6 +538,86 @@
return static_cast<IdentifierType>(typeAsInt);
}
+uint32_t getDabSId(const ProgramSelector& sel) {
+ int64_t dabSidExt = getId(sel, IdentifierType::DAB_SID_EXT, /* defaultValue */ 0);
+ return static_cast<uint32_t>(dabSidExt & 0xFFFFFFFF);
+}
+
+int getDabEccCode(const ProgramSelector& sel) {
+ int64_t dabSidExt = getId(sel, IdentifierType::DAB_SID_EXT, /* defaultValue */ 0);
+ return static_cast<uint32_t>((dabSidExt >> 32) & 0xFF);
+}
+
+int getDabSCIdS(const ProgramSelector& sel) {
+ int64_t dabSidExt = getId(sel, IdentifierType::DAB_SID_EXT, /* defaultValue */ 0);
+ return static_cast<uint32_t>((dabSidExt >> 40) & 0xF);
+}
+
+int getHdSubchannel(const ProgramSelector& sel) {
+ int64_t hdSidExt = getId(sel, IdentifierType::HD_STATION_ID_EXT, kValueForNotFoundIdentifier);
+ hdSidExt >>= 32; // Station ID number
+ return hdSidExt & 0xF; // HD Radio subchannel
+}
+
+uint32_t getHdFrequency(const ProgramSelector& sel) {
+ int64_t hdSidExt = getId(sel, IdentifierType::HD_STATION_ID_EXT, kValueForNotFoundIdentifier);
+ if (hdSidExt == kValueForNotFoundIdentifier) {
+ return kValueForNotFoundIdentifier;
+ }
+ return static_cast<uint32_t>((hdSidExt >> 36) & 0x3FFFF); // HD Radio subchannel
+}
+
+bool hasAmFmFrequency(const ProgramSelector& sel) {
+ return hasId(sel, IdentifierType::AMFM_FREQUENCY_KHZ) ||
+ sel.primaryId.type == IdentifierType::HD_STATION_ID_EXT;
+}
+
+uint32_t getAmFmFrequency(const ProgramSelector& sel) {
+ if (hasId(sel, IdentifierType::AMFM_FREQUENCY_KHZ)) {
+ return static_cast<uint32_t>(getId(sel, IdentifierType::AMFM_FREQUENCY_KHZ));
+ }
+ return getHdFrequency(sel);
+}
+
+bool isValidMetadata(const Metadata& metadata) {
+ bool valid = true;
+
+ auto expect = [&valid](bool condition, const std::string& message) {
+ if (!condition) {
+ valid = false;
+ LOG(ERROR) << "metadata not valid, expected " << message;
+ }
+ };
+
+ switch (metadata.getTag()) {
+ case Metadata::rdsPty:
+ expect(metadata.get<Metadata::rdsPty>() >= 0, "RDS PTY >= 0");
+ expect(metadata.get<Metadata::rdsPty>() <= std::numeric_limits<uint8_t>::max(),
+ "8bit RDS PTY");
+ break;
+ case Metadata::rbdsPty:
+ expect(metadata.get<Metadata::rbdsPty>() >= 0, "RBDS PTY >= 0");
+ expect(metadata.get<Metadata::rbdsPty>() <= std::numeric_limits<uint8_t>::max(),
+ "8bit RBDS PTY");
+ break;
+ case Metadata::dabEnsembleNameShort:
+ expect(metadata.get<Metadata::dabEnsembleNameShort>().size() <= 8,
+ "Dab ensemble name abbreviated length <= 8");
+ break;
+ case Metadata::dabServiceNameShort:
+ expect(metadata.get<Metadata::dabServiceNameShort>().size() <= 8,
+ "Dab component name abbreviated length <= 8");
+ break;
+ case Metadata::dabComponentNameShort:
+ expect(metadata.get<Metadata::dabComponentNameShort>().size() <= 8,
+ "Dab component name abbreviated length <= 8");
+ break;
+ default:
+ break;
+ }
+ return valid;
+}
+
bool parseArgInt(const std::string& s, int* out) {
return ::android::base::ParseInt(s, out);
}
diff --git a/broadcastradio/common/utilsaidl/src/UtilsV2.cpp b/broadcastradio/common/utilsaidl/src/UtilsV2.cpp
index ef739df..6c75759 100644
--- a/broadcastradio/common/utilsaidl/src/UtilsV2.cpp
+++ b/broadcastradio/common/utilsaidl/src/UtilsV2.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "BcRadioAidlDef.utilsV2"
#include "broadcastradio-utils-aidl/UtilsV2.h"
+#include "broadcastradio-utils-aidl/Utils.h"
#include <android-base/logging.h>
#include <android-base/strings.h>
@@ -137,10 +138,33 @@
return isValidV2(sel.primaryId);
}
-std::optional<std::string> getMetadataStringV2(const ProgramInfo& info, const Metadata::Tag& tag) {
- auto isRdsPs = [tag](const Metadata& item) { return item.getTag() == tag; };
+bool isValidMetadataV2(const Metadata& metadata) {
+ if (!isValidMetadata(metadata)) {
+ return false;
+ }
- auto it = std::find_if(info.metadata.begin(), info.metadata.end(), isRdsPs);
+ if (metadata.getTag() == Metadata::hdStationNameShort) {
+ if (metadata.get<Metadata::hdStationNameShort>().size() > 12) {
+ LOG(ERROR) << "metadata not valid, expected HD short name length <= 12";
+ return false;
+ }
+ } else if (metadata.getTag() == Metadata::hdSubChannelsAvailable) {
+ if (metadata.get<Metadata::hdSubChannelsAvailable>() < 0) {
+ LOG(ERROR) << "metadata not valid, expected HD subchannels available >= 0";
+ return false;
+ } else if (metadata.get<Metadata::hdSubChannelsAvailable>() >
+ std::numeric_limits<uint8_t>::max()) {
+ LOG(ERROR) << "metadata not valid, expected 8bit HD subchannels available";
+ return false;
+ }
+ }
+ return true;
+}
+
+std::optional<std::string> getMetadataStringV2(const ProgramInfo& info, const Metadata::Tag& tag) {
+ auto hasMetadataType = [tag](const Metadata& item) { return item.getTag() == tag; };
+
+ auto it = std::find_if(info.metadata.begin(), info.metadata.end(), hasMetadataType);
if (it == info.metadata.end()) {
return std::nullopt;
}
diff --git a/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsTest.cpp b/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsTest.cpp
new file mode 100644
index 0000000..a5c9073
--- /dev/null
+++ b/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsTest.cpp
@@ -0,0 +1,811 @@
+/*
+ * 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.
+ */
+
+#include <broadcastradio-utils-aidl/Utils.h>
+#include <gtest/gtest.h>
+
+namespace aidl::android::hardware::broadcastradio {
+
+namespace {
+constexpr int64_t kFmFrequencyKHz = 97900;
+constexpr uint32_t kDabSid = 0x0000C221u;
+constexpr int kDabEccCode = 0xE1u;
+constexpr int kDabSCIdS = 0x1u;
+constexpr uint64_t kDabSidExt = static_cast<uint64_t>(kDabSid) |
+ (static_cast<uint64_t>(kDabEccCode) << 32) |
+ (static_cast<uint64_t>(kDabSCIdS) << 40);
+constexpr uint32_t kDabEnsemble = 0xCE15u;
+constexpr uint64_t kDabFrequencyKhz = 225648u;
+constexpr uint64_t kHdStationId = 0xA0000001u;
+constexpr uint64_t kHdSubChannel = 1u;
+constexpr uint64_t kHdFrequency = 97700u;
+constexpr int64_t kRdsValue = 0xBEEF;
+
+const Properties kAmFmTunerProp = {
+ .maker = "makerTest",
+ .product = "productTest",
+ .supportedIdentifierTypes = {IdentifierType::AMFM_FREQUENCY_KHZ, IdentifierType::RDS_PI,
+ IdentifierType::HD_STATION_ID_EXT}};
+
+struct GetBandTestCase {
+ std::string name;
+ int64_t frequency;
+ utils::FrequencyBand bandResult;
+};
+
+std::vector<GetBandTestCase> getBandTestCases() {
+ return std::vector<GetBandTestCase>(
+ {GetBandTestCase{.name = "unknown_low_band",
+ .frequency = 0,
+ .bandResult = utils::FrequencyBand::UNKNOWN},
+ GetBandTestCase{.name = "am_lw_band",
+ .frequency = 30,
+ .bandResult = utils::FrequencyBand::AM_LW},
+ GetBandTestCase{.name = "am_mw_band",
+ .frequency = 700,
+ .bandResult = utils::FrequencyBand::AM_MW},
+ GetBandTestCase{.name = "am_sw_band",
+ .frequency = 2000,
+ .bandResult = utils::FrequencyBand::AM_SW},
+ GetBandTestCase{
+ .name = "fm_band", .frequency = 97900, .bandResult = utils::FrequencyBand::FM},
+ GetBandTestCase{.name = "unknown_high_band",
+ .frequency = 110000,
+ .bandResult = utils::FrequencyBand::UNKNOWN}});
+}
+
+struct IsValidIdentifierTestCase {
+ std::string name;
+ ProgramIdentifier id;
+ bool valid;
+};
+
+std::vector<IsValidIdentifierTestCase> getIsValidIdentifierTestCases() {
+ return std::vector<IsValidIdentifierTestCase>({
+ IsValidIdentifierTestCase{.name = "invalid_id_type",
+ .id = utils::makeIdentifier(IdentifierType::INVALID, 0),
+ .valid = false},
+ IsValidIdentifierTestCase{
+ .name = "invalid_dab_frequency_high",
+ .id = utils::makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ, 10000000u),
+ .valid = false},
+ IsValidIdentifierTestCase{
+ .name = "invalid_dab_frequency_low",
+ .id = utils::makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ, 100000u),
+ .valid = false},
+ IsValidIdentifierTestCase{
+ .name = "valid_dab_frequency",
+ .id = utils::makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ, 1000000u),
+ .valid = true},
+ IsValidIdentifierTestCase{
+ .name = "invalid_am_fm_frequency_high",
+ .id = utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, 10000000u),
+ .valid = false},
+ IsValidIdentifierTestCase{
+ .name = "invalid_am_fm_frequency_low",
+ .id = utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, 100u),
+ .valid = false},
+ IsValidIdentifierTestCase{.name = "valid_am_fm_frequency",
+ .id = utils::makeIdentifier(
+ IdentifierType::AMFM_FREQUENCY_KHZ, kFmFrequencyKHz),
+ .valid = true},
+ IsValidIdentifierTestCase{
+ .name = "drmo_frequency_high",
+ .id = utils::makeIdentifier(IdentifierType::DRMO_FREQUENCY_KHZ, 10000000u),
+ .valid = false},
+ IsValidIdentifierTestCase{
+ .name = "drmo_frequency_low",
+ .id = utils::makeIdentifier(IdentifierType::DRMO_FREQUENCY_KHZ, 100u),
+ .valid = false},
+ IsValidIdentifierTestCase{.name = "valid_drmo_frequency",
+ .id = utils::makeIdentifier(
+ IdentifierType::DRMO_FREQUENCY_KHZ, kFmFrequencyKHz),
+ .valid = true},
+ IsValidIdentifierTestCase{.name = "invalid_rds_low",
+ .id = utils::makeIdentifier(IdentifierType::RDS_PI, 0x0),
+ .valid = false},
+ IsValidIdentifierTestCase{.name = "invalid_rds_high",
+ .id = utils::makeIdentifier(IdentifierType::RDS_PI, 0x10000),
+ .valid = false},
+ IsValidIdentifierTestCase{.name = "valid_rds",
+ .id = utils::makeIdentifier(IdentifierType::RDS_PI, 0x1000),
+ .valid = true},
+ IsValidIdentifierTestCase{
+ .name = "invalid_hd_id_zero",
+ .id = utils::makeSelectorHd(/* stationId= */ 0u, kHdSubChannel, kHdFrequency)
+ .primaryId,
+ .valid = false},
+ IsValidIdentifierTestCase{
+ .name = "invalid_hd_suchannel",
+ .id = utils::makeSelectorHd(kHdStationId, /* subChannel= */ 8u, kHdFrequency)
+ .primaryId,
+ .valid = false},
+ IsValidIdentifierTestCase{
+ .name = "invalid_hd_frequency_low",
+ .id = utils::makeSelectorHd(kHdStationId, kHdSubChannel, /* frequency= */ 100u)
+ .primaryId,
+ .valid = false},
+ IsValidIdentifierTestCase{
+ .name = "valid_hd_id",
+ .id = utils::makeSelectorHd(kHdStationId, kHdSubChannel, kHdFrequency)
+ .primaryId,
+ .valid = true},
+ IsValidIdentifierTestCase{
+ .name = "invalid_hd_station_name",
+ .id = utils::makeIdentifier(IdentifierType::HD_STATION_NAME, 0x41422D464D),
+ .valid = false},
+ IsValidIdentifierTestCase{
+ .name = "valid_hd_station_name",
+ .id = utils::makeIdentifier(IdentifierType::HD_STATION_NAME, 0x414231464D),
+ .valid = true},
+ IsValidIdentifierTestCase{
+ .name = "invalid_dab_sid",
+ .id = utils::makeIdentifier(IdentifierType::DAB_SID_EXT, 0x0E100000000u),
+ .valid = false},
+ IsValidIdentifierTestCase{
+ .name = "invalid_dab_ecc_low",
+ .id = utils::makeIdentifier(IdentifierType::DAB_SID_EXT, 0x0F700000221u),
+ .valid = false},
+ IsValidIdentifierTestCase{
+ .name = "invalid_dab_ecc_high",
+ .id = utils::makeIdentifier(IdentifierType::DAB_SID_EXT, 0x09900000221u),
+ .valid = false},
+ IsValidIdentifierTestCase{
+ .name = "valid_dab_sid_ext",
+ .id = utils::makeIdentifier(IdentifierType::DAB_SID_EXT, kDabSidExt),
+ .valid = true},
+ IsValidIdentifierTestCase{
+ .name = "invalid_dab_ensemble_zero",
+ .id = utils::makeIdentifier(IdentifierType::DAB_ENSEMBLE, 0x0),
+ .valid = false},
+ IsValidIdentifierTestCase{
+ .name = "invalid_dab_ensemble_high",
+ .id = utils::makeIdentifier(IdentifierType::DAB_ENSEMBLE, 0x10000),
+ .valid = false},
+ IsValidIdentifierTestCase{
+ .name = "valid_dab_ensemble",
+ .id = utils::makeIdentifier(IdentifierType::DAB_ENSEMBLE, kDabEnsemble),
+ .valid = true},
+ IsValidIdentifierTestCase{.name = "invalid_dab_scid_low",
+ .id = utils::makeIdentifier(IdentifierType::DAB_SCID, 0xF),
+ .valid = false},
+ IsValidIdentifierTestCase{.name = "invalid_dab_scid_high",
+ .id = utils::makeIdentifier(IdentifierType::DAB_SCID, 0x1000),
+ .valid = false},
+ IsValidIdentifierTestCase{.name = "valid_dab_scid",
+ .id = utils::makeIdentifier(IdentifierType::DAB_SCID, 0x100),
+ .valid = true},
+ IsValidIdentifierTestCase{
+ .name = "invalid_drmo_id_zero",
+ .id = utils::makeIdentifier(IdentifierType::DRMO_SERVICE_ID, 0x0),
+ .valid = false},
+ IsValidIdentifierTestCase{
+ .name = "invalid_drmo_id_high",
+ .id = utils::makeIdentifier(IdentifierType::DRMO_SERVICE_ID, 0x1000000),
+ .valid = false},
+ IsValidIdentifierTestCase{
+ .name = "valid_drmo_id",
+ .id = utils::makeIdentifier(IdentifierType::DRMO_SERVICE_ID, 0x100000),
+ .valid = true},
+ });
+}
+
+struct IsValidSelectorTestCase {
+ std::string name;
+ ProgramSelector sel;
+ bool valid;
+};
+
+std::vector<IsValidSelectorTestCase> getIsValidSelectorTestCases() {
+ return std::vector<IsValidSelectorTestCase>({
+ IsValidSelectorTestCase{.name = "valid_am_fm_selector",
+ .sel = utils::makeSelectorAmfm(kFmFrequencyKHz),
+ .valid = true},
+ IsValidSelectorTestCase{
+ .name = "valid_hd_selector",
+ .sel = utils::makeSelectorHd(kHdStationId, kHdSubChannel, kHdFrequency),
+ .valid = true},
+ IsValidSelectorTestCase{
+ .name = "valid_dab_selector",
+ .sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz),
+ .valid = true},
+ IsValidSelectorTestCase{.name = "valid_rds_selector",
+ .sel = ProgramSelector{.primaryId = utils::makeIdentifier(
+ IdentifierType::RDS_PI, 0x1000)},
+ .valid = true},
+ IsValidSelectorTestCase{.name = "selector_with_invalid_id",
+ .sel = utils::makeSelectorHd(kHdStationId, kHdSubChannel,
+ /* frequency= */ 100u),
+ .valid = false},
+ IsValidSelectorTestCase{
+ .name = "selector_with_invalid_primary_id_type",
+ .sel = ProgramSelector{.primaryId = utils::makeIdentifier(
+ IdentifierType::DAB_ENSEMBLE, kDabEnsemble)},
+ .valid = false},
+ });
+}
+
+struct IsValidMetadataTestCase {
+ std::string name;
+ Metadata metadata;
+ bool valid;
+};
+
+std::vector<IsValidMetadataTestCase> getIsValidMetadataTestCases() {
+ return std::vector<IsValidMetadataTestCase>({
+ IsValidMetadataTestCase{.name = "valid_rds_pty",
+ .metadata = Metadata::make<Metadata::rdsPty>(1),
+ .valid = true},
+ IsValidMetadataTestCase{.name = "negative_rds_pty",
+ .metadata = Metadata::make<Metadata::rdsPty>(-1),
+ .valid = false},
+ IsValidMetadataTestCase{.name = "large_rds_pty",
+ .metadata = Metadata::make<Metadata::rdsPty>(256),
+ .valid = false},
+ IsValidMetadataTestCase{.name = "valid_rbds_pty",
+ .metadata = Metadata::make<Metadata::rbdsPty>(1),
+ .valid = true},
+ IsValidMetadataTestCase{.name = "negative_rbds_pty",
+ .metadata = Metadata::make<Metadata::rbdsPty>(-1),
+ .valid = false},
+ IsValidMetadataTestCase{.name = "large_rbds_pty",
+ .metadata = Metadata::make<Metadata::rbdsPty>(256),
+ .valid = false},
+ IsValidMetadataTestCase{
+ .name = "valid_dab_ensemble_name_short",
+ .metadata = Metadata::make<Metadata::dabEnsembleNameShort>("name"),
+ .valid = true},
+ IsValidMetadataTestCase{
+ .name = "too_long_dab_ensemble_name_short",
+ .metadata = Metadata::make<Metadata::dabEnsembleNameShort>("name_long"),
+ .valid = false},
+ IsValidMetadataTestCase{
+ .name = "valid_dab_service_name_short",
+ .metadata = Metadata::make<Metadata::dabServiceNameShort>("name"),
+ .valid = true},
+ IsValidMetadataTestCase{
+ .name = "too_long_dab_service_name_short",
+ .metadata = Metadata::make<Metadata::dabServiceNameShort>("name_long"),
+ .valid = false},
+ IsValidMetadataTestCase{
+ .name = "valid_dab_component_name_short",
+ .metadata = Metadata::make<Metadata::dabComponentNameShort>("name"),
+ .valid = true},
+ IsValidMetadataTestCase{
+ .name = "too_long_dab_component_name_short",
+ .metadata = Metadata::make<Metadata::dabComponentNameShort>("name_long"),
+ .valid = false},
+ });
+}
+} // namespace
+
+class GetBandTest : public testing::TestWithParam<GetBandTestCase> {};
+
+INSTANTIATE_TEST_SUITE_P(GetBandTests, GetBandTest, testing::ValuesIn(getBandTestCases()),
+ [](const testing::TestParamInfo<GetBandTest::ParamType>& info) {
+ return info.param.name;
+ });
+
+TEST_P(GetBandTest, GetBand) {
+ GetBandTestCase testcase = GetParam();
+
+ ASSERT_EQ(utils::getBand(testcase.frequency), testcase.bandResult);
+}
+
+class IsValidMetadataTest : public testing::TestWithParam<IsValidMetadataTestCase> {};
+
+INSTANTIATE_TEST_SUITE_P(IsValidMetadataTests, IsValidMetadataTest,
+ testing::ValuesIn(getIsValidMetadataTestCases()),
+ [](const testing::TestParamInfo<IsValidMetadataTest::ParamType>& info) {
+ return info.param.name;
+ });
+
+TEST_P(IsValidMetadataTest, IsValidMetadata) {
+ IsValidMetadataTestCase testParam = GetParam();
+
+ ASSERT_EQ(utils::isValidMetadata(testParam.metadata), testParam.valid);
+}
+
+class IsValidIdentifierTest : public testing::TestWithParam<IsValidIdentifierTestCase> {};
+
+INSTANTIATE_TEST_SUITE_P(IsValidIdentifierTests, IsValidIdentifierTest,
+ testing::ValuesIn(getIsValidIdentifierTestCases()),
+ [](const testing::TestParamInfo<IsValidIdentifierTest::ParamType>& info) {
+ return info.param.name;
+ });
+
+TEST_P(IsValidIdentifierTest, IsValid) {
+ IsValidIdentifierTestCase testcase = GetParam();
+
+ ASSERT_EQ(utils::isValid(testcase.id), testcase.valid);
+}
+
+class IsValidSelectorTest : public testing::TestWithParam<IsValidSelectorTestCase> {};
+
+INSTANTIATE_TEST_SUITE_P(IsValidSelectorTests, IsValidSelectorTest,
+ testing::ValuesIn(getIsValidSelectorTestCases()),
+ [](const testing::TestParamInfo<IsValidSelectorTest::ParamType>& info) {
+ return info.param.name;
+ });
+
+TEST_P(IsValidSelectorTest, IsValid) {
+ IsValidSelectorTestCase testcase = GetParam();
+
+ ASSERT_EQ(utils::isValid(testcase.sel), testcase.valid);
+}
+
+TEST(BroadcastRadioUtilsTest, IdentifierIteratorBegin) {
+ ProgramSelector sel = {
+ .primaryId = utils::makeIdentifier(IdentifierType::RDS_PI, kRdsValue),
+ .secondaryIds = {
+ utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, kFmFrequencyKHz),
+ utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ,
+ kFmFrequencyKHz + 200)}};
+
+ utils::IdentifierIterator it = begin(sel);
+
+ utils::IdentifierIterator selEnd = end(sel);
+ ASSERT_NE(selEnd, it);
+ EXPECT_EQ(sel.primaryId, *it);
+}
+
+TEST(BroadcastRadioUtilsTest, IdentifierIteratorIncrement) {
+ ProgramSelector sel = {
+ .primaryId = utils::makeIdentifier(IdentifierType::RDS_PI, kRdsValue),
+ .secondaryIds = {
+ utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, kFmFrequencyKHz),
+ utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ,
+ kFmFrequencyKHz + 200)}};
+ utils::IdentifierIterator it = begin(sel);
+ utils::IdentifierIterator selEnd = end(sel);
+
+ ASSERT_NE(selEnd, ++it);
+ EXPECT_EQ(sel.secondaryIds[0], *it);
+ ASSERT_NE(selEnd, ++it);
+ EXPECT_EQ(sel.secondaryIds[1], *it);
+ ASSERT_EQ(selEnd, ++it);
+}
+
+TEST(BroadcastRadioUtilsTest, IdentifierIteratorIncrementWithValue) {
+ ProgramSelector sel = {
+ .primaryId = utils::makeIdentifier(IdentifierType::RDS_PI, kRdsValue),
+ .secondaryIds = {
+ utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, kFmFrequencyKHz),
+ utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ,
+ kFmFrequencyKHz + 200)}};
+ utils::IdentifierIterator it1 = begin(sel);
+ utils::IdentifierIterator it2 = it1;
+ it2++;
+ it2++;
+
+ ASSERT_EQ(it1 + 2, it2);
+}
+
+TEST(BroadcastRadioUtilsTest, IdentifierIteratorBeginEndWithoutSecondaryIds) {
+ ProgramSelector sel = {.primaryId = utils::makeIdentifier(IdentifierType::RDS_PI, kRdsValue)};
+
+ utils::IdentifierIterator it = begin(sel);
+ utils::IdentifierIterator selEnd = end(sel);
+
+ ASSERT_EQ(selEnd, ++it);
+}
+
+TEST(BroadcastRadioUtilsTest, IdentifierIteratorBeginEndWithDifferentObjects) {
+ ProgramSelector sel1 = utils::makeSelectorAmfm(kFmFrequencyKHz);
+ ProgramSelector sel2 = utils::makeSelectorAmfm(kFmFrequencyKHz);
+
+ utils::IdentifierIterator it1 = begin(sel1);
+ utils::IdentifierIterator it2 = begin(sel2);
+ utils::IdentifierIterator end1 = end(sel1);
+ utils::IdentifierIterator end2 = end(sel2);
+
+ ASSERT_NE(it1, it2);
+ ASSERT_NE(end1, end2);
+}
+
+TEST(BroadcastRadioUtilsTest, IdentifierIteratorBeginEndWithTheSameObject) {
+ ProgramSelector sel = utils::makeSelectorAmfm(kFmFrequencyKHz);
+
+ utils::IdentifierIterator it1 = begin(sel);
+ utils::IdentifierIterator it2 = begin(sel);
+ utils::IdentifierIterator end1 = end(sel);
+ utils::IdentifierIterator end2 = end(sel);
+
+ ASSERT_EQ(it1, it2);
+ ASSERT_EQ(end1, end2);
+}
+
+TEST(BroadcastRadioUtilsTest, IsSupportedWithSupportedSelector) {
+ ProgramSelector sel = utils::makeSelectorAmfm(kFmFrequencyKHz);
+
+ ASSERT_TRUE(utils::isSupported(kAmFmTunerProp, sel));
+}
+
+TEST(BroadcastRadioUtilsTest, IsSupportedWithUnsupportedSelector) {
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+ ASSERT_FALSE(utils::isSupported(kAmFmTunerProp, sel));
+}
+
+TEST(BroadcastRadioUtilsTest, GetBandWithFmFrequency) {
+ ProgramSelector sel = utils::makeSelectorAmfm(kFmFrequencyKHz);
+
+ ASSERT_TRUE(utils::hasId(sel, IdentifierType::AMFM_FREQUENCY_KHZ));
+}
+
+TEST(BroadcastRadioUtilsTest, HasIdWithPrimaryIdType) {
+ ProgramSelector sel = utils::makeSelectorAmfm(kFmFrequencyKHz);
+
+ ASSERT_TRUE(utils::hasId(sel, IdentifierType::AMFM_FREQUENCY_KHZ));
+}
+
+TEST(BroadcastRadioUtilsTest, HasIdWithSecondaryIdType) {
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+ ASSERT_TRUE(utils::hasId(sel, IdentifierType::DAB_FREQUENCY_KHZ));
+}
+
+TEST(BroadcastRadioUtilsTest, HasIdWithIdNotInSelector) {
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+ ASSERT_FALSE(utils::hasId(sel, IdentifierType::AMFM_FREQUENCY_KHZ));
+}
+
+TEST(BroadcastRadioUtilsTest, GetIdWithPrimaryIdType) {
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+ ASSERT_EQ(utils::getId(sel, IdentifierType::DAB_SID_EXT), static_cast<int64_t>(kDabSidExt));
+}
+
+TEST(BroadcastRadioUtilsTest, GetIdWithSecondaryIdType) {
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+ ASSERT_EQ(utils::getId(sel, IdentifierType::DAB_ENSEMBLE), static_cast<int64_t>(kDabEnsemble));
+}
+
+TEST(BroadcastRadioUtilsTest, GetIdWithIdNotFound) {
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+ ASSERT_EQ(utils::getId(sel, IdentifierType::AMFM_FREQUENCY_KHZ), 0);
+}
+
+TEST(BroadcastRadioUtilsTest, GetIdWithIdFoundAndDefaultValue) {
+ int64_t defaultValue = 0x0E10000C222u;
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+ ASSERT_EQ(utils::getId(sel, IdentifierType::DAB_SID_EXT, defaultValue),
+ static_cast<int64_t>(kDabSidExt));
+}
+
+TEST(BroadcastRadioUtilsTest, GetIdWithIdNotFoundAndDefaultValue) {
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+ ASSERT_EQ(utils::getId(sel, IdentifierType::AMFM_FREQUENCY_KHZ, kFmFrequencyKHz),
+ static_cast<int64_t>(kFmFrequencyKHz));
+}
+
+TEST(BroadcastRadioUtilsTest, GetAllIdsWithAvailableIds) {
+ int64_t secondaryFrequencyKHz = kFmFrequencyKHz + 200;
+ ProgramSelector sel = utils::makeSelectorAmfm(kFmFrequencyKHz);
+ sel.secondaryIds.push_back(
+ utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, secondaryFrequencyKHz));
+
+ std::vector<int> allIds = utils::getAllIds(sel, IdentifierType::AMFM_FREQUENCY_KHZ);
+
+ ASSERT_EQ(allIds.size(), 2u);
+ EXPECT_NE(std::find(allIds.begin(), allIds.end(), kFmFrequencyKHz), allIds.end());
+ EXPECT_NE(std::find(allIds.begin(), allIds.end(), secondaryFrequencyKHz), allIds.end());
+}
+
+TEST(BroadcastRadioUtilsTest, GetAllIdsWithIdNotFound) {
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+ ASSERT_TRUE(utils::getAllIds(sel, IdentifierType::AMFM_FREQUENCY_KHZ).empty());
+}
+
+TEST(BroadcastRadioUtilsTest, MakeIdentifier) {
+ ProgramIdentifier id =
+ utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, kFmFrequencyKHz);
+
+ EXPECT_EQ(id.type, IdentifierType::AMFM_FREQUENCY_KHZ);
+ EXPECT_EQ(id.value, kFmFrequencyKHz);
+}
+
+TEST(BroadcastRadioUtilsTest, MakeSelectorAmfm) {
+ ProgramSelector sel = utils::makeSelectorAmfm(kFmFrequencyKHz);
+
+ EXPECT_EQ(sel.primaryId.type, IdentifierType::AMFM_FREQUENCY_KHZ);
+ EXPECT_EQ(sel.primaryId.value, kFmFrequencyKHz);
+ EXPECT_TRUE(sel.secondaryIds.empty());
+}
+
+TEST(BroadcastRadioUtilsTest, MakeSelectorHd) {
+ ProgramSelector sel = utils::makeSelectorHd(kHdStationId, kHdSubChannel, kHdFrequency);
+
+ EXPECT_EQ(sel.primaryId.type, IdentifierType::HD_STATION_ID_EXT);
+ EXPECT_TRUE(sel.secondaryIds.empty());
+ EXPECT_EQ(utils::getHdSubchannel(sel), static_cast<int>(kHdSubChannel));
+ EXPECT_EQ(utils::getHdFrequency(sel), static_cast<uint32_t>(kHdFrequency));
+}
+
+TEST(BroadcastRadioUtilsTest, MakeHdRadioStationName) {
+ std::string stationName = "aB1-FM";
+ int64_t expectedIdValue = 0x4D46314241;
+
+ ProgramIdentifier stationNameId = utils::makeHdRadioStationName(stationName);
+
+ EXPECT_EQ(stationNameId.type, IdentifierType::HD_STATION_NAME);
+ EXPECT_EQ(stationNameId.value, expectedIdValue);
+}
+
+TEST(BroadcastRadioUtilsTest, GetHdFrequencyWithoutHdId) {
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+ ASSERT_EQ(utils::getHdFrequency(sel), 0u);
+}
+
+TEST(BroadcastRadioUtilsTest, HasAmFmFrequencyWithAmFmSelector) {
+ ProgramSelector sel = utils::makeSelectorAmfm(kFmFrequencyKHz);
+
+ ASSERT_TRUE(utils::hasAmFmFrequency(sel));
+}
+
+TEST(BroadcastRadioUtilsTest, HasAmFmFrequencyWithHdSelector) {
+ ProgramSelector sel = utils::makeSelectorHd(kHdStationId, kHdSubChannel, kHdFrequency);
+
+ ASSERT_TRUE(utils::hasAmFmFrequency(sel));
+}
+
+TEST(BroadcastRadioUtilsTest, HasAmFmFrequencyWithNonAmFmHdSelector) {
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+ ASSERT_FALSE(utils::hasAmFmFrequency(sel));
+}
+
+TEST(BroadcastRadioUtilsTest, GetAmFmFrequencyWithAmFmSelector) {
+ ProgramSelector sel = utils::makeSelectorAmfm(kFmFrequencyKHz);
+
+ ASSERT_EQ(utils::getAmFmFrequency(sel), static_cast<uint32_t>(kFmFrequencyKHz));
+}
+
+TEST(BroadcastRadioUtilsTest, GetAmFmFrequencyWithHdSelector) {
+ ProgramSelector sel = utils::makeSelectorHd(kHdStationId, kHdSubChannel, kHdFrequency);
+
+ ASSERT_EQ(utils::getAmFmFrequency(sel), static_cast<uint32_t>(kHdFrequency));
+}
+
+TEST(BroadcastRadioUtilsTest, GetAmFmFrequencyWithNonAmFmHdSelector) {
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+ ASSERT_EQ(utils::getAmFmFrequency(sel), 0u);
+}
+
+TEST(BroadcastRadioUtilsTest, MakeSelectorDabWithOnlySidExt) {
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt);
+
+ EXPECT_EQ(sel.primaryId.type, IdentifierType::DAB_SID_EXT);
+ EXPECT_EQ(sel.primaryId.value, static_cast<int64_t>(kDabSidExt));
+ EXPECT_TRUE(sel.secondaryIds.empty());
+}
+
+TEST(BroadcastRadioUtilsTest, MakeSelectorDab) {
+ ProgramIdentifier ensembleIdExpected =
+ utils::makeIdentifier(IdentifierType::DAB_ENSEMBLE, kDabEnsemble);
+ ProgramIdentifier frequencyIdExpected =
+ utils::makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ, kDabFrequencyKhz);
+
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+ EXPECT_EQ(sel.primaryId.type, IdentifierType::DAB_SID_EXT);
+ EXPECT_EQ(sel.primaryId.value, static_cast<int64_t>(kDabSidExt));
+ EXPECT_EQ(sel.secondaryIds.size(), 2u);
+ EXPECT_NE(std::find(sel.secondaryIds.begin(), sel.secondaryIds.end(), ensembleIdExpected),
+ sel.secondaryIds.end());
+ EXPECT_NE(std::find(sel.secondaryIds.begin(), sel.secondaryIds.end(), frequencyIdExpected),
+ sel.secondaryIds.end());
+}
+
+TEST(BroadcastRadioUtilsTest, GetDabSId) {
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+ ASSERT_EQ(utils::getDabSId(sel), kDabSid);
+}
+
+TEST(BroadcastRadioUtilsTest, GetDabEccCode) {
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+ ASSERT_EQ(utils::getDabEccCode(sel), kDabEccCode);
+}
+
+TEST(BroadcastRadioUtilsTest, GetDabSCIdS) {
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+ ASSERT_EQ(utils::getDabSCIdS(sel), kDabSCIdS);
+}
+
+TEST(BroadcastRadioUtilsTest, TunesToWithTheSameHdSelector) {
+ ProgramSelector sel = utils::makeSelectorHd(kHdStationId, kHdSubChannel, kHdFrequency);
+ ProgramSelector selTarget = utils::makeSelectorHd(kHdStationId, kHdSubChannel, kHdFrequency);
+
+ ASSERT_TRUE(utils::tunesTo(sel, selTarget));
+}
+
+TEST(BroadcastRadioUtilsTest, TunesToAmFmSelectorWithDifferentSubChannels) {
+ ProgramSelector sel = utils::makeSelectorHd(kHdStationId, kHdSubChannel, kHdFrequency);
+ ProgramSelector selTarget = utils::makeSelectorAmfm(kHdFrequency);
+
+ ASSERT_FALSE(utils::tunesTo(sel, selTarget));
+}
+
+TEST(BroadcastRadioUtilsTest, TunesToMainHdChannelWithDifferentSubChannels) {
+ ProgramSelector sel = utils::makeSelectorAmfm(kHdFrequency);
+ ProgramSelector selTarget =
+ utils::makeSelectorHd(kHdStationId, /* subChannel= */ 0, kHdFrequency);
+
+ ASSERT_TRUE(utils::tunesTo(sel, selTarget));
+}
+
+TEST(BroadcastRadioUtilsTest, TunesToWithTheSameAmFmSelector) {
+ ProgramSelector sel = utils::makeSelectorAmfm(kFmFrequencyKHz);
+ ProgramSelector selTarget = utils::makeSelectorAmfm(kFmFrequencyKHz);
+
+ ASSERT_TRUE(utils::tunesTo(sel, selTarget));
+}
+
+TEST(BroadcastRadioUtilsTest, TunesToWithDifferentFrequencies) {
+ ProgramSelector sel = utils::makeSelectorAmfm(kFmFrequencyKHz);
+ ProgramSelector selTarget = utils::makeSelectorAmfm(kFmFrequencyKHz + 200);
+
+ ASSERT_FALSE(utils::tunesTo(sel, selTarget));
+}
+
+TEST(BroadcastRadioUtilsTest, TunesToWithTheSameDabSelector) {
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+ ProgramSelector selTarget = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+ ASSERT_TRUE(utils::tunesTo(sel, selTarget));
+}
+
+TEST(BroadcastRadioUtilsTest, TunesToWithDabSelectorOfDifferentPrimaryIds) {
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt + 1, kDabEnsemble, kDabFrequencyKhz);
+ ProgramSelector selTarget = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+ ASSERT_FALSE(utils::tunesTo(sel, selTarget));
+}
+
+TEST(BroadcastRadioUtilsTest, TunesToWithDabSelectorOfDifferentSecondayIds) {
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble + 100, kDabFrequencyKhz);
+ ProgramSelector selTarget = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+ ASSERT_FALSE(utils::tunesTo(sel, selTarget));
+}
+
+TEST(BroadcastRadioUtilsTest, TunesToWithDabSelectorWithoutSecondaryIds) {
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt);
+ ProgramSelector selTarget = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+ ASSERT_TRUE(utils::tunesTo(sel, selTarget));
+}
+
+TEST(BroadcastRadioUtilsTest, SatisfiesWithSatisfiedIdTypesFilter) {
+ ProgramFilter filter = ProgramFilter{.identifierTypes = {IdentifierType::DAB_FREQUENCY_KHZ}};
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+ ASSERT_TRUE(utils::satisfies(filter, sel));
+}
+
+TEST(BroadcastRadioUtilsTest, SatisfiesWithUnsatisfiedIdTypesFilter) {
+ ProgramFilter filter = ProgramFilter{.identifierTypes = {IdentifierType::DAB_FREQUENCY_KHZ}};
+ ProgramSelector sel = utils::makeSelectorAmfm(kFmFrequencyKHz);
+
+ ASSERT_FALSE(utils::satisfies(filter, sel));
+}
+
+TEST(BroadcastRadioUtilsTest, SatisfiesWithSatisfiedIdsFilter) {
+ ProgramFilter filter =
+ ProgramFilter{.identifiers = {utils::makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ,
+ kDabFrequencyKhz)}};
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+ ASSERT_TRUE(utils::satisfies(filter, sel));
+}
+
+TEST(BroadcastRadioUtilsTest, SatisfiesWithUnsatisfiedIdsFilter) {
+ ProgramFilter filter =
+ ProgramFilter{.identifiers = {utils::makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ,
+ kDabFrequencyKhz)}};
+ ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz + 100);
+
+ ASSERT_FALSE(utils::satisfies(filter, sel));
+}
+
+TEST(BroadcastRadioUtilsTest, ProgramSelectorComparatorWithDifferentAmFmFrequencies) {
+ ProgramSelector sel1 = utils::makeSelectorAmfm(kHdFrequency - 200);
+ ProgramSelector sel2 = utils::makeSelectorHd(kHdStationId, kHdSubChannel, kHdFrequency);
+
+ EXPECT_TRUE(utils::ProgramSelectorComparator()(sel1, sel2));
+ EXPECT_FALSE(utils::ProgramSelectorComparator()(sel2, sel1));
+}
+
+TEST(BroadcastRadioUtilsTest, ProgramSelectorComparatorWithDifferentAmFmSubChannels) {
+ ProgramSelector sel1 = utils::makeSelectorHd(kHdStationId, kHdSubChannel, kHdFrequency);
+ ProgramSelector sel2 = utils::makeSelectorHd(kHdStationId, kHdSubChannel + 1, kHdFrequency);
+
+ EXPECT_TRUE(utils::ProgramSelectorComparator()(sel1, sel2));
+ EXPECT_FALSE(utils::ProgramSelectorComparator()(sel2, sel1));
+}
+
+TEST(BroadcastRadioUtilsTest, ProgramSelectorComparatorWithDifferentDabFrequencies) {
+ ProgramSelector sel1 = utils::makeSelectorDab(kDabSidExt + 100, kDabEnsemble, kDabFrequencyKhz);
+ ProgramSelector sel2 = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz + 100);
+
+ EXPECT_TRUE(utils::ProgramSelectorComparator()(sel1, sel2));
+ EXPECT_FALSE(utils::ProgramSelectorComparator()(sel2, sel1));
+}
+
+TEST(BroadcastRadioUtilsTest, ProgramSelectorComparatorWithDifferentDabEccCode) {
+ ProgramSelector sel1 =
+ utils::makeSelectorDab(/* stationId= */ 0x0E10000C221u, kDabEnsemble, kDabFrequencyKhz);
+ ProgramSelector sel2 =
+ utils::makeSelectorDab(/* stationId= */ 0x0E20000C221u, kDabEnsemble, kDabFrequencyKhz);
+
+ EXPECT_TRUE(utils::ProgramSelectorComparator()(sel1, sel2));
+ EXPECT_FALSE(utils::ProgramSelectorComparator()(sel2, sel1));
+}
+
+TEST(BroadcastRadioUtilsTest, ProgramSelectorComparatorWithDifferentDabEnsembles) {
+ ProgramSelector sel1 = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+ ProgramSelector sel2 = utils::makeSelectorDab(kDabSidExt, kDabEnsemble + 1, kDabFrequencyKhz);
+
+ EXPECT_TRUE(utils::ProgramSelectorComparator()(sel1, sel2));
+ EXPECT_FALSE(utils::ProgramSelectorComparator()(sel2, sel1));
+}
+
+TEST(BroadcastRadioUtilsTest, ProgramSelectorComparatorWithDifferentDabSid) {
+ ProgramSelector sel1 =
+ utils::makeSelectorDab(/* stationId= */ 0x0E10000C221u, kDabEnsemble, kDabFrequencyKhz);
+ ProgramSelector sel2 =
+ utils::makeSelectorDab(/* stationId= */ 0x0E10000C222u, kDabEnsemble, kDabFrequencyKhz);
+
+ EXPECT_TRUE(utils::ProgramSelectorComparator()(sel1, sel2));
+ EXPECT_FALSE(utils::ProgramSelectorComparator()(sel2, sel1));
+}
+
+TEST(BroadcastRadioUtilsTest, ProgramSelectorComparatorWithDifferentDabSCIdS) {
+ ProgramSelector sel1 =
+ utils::makeSelectorDab(/* stationId= */ 0x0E10000C221u, kDabEnsemble, kDabFrequencyKhz);
+ ProgramSelector sel2 =
+ utils::makeSelectorDab(/* stationId= */ 0x1E10000C221u, kDabEnsemble, kDabFrequencyKhz);
+
+ EXPECT_TRUE(utils::ProgramSelectorComparator()(sel1, sel2));
+ EXPECT_FALSE(utils::ProgramSelectorComparator()(sel2, sel1));
+}
+
+TEST(BroadcastRadioUtilsTest, ProgramInfoComparator) {
+ ProgramSelector sel1 = utils::makeSelectorAmfm(kFmFrequencyKHz);
+ ProgramSelector sel2 = utils::makeSelectorAmfm(kFmFrequencyKHz + 200);
+ ProgramInfo info1 = {.selector = sel1,
+ .logicallyTunedTo = sel1.primaryId,
+ .physicallyTunedTo = sel1.primaryId};
+ ProgramInfo info2 = {.selector = sel2,
+ .logicallyTunedTo = sel2.primaryId,
+ .physicallyTunedTo = sel2.primaryId};
+
+ EXPECT_TRUE(utils::ProgramInfoComparator()(info1, info2));
+ EXPECT_FALSE(utils::ProgramInfoComparator()(info2, info1));
+}
+
+} // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsV2Test.cpp b/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsV2Test.cpp
new file mode 100644
index 0000000..cf9f9e9
--- /dev/null
+++ b/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsV2Test.cpp
@@ -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.
+ */
+
+#include <broadcastradio-utils-aidl/UtilsV2.h>
+#include <gtest/gtest.h>
+
+namespace aidl::android::hardware::broadcastradio {
+
+namespace {
+struct IsValidMetadataV2TestCase {
+ std::string name;
+ Metadata metadata;
+ bool valid;
+};
+
+std::vector<IsValidMetadataV2TestCase> getIsValidMetadataV2TestCases() {
+ return std::vector<IsValidMetadataV2TestCase>({
+ IsValidMetadataV2TestCase{.name = "valid_rds_pty",
+ .metadata = Metadata::make<Metadata::rdsPty>(1),
+ .valid = true},
+ IsValidMetadataV2TestCase{.name = "negative_rds_pty",
+ .metadata = Metadata::make<Metadata::rdsPty>(-1),
+ .valid = false},
+ IsValidMetadataV2TestCase{
+ .name = "valid_hd_station_name_short",
+ .metadata = Metadata::make<Metadata::hdStationNameShort>("name_short"),
+ .valid = true},
+ IsValidMetadataV2TestCase{
+ .name = "too_long_hd_station_name_short",
+ .metadata = Metadata::make<Metadata::hdStationNameShort>("name_too_long"),
+ .valid = false},
+ IsValidMetadataV2TestCase{
+ .name = "valid_hd_subchannel_available",
+ .metadata = Metadata::make<Metadata::hdSubChannelsAvailable>(1),
+ .valid = true},
+ IsValidMetadataV2TestCase{
+ .name = "negative_subchannel_available",
+ .metadata = Metadata::make<Metadata::hdSubChannelsAvailable>(-1),
+ .valid = false},
+ IsValidMetadataV2TestCase{
+ .name = "large_subchannel_available",
+ .metadata = Metadata::make<Metadata::hdSubChannelsAvailable>(256),
+ .valid = false},
+ });
+}
+} // namespace
+
+class IsValidMetadataV2Test : public testing::TestWithParam<IsValidMetadataV2TestCase> {};
+
+INSTANTIATE_TEST_SUITE_P(IsValidMetadataV2Tests, IsValidMetadataV2Test,
+ testing::ValuesIn(getIsValidMetadataV2TestCases()),
+ [](const testing::TestParamInfo<IsValidMetadataV2Test::ParamType>& info) {
+ return info.param.name;
+ });
+
+TEST_P(IsValidMetadataV2Test, IsValidMetadataV2) {
+ IsValidMetadataV2TestCase testParam = GetParam();
+
+ ASSERT_EQ(utils::isValidMetadataV2(testParam.metadata), testParam.valid);
+}
+
+} // namespace aidl::android::hardware::broadcastradio
diff --git a/camera/common/1.0/Android.bp b/camera/common/1.0/Android.bp
index 3eb12b9..5952ac8 100644
--- a/camera/common/1.0/Android.bp
+++ b/camera/common/1.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/common/aidl/Android.bp b/camera/common/aidl/Android.bp
index 4ffcfd9..8f7d19d 100644
--- a/camera/common/aidl/Android.bp
+++ b/camera/common/aidl/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -22,7 +23,7 @@
},
rust: {
enabled: true,
- }
+ },
},
versions_with_info: [
{
diff --git a/camera/common/default/Android.bp b/camera/common/default/Android.bp
index b5d3095..ad2c139 100644
--- a/camera/common/default/Android.bp
+++ b/camera/common/default/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/device/1.0/Android.bp b/camera/device/1.0/Android.bp
index 6947779..e3a85e0 100644
--- a/camera/device/1.0/Android.bp
+++ b/camera/device/1.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/device/1.0/default/Android.bp b/camera/device/1.0/default/Android.bp
index 6992ff0..65891df 100644
--- a/camera/device/1.0/default/Android.bp
+++ b/camera/device/1.0/default/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/device/3.2/Android.bp b/camera/device/3.2/Android.bp
index c80538c..afeba17 100644
--- a/camera/device/3.2/Android.bp
+++ b/camera/device/3.2/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/device/3.2/default/Android.bp b/camera/device/3.2/default/Android.bp
index adf834a..00e59ec 100644
--- a/camera/device/3.2/default/Android.bp
+++ b/camera/device/3.2/default/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/device/3.3/Android.bp b/camera/device/3.3/Android.bp
index f5e51d6..becc67e 100644
--- a/camera/device/3.3/Android.bp
+++ b/camera/device/3.3/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/device/3.3/default/Android.bp b/camera/device/3.3/default/Android.bp
index cc0dd39..5bc2b51 100644
--- a/camera/device/3.3/default/Android.bp
+++ b/camera/device/3.3/default/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/device/3.4/Android.bp b/camera/device/3.4/Android.bp
index 2a6faab..bde7c9f 100644
--- a/camera/device/3.4/Android.bp
+++ b/camera/device/3.4/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/device/3.4/default/Android.bp b/camera/device/3.4/default/Android.bp
index 100106e..95bc323 100644
--- a/camera/device/3.4/default/Android.bp
+++ b/camera/device/3.4/default/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/device/3.5/Android.bp b/camera/device/3.5/Android.bp
index f29f936..6e23ee0 100644
--- a/camera/device/3.5/Android.bp
+++ b/camera/device/3.5/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/device/3.5/default/Android.bp b/camera/device/3.5/default/Android.bp
index bc15629..b6dee79 100644
--- a/camera/device/3.5/default/Android.bp
+++ b/camera/device/3.5/default/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/device/3.6/Android.bp b/camera/device/3.6/Android.bp
index ff37ca3..4fb56cf 100644
--- a/camera/device/3.6/Android.bp
+++ b/camera/device/3.6/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/device/3.6/default/Android.bp b/camera/device/3.6/default/Android.bp
index b4a486f..5c5f911 100644
--- a/camera/device/3.6/default/Android.bp
+++ b/camera/device/3.6/default/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/device/3.7/Android.bp b/camera/device/3.7/Android.bp
index be08e91..4312c04 100644
--- a/camera/device/3.7/Android.bp
+++ b/camera/device/3.7/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/device/aidl/Android.bp b/camera/device/aidl/Android.bp
index 1a665fb..e4006e7 100644
--- a/camera/device/aidl/Android.bp
+++ b/camera/device/aidl/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -11,13 +12,13 @@
name: "android.hardware.camera.device",
vendor_available: true,
srcs: ["android/hardware/camera/device/*.aidl"],
- frozen: true,
+ frozen: false,
stability: "vintf",
imports: [
"android.hardware.common-V2",
"android.hardware.common.fmq-V1",
"android.hardware.camera.common-V1",
- "android.hardware.camera.metadata-V2",
+ "android.hardware.camera.metadata-V3",
"android.hardware.graphics.common-V5",
],
backend: {
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ConfigureStreamsRet.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ConfigureStreamsRet.aidl
new file mode 100644
index 0000000..670f7d2
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ConfigureStreamsRet.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.camera.device;
+@VintfStability
+parcelable ConfigureStreamsRet {
+ android.hardware.camera.device.HalStream[] halStreams;
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/HalStream.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/HalStream.aidl
index a5784bc..3ae261d 100644
--- a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/HalStream.aidl
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/HalStream.aidl
@@ -42,4 +42,5 @@
android.hardware.graphics.common.Dataspace overrideDataSpace;
String physicalCameraId;
boolean supportOffline;
+ boolean enableHalBufferManager;
}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ICameraDevice.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ICameraDevice.aidl
index 51c6067..f73483a 100644
--- a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ICameraDevice.aidl
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ICameraDevice.aidl
@@ -43,4 +43,7 @@
void setTorchMode(boolean on);
void turnOnTorchWithStrengthLevel(int torchStrength);
int getTorchStrengthLevel();
+ android.hardware.camera.device.CameraMetadata constructDefaultRequestSettings(in android.hardware.camera.device.RequestTemplate type);
+ boolean isStreamCombinationWithSettingsSupported(in android.hardware.camera.device.StreamConfiguration streams);
+ android.hardware.camera.device.CameraMetadata getSessionCharacteristics(in android.hardware.camera.device.StreamConfiguration sessionConfig);
}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ICameraDeviceSession.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ICameraDeviceSession.aidl
index 2196d37..b6ae734 100644
--- a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ICameraDeviceSession.aidl
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ICameraDeviceSession.aidl
@@ -45,4 +45,5 @@
oneway void signalStreamFlush(in int[] streamIds, in int streamConfigCounter);
android.hardware.camera.device.ICameraOfflineSession switchToOffline(in int[] streamsToKeep, out android.hardware.camera.device.CameraOfflineSessionInfo offlineSessionInfo);
void repeatingRequestEnd(in int frameNumber, in int[] streamIds);
+ android.hardware.camera.device.ConfigureStreamsRet configureStreamsV2(in android.hardware.camera.device.StreamConfiguration requestedConfiguration);
}
diff --git a/camera/device/aidl/android/hardware/camera/device/ConfigureStreamsRet.aidl b/camera/device/aidl/android/hardware/camera/device/ConfigureStreamsRet.aidl
new file mode 100644
index 0000000..702901f
--- /dev/null
+++ b/camera/device/aidl/android/hardware/camera/device/ConfigureStreamsRet.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.camera.device;
+
+import android.hardware.camera.device.HalStream;
+
+/**
+ * ConfigureStreamsRet.
+ *
+ * Parcelable returned by the 'configureStreamsV2' call.
+ * This contains information which informs the camera framework
+ * about properties of each stream configured and also whether the
+ * the hal buffer manager must be used for the session configured.
+ */
+@VintfStability
+parcelable ConfigureStreamsRet {
+ /**
+ * A vector of HalStream Parcelables, which contain information
+ * about the stream parameters desired by the HAL such as usage flags,
+ * overridden format, maximum buffers etc.
+ */
+ HalStream[] halStreams;
+}
diff --git a/camera/device/aidl/android/hardware/camera/device/HalStream.aidl b/camera/device/aidl/android/hardware/camera/device/HalStream.aidl
index 25a80bc..fac89e6 100644
--- a/camera/device/aidl/android/hardware/camera/device/HalStream.aidl
+++ b/camera/device/aidl/android/hardware/camera/device/HalStream.aidl
@@ -127,4 +127,24 @@
*
*/
boolean supportOffline;
+
+ /**
+ * Whether the buffers for this stream are HAL buffer managed.
+ *
+ * If ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION is
+ * ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE, this field
+ * must be set by the HAL to inform the camera framework, whether output buffers for this
+ * stream will be HAL buffer managed - i.e. requested through the
+ * ICameraDeviceCallback.requestStreamsBuffers() API. Only the output buffers for the streams
+ * that have this field set to 'true' will be HAL buffer managed. The output buffers for other
+ * streams will be managed by the camera framework.
+ *
+ * If the value of ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION is
+ * ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_AIDL_DEVICE, the camera framework
+ * will ignore this field and assume that all output streams are hal buffer managed.
+ *
+ * If ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION is not set at all, the camera framework
+ * will ignore this field and assume output buffers are managed by the camera framework.
+ */
+ boolean enableHalBufferManager;
}
diff --git a/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl b/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
index f940000..da3d5df 100644
--- a/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
+++ b/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
@@ -21,6 +21,7 @@
import android.hardware.camera.device.ICameraDeviceCallback;
import android.hardware.camera.device.ICameraDeviceSession;
import android.hardware.camera.device.ICameraInjectionSession;
+import android.hardware.camera.device.RequestTemplate;
import android.hardware.camera.device.StreamConfiguration;
import android.os.ParcelFileDescriptor;
@@ -346,4 +347,127 @@
*
*/
int getTorchStrengthLevel();
+
+ /**
+ * constructDefaultRequestSettings:
+ *
+ * This is the same as ICameraDeviceSession.constructDefaultRequestSettings, with
+ * the exception that it can be called before the ICameraDevice.open call.
+ *
+ * @param type The requested template CaptureRequest type to create the default settings for.
+ *
+ * @return capture settings for the requested use case.
+ *
+ */
+ CameraMetadata constructDefaultRequestSettings(in RequestTemplate type);
+
+ /**
+ * isStreamCombinationWithSettingsSupported:
+ *
+ * This is the same as isStreamCombinationSupported with below exceptions:
+ * 1. The input StreamConfiguration parameter may contain session parameters
+ * as well as additional CaptureRequest keys. See the comment
+ * sections below on what additional capture request keys are passed in
+ * StreamConfiguration::sessionParameters for each interface version. When checking if
+ * the particular StreamConfiguration is supported, the camera HAL must take all
+ * the keys in sessionParameters into consideration.
+ *
+ * 2. For version 3 of this interface, the camera compliance test will verify that
+ * isStreamCombinationWithSettingsSupported behaves properly for all combinations of
+ * below features. This function must return true for all supported combinations,
+ * and return false for non-supported feature combinations. The list of features
+ * required may grow in future versions. The additional metadata entries in
+ * StreamConfiguration::sessionParameters are {CONTROL_AE_TARGET_FPS_RANGE,
+ * CONTROL_VIDEO_STABILIZATION_MODE}.
+ *
+ * - Stream Combinations (a subset of LEGACY device mandatory stream combinations):
+ * {
+ * // 4:3 16:9
+ * // S1440P: 1920 x 1440 2560 x 1440
+ * // S1080P: 1440 x 1080 1920 x 1080
+ * // S720P: 960 x 720 1280 x 720
+ *
+ * // Simple preview, GPU video processing, or no-preview video recording
+ * {PRIV, MAXIMUM},
+ * {PRIV, PREVIEW},
+ * {PRIV, S1440P},
+ * {PRIV, S1080P},
+ * {PRIV, S720P},
+ * // In-application video/image processing
+ * {YUV, MAXIMUM},
+ * {YUV, PREVIEW},
+ * {YUV, S1440P},
+ * {YUV, S1080P},
+ * {YUV, S720P},
+ * // Standard still imaging.
+ * {PRIV, PREVIEW, JPEG, MAXIMUM},
+ * {PRIV, S1440P, JPEG, MAXIMUM},
+ * {PRIV, S1080P, JPEG, MAXIMUM},
+ * {PRIV, S720P, JPEG, MAXIMUM},
+ * {PRIV, S1440P, JPEG, S1440P},
+ * {PRIV, S1080P, JPEG, S1080P},
+ * {PRIV, S720P, JPEG, S1080P},
+ * // In-app processing plus still capture.
+ * {YUV, PREVIEW, JPEG, MAXIMUM},
+ * {YUV, S1440P, JPEG, MAXIMUM},
+ * {YUV, S1080P, JPEG, MAXIMUM},
+ * {YUV, S720P, JPEG, MAXIMUM},
+ * // Standard recording.
+ * {PRIV, PREVIEW, PRIV, PREVIEW},
+ * {PRIV, S1440P, PRIV, S1440P},
+ * {PRIV, S1080P, PRIV, S1080P},
+ * {PRIV, S720P, PRIV, S720P},
+ * // Preview plus in-app processing.
+ * {PRIV, PREVIEW, YUV, PREVIEW},
+ * {PRIV, S1440P, YUV, S1440P},
+ * {PRIV, S1080P, YUV, S1080P},
+ * {PRIV, S720P, YUV, S720P},
+ * }
+ * - VIDEO_STABILIZATION_MODES: {OFF, PREVIEW}
+ * - AE_TARGET_FPS_RANGE: {{*, 30}, {*, 60}}
+ * - DYNAMIC_RANGE_PROFILE: {STANDARD, HLG10}
+ *
+ * Note: If a combination contains a S1440P, S1080P, or S720P stream,
+ * both 4:3 and 16:9 aspect ratio will be considered. For example, for the
+ * stream combination of {PRIV, S1440P, JPEG, MAXIMUM}, and if MAXIMUM ==
+ * 4032 x 3024, the camera compliance test will verify both
+ * {PRIV, 1920 x 1440, JPEG, 4032 x 3024} and {PRIV, 2560 x 1440, JPEG, 4032 x 2268}.
+ *
+ * @param streams The StreamConfiguration to be tested, with optional CaptureRequest parameters.
+ *
+ * @return true in case the stream combination is supported, false otherwise.
+ *
+ */
+ boolean isStreamCombinationWithSettingsSupported(in StreamConfiguration streams);
+
+ /**
+ * getSessionCharacteristics
+ *
+ * Gets the session characteristics associated with a particular session
+ * configuration by the CameraDevice.
+ *
+ * For Android 15, the characteristics which need to be set are:
+ * - ANDROID_CONTROL_ZOOM_RATIO_RANGE
+ * - SCALER_AVAILABLE_MAX_DIGITAL_ZOOM
+ *
+ * A service specific error will be returned on the following conditions
+ * INTERNAL_ERROR:
+ * The camera device cannot be opened due to an internal
+ * error.
+ * CAMERA_DISCONNECTED:
+ * An external camera device has been disconnected, and is no longer
+ * available. This camera device interface is now stale, and a new
+ * instance must be acquired if the device is reconnected. All
+ * subsequent calls on this interface must return
+ * CAMERA_DISCONNECTED.
+ * ILLEGAL_ARGUMENT:
+ * If the given session configuration is not supported.
+ *
+ * @param sessionConfig: The session configuration for which the
+ * characteristics are being fetched.
+ *
+ * @return The static metadata for this particular session config, or an
+ * empty metadata structure if a service specific error is returned.
+ */
+ CameraMetadata getSessionCharacteristics(in StreamConfiguration sessionConfig);
}
diff --git a/camera/device/aidl/android/hardware/camera/device/ICameraDeviceSession.aidl b/camera/device/aidl/android/hardware/camera/device/ICameraDeviceSession.aidl
index 885c71a..62a19cf 100644
--- a/camera/device/aidl/android/hardware/camera/device/ICameraDeviceSession.aidl
+++ b/camera/device/aidl/android/hardware/camera/device/ICameraDeviceSession.aidl
@@ -20,6 +20,7 @@
import android.hardware.camera.device.CameraMetadata;
import android.hardware.camera.device.CameraOfflineSessionInfo;
import android.hardware.camera.device.CaptureRequest;
+import android.hardware.camera.device.ConfigureStreamsRet;
import android.hardware.camera.device.HalStream;
import android.hardware.camera.device.ICameraOfflineSession;
import android.hardware.camera.device.RequestTemplate;
@@ -88,6 +89,13 @@
* with processCaptureResult (and its respective releaseFence has been
* signaled) the framework may free or reuse it at any time.
*
+ * This method must only be called by the framework if
+ * ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION is either not advertised or is
+ * ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_AIDL. If the value of
+ * ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION is
+ * ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE, configureStreamsV2
+ * must be called instead.
+ *
* ------------------------------------------------------------------------
*
* Preconditions:
@@ -386,8 +394,8 @@
* error.
* @return true in case the stream reconfiguration is required, false otherwise.
*/
- boolean isReconfigurationRequired(in CameraMetadata oldSessionParams,
- in CameraMetadata newSessionParams);
+ boolean isReconfigurationRequired(
+ in CameraMetadata oldSessionParams, in CameraMetadata newSessionParams);
/**
* processCaptureRequest:
@@ -576,4 +584,29 @@
*/
void repeatingRequestEnd(in int frameNumber, in int[] streamIds);
+ /**
+ *
+ * configureStreamsV2:
+ *
+ * Performs the same function as 'configureStreams'. This function returns a
+ * 'ConfigureStreamsRet' Parcelable. This tells the framework about the desired stream
+ * parameters such as usage flags, maximum buffers, overridden format etc. It also informs
+ * camera framework whether the HAL will use the HAL buffer manager APIs 'requestStreamBuffers'
+ * and 'returnStreamBuffers' to request and return buffers to the framework.
+ *
+ * This method is only supported if
+ * ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION is
+ * ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE. It must not be
+ * called by the camera framework if it isn't supported. That is, the framework will only
+ * ever call one of 'configureStreams' or 'configureStreamsV2' depending on the value of
+ * ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION.
+ *
+ * @param requestedConfiguration The stream configuration requested by the camera framework to
+ * be configured by the camera HAL.
+ * @return A ConfigureStreamsRet Parcelable containing a vector of HalStreams and a boolean
+ * specifying whether the HAL buffer manager must be used for this session
+ * configuration.
+ *
+ */
+ ConfigureStreamsRet configureStreamsV2(in StreamConfiguration requestedConfiguration);
}
diff --git a/camera/device/aidl/android/hardware/camera/device/StreamConfiguration.aidl b/camera/device/aidl/android/hardware/camera/device/StreamConfiguration.aidl
index 197d9af..0f5bad9 100644
--- a/camera/device/aidl/android/hardware/camera/device/StreamConfiguration.aidl
+++ b/camera/device/aidl/android/hardware/camera/device/StreamConfiguration.aidl
@@ -59,6 +59,14 @@
* pipeline updates. The field is optional, clients can choose to ignore it and avoid
* including any initial settings. If parameters are present, then hal must examine
* their values and configure the internal camera pipeline accordingly.
+ *
+ * A null pointer is equivalent to a valid CameraMetadata object with zero entries.
+ *
+ * For a StreamConfiguration passed to ICameraDevice.isStreamCombinationWithSettingsSupported
+ * or ICameraDevice.getSessionCharacteristics, this variable may also contain keys
+ * that are not session parameters, but are used to specify certain features for a
+ * session. For example, CONTROL_VIDEO_STABILIZATION_MODE may be included even if it's not a
+ * session parameter.
*/
CameraMetadata sessionParams;
diff --git a/camera/device/default/Android.bp b/camera/device/default/Android.bp
index 5fbcb5d..10cee12 100644
--- a/camera/device/default/Android.bp
+++ b/camera/device/default/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/device/default/ExternalCameraDevice.cpp b/camera/device/default/ExternalCameraDevice.cpp
index 677fb42..8e84748 100644
--- a/camera/device/default/ExternalCameraDevice.cpp
+++ b/camera/device/default/ExternalCameraDevice.cpp
@@ -399,6 +399,10 @@
const uint8_t hotPixelMode = ANDROID_HOT_PIXEL_MODE_OFF;
UPDATE(ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES, &hotPixelMode, 1);
+ // android.info
+ const uint8_t bufMgrVer = ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5;
+ UPDATE(ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &bufMgrVer, 1);
+
// android.jpeg
const int32_t jpegAvailableThumbnailSizes[] = {0, 0, 176, 144, 240, 144, 256,
144, 240, 160, 256, 154, 240, 180};
@@ -493,6 +497,9 @@
const int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
UPDATE(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
+ const uint8_t sensorReadoutTimestamp = ANDROID_SENSOR_READOUT_TIMESTAMP_NOT_SUPPORTED;
+ UPDATE(ANDROID_SENSOR_READOUT_TIMESTAMP, &sensorReadoutTimestamp, 1);
+
/* Other sensor/RAW related keys:
* android.sensor.info.colorFilterArrangement -> no need if we don't do RAW
* android.sensor.info.physicalSize -> not available
@@ -998,4 +1005,4 @@
} // namespace device
} // namespace camera
} // namespace hardware
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/camera/device/default/ExternalCameraDeviceSession.cpp b/camera/device/default/ExternalCameraDeviceSession.cpp
index a6ec4c7..91196d4 100644
--- a/camera/device/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/default/ExternalCameraDeviceSession.cpp
@@ -538,6 +538,19 @@
return Status::INTERNAL_ERROR;
}
+ if (request.outputBuffers.empty()) {
+ ALOGE("%s: No output buffers provided.", __FUNCTION__);
+ return Status::ILLEGAL_ARGUMENT;
+ }
+
+ for (auto& outputBuf : request.outputBuffers) {
+ if (outputBuf.streamId == -1 || mStreamMap.find(outputBuf.streamId) == mStreamMap.end()) {
+ ALOGE("%s: Invalid streamId in CaptureRequest.outputBuffers: %d", __FUNCTION__,
+ outputBuf.streamId);
+ return Status::ILLEGAL_ARGUMENT;
+ }
+ }
+
const camera_metadata_t* rawSettings = nullptr;
bool converted;
CameraMetadata settingsFmq; // settings from FMQ
@@ -572,8 +585,6 @@
return Status::ILLEGAL_ARGUMENT;
}
- std::vector<buffer_handle_t*> allBufPtrs;
- std::vector<int> allFences;
size_t numOutputBufs = request.outputBuffers.size();
if (numOutputBufs == 0) {
@@ -629,11 +640,6 @@
}
}
- status = importRequestLocked(request, allBufPtrs, allFences);
- if (status != Status::OK) {
- return status;
- }
-
nsecs_t shutterTs = 0;
std::unique_ptr<V4L2Frame> frameIn = dequeueV4l2FrameLocked(&shutterTs);
if (frameIn == nullptr) {
@@ -656,8 +662,8 @@
halBuf.height = stream.height;
halBuf.format = stream.format;
halBuf.usage = stream.usage;
- halBuf.bufPtr = allBufPtrs[i];
- halBuf.acquireFence = allFences[i];
+ halBuf.bufPtr = nullptr; // threadloop will request buffer from cameraservice
+ halBuf.acquireFence = 0; // threadloop will request fence from cameraservice
halBuf.fenceTimeout = false;
}
{
@@ -789,8 +795,10 @@
outputBuffer.bufferId = buffer.bufferId;
outputBuffer.status = BufferStatus::ERROR;
if (buffer.acquireFence >= 0) {
- outputBuffer.releaseFence.fds.resize(1);
- outputBuffer.releaseFence.fds.at(0).set(buffer.acquireFence);
+ native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+ handle->data[0] = buffer.acquireFence;
+ outputBuffer.releaseFence = android::dupToAidl(handle);
+ native_handle_delete(handle);
}
} else {
offlineBuffers.push_back(buffer);
@@ -1349,56 +1357,6 @@
return false;
}
-Status ExternalCameraDeviceSession::importRequestLocked(const CaptureRequest& request,
- std::vector<buffer_handle_t*>& allBufPtrs,
- std::vector<int>& allFences) {
- return importRequestLockedImpl(request, allBufPtrs, allFences);
-}
-
-Status ExternalCameraDeviceSession::importRequestLockedImpl(
- const CaptureRequest& request, std::vector<buffer_handle_t*>& allBufPtrs,
- std::vector<int>& allFences) {
- size_t numOutputBufs = request.outputBuffers.size();
- size_t numBufs = numOutputBufs;
- // Validate all I/O buffers
- std::vector<buffer_handle_t> allBufs;
- std::vector<uint64_t> allBufIds;
- allBufs.resize(numBufs);
- allBufIds.resize(numBufs);
- allBufPtrs.resize(numBufs);
- allFences.resize(numBufs);
- std::vector<int32_t> streamIds(numBufs);
-
- for (size_t i = 0; i < numOutputBufs; i++) {
- allBufs[i] = ::android::makeFromAidl(request.outputBuffers[i].buffer);
- allBufIds[i] = request.outputBuffers[i].bufferId;
- allBufPtrs[i] = &allBufs[i];
- streamIds[i] = request.outputBuffers[i].streamId;
- }
-
- {
- Mutex::Autolock _l(mCbsLock);
- for (size_t i = 0; i < numBufs; i++) {
- Status st = importBufferLocked(streamIds[i], allBufIds[i], allBufs[i], &allBufPtrs[i]);
- if (st != Status::OK) {
- // Detailed error logs printed in importBuffer
- return st;
- }
- }
- }
-
- // All buffers are imported. Now validate output buffer acquire fences
- for (size_t i = 0; i < numOutputBufs; i++) {
- if (!sHandleImporter.importFence(
- ::android::makeFromAidl(request.outputBuffers[i].acquireFence), allFences[i])) {
- ALOGE("%s: output buffer %zu acquire fence is invalid", __FUNCTION__, i);
- cleanupInflightFences(allFences, i);
- return Status::INTERNAL_ERROR;
- }
- }
- return Status::OK;
-}
-
Status ExternalCameraDeviceSession::importBuffer(int32_t streamId, uint64_t bufId,
buffer_handle_t buf,
/*out*/ buffer_handle_t** outBufPtr) {
@@ -1768,8 +1726,10 @@
result.outputBuffers[i].bufferId = req->buffers[i].bufferId;
result.outputBuffers[i].status = BufferStatus::ERROR;
if (req->buffers[i].acquireFence >= 0) {
- result.outputBuffers[i].releaseFence.fds.resize(1);
- result.outputBuffers[i].releaseFence.fds.at(0).set(req->buffers[i].acquireFence);
+ // numFds = 0 for error
+ native_handle_t* handle = native_handle_create(/*numFds*/ 0, /*numInts*/ 0);
+ result.outputBuffers[i].releaseFence = android::dupToAidl(handle);
+ native_handle_delete(handle);
}
}
@@ -1813,16 +1773,20 @@
if (req->buffers[i].fenceTimeout) {
result.outputBuffers[i].status = BufferStatus::ERROR;
if (req->buffers[i].acquireFence >= 0) {
- result.outputBuffers[i].releaseFence.fds.resize(1);
- result.outputBuffers[i].releaseFence.fds.at(0).set(req->buffers[i].acquireFence);
+ native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+ handle->data[0] = req->buffers[i].acquireFence;
+ result.outputBuffers[i].releaseFence = android::dupToAidl(handle);
+ native_handle_delete(handle);
}
notifyError(req->frameNumber, req->buffers[i].streamId, ErrorCode::ERROR_BUFFER);
} else {
result.outputBuffers[i].status = BufferStatus::OK;
// TODO: refactor
if (req->buffers[i].acquireFence >= 0) {
- result.outputBuffers[i].releaseFence.fds.resize(1);
- result.outputBuffers[i].releaseFence.fds.at(0).set(req->buffers[i].acquireFence);
+ native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+ handle->data[0] = req->buffers[i].acquireFence;
+ result.outputBuffers[i].releaseFence = android::dupToAidl(handle);
+ native_handle_delete(handle);
}
}
}
@@ -1997,9 +1961,16 @@
std::chrono::milliseconds timeout = std::chrono::milliseconds(kReqProcTimeoutMs);
auto st = mRequestDoneCond.wait_for(lk, timeout);
if (st == std::cv_status::timeout) {
+ mRequestingBuffer = false;
ALOGE("%s: wait for buffer request finish timeout!", __FUNCTION__);
return -1;
}
+
+ if (mPendingReturnBufferReqs.empty()) {
+ mRequestingBuffer = false;
+ ALOGE("%s: cameraservice did not return any buffers!", __FUNCTION__);
+ return -1;
+ }
}
mRequestingBuffer = false;
*outBufReqs = std::move(mPendingReturnBufferReqs);
@@ -2049,6 +2020,8 @@
if (!ret.isOk()) {
ALOGE("%s: Transaction error: %d:%d", __FUNCTION__, ret.getExceptionCode(),
ret.getServiceSpecificError());
+ mBufferReqs.clear();
+ mRequestDoneCond.notify_one();
return false;
}
@@ -2057,17 +2030,24 @@
if (bufRets.size() != mHalBufferReqs.size()) {
ALOGE("%s: expect %zu buffer requests returned, only got %zu", __FUNCTION__,
mHalBufferReqs.size(), bufRets.size());
+ mBufferReqs.clear();
+ lk.unlock();
+ mRequestDoneCond.notify_one();
return false;
}
auto parent = mParent.lock();
if (parent == nullptr) {
ALOGE("%s: session has been disconnected!", __FUNCTION__);
+ mBufferReqs.clear();
+ lk.unlock();
+ mRequestDoneCond.notify_one();
return false;
}
std::vector<int> importedFences;
importedFences.resize(bufRets.size());
+ bool hasError = false;
for (size_t i = 0; i < bufRets.size(); i++) {
int streamId = bufRets[i].streamId;
switch (bufRets[i].val.getTag()) {
@@ -2078,7 +2058,8 @@
bufRets[i].val.get<StreamBuffersVal::Tag::buffers>();
if (hBufs.size() != 1) {
ALOGE("%s: expect 1 buffer returned, got %zu!", __FUNCTION__, hBufs.size());
- return false;
+ hasError = true;
+ break;
}
const StreamBuffer& hBuf = hBufs[0];
@@ -2086,31 +2067,47 @@
// TODO: create a batch import API so we don't need to lock/unlock mCbsLock
// repeatedly?
lk.unlock();
- Status s =
- parent->importBuffer(streamId, hBuf.bufferId, makeFromAidl(hBuf.buffer),
- /*out*/ &mBufferReqs[i].bufPtr);
+ native_handle_t* h = makeFromAidl(hBuf.buffer);
+ Status s = parent->importBuffer(streamId, hBuf.bufferId, h,
+ /*out*/ &mBufferReqs[i].bufPtr);
+ native_handle_delete(h);
lk.lock();
if (s != Status::OK) {
ALOGE("%s: stream %d import buffer failed!", __FUNCTION__, streamId);
cleanupInflightFences(importedFences, i - 1);
- return false;
+ hasError = true;
+ break;
}
- if (!sHandleImporter.importFence(makeFromAidl(hBuf.acquireFence),
- mBufferReqs[i].acquireFence)) {
+ h = makeFromAidl(hBuf.acquireFence);
+ if (!sHandleImporter.importFence(h, mBufferReqs[i].acquireFence)) {
ALOGE("%s: stream %d import fence failed!", __FUNCTION__, streamId);
cleanupInflightFences(importedFences, i - 1);
- return false;
+ native_handle_delete(h);
+ hasError = true;
+ break;
}
+ native_handle_delete(h);
importedFences[i] = mBufferReqs[i].acquireFence;
} break;
default:
ALOGE("%s: Unknown StreamBuffersVal!", __FUNCTION__);
- return false;
+ hasError = true;
+ break;
+ }
+ if (hasError) {
+ mBufferReqs.clear();
+ lk.unlock();
+ mRequestDoneCond.notify_one();
+ return true;
}
}
} else {
ALOGE("%s: requestStreamBuffers call failed!", __FUNCTION__);
+ mBufferReqs.clear();
+ lk.unlock();
+ mRequestDoneCond.notify_one();
+ return true;
}
mPendingReturnBufferReqs = std::move(mBufferReqs);
@@ -2815,6 +2812,11 @@
if (res != 0) {
// For some webcam, the first few V4L2 frames might be malformed...
ALOGE("%s: Convert V4L2 frame to YU12 failed! res %d", __FUNCTION__, res);
+
+ ATRACE_BEGIN("Wait for BufferRequest done");
+ res = waitForBufferRequestDone(&req->buffers);
+ ATRACE_END();
+
lk.unlock();
Status st = parent->processCaptureRequestError(req);
if (st != Status::OK) {
@@ -2830,9 +2832,15 @@
ATRACE_END();
if (res != 0) {
+ // HAL buffer management buffer request can fail
ALOGE("%s: wait for BufferRequest done failed! res %d", __FUNCTION__, res);
lk.unlock();
- return onDeviceError("%s: failed to process buffer request error!", __FUNCTION__);
+ Status st = parent->processCaptureRequestError(req);
+ if (st != Status::OK) {
+ return onDeviceError("%s: failed to process capture request error!", __FUNCTION__);
+ }
+ signalRequestDone();
+ return true;
}
ALOGV("%s processing new request", __FUNCTION__);
diff --git a/camera/device/default/ExternalCameraDeviceSession.h b/camera/device/default/ExternalCameraDeviceSession.h
index 736bfd1..795b589 100644
--- a/camera/device/default/ExternalCameraDeviceSession.h
+++ b/camera/device/default/ExternalCameraDeviceSession.h
@@ -266,15 +266,6 @@
const std::vector<SupportedV4L2Format>& supportedFormats,
const ExternalCameraConfig& cfg);
- // Validate and import request's output buffers and acquire fence
- Status importRequestLocked(const CaptureRequest& request,
- std::vector<buffer_handle_t*>& allBufPtrs,
- std::vector<int>& allFences);
-
- Status importRequestLockedImpl(const CaptureRequest& request,
- std::vector<buffer_handle_t*>& allBufPtrs,
- std::vector<int>& allFences);
-
Status importBufferLocked(int32_t streamId, uint64_t bufId, buffer_handle_t buf,
/*out*/ buffer_handle_t** outBufPtr);
static void cleanupInflightFences(std::vector<int>& allFences, size_t numFences);
diff --git a/camera/device/default/ExternalCameraOfflineSession.cpp b/camera/device/default/ExternalCameraOfflineSession.cpp
index 53bd44f..2d4e2e0 100644
--- a/camera/device/default/ExternalCameraOfflineSession.cpp
+++ b/camera/device/default/ExternalCameraOfflineSession.cpp
@@ -110,7 +110,8 @@
if (req->buffers[i].acquireFence >= 0) {
native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
handle->data[0] = req->buffers[i].acquireFence;
- result.outputBuffers[i].releaseFence = android::makeToAidl(handle);
+ result.outputBuffers[i].releaseFence = android::dupToAidl(handle);
+ native_handle_delete(handle);
}
notifyError(req->frameNumber, req->buffers[i].streamId, ErrorCode::ERROR_BUFFER);
} else {
@@ -119,7 +120,8 @@
if (req->buffers[i].acquireFence >= 0) {
native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
handle->data[0] = req->buffers[i].acquireFence;
- outputBuffer.releaseFence = android::makeToAidl(handle);
+ outputBuffer.releaseFence = android::dupToAidl(handle);
+ native_handle_delete(handle);
}
}
}
@@ -247,7 +249,8 @@
if (req->buffers[i].acquireFence >= 0) {
native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
handle->data[0] = req->buffers[i].acquireFence;
- outputBuffer.releaseFence = makeToAidl(handle);
+ outputBuffer.releaseFence = dupToAidl(handle);
+ native_handle_delete(handle);
}
}
diff --git a/camera/device/default/ExternalCameraUtils.cpp b/camera/device/default/ExternalCameraUtils.cpp
index 30c216f..2dc3c77 100644
--- a/camera/device/default/ExternalCameraUtils.cpp
+++ b/camera/device/default/ExternalCameraUtils.cpp
@@ -750,18 +750,12 @@
void freeReleaseFences(std::vector<CaptureResult>& results) {
for (auto& result : results) {
- native_handle_t* inputReleaseFence =
- ::android::makeFromAidl(result.inputBuffer.releaseFence);
- if (inputReleaseFence != nullptr) {
- native_handle_close(inputReleaseFence);
- native_handle_delete(inputReleaseFence);
- }
+ // NativeHandles free fd's on desctruction. Simply delete the objects!
+ result.inputBuffer.releaseFence.fds.clear(); // Implicitly closes fds
+ result.inputBuffer.releaseFence.ints.clear();
for (auto& buf : result.outputBuffers) {
- native_handle_t* outReleaseFence = ::android::makeFromAidl(buf.releaseFence);
- if (outReleaseFence != nullptr) {
- native_handle_close(outReleaseFence);
- native_handle_delete(outReleaseFence);
- }
+ buf.releaseFence.fds.clear(); // Implicitly closes fds
+ buf.releaseFence.ints.clear();
}
}
}
diff --git a/camera/metadata/3.2/Android.bp b/camera/metadata/3.2/Android.bp
index ec8107e..4602923 100644
--- a/camera/metadata/3.2/Android.bp
+++ b/camera/metadata/3.2/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/metadata/3.3/Android.bp b/camera/metadata/3.3/Android.bp
index 4bed25b..ba0ec80 100644
--- a/camera/metadata/3.3/Android.bp
+++ b/camera/metadata/3.3/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/metadata/3.4/Android.bp b/camera/metadata/3.4/Android.bp
index fdddfdf..893a6aa 100644
--- a/camera/metadata/3.4/Android.bp
+++ b/camera/metadata/3.4/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/metadata/3.5/Android.bp b/camera/metadata/3.5/Android.bp
index 9349d54..df4dddd 100644
--- a/camera/metadata/3.5/Android.bp
+++ b/camera/metadata/3.5/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/metadata/3.6/Android.bp b/camera/metadata/3.6/Android.bp
index 9e2b8a3..40f22fd 100644
--- a/camera/metadata/3.6/Android.bp
+++ b/camera/metadata/3.6/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/metadata/3.7/Android.bp b/camera/metadata/3.7/Android.bp
index 14981b8..70a9d56 100644
--- a/camera/metadata/3.7/Android.bp
+++ b/camera/metadata/3.7/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/metadata/aidl/Android.bp b/camera/metadata/aidl/Android.bp
index 2b2be55..374eefc 100644
--- a/camera/metadata/aidl/Android.bp
+++ b/camera/metadata/aidl/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
index 0290aef..9321ec0 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
@@ -98,6 +98,8 @@
ANDROID_CONTROL_AUTOFRAMING,
ANDROID_CONTROL_AUTOFRAMING_AVAILABLE,
ANDROID_CONTROL_AUTOFRAMING_STATE,
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_INFO_LUMINANCE_RANGE,
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE,
ANDROID_DEMOSAIC_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_DEMOSAIC_START /* 131072 */,
ANDROID_EDGE_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_EDGE_START /* 196608 */,
ANDROID_EDGE_STRENGTH,
@@ -244,6 +246,7 @@
ANDROID_SENSOR_OPAQUE_RAW_SIZE_MAXIMUM_RESOLUTION,
ANDROID_SENSOR_PIXEL_MODE,
ANDROID_SENSOR_RAW_BINNING_FACTOR_USED,
+ ANDROID_SENSOR_READOUT_TIMESTAMP,
ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_SENSOR_INFO_START /* 983040 */,
ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
@@ -283,6 +286,8 @@
ANDROID_STATISTICS_OIS_TIMESTAMPS,
ANDROID_STATISTICS_OIS_X_SHIFTS,
ANDROID_STATISTICS_OIS_Y_SHIFTS,
+ ANDROID_STATISTICS_LENS_INTRINSIC_TIMESTAMPS,
+ ANDROID_STATISTICS_LENS_INTRINSIC_SAMPLES,
ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_STATISTICS_INFO_START /* 1179648 */,
ANDROID_STATISTICS_INFO_HISTOGRAM_BUCKET_COUNT,
ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
@@ -329,6 +334,7 @@
ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_LOGICAL_MULTI_CAMERA_START /* 1703936 */,
ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE,
ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID,
+ ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_SENSOR_CROP_REGION,
ANDROID_DISTORTION_CORRECTION_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_DISTORTION_CORRECTION_START /* 1769472 */,
ANDROID_DISTORTION_CORRECTION_AVAILABLE_MODES,
ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_HEIC_START /* 1835008 */,
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeMode.aidl
index 5e1b871..c1423aa 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeMode.aidl
@@ -44,4 +44,5 @@
ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH,
ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE,
ANDROID_CONTROL_AE_MODE_ON_EXTERNAL_FLASH,
+ ANDROID_CONTROL_AE_MODE_ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlLowLightBoostState.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlLowLightBoostState.aidl
new file mode 100644
index 0000000..f8ae013
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlLowLightBoostState.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 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.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlLowLightBoostState {
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE_INACTIVE,
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE_ACTIVE,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/InfoSupportedBufferManagementVersion.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/InfoSupportedBufferManagementVersion.aidl
index 7303ff5..2c31cff 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/InfoSupportedBufferManagementVersion.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/InfoSupportedBufferManagementVersion.aidl
@@ -39,4 +39,5 @@
@Backing(type="int") @VintfStability
enum InfoSupportedBufferManagementVersion {
ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_AIDL_DEVICE,
+ ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorReadoutTimestamp.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorReadoutTimestamp.aidl
new file mode 100644
index 0000000..35dc1a9
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorReadoutTimestamp.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.camera.metadata;
+@Backing(type="int") @VintfStability
+enum SensorReadoutTimestamp {
+ ANDROID_SENSOR_READOUT_TIMESTAMP_NOT_SUPPORTED,
+ ANDROID_SENSOR_READOUT_TIMESTAMP_HARDWARE,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/AutomotiveLensFacing.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/AutomotiveLensFacing.aidl
index 8cd2229..19822fc 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/AutomotiveLensFacing.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/AutomotiveLensFacing.aidl
@@ -25,6 +25,7 @@
/**
* android.automotive.lens.facing enumeration values
* @see ANDROID_AUTOMOTIVE_LENS_FACING
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/AutomotiveLocation.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/AutomotiveLocation.aidl
index 0ef64b4..6c3edbe 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/AutomotiveLocation.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/AutomotiveLocation.aidl
@@ -25,6 +25,7 @@
/**
* android.automotive.location enumeration values
* @see ANDROID_AUTOMOTIVE_LOCATION
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/BlackLevelLock.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/BlackLevelLock.aidl
index 4746cf3..8d3443a 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/BlackLevelLock.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/BlackLevelLock.aidl
@@ -25,6 +25,7 @@
/**
* android.blackLevel.lock enumeration values
* @see ANDROID_BLACK_LEVEL_LOCK
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
index cfc9907..f133372 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
@@ -490,6 +490,18 @@
*/
ANDROID_CONTROL_AUTOFRAMING_STATE,
/**
+ * android.control.lowLightBoostInfoLuminanceRange [static, float[], public]
+ *
+ * <p>The operating luminance range of low light boost measured in lux (lx).</p>
+ */
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_INFO_LUMINANCE_RANGE,
+ /**
+ * android.control.lowLightBoostState [dynamic, enum, public]
+ *
+ * <p>Current state of the low light boost AE mode.</p>
+ */
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE,
+ /**
* android.demosaic.mode [controls, enum, system]
*
* <p>Controls the quality of the demosaicing
@@ -1579,6 +1591,13 @@
*/
ANDROID_SENSOR_RAW_BINNING_FACTOR_USED,
/**
+ * android.sensor.readoutTimestamp [static, enum, java_public]
+ *
+ * <p>Whether or not the camera device supports readout timestamp and
+ * {@code onReadoutStarted} callback.</p>
+ */
+ ANDROID_SENSOR_READOUT_TIMESTAMP,
+ /**
* android.sensor.info.activeArraySize [static, int32[], public]
*
* <p>The area of the image sensor which corresponds to active pixels after any geometric
@@ -1868,6 +1887,18 @@
*/
ANDROID_STATISTICS_OIS_Y_SHIFTS,
/**
+ * android.statistics.lensIntrinsicTimestamps [dynamic, int64[], ndk_public]
+ *
+ * <p>An array of timestamps of lens intrinsics samples, in nanoseconds.</p>
+ */
+ ANDROID_STATISTICS_LENS_INTRINSIC_TIMESTAMPS,
+ /**
+ * android.statistics.lensIntrinsicSamples [dynamic, float[], ndk_public]
+ *
+ * <p>An array of intra-frame lens intrinsics.</p>
+ */
+ ANDROID_STATISTICS_LENS_INTRINSIC_SAMPLES,
+ /**
* android.statistics.info.availableFaceDetectModes [static, byte[], public]
*
* <p>List of face detection modes for ANDROID_STATISTICS_FACE_DETECT_MODE that are
@@ -2241,6 +2272,13 @@
*/
ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID,
/**
+ * android.logicalMultiCamera.activePhysicalSensorCropRegion [dynamic, int32[], public]
+ *
+ * <p>The current region of the active physical sensor that will be read out for this
+ * capture.</p>
+ */
+ ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_SENSOR_CROP_REGION,
+ /**
* android.distortionCorrection.mode [dynamic, enum, public]
*
* <p>Mode of operation for the lens distortion correction block.</p>
@@ -2312,7 +2350,8 @@
*
* <p>Whether this camera device can support identical set of stream combinations
* involving HEIC image format, compared to the
- * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraDevice.html#legacy-level-guaranteed-configurations">table of combinations</a> involving JPEG image format required for the device's hardware
+ * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraDevice#legacy-level-guaranteed-configurations">table of combinations</a>
+ * involving JPEG image format required for the device's hardware
* level and capabilities.</p>
*/
ANDROID_HEIC_INFO_SUPPORTED = CameraMetadataSectionStart.ANDROID_HEIC_INFO_START,
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ColorCorrectionAberrationMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ColorCorrectionAberrationMode.aidl
index 890ac0e..a0f6c83 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ColorCorrectionAberrationMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ColorCorrectionAberrationMode.aidl
@@ -25,6 +25,7 @@
/**
* android.colorCorrection.aberrationMode enumeration values
* @see ANDROID_COLOR_CORRECTION_ABERRATION_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ColorCorrectionMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ColorCorrectionMode.aidl
index 080ca02..2a51bfc 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ColorCorrectionMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ColorCorrectionMode.aidl
@@ -25,6 +25,7 @@
/**
* android.colorCorrection.mode enumeration values
* @see ANDROID_COLOR_CORRECTION_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeAntibandingMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeAntibandingMode.aidl
index 8a2f501..47f7ebf 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeAntibandingMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeAntibandingMode.aidl
@@ -25,6 +25,7 @@
/**
* android.control.aeAntibandingMode enumeration values
* @see ANDROID_CONTROL_AE_ANTIBANDING_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeLock.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeLock.aidl
index ab56fdc..e226ac0 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeLock.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeLock.aidl
@@ -25,6 +25,7 @@
/**
* android.control.aeLock enumeration values
* @see ANDROID_CONTROL_AE_LOCK
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeLockAvailable.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeLockAvailable.aidl
index b846fc1..a62cd27 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeLockAvailable.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeLockAvailable.aidl
@@ -25,6 +25,7 @@
/**
* android.control.aeLockAvailable enumeration values
* @see ANDROID_CONTROL_AE_LOCK_AVAILABLE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeMode.aidl
index e2f5553..9f7aaae 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeMode.aidl
@@ -25,6 +25,7 @@
/**
* android.control.aeMode enumeration values
* @see ANDROID_CONTROL_AE_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
@@ -35,4 +36,5 @@
ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH,
ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE,
ANDROID_CONTROL_AE_MODE_ON_EXTERNAL_FLASH,
+ ANDROID_CONTROL_AE_MODE_ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY,
}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAePrecaptureTrigger.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAePrecaptureTrigger.aidl
index 2229712..5275cd1 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAePrecaptureTrigger.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAePrecaptureTrigger.aidl
@@ -25,6 +25,7 @@
/**
* android.control.aePrecaptureTrigger enumeration values
* @see ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeState.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeState.aidl
index af8c2cf..ffdf7d4 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeState.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeState.aidl
@@ -25,6 +25,7 @@
/**
* android.control.aeState enumeration values
* @see ANDROID_CONTROL_AE_STATE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAfMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAfMode.aidl
index 344f2de..cff3a25 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAfMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAfMode.aidl
@@ -25,6 +25,7 @@
/**
* android.control.afMode enumeration values
* @see ANDROID_CONTROL_AF_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAfSceneChange.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAfSceneChange.aidl
index 153611a..dce31de 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAfSceneChange.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAfSceneChange.aidl
@@ -25,6 +25,7 @@
/**
* android.control.afSceneChange enumeration values
* @see ANDROID_CONTROL_AF_SCENE_CHANGE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAfState.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAfState.aidl
index 2c8d602..cbdc28f 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAfState.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAfState.aidl
@@ -25,6 +25,7 @@
/**
* android.control.afState enumeration values
* @see ANDROID_CONTROL_AF_STATE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAfTrigger.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAfTrigger.aidl
index b68d4c7..0c82b25 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAfTrigger.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAfTrigger.aidl
@@ -25,6 +25,7 @@
/**
* android.control.afTrigger enumeration values
* @see ANDROID_CONTROL_AF_TRIGGER
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframing.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframing.aidl
index 0fef373..ba18491 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframing.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframing.aidl
@@ -25,6 +25,7 @@
/**
* android.control.autoframing enumeration values
* @see ANDROID_CONTROL_AUTOFRAMING
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframingAvailable.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframingAvailable.aidl
index da0d348..fd45647 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframingAvailable.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframingAvailable.aidl
@@ -25,6 +25,7 @@
/**
* android.control.autoframingAvailable enumeration values
* @see ANDROID_CONTROL_AUTOFRAMING_AVAILABLE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframingState.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframingState.aidl
index 13183a5..9ac200a 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframingState.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframingState.aidl
@@ -25,6 +25,7 @@
/**
* android.control.autoframingState enumeration values
* @see ANDROID_CONTROL_AUTOFRAMING_STATE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAwbLock.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAwbLock.aidl
index f7229f2..a1e6a79 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAwbLock.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAwbLock.aidl
@@ -25,6 +25,7 @@
/**
* android.control.awbLock enumeration values
* @see ANDROID_CONTROL_AWB_LOCK
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAwbLockAvailable.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAwbLockAvailable.aidl
index 0cb6ebe..4a69f87 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAwbLockAvailable.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAwbLockAvailable.aidl
@@ -25,6 +25,7 @@
/**
* android.control.awbLockAvailable enumeration values
* @see ANDROID_CONTROL_AWB_LOCK_AVAILABLE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAwbMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAwbMode.aidl
index 2f9b801..043841a 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAwbMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAwbMode.aidl
@@ -25,6 +25,7 @@
/**
* android.control.awbMode enumeration values
* @see ANDROID_CONTROL_AWB_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAwbState.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAwbState.aidl
index 1a93191..835d299 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAwbState.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAwbState.aidl
@@ -25,6 +25,7 @@
/**
* android.control.awbState enumeration values
* @see ANDROID_CONTROL_AWB_STATE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlCaptureIntent.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlCaptureIntent.aidl
index 132d98c..1cd5467 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlCaptureIntent.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlCaptureIntent.aidl
@@ -25,6 +25,7 @@
/**
* android.control.captureIntent enumeration values
* @see ANDROID_CONTROL_CAPTURE_INTENT
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlEffectMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlEffectMode.aidl
index 1668cb3..f4586c2 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlEffectMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlEffectMode.aidl
@@ -25,6 +25,7 @@
/**
* android.control.effectMode enumeration values
* @see ANDROID_CONTROL_EFFECT_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlEnableZsl.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlEnableZsl.aidl
index a83c051..6fffa5e 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlEnableZsl.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlEnableZsl.aidl
@@ -25,6 +25,7 @@
/**
* android.control.enableZsl enumeration values
* @see ANDROID_CONTROL_ENABLE_ZSL
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlExtendedSceneMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlExtendedSceneMode.aidl
index 2fe66cf..b95a4f5 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlExtendedSceneMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlExtendedSceneMode.aidl
@@ -25,6 +25,7 @@
/**
* android.control.extendedSceneMode enumeration values
* @see ANDROID_CONTROL_EXTENDED_SCENE_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlLowLightBoostState.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlLowLightBoostState.aidl
new file mode 100644
index 0000000..19be8fc
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlLowLightBoostState.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.control.lowLightBoostState enumeration values
+ * @see ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
+ */
+@VintfStability
+@Backing(type="int")
+enum ControlLowLightBoostState {
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE_INACTIVE,
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE_ACTIVE,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlMode.aidl
index d9ab9ab..b964d45 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlMode.aidl
@@ -25,6 +25,7 @@
/**
* android.control.mode enumeration values
* @see ANDROID_CONTROL_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlSceneMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlSceneMode.aidl
index 0f90aaa..f5c0a4a 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlSceneMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlSceneMode.aidl
@@ -25,6 +25,7 @@
/**
* android.control.sceneMode enumeration values
* @see ANDROID_CONTROL_SCENE_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlSettingsOverride.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlSettingsOverride.aidl
index d97f7c8..d0ee992 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlSettingsOverride.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlSettingsOverride.aidl
@@ -25,6 +25,7 @@
/**
* android.control.settingsOverride enumeration values
* @see ANDROID_CONTROL_SETTINGS_OVERRIDE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlVideoStabilizationMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlVideoStabilizationMode.aidl
index 497846c..94cc626 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlVideoStabilizationMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlVideoStabilizationMode.aidl
@@ -25,6 +25,7 @@
/**
* android.control.videoStabilizationMode enumeration values
* @see ANDROID_CONTROL_VIDEO_STABILIZATION_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/DemosaicMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/DemosaicMode.aidl
index 7d8cdcf..0c389aa 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/DemosaicMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/DemosaicMode.aidl
@@ -25,6 +25,7 @@
/**
* android.demosaic.mode enumeration values
* @see ANDROID_DEMOSAIC_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurations.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurations.aidl
index 7deb350..3cc882b 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurations.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurations.aidl
@@ -25,6 +25,7 @@
/**
* android.depth.availableDepthStreamConfigurations enumeration values
* @see ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurationsMaximumResolution.aidl
index 5d06be1..658f3bb 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurationsMaximumResolution.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurationsMaximumResolution.aidl
@@ -25,6 +25,7 @@
/**
* android.depth.availableDepthStreamConfigurationsMaximumResolution enumeration values
* @see ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurations.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurations.aidl
index 39a99b9..1ec3d11 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurations.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurations.aidl
@@ -25,6 +25,7 @@
/**
* android.depth.availableDynamicDepthStreamConfigurations enumeration values
* @see ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurationsMaximumResolution.aidl
index 30ea9b7..b0ad00e 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurationsMaximumResolution.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurationsMaximumResolution.aidl
@@ -25,6 +25,7 @@
/**
* android.depth.availableDynamicDepthStreamConfigurationsMaximumResolution enumeration values
* @see ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/DepthDepthIsExclusive.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/DepthDepthIsExclusive.aidl
index 4af81d9..de31b41 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/DepthDepthIsExclusive.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/DepthDepthIsExclusive.aidl
@@ -25,6 +25,7 @@
/**
* android.depth.depthIsExclusive enumeration values
* @see ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/DistortionCorrectionMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/DistortionCorrectionMode.aidl
index 3456207..fbf7abb 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/DistortionCorrectionMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/DistortionCorrectionMode.aidl
@@ -25,6 +25,7 @@
/**
* android.distortionCorrection.mode enumeration values
* @see ANDROID_DISTORTION_CORRECTION_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/EdgeMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/EdgeMode.aidl
index 1e15523..81bd04c 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/EdgeMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/EdgeMode.aidl
@@ -25,6 +25,7 @@
/**
* android.edge.mode enumeration values
* @see ANDROID_EDGE_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/FlashInfoAvailable.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/FlashInfoAvailable.aidl
index 0528037..b938d82 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/FlashInfoAvailable.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/FlashInfoAvailable.aidl
@@ -25,6 +25,7 @@
/**
* android.flash.info.available enumeration values
* @see ANDROID_FLASH_INFO_AVAILABLE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/FlashMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/FlashMode.aidl
index e175596..b279c44 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/FlashMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/FlashMode.aidl
@@ -25,6 +25,7 @@
/**
* android.flash.mode enumeration values
* @see ANDROID_FLASH_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/FlashState.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/FlashState.aidl
index fc398f8..b029566 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/FlashState.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/FlashState.aidl
@@ -25,6 +25,7 @@
/**
* android.flash.state enumeration values
* @see ANDROID_FLASH_STATE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurations.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurations.aidl
index fc9b6ec..c31cfba 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurations.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurations.aidl
@@ -25,6 +25,7 @@
/**
* android.heic.availableHeicStreamConfigurations enumeration values
* @see ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurationsMaximumResolution.aidl
index 13b50ab..bf5d92e 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurationsMaximumResolution.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurationsMaximumResolution.aidl
@@ -25,6 +25,7 @@
/**
* android.heic.availableHeicStreamConfigurationsMaximumResolution enumeration values
* @see ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/HeicInfoSupported.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/HeicInfoSupported.aidl
index c4e04f1..88825e6 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/HeicInfoSupported.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/HeicInfoSupported.aidl
@@ -25,6 +25,7 @@
/**
* android.heic.info.supported enumeration values
* @see ANDROID_HEIC_INFO_SUPPORTED
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/HotPixelMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/HotPixelMode.aidl
index 7b7aa21..bd99569 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/HotPixelMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/HotPixelMode.aidl
@@ -25,6 +25,7 @@
/**
* android.hotPixel.mode enumeration values
* @see ANDROID_HOT_PIXEL_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/InfoSupportedBufferManagementVersion.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/InfoSupportedBufferManagementVersion.aidl
index 9522377..a84f3cc 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/InfoSupportedBufferManagementVersion.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/InfoSupportedBufferManagementVersion.aidl
@@ -25,9 +25,11 @@
/**
* android.info.supportedBufferManagementVersion enumeration values
* @see ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
enum InfoSupportedBufferManagementVersion {
ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_AIDL_DEVICE,
+ ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE,
}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/InfoSupportedHardwareLevel.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/InfoSupportedHardwareLevel.aidl
index f242009..0ea6287 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/InfoSupportedHardwareLevel.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/InfoSupportedHardwareLevel.aidl
@@ -25,6 +25,7 @@
/**
* android.info.supportedHardwareLevel enumeration values
* @see ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurations.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurations.aidl
index 911a062..834ed5d 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurations.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurations.aidl
@@ -25,6 +25,7 @@
/**
* android.jpegr.availableJpegRStreamConfigurations enumeration values
* @see ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurationsMaximumResolution.aidl
index 9e78662..eb0d847 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurationsMaximumResolution.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurationsMaximumResolution.aidl
@@ -25,6 +25,7 @@
/**
* android.jpegr.availableJpegRStreamConfigurationsMaximumResolution enumeration values
* @see ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/LedAvailableLeds.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/LedAvailableLeds.aidl
index f26fcde..ba564c4 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/LedAvailableLeds.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/LedAvailableLeds.aidl
@@ -25,6 +25,7 @@
/**
* android.led.availableLeds enumeration values
* @see ANDROID_LED_AVAILABLE_LEDS
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/LedTransmit.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/LedTransmit.aidl
index 62c9bd7..f8b40ca 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/LedTransmit.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/LedTransmit.aidl
@@ -25,6 +25,7 @@
/**
* android.led.transmit enumeration values
* @see ANDROID_LED_TRANSMIT
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/LensFacing.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/LensFacing.aidl
index 0677ea9..fa9cb14 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/LensFacing.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/LensFacing.aidl
@@ -25,6 +25,7 @@
/**
* android.lens.facing enumeration values
* @see ANDROID_LENS_FACING
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/LensInfoFocusDistanceCalibration.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/LensInfoFocusDistanceCalibration.aidl
index 1c82bb0..2060e97 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/LensInfoFocusDistanceCalibration.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/LensInfoFocusDistanceCalibration.aidl
@@ -25,6 +25,7 @@
/**
* android.lens.info.focusDistanceCalibration enumeration values
* @see ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/LensOpticalStabilizationMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/LensOpticalStabilizationMode.aidl
index e350e15..03f8711 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/LensOpticalStabilizationMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/LensOpticalStabilizationMode.aidl
@@ -25,6 +25,7 @@
/**
* android.lens.opticalStabilizationMode enumeration values
* @see ANDROID_LENS_OPTICAL_STABILIZATION_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/LensPoseReference.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/LensPoseReference.aidl
index 3e6034b..124c670 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/LensPoseReference.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/LensPoseReference.aidl
@@ -25,6 +25,7 @@
/**
* android.lens.poseReference enumeration values
* @see ANDROID_LENS_POSE_REFERENCE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/LensState.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/LensState.aidl
index 0e5a04c..216bfb1 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/LensState.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/LensState.aidl
@@ -25,6 +25,7 @@
/**
* android.lens.state enumeration values
* @see ANDROID_LENS_STATE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/LogicalMultiCameraSensorSyncType.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/LogicalMultiCameraSensorSyncType.aidl
index 623a15c..ee6a1a0 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/LogicalMultiCameraSensorSyncType.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/LogicalMultiCameraSensorSyncType.aidl
@@ -25,6 +25,7 @@
/**
* android.logicalMultiCamera.sensorSyncType enumeration values
* @see ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/NoiseReductionMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/NoiseReductionMode.aidl
index 947361d..7303512 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/NoiseReductionMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/NoiseReductionMode.aidl
@@ -25,6 +25,7 @@
/**
* android.noiseReduction.mode enumeration values
* @see ANDROID_NOISE_REDUCTION_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/QuirksPartialResult.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/QuirksPartialResult.aidl
index 15a79b0..3af9f85 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/QuirksPartialResult.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/QuirksPartialResult.aidl
@@ -25,6 +25,7 @@
/**
* android.quirks.partialResult enumeration values
* @see ANDROID_QUIRKS_PARTIAL_RESULT
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableCapabilities.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableCapabilities.aidl
index ebe0b4c..a8e5fe0 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableCapabilities.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableCapabilities.aidl
@@ -25,6 +25,7 @@
/**
* android.request.availableCapabilities enumeration values
* @see ANDROID_REQUEST_AVAILABLE_CAPABILITIES
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableColorSpaceProfilesMap.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableColorSpaceProfilesMap.aidl
index b397dea..ee36480 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableColorSpaceProfilesMap.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableColorSpaceProfilesMap.aidl
@@ -25,6 +25,7 @@
/**
* android.request.availableColorSpaceProfilesMap enumeration values
* @see ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="long")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableDynamicRangeProfilesMap.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableDynamicRangeProfilesMap.aidl
index f04fae3..d7598d6 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableDynamicRangeProfilesMap.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableDynamicRangeProfilesMap.aidl
@@ -25,6 +25,7 @@
/**
* android.request.availableDynamicRangeProfilesMap enumeration values
* @see ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="long")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/RequestMetadataMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/RequestMetadataMode.aidl
index 37d4095..d526393 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/RequestMetadataMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/RequestMetadataMode.aidl
@@ -25,6 +25,7 @@
/**
* android.request.metadataMode enumeration values
* @see ANDROID_REQUEST_METADATA_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/RequestType.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/RequestType.aidl
index 5010a37..a8c97cb 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/RequestType.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/RequestType.aidl
@@ -25,6 +25,7 @@
/**
* android.request.type enumeration values
* @see ANDROID_REQUEST_TYPE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableFormats.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableFormats.aidl
index a8e67bb..fb42654 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableFormats.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableFormats.aidl
@@ -25,6 +25,7 @@
/**
* android.scaler.availableFormats enumeration values
* @see ANDROID_SCALER_AVAILABLE_FORMATS
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableRecommendedStreamConfigurations.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableRecommendedStreamConfigurations.aidl
index 57c3989..7498abf 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableRecommendedStreamConfigurations.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableRecommendedStreamConfigurations.aidl
@@ -25,6 +25,7 @@
/**
* android.scaler.availableRecommendedStreamConfigurations enumeration values
* @see ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamConfigurations.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamConfigurations.aidl
index 2b493ae..66599ae 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamConfigurations.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamConfigurations.aidl
@@ -25,6 +25,7 @@
/**
* android.scaler.availableStreamConfigurations enumeration values
* @see ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamConfigurationsMaximumResolution.aidl
index 4f6cb5e..ec9c5db 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamConfigurationsMaximumResolution.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamConfigurationsMaximumResolution.aidl
@@ -25,6 +25,7 @@
/**
* android.scaler.availableStreamConfigurationsMaximumResolution enumeration values
* @see ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl
index da27a48..eed16fa 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl
@@ -25,6 +25,7 @@
/**
* android.scaler.availableStreamUseCases enumeration values
* @see ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="long")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerCroppingType.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerCroppingType.aidl
index e44eff1..bf3672d 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerCroppingType.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerCroppingType.aidl
@@ -25,6 +25,7 @@
/**
* android.scaler.croppingType enumeration values
* @see ANDROID_SCALER_CROPPING_TYPE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerMultiResolutionStreamSupported.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerMultiResolutionStreamSupported.aidl
index f7cbc0f..d75aa7d 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerMultiResolutionStreamSupported.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerMultiResolutionStreamSupported.aidl
@@ -25,6 +25,7 @@
/**
* android.scaler.multiResolutionStreamSupported enumeration values
* @see ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerPhysicalCameraMultiResolutionStreamConfigurations.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerPhysicalCameraMultiResolutionStreamConfigurations.aidl
index 9427854..c725572 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerPhysicalCameraMultiResolutionStreamConfigurations.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerPhysicalCameraMultiResolutionStreamConfigurations.aidl
@@ -25,6 +25,7 @@
/**
* android.scaler.physicalCameraMultiResolutionStreamConfigurations enumeration values
* @see ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerRotateAndCrop.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerRotateAndCrop.aidl
index 9050153..b49dec0 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerRotateAndCrop.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerRotateAndCrop.aidl
@@ -25,6 +25,7 @@
/**
* android.scaler.rotateAndCrop enumeration values
* @see ANDROID_SCALER_ROTATE_AND_CROP
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/SensorInfoColorFilterArrangement.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/SensorInfoColorFilterArrangement.aidl
index 59a4038..1d8190c 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/SensorInfoColorFilterArrangement.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/SensorInfoColorFilterArrangement.aidl
@@ -25,6 +25,7 @@
/**
* android.sensor.info.colorFilterArrangement enumeration values
* @see ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/SensorInfoLensShadingApplied.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/SensorInfoLensShadingApplied.aidl
index 8892ad3..c5169af 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/SensorInfoLensShadingApplied.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/SensorInfoLensShadingApplied.aidl
@@ -25,6 +25,7 @@
/**
* android.sensor.info.lensShadingApplied enumeration values
* @see ANDROID_SENSOR_INFO_LENS_SHADING_APPLIED
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/SensorInfoTimestampSource.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/SensorInfoTimestampSource.aidl
index 2a5860b..de65ef7 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/SensorInfoTimestampSource.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/SensorInfoTimestampSource.aidl
@@ -25,6 +25,7 @@
/**
* android.sensor.info.timestampSource enumeration values
* @see ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/SensorPixelMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/SensorPixelMode.aidl
index 3dda07b..a76e479 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/SensorPixelMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/SensorPixelMode.aidl
@@ -25,6 +25,7 @@
/**
* android.sensor.pixelMode enumeration values
* @see ANDROID_SENSOR_PIXEL_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/SensorRawBinningFactorUsed.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/SensorRawBinningFactorUsed.aidl
index 20e92e4..8b421ba 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/SensorRawBinningFactorUsed.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/SensorRawBinningFactorUsed.aidl
@@ -25,6 +25,7 @@
/**
* android.sensor.rawBinningFactorUsed enumeration values
* @see ANDROID_SENSOR_RAW_BINNING_FACTOR_USED
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/SensorReadoutTimestamp.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/SensorReadoutTimestamp.aidl
new file mode 100644
index 0000000..f5ab369
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/SensorReadoutTimestamp.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.sensor.readoutTimestamp enumeration values
+ * @see ANDROID_SENSOR_READOUT_TIMESTAMP
+ * See system/media/camera/docs/metadata_definitions.xml for details.
+ */
+@VintfStability
+@Backing(type="int")
+enum SensorReadoutTimestamp {
+ ANDROID_SENSOR_READOUT_TIMESTAMP_NOT_SUPPORTED,
+ ANDROID_SENSOR_READOUT_TIMESTAMP_HARDWARE,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/SensorReferenceIlluminant1.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/SensorReferenceIlluminant1.aidl
index c8c9216..a0a3a40 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/SensorReferenceIlluminant1.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/SensorReferenceIlluminant1.aidl
@@ -25,6 +25,7 @@
/**
* android.sensor.referenceIlluminant1 enumeration values
* @see ANDROID_SENSOR_REFERENCE_ILLUMINANT1
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/SensorTestPatternMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/SensorTestPatternMode.aidl
index 29aede4..4ad0503 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/SensorTestPatternMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/SensorTestPatternMode.aidl
@@ -25,6 +25,7 @@
/**
* android.sensor.testPatternMode enumeration values
* @see ANDROID_SENSOR_TEST_PATTERN_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ShadingMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ShadingMode.aidl
index 6939b72..2080195 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ShadingMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ShadingMode.aidl
@@ -25,6 +25,7 @@
/**
* android.shading.mode enumeration values
* @see ANDROID_SHADING_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsFaceDetectMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsFaceDetectMode.aidl
index 0d17791..55d79cd 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsFaceDetectMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsFaceDetectMode.aidl
@@ -25,6 +25,7 @@
/**
* android.statistics.faceDetectMode enumeration values
* @see ANDROID_STATISTICS_FACE_DETECT_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsHistogramMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsHistogramMode.aidl
index a9b6f68..de1cfee 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsHistogramMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsHistogramMode.aidl
@@ -25,6 +25,7 @@
/**
* android.statistics.histogramMode enumeration values
* @see ANDROID_STATISTICS_HISTOGRAM_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsHotPixelMapMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsHotPixelMapMode.aidl
index 286291a..b81a7cd 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsHotPixelMapMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsHotPixelMapMode.aidl
@@ -25,6 +25,7 @@
/**
* android.statistics.hotPixelMapMode enumeration values
* @see ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsLensShadingMapMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsLensShadingMapMode.aidl
index d21b222..3a91c71 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsLensShadingMapMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsLensShadingMapMode.aidl
@@ -25,6 +25,7 @@
/**
* android.statistics.lensShadingMapMode enumeration values
* @see ANDROID_STATISTICS_LENS_SHADING_MAP_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsOisDataMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsOisDataMode.aidl
index afb281f..42801ed 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsOisDataMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsOisDataMode.aidl
@@ -25,6 +25,7 @@
/**
* android.statistics.oisDataMode enumeration values
* @see ANDROID_STATISTICS_OIS_DATA_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsSceneFlicker.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsSceneFlicker.aidl
index da2402af..371e9fb 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsSceneFlicker.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsSceneFlicker.aidl
@@ -25,6 +25,7 @@
/**
* android.statistics.sceneFlicker enumeration values
* @see ANDROID_STATISTICS_SCENE_FLICKER
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsSharpnessMapMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsSharpnessMapMode.aidl
index ed6c65c..487e8ac 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsSharpnessMapMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/StatisticsSharpnessMapMode.aidl
@@ -25,6 +25,7 @@
/**
* android.statistics.sharpnessMapMode enumeration values
* @see ANDROID_STATISTICS_SHARPNESS_MAP_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/SyncFrameNumber.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/SyncFrameNumber.aidl
index e33319e..148718d 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/SyncFrameNumber.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/SyncFrameNumber.aidl
@@ -25,6 +25,7 @@
/**
* android.sync.frameNumber enumeration values
* @see ANDROID_SYNC_FRAME_NUMBER
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/SyncMaxLatency.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/SyncMaxLatency.aidl
index cb0668f..7df4ff0 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/SyncMaxLatency.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/SyncMaxLatency.aidl
@@ -25,6 +25,7 @@
/**
* android.sync.maxLatency enumeration values
* @see ANDROID_SYNC_MAX_LATENCY
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/TonemapMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/TonemapMode.aidl
index d4b7e0eb..ed53060 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/TonemapMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/TonemapMode.aidl
@@ -25,6 +25,7 @@
/**
* android.tonemap.mode enumeration values
* @see ANDROID_TONEMAP_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/TonemapPresetCurve.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/TonemapPresetCurve.aidl
index 2da3704..c6fed00 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/TonemapPresetCurve.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/TonemapPresetCurve.aidl
@@ -25,6 +25,7 @@
/**
* android.tonemap.presetCurve enumeration values
* @see ANDROID_TONEMAP_PRESET_CURVE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
*/
@VintfStability
@Backing(type="int")
diff --git a/camera/provider/2.4/Android.bp b/camera/provider/2.4/Android.bp
index a4c0dd2..fbdc763 100644
--- a/camera/provider/2.4/Android.bp
+++ b/camera/provider/2.4/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/provider/2.4/default/Android.bp b/camera/provider/2.4/default/Android.bp
index bccd6cb..db4453d 100644
--- a/camera/provider/2.4/default/Android.bp
+++ b/camera/provider/2.4/default/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
index 2d919cc..bb76795 100644
--- a/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
+++ b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
@@ -95,14 +95,13 @@
Return<Status> ExternalCameraProviderImpl_2_4::setCallback(
const sp<ICameraProviderCallback>& callback) {
- if (callback == nullptr) {
- return Status::ILLEGAL_ARGUMENT;
- }
-
{
Mutex::Autolock _l(mLock);
mCallbacks = callback;
}
+ if (callback == nullptr) {
+ return Status::OK;
+ }
// Send a callback for all devices to initialize
{
for (const auto& pair : mCameraStatusMap) {
diff --git a/camera/provider/2.4/default/LegacyCameraProviderImpl_2_4.cpp b/camera/provider/2.4/default/LegacyCameraProviderImpl_2_4.cpp
index 07ed689..f039644 100644
--- a/camera/provider/2.4/default/LegacyCameraProviderImpl_2_4.cpp
+++ b/camera/provider/2.4/default/LegacyCameraProviderImpl_2_4.cpp
@@ -448,11 +448,11 @@
// Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow.
Return<Status> LegacyCameraProviderImpl_2_4::setCallback(
const sp<ICameraProviderCallback>& callback) {
- if (callback == nullptr) {
- return Status::ILLEGAL_ARGUMENT;
- }
Mutex::Autolock _l(mCbLock);
mCallbacks = callback;
+ if (callback == nullptr) {
+ return Status::OK;
+ }
// Add and report all presenting external cameras.
for (auto const& statusPair : mCameraStatusMap) {
int id = std::stoi(statusPair.first);
diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp
index 85e69eb..4e59d28 100644
--- a/camera/provider/2.4/vts/functional/Android.bp
+++ b/camera/provider/2.4/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/provider/2.5/Android.bp b/camera/provider/2.5/Android.bp
index e14c0a8..e082442 100644
--- a/camera/provider/2.5/Android.bp
+++ b/camera/provider/2.5/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/provider/2.5/default/Android.bp b/camera/provider/2.5/default/Android.bp
index 2fcb35a..ae0c2f9 100644
--- a/camera/provider/2.5/default/Android.bp
+++ b/camera/provider/2.5/default/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -84,7 +85,7 @@
header_libs: [
"camera.device@3.4-external-impl_headers",
"camera.device@3.5-external-impl_headers",
- "camera.device@3.6-external-impl_headers"
+ "camera.device@3.6-external-impl_headers",
],
export_include_dirs: ["."],
}
@@ -121,7 +122,7 @@
],
header_libs: [
"camera.device@3.4-impl_headers",
- "camera.device@3.5-impl_headers"
+ "camera.device@3.5-impl_headers",
],
}
diff --git a/camera/provider/2.6/Android.bp b/camera/provider/2.6/Android.bp
index f402a56..9e4a4d6 100644
--- a/camera/provider/2.6/Android.bp
+++ b/camera/provider/2.6/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/provider/2.7/Android.bp b/camera/provider/2.7/Android.bp
index ba59b38..d4369fa 100644
--- a/camera/provider/2.7/Android.bp
+++ b/camera/provider/2.7/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/provider/2.7/default/Android.bp b/camera/provider/2.7/default/Android.bp
index bd5da2d..8d7cd72 100644
--- a/camera/provider/2.7/default/Android.bp
+++ b/camera/provider/2.7/default/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/camera/provider/aidl/Android.bp b/camera/provider/aidl/Android.bp
index 35ec976..b0bd8d9 100644
--- a/camera/provider/aidl/Android.bp
+++ b/camera/provider/aidl/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -14,10 +15,10 @@
"android/hardware/camera/provider/*.aidl",
],
imports: [
- "android.hardware.camera.device-V2",
+ "android.hardware.camera.device-V3",
"android.hardware.camera.common-V1",
],
- frozen: true,
+ frozen: false,
stability: "vintf",
backend: {
java: {
diff --git a/camera/provider/aidl/vts/Android.bp b/camera/provider/aidl/vts/Android.bp
index cfcaec5..6716b8e 100644
--- a/camera/provider/aidl/vts/Android.bp
+++ b/camera/provider/aidl/vts/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -60,9 +61,9 @@
static_libs: [
"android.hardware.camera.common@1.0-helper",
"android.hardware.camera.common-V1-ndk",
- "android.hardware.camera.device-V2-ndk",
- "android.hardware.camera.metadata-V2-ndk",
- "android.hardware.camera.provider-V2-ndk",
+ "android.hardware.camera.device-V3-ndk",
+ "android.hardware.camera.metadata-V3-ndk",
+ "android.hardware.camera.provider-V3-ndk",
"android.hidl.allocator@1.0",
"libgrallocusage",
"libhidlmemory",
diff --git a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
index def6233..9a5f248 100644
--- a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
+++ b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
@@ -283,6 +283,64 @@
}
}
+TEST_P(CameraAidlTest, getSessionCharacteristics) {
+ if (flags::feature_combination_query()) {
+ std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
+
+ for (const auto& name : cameraDeviceNames) {
+ std::shared_ptr<ICameraDevice> device;
+ ALOGI("getSessionCharacteristics: Testing camera device %s", name.c_str());
+ ndk::ScopedAStatus ret = mProvider->getCameraDeviceInterface(name, &device);
+ ALOGI("getCameraDeviceInterface returns: %d:%d", ret.getExceptionCode(),
+ ret.getServiceSpecificError());
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_NE(device, nullptr);
+
+ CameraMetadata meta;
+ openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
+ &device /*out*/);
+
+ std::vector<AvailableStream> outputStreams;
+ camera_metadata_t* staticMeta =
+ reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
+ outputStreams.clear();
+ ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
+ ASSERT_NE(0u, outputStreams.size());
+
+ AvailableStream sampleStream = outputStreams[0];
+
+ int32_t streamId = 0;
+ Stream stream = {streamId,
+ StreamType::OUTPUT,
+ sampleStream.width,
+ sampleStream.height,
+ static_cast<PixelFormat>(sampleStream.format),
+ static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
+ GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER),
+ Dataspace::UNKNOWN,
+ StreamRotation::ROTATION_0,
+ std::string(),
+ /*bufferSize*/ 0,
+ /*groupId*/ -1,
+ {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
+ RequestAvailableDynamicRangeProfilesMap::
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
+
+ std::vector<Stream> streams = {stream};
+ StreamConfiguration config;
+ createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config);
+
+ CameraMetadata chars;
+ ret = device->getSessionCharacteristics(config, &chars);
+ ASSERT_TRUE(ret.isOk());
+ verifySessionCharacteristics(chars);
+ }
+ } else {
+ ALOGI("getSessionCharacteristics: Test skipped.\n");
+ GTEST_SKIP();
+ }
+}
+
// Verify that the torch strength level can be set and retrieved successfully.
TEST_P(CameraAidlTest, turnOnTorchWithStrengthLevel) {
std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
@@ -500,6 +558,12 @@
ASSERT_TRUE(ret.isOk());
ASSERT_NE(device, nullptr);
+ int32_t interfaceVersion;
+ ret = device->getInterfaceVersion(&interfaceVersion);
+ ASSERT_TRUE(ret.isOk());
+ bool supportFeatureCombinationQuery =
+ (interfaceVersion >= CAMERA_DEVICE_API_MINOR_VERSION_3);
+
std::shared_ptr<EmptyDeviceCb> cb = ndk::SharedRefBase::make<EmptyDeviceCb>();
ret = device->open(cb, &mSession);
ALOGI("device::open returns status:%d:%d", ret.getExceptionCode(),
@@ -525,14 +589,26 @@
}
if (ret.isOk()) {
- const camera_metadata_t* metadata = (camera_metadata_t*)rawMetadata.metadata.data();
- size_t expectedSize = rawMetadata.metadata.size();
- int result = validate_camera_metadata_structure(metadata, &expectedSize);
- ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
- verifyRequestTemplate(metadata, reqTemplate);
+ validateDefaultRequestMetadata(reqTemplate, rawMetadata);
} else {
ASSERT_EQ(0u, rawMetadata.metadata.size());
}
+
+ if (flags::feature_combination_query()) {
+ if (supportFeatureCombinationQuery) {
+ CameraMetadata rawMetadata2;
+ ndk::ScopedAStatus ret2 =
+ device->constructDefaultRequestSettings(reqTemplate, &rawMetadata2);
+
+ ASSERT_EQ(ret.isOk(), ret2.isOk());
+ ASSERT_EQ(ret.getStatus(), ret2.getStatus());
+
+ ASSERT_EQ(rawMetadata.metadata.size(), rawMetadata2.metadata.size());
+ if (ret2.isOk()) {
+ validateDefaultRequestMetadata(reqTemplate, rawMetadata2);
+ }
+ }
+ }
}
ret = mSession->close();
mSession = nullptr;
@@ -588,8 +664,7 @@
createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
jpegBufferSize);
- bool expectStreamCombQuery = (isLogicalMultiCamera(staticMeta) == Status::OK);
- verifyStreamCombination(device, config, /*expectedStatus*/ true, expectStreamCombQuery);
+ verifyStreamCombination(device, config, /*expectedStatus*/ true);
config.streamConfigCounter = streamConfigCounter++;
std::vector<HalStream> halConfigs;
@@ -623,7 +698,6 @@
for (const auto& cameraDeviceIds : concurrentDeviceCombinations) {
std::vector<CameraIdAndStreamCombination> cameraIdsAndStreamCombinations;
std::vector<CameraTestInfo> cameraTestInfos;
- size_t i = 0;
for (const auto& id : cameraDeviceIds.combination) {
CameraTestInfo cti;
auto it = idToNameMap.find(id);
@@ -674,7 +748,6 @@
cameraIdAndStreamCombination.cameraId = id;
cameraIdAndStreamCombination.streamConfiguration = cti.config;
cameraIdsAndStreamCombinations.push_back(cameraIdAndStreamCombination);
- i++;
cameraTestInfos.push_back(cti);
}
// Now verify that concurrent streams are supported
@@ -687,11 +760,7 @@
// Test the stream can actually be configured
for (auto& cti : cameraTestInfos) {
if (cti.session != nullptr) {
- camera_metadata_t* staticMeta =
- reinterpret_cast<camera_metadata_t*>(cti.staticMeta.metadata.data());
- bool expectStreamCombQuery = (isLogicalMultiCamera(staticMeta) == Status::OK);
- verifyStreamCombination(cti.cameraDevice, cti.config, /*expectedStatus*/ true,
- expectStreamCombQuery);
+ verifyStreamCombination(cti.cameraDevice, cti.config, /*expectedStatus*/ true);
}
if (cti.session != nullptr) {
@@ -752,8 +821,7 @@
createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
jpegBufferSize);
- verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ false,
- /*expectStreamCombQuery*/ false);
+ verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ false);
config.streamConfigCounter = streamConfigCounter++;
std::vector<HalStream> halConfigs;
@@ -972,8 +1040,7 @@
createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
jpegBufferSize);
- verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true,
- /*expectStreamCombQuery*/ false);
+ verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true);
config.streamConfigCounter = streamConfigCounter++;
std::vector<HalStream> halConfigs;
@@ -1191,8 +1258,7 @@
createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
jpegBufferSize);
config.streamConfigCounter = streamConfigCounter++;
- verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true,
- /*expectStreamCombQuery*/ false);
+ verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true);
std::vector<HalStream> halConfigs;
ndk::ScopedAStatus ret = mSession->configureStreams(config, &halConfigs);
@@ -1256,8 +1322,7 @@
createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE,
&config);
- verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true,
- /*expectStreamCombQuery*/ false);
+ verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true);
config.streamConfigCounter = streamConfigCounter++;
std::vector<HalStream> halConfigs;
@@ -1429,8 +1494,7 @@
createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
jpegBufferSize);
- verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true,
- /*expectStreamCombQuery*/ false);
+ verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true);
config.streamConfigCounter = streamConfigCounter++;
std::vector<HalStream> halConfigs;
@@ -1548,7 +1612,7 @@
std::vector<HalStream> halStreams;
bool supportsPartialResults = false;
- bool useHalBufManager = false;
+ std::set<int32_t> halBufManagedStreamIds;
int32_t partialResultCount = 0;
Stream previewStream;
std::shared_ptr<DeviceCb> cb;
@@ -1556,7 +1620,7 @@
configurePreviewStreams(
name, mProvider, &previewThreshold, physicalIds, &mSession, &previewStream,
&halStreams /*out*/, &supportsPartialResults /*out*/, &partialResultCount /*out*/,
- &useHalBufManager /*out*/, &cb /*out*/, 0 /*streamConfigCounter*/, true);
+ &halBufManagedStreamIds /*out*/, &cb /*out*/, 0 /*streamConfigCounter*/, true);
if (mSession == nullptr) {
// stream combination not supported by HAL, skip test for device
continue;
@@ -1593,7 +1657,9 @@
size_t k = 0;
for (const auto& halStream : halStreams) {
buffer_handle_t buffer_handle;
- if (useHalBufManager) {
+ bool useHalBufManagerForStream =
+ halBufManagedStreamIds.find(halStream.id) != halBufManagedStreamIds.end();
+ if (useHalBufManagerForStream) {
outputBuffers[k] = {halStream.id, /*bufferId*/ 0, NativeHandle(),
BufferStatus::OK, NativeHandle(), NativeHandle()};
} else {
@@ -1697,10 +1763,13 @@
defaultPreviewSettings.unlock(settingsBuffer);
filteredSettings.unlock(filteredSettingsBuffer);
- if (useHalBufManager) {
- std::vector<int32_t> streamIds(halStreams.size());
- for (size_t i = 0; i < streamIds.size(); i++) {
- streamIds[i] = halStreams[i].id;
+ if (halBufManagedStreamIds.size() != 0) {
+ std::vector<int32_t> streamIds;
+ for (size_t i = 0; i < halStreams.size(); i++) {
+ int32_t streamId = halStreams[i].id;
+ if (halBufManagedStreamIds.find(streamId) != halBufManagedStreamIds.end()) {
+ streamIds.emplace_back(streamId);
+ }
}
verifyBuffersReturned(mSession, streamIds, cb);
}
@@ -1764,7 +1833,7 @@
std::vector<HalStream> halStreams;
bool supportsPartialResults = false;
- bool useHalBufManager = false;
+ std::set<int32_t> halBufManagedStreamIds;
int32_t partialResultCount = 0;
Stream previewStream;
std::shared_ptr<DeviceCb> cb;
@@ -1776,8 +1845,8 @@
GRALLOC1_CONSUMER_USAGE_CPU_READ);
previewStream.dataSpace = Dataspace::UNKNOWN;
configureStreams(name, mProvider, format, &mSession, &previewStream, &halStreams,
- &supportsPartialResults, &partialResultCount, &useHalBufManager, &cb,
- 0, /*maxResolution*/ true);
+ &supportsPartialResults, &partialResultCount, &halBufManagedStreamIds,
+ &cb, 0, /*maxResolution*/ true);
ASSERT_NE(mSession, nullptr);
::aidl::android::hardware::common::fmq::MQDescriptor<
@@ -1808,7 +1877,9 @@
size_t k = 0;
for (const auto& halStream : halStreams) {
buffer_handle_t buffer_handle;
- if (useHalBufManager) {
+ bool halBufManagerUsed =
+ halBufManagedStreamIds.find(halStream.id) != halBufManagedStreamIds.end();
+ if (halBufManagerUsed) {
outputBuffers[k] = {halStream.id, 0,
NativeHandle(), BufferStatus::OK,
NativeHandle(), NativeHandle()};
@@ -1860,10 +1931,12 @@
ASSERT_FALSE(inflightReq->errorCodeValid);
ASSERT_NE(inflightReq->resultOutputBuffers.size(), 0u);
}
- if (useHalBufManager) {
- std::vector<int32_t> streamIds(halStreams.size());
- for (size_t i = 0; i < streamIds.size(); i++) {
- streamIds[i] = halStreams[i].id;
+ if (halBufManagedStreamIds.size()) {
+ std::vector<int32_t> streamIds;
+ for (size_t i = 0; i < halStreams.size(); i++) {
+ if (contains(halBufManagedStreamIds, halStreams[i].id)) {
+ streamIds.emplace_back(halStreams[i].id);
+ }
}
verifyBuffersReturned(mSession, streamIds, cb);
}
@@ -1925,7 +1998,7 @@
std::vector<HalStream> halStreams;
bool supportsPartialResults = false;
- bool useHalBufManager = false;
+ std::set<int32_t> halBufManagedStreamIds;
int32_t partialResultCount = 0;
Stream previewStream;
std::shared_ptr<DeviceCb> cb;
@@ -1936,7 +2009,7 @@
previewStream.dataSpace = getDataspace(PixelFormat::IMPLEMENTATION_DEFINED);
configureStreams(name, mProvider, PixelFormat::IMPLEMENTATION_DEFINED, &mSession,
&previewStream, &halStreams, &supportsPartialResults,
- &partialResultCount, &useHalBufManager, &cb, 0,
+ &partialResultCount, &halBufManagedStreamIds, &cb, 0,
/*maxResolution*/ false, profile);
ASSERT_NE(mSession, nullptr);
@@ -1975,7 +2048,7 @@
auto bufferId = requestId + 1; // Buffer id value 0 is not valid
for (const auto& halStream : halStreams) {
buffer_handle_t buffer_handle;
- if (useHalBufManager) {
+ if (contains(halBufManagedStreamIds, halStream.id)) {
outputBuffers[k] = {halStream.id, 0,
NativeHandle(), BufferStatus::OK,
NativeHandle(), NativeHandle()};
@@ -2041,10 +2114,12 @@
verify10BitMetadata(mHandleImporter, *inflightReq, profile);
}
- if (useHalBufManager) {
- std::vector<int32_t> streamIds(halStreams.size());
- for (size_t i = 0; i < streamIds.size(); i++) {
- streamIds[i] = halStreams[i].id;
+ if (halBufManagedStreamIds.size() != 0) {
+ std::vector<int32_t> streamIds;
+ for (size_t i = 0; i < halStreams.size(); i++) {
+ if (contains(halBufManagedStreamIds, halStreams[i].id)) {
+ streamIds.emplace_back(halStreams[i].id);
+ }
}
mSession->signalStreamFlush(streamIds, /*streamConfigCounter*/ 0);
cb->waitForBuffersReturned();
@@ -2376,11 +2451,11 @@
std::vector<HalStream> halStreams;
std::shared_ptr<DeviceCb> cb;
int32_t jpegBufferSize;
- bool useHalBufManager;
+ std::set<int32_t> halBufManagedStreamIds;
configureOfflineStillStream(name, mProvider, &threshold, &mSession /*out*/, &stream /*out*/,
&halStreams /*out*/, &supportsPartialResults /*out*/,
&partialResultCount /*out*/, &cb /*out*/,
- &jpegBufferSize /*out*/, &useHalBufManager /*out*/);
+ &jpegBufferSize /*out*/, &halBufManagedStreamIds /*out*/);
auto ret = mSession->constructDefaultRequestSettings(RequestTemplate::STILL_CAPTURE,
&settings);
@@ -2416,7 +2491,7 @@
StreamBuffer& outputBuffer = outputBuffers[0];
std::unique_lock<std::mutex> l(mLock);
- if (useHalBufManager) {
+ if (contains(halBufManagedStreamIds, halStream.id)) {
outputBuffer = {halStream.id, 0, NativeHandle(), BufferStatus::OK, NativeHandle(),
NativeHandle()};
} else {
diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp
index e5bf637..ce5b849 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.cpp
+++ b/camera/provider/aidl/vts/camera_aidl_test.cpp
@@ -30,6 +30,7 @@
#include <aidlcommonsupport/NativeHandle.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
+#include <com_android_internal_camera_flags.h>
#include <device_cb.h>
#include <empty_device_cb.h>
#include <grallocusage/GrallocUsageConversion.h>
@@ -39,6 +40,7 @@
#include <ui/GraphicBufferAllocator.h>
#include <regex>
#include <typeinfo>
+#include "utils/Errors.h"
using ::aidl::android::hardware::camera::common::CameraDeviceStatus;
using ::aidl::android::hardware::camera::common::TorchModeStatus;
@@ -56,6 +58,8 @@
using ::ndk::SpAIBinder;
namespace {
+namespace flags = com::android::internal::camera::flags;
+
bool parseProviderName(const std::string& serviceDescriptor, std::string* type /*out*/,
uint32_t* id /*out*/) {
if (!type || !id) {
@@ -101,6 +105,8 @@
return true;
}
+namespace flags = com::android::internal::camera::flags;
+
const std::vector<int64_t> kMandatoryUseCases = {
ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW,
@@ -310,21 +316,11 @@
void CameraAidlTest::verifyStreamUseCaseCharacteristics(const camera_metadata_t* metadata) {
camera_metadata_ro_entry entry;
- // Check capabilities
- int retcode =
- find_camera_metadata_ro_entry(metadata, ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
- bool hasStreamUseCaseCap = false;
- if ((0 == retcode) && (entry.count > 0)) {
- if (std::find(entry.data.u8, entry.data.u8 + entry.count,
- ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE) !=
- entry.data.u8 + entry.count) {
- hasStreamUseCaseCap = true;
- }
- }
+ bool hasStreamUseCaseCap = supportsStreamUseCaseCap(metadata);
bool supportMandatoryUseCases = false;
- retcode = find_camera_metadata_ro_entry(metadata, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES,
- &entry);
+ int retcode = find_camera_metadata_ro_entry(metadata, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES,
+ &entry);
if ((0 == retcode) && (entry.count > 0)) {
supportMandatoryUseCases = true;
for (size_t i = 0; i < kMandatoryUseCases.size(); i++) {
@@ -478,6 +474,38 @@
} else {
ADD_FAILURE() << "Get LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID failed!";
}
+
+ if (flags::concert_mode()) {
+ auto ret = find_camera_metadata_ro_entry(
+ metadata, ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_SENSOR_CROP_REGION, &entry);
+ if ((ret == android::OK) && (entry.count > 0)) {
+ ASSERT_TRUE(entry.count == 4);
+ ASSERT_GE(entry.data.i32[0], 0); // Top must be non-negative
+ ASSERT_GE(entry.data.i32[1], 0); // Left must be non-negative
+ ASSERT_GT(entry.data.i32[2], 0); // Width must be positive
+ ASSERT_GT(entry.data.i32[3], 0); // Height must be positive
+ }
+ }
+}
+
+void CameraAidlTest::verifyLensIntrinsicsResult(const std::vector<uint8_t>& resultMetadata) {
+ if (flags::concert_mode()) {
+ camera_metadata_t* metadata = (camera_metadata_t*)resultMetadata.data();
+
+ camera_metadata_ro_entry timestampsEntry, intrinsicsEntry;
+ auto tsRet = find_camera_metadata_ro_entry(
+ metadata, ANDROID_STATISTICS_LENS_INTRINSIC_TIMESTAMPS, ×tampsEntry);
+ auto inRet = find_camera_metadata_ro_entry(
+ metadata, ANDROID_STATISTICS_LENS_INTRINSIC_SAMPLES, &intrinsicsEntry);
+ ASSERT_EQ(tsRet, inRet);
+ ASSERT_TRUE((intrinsicsEntry.count % 5) == 0);
+ ASSERT_EQ(timestampsEntry.count, intrinsicsEntry.count / 5);
+ if (timestampsEntry.count > 0) {
+ for (size_t i = 0; i < timestampsEntry.count - 1; i++) {
+ ASSERT_GE(timestampsEntry.data.i64[i + 1], timestampsEntry.data.i64[i]);
+ }
+ }
+ }
}
Status CameraAidlTest::getPhysicalCameraIds(const camera_metadata_t* staticMeta,
@@ -1350,13 +1378,17 @@
bool hasHalBufferManager =
(0 == retcode && 1 == entry.count &&
entry.data.i32[0] == ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
+ bool sessionHalBufferManager =
+ (0 == retcode && 1 == entry.count &&
+ entry.data.i32[0] ==
+ ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE);
retcode = find_camera_metadata_ro_entry(
metadata, ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED, &entry);
bool multiResolutionStreamSupported =
(0 == retcode && 1 == entry.count &&
entry.data.u8[0] == ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED_TRUE);
if (multiResolutionStreamSupported) {
- ASSERT_TRUE(hasHalBufferManager);
+ ASSERT_TRUE(hasHalBufferManager || sessionHalBufferManager);
}
std::string version, cameraId;
@@ -1859,17 +1891,76 @@
}
void CameraAidlTest::verifyStreamCombination(const std::shared_ptr<ICameraDevice>& device,
- const StreamConfiguration& config, bool expectedStatus,
- bool expectStreamCombQuery) {
+ const StreamConfiguration& config,
+ bool expectedStatus) {
if (device != nullptr) {
bool streamCombinationSupported;
ScopedAStatus ret =
device->isStreamCombinationSupported(config, &streamCombinationSupported);
- // TODO: Check is unsupported operation is correct.
- ASSERT_TRUE(ret.isOk() ||
- (expectStreamCombQuery && ret.getExceptionCode() == EX_UNSUPPORTED_OPERATION));
- if (ret.isOk()) {
- ASSERT_EQ(expectedStatus, streamCombinationSupported);
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_EQ(expectedStatus, streamCombinationSupported);
+
+ if (flags::feature_combination_query()) {
+ int32_t interfaceVersion;
+ ret = device->getInterfaceVersion(&interfaceVersion);
+ ASSERT_TRUE(ret.isOk());
+ bool supportFeatureCombinationQuery =
+ (interfaceVersion >= CAMERA_DEVICE_API_MINOR_VERSION_3);
+ if (supportFeatureCombinationQuery) {
+ ret = device->isStreamCombinationWithSettingsSupported(config,
+ &streamCombinationSupported);
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_EQ(expectedStatus, streamCombinationSupported);
+ }
+ }
+ }
+}
+
+void CameraAidlTest::verifySessionCharacteristics(const CameraMetadata& chars) {
+ if (flags::feature_combination_query()) {
+ const camera_metadata_t* metadata =
+ reinterpret_cast<const camera_metadata_t*>(chars.metadata.data());
+
+ size_t expectedSize = chars.metadata.size();
+ int result = validate_camera_metadata_structure(metadata, &expectedSize);
+ ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
+ size_t entryCount = get_camera_metadata_entry_count(metadata);
+ ASSERT_GT(entryCount, 0u);
+
+ camera_metadata_ro_entry entry;
+ int retcode = 0;
+ float maxDigitalZoom = 1.0;
+
+ retcode = find_camera_metadata_ro_entry(metadata, ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
+ &entry);
+ // ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM should always be present.
+ if ((0 == retcode) && (entry.count == 1)) {
+ maxDigitalZoom = entry.data.f[0];
+ } else {
+ ADD_FAILURE() << "Get camera scalerAvailableMaxDigitalZoom failed!";
+ }
+
+ retcode = find_camera_metadata_ro_entry(metadata, ANDROID_CONTROL_ZOOM_RATIO_RANGE, &entry);
+ bool hasZoomRatioRange = (0 == retcode && entry.count == 2);
+ if (!hasZoomRatioRange) {
+ return;
+ }
+ float minZoomRatio = entry.data.f[0];
+ float maxZoomRatio = entry.data.f[1];
+ constexpr float FLOATING_POINT_THRESHOLD = 0.00001f;
+ if (abs(maxDigitalZoom - maxZoomRatio) > FLOATING_POINT_THRESHOLD) {
+ ADD_FAILURE() << "Difference between maximum digital zoom " << maxDigitalZoom
+ << " and maximum zoom ratio " << maxZoomRatio
+ << " is greater than the threshold " << FLOATING_POINT_THRESHOLD << "!";
+ }
+ if (minZoomRatio > maxZoomRatio) {
+ ADD_FAILURE() << "Maximum zoom ratio is less than minimum zoom ratio!";
+ }
+ if (minZoomRatio > 1.0f) {
+ ADD_FAILURE() << "Minimum zoom ratio is more than 1.0!";
+ }
+ if (maxZoomRatio < 1.0f) {
+ ADD_FAILURE() << "Maximum zoom ratio is less than 1.0!";
}
}
}
@@ -2152,7 +2243,6 @@
int64_t bufferId = 1;
int32_t frameNumber = 1;
CameraMetadata settings;
-
for (const auto& name : cameraDeviceNames) {
Stream testStream;
std::vector<HalStream> halStreams;
@@ -2331,10 +2421,10 @@
&cameraDevice /*out*/);
camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
- // Check if camera support depth only
- if (isDepthOnly(staticMeta) ||
- (threshold.format == static_cast<int32_t>(PixelFormat::RAW16) &&
- !supportsCroppedRawUseCase(staticMeta))) {
+ // Check if camera support depth only or doesn't support stream use case capability
+ if (isDepthOnly(staticMeta) || !supportsStreamUseCaseCap(staticMeta) ||
+ (threshold.format == static_cast<int32_t>(PixelFormat::RAW16) &&
+ !supportsCroppedRawUseCase(staticMeta))) {
ndk::ScopedAStatus ret = mSession->close();
mSession = nullptr;
ASSERT_TRUE(ret.isOk());
@@ -2348,18 +2438,20 @@
ASSERT_NE(0u, outputPreviewStreams.size());
// Combine valid and invalid stream use cases
- std::vector<int64_t> useCases(kMandatoryUseCases);
- useCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW + 1);
+ std::vector<int64_t> testedUseCases;
+ testedUseCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW + 1);
std::vector<int64_t> supportedUseCases;
if (threshold.format == static_cast<int32_t>(PixelFormat::RAW16)) {
// If the format is RAW16, supported use case is only CROPPED_RAW.
// All others are unsupported for this format.
- useCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW);
+ testedUseCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW);
supportedUseCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW);
supportedUseCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
} else {
camera_metadata_ro_entry entry;
+ testedUseCases.insert(testedUseCases.end(), kMandatoryUseCases.begin(),
+ kMandatoryUseCases.end());
auto retcode = find_camera_metadata_ro_entry(
staticMeta, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES, &entry);
if ((0 == retcode) && (entry.count > 0)) {
@@ -2400,7 +2492,7 @@
ASSERT_TRUE(ret.isOk());
config.sessionParams = req;
- for (int64_t useCase : useCases) {
+ for (int64_t useCase : testedUseCases) {
bool useCaseSupported = std::find(supportedUseCases.begin(), supportedUseCases.end(),
useCase) != supportedUseCases.end();
@@ -2440,6 +2532,41 @@
}
+ndk::ScopedAStatus CameraAidlTest::configureStreams(std::shared_ptr<ICameraDeviceSession>& session,
+ const StreamConfiguration& config,
+ BufferManagerType bufferManagerType,
+ std::set<int32_t>* halBufManagedStreamIds,
+ std::vector<HalStream>* halStreams) {
+ auto ret = ndk::ScopedAStatus::ok();
+ ConfigureStreamsRet aidl_return;
+ int32_t interfaceVersion = -1;
+ ret = session->getInterfaceVersion(&interfaceVersion);
+ if (!ret.isOk()) {
+ return ret;
+ }
+
+ if (flags::session_hal_buf_manager() &&
+ (bufferManagerType == BufferManagerType::SESSION && interfaceVersion >= 3)) {
+ ret = session->configureStreamsV2(config, &aidl_return);
+ } else {
+ ret = session->configureStreams(config, halStreams);
+ }
+ if (!ret.isOk()) {
+ return ret;
+ }
+ if (flags::session_hal_buf_manager() && bufferManagerType == BufferManagerType::SESSION) {
+ *halStreams = std::move(aidl_return.halStreams);
+ }
+ for (const auto& halStream : *halStreams) {
+ if ((flags::session_hal_buf_manager() && bufferManagerType == BufferManagerType::SESSION &&
+ halStream.enableHalBufferManager) ||
+ bufferManagerType == BufferManagerType::HAL) {
+ halBufManagedStreamIds->insert(halStream.id);
+ }
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
void CameraAidlTest::configureSingleStream(
const std::string& name, const std::shared_ptr<ICameraProvider>& provider,
const AvailableStream* previewThreshold, uint64_t bufferUsage, RequestTemplate reqTemplate,
@@ -2493,12 +2620,16 @@
ASSERT_TRUE(ret.isOk());
ASSERT_NE(*session, nullptr);
- *useHalBufManager = false;
+ BufferManagerType bufferManagerType = BufferManagerType::FRAMEWORK;
status = find_camera_metadata_ro_entry(
staticMeta, ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &entry);
if ((0 == status) && (entry.count == 1)) {
- *useHalBufManager = (entry.data.u8[0] ==
- ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
+ if (entry.data.u8[0] == ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5) {
+ bufferManagerType = BufferManagerType::HAL;
+ } else if (entry.data.u8[0] ==
+ ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE) {
+ bufferManagerType = BufferManagerType::SESSION;
+ }
}
outputPreviewStreams.clear();
@@ -2557,13 +2688,16 @@
ASSERT_EQ(supported, true);
std::vector<HalStream> halConfigs;
- ret = (*session)->configureStreams(config, &halConfigs);
+ std::set<int32_t> halBufManagedStreamIds;
+ ret = configureStreams(*session, config, bufferManagerType, &halBufManagedStreamIds,
+ &halConfigs);
ALOGI("configureStreams returns status: %d:%d", ret.getExceptionCode(),
ret.getServiceSpecificError());
ASSERT_TRUE(ret.isOk());
ASSERT_EQ(1u, halConfigs.size());
halStreams->clear();
halStreams->push_back(halConfigs[0]);
+ *useHalBufManager = halBufManagedStreamIds.size() != 0;
if (*useHalBufManager) {
std::vector<Stream> ss(1);
std::vector<HalStream> hs(1);
@@ -2690,6 +2824,7 @@
overrideRotateAndCrop(&request.settings);
request.outputBuffers = std::vector<StreamBuffer>(1);
StreamBuffer& outputBuffer = request.outputBuffers[0];
+
if (useHalBufManager) {
outputBuffer = {halStreams[0].id,
/*bufferId*/ 0, NativeHandle(), BufferStatus::OK,
@@ -2808,14 +2943,14 @@
const AvailableStream* previewThreshold, const std::unordered_set<std::string>& physicalIds,
std::shared_ptr<ICameraDeviceSession>* session, Stream* previewStream,
std::vector<HalStream>* halStreams, bool* supportsPartialResults,
- int32_t* partialResultCount, bool* useHalBufManager, std::shared_ptr<DeviceCb>* cb,
- int32_t streamConfigCounter, bool allowUnsupport) {
+ int32_t* partialResultCount, std::set<int32_t>* halBufManagedStreamIds,
+ std::shared_ptr<DeviceCb>* cb, int32_t streamConfigCounter, bool allowUnsupport) {
ASSERT_NE(nullptr, session);
ASSERT_NE(nullptr, halStreams);
ASSERT_NE(nullptr, previewStream);
ASSERT_NE(nullptr, supportsPartialResults);
ASSERT_NE(nullptr, partialResultCount);
- ASSERT_NE(nullptr, useHalBufManager);
+ ASSERT_NE(nullptr, halBufManagedStreamIds);
ASSERT_NE(nullptr, cb);
ASSERT_FALSE(physicalIds.empty());
@@ -2852,12 +2987,16 @@
ASSERT_TRUE(ret.isOk());
ASSERT_NE(*session, nullptr);
- *useHalBufManager = false;
+ BufferManagerType bufferManagerType = BufferManagerType::FRAMEWORK;
status = find_camera_metadata_ro_entry(
staticMeta, ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &entry);
if ((0 == status) && (entry.count == 1)) {
- *useHalBufManager = (entry.data.u8[0] ==
- ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
+ if (entry.data.u8[0] == ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5) {
+ bufferManagerType = BufferManagerType::HAL;
+ } else if (entry.data.u8[0] ==
+ ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE) {
+ bufferManagerType = BufferManagerType::SESSION;
+ }
}
outputPreviewStreams.clear();
@@ -2912,16 +3051,21 @@
config.streamConfigCounter = streamConfigCounter;
std::vector<HalStream> halConfigs;
- ret = (*session)->configureStreams(config, &halConfigs);
+ ret = configureStreams(*session, config, bufferManagerType, halBufManagedStreamIds,
+ &halConfigs);
+
ASSERT_TRUE(ret.isOk());
ASSERT_EQ(physicalIds.size(), halConfigs.size());
*halStreams = halConfigs;
- if (*useHalBufManager) {
- std::vector<Stream> ss(physicalIds.size());
- std::vector<HalStream> hs(physicalIds.size());
+ if (halBufManagedStreamIds->size() != 0) {
+ // Only include the streams that are HAL buffer managed
+ std::vector<Stream> ss;
+ std::vector<HalStream> hs;
for (size_t i = 0; i < physicalIds.size(); i++) {
- ss[i] = streams[i];
- hs[i] = halConfigs[i];
+ if (contains(*halBufManagedStreamIds, halConfigs[i].id)) {
+ ss.emplace_back(streams[i]);
+ hs.emplace_back(halConfigs[i]);
+ }
}
(*cb)->setCurrentStreamConfig(ss, hs);
}
@@ -2939,22 +3083,20 @@
cb->waitForBuffersReturned();
}
-void CameraAidlTest::configureStreams(const std::string& name,
- const std::shared_ptr<ICameraProvider>& provider,
- PixelFormat format,
- std::shared_ptr<ICameraDeviceSession>* session,
- Stream* previewStream, std::vector<HalStream>* halStreams,
- bool* supportsPartialResults, int32_t* partialResultCount,
- bool* useHalBufManager, std::shared_ptr<DeviceCb>* outCb,
- uint32_t streamConfigCounter, bool maxResolution,
- RequestAvailableDynamicRangeProfilesMap dynamicRangeProf,
- RequestAvailableColorSpaceProfilesMap colorSpaceProf) {
+void CameraAidlTest::configureStreams(
+ const std::string& name, const std::shared_ptr<ICameraProvider>& provider,
+ PixelFormat format, std::shared_ptr<ICameraDeviceSession>* session, Stream* previewStream,
+ std::vector<HalStream>* halStreams, bool* supportsPartialResults,
+ int32_t* partialResultCount, std::set<int32_t>* halBufManagedStreamIds,
+ std::shared_ptr<DeviceCb>* outCb, uint32_t streamConfigCounter, bool maxResolution,
+ RequestAvailableDynamicRangeProfilesMap dynamicRangeProf,
+ RequestAvailableColorSpaceProfilesMap colorSpaceProf) {
ASSERT_NE(nullptr, session);
ASSERT_NE(nullptr, halStreams);
ASSERT_NE(nullptr, previewStream);
ASSERT_NE(nullptr, supportsPartialResults);
ASSERT_NE(nullptr, partialResultCount);
- ASSERT_NE(nullptr, useHalBufManager);
+ ASSERT_NE(nullptr, halBufManagedStreamIds);
ASSERT_NE(nullptr, outCb);
ALOGI("configureStreams: Testing camera device %s", name.c_str());
@@ -2991,12 +3133,16 @@
ASSERT_TRUE(ret.isOk());
ASSERT_NE(*session, nullptr);
- *useHalBufManager = false;
+ BufferManagerType bufferManagerType = BufferManagerType::FRAMEWORK;
status = find_camera_metadata_ro_entry(
staticMeta, ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &entry);
if ((0 == status) && (entry.count == 1)) {
- *useHalBufManager = (entry.data.u8[0] ==
- ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
+ if (entry.data.u8[0] == ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5) {
+ bufferManagerType = BufferManagerType::HAL;
+ } else if (entry.data.u8[0] ==
+ ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE) {
+ bufferManagerType = BufferManagerType::SESSION;
+ }
}
outputStreams.clear();
@@ -3050,10 +3196,11 @@
ASSERT_TRUE(ret.isOk());
ASSERT_EQ(supported, true);
- ret = (*session)->configureStreams(config, halStreams);
+ ret = configureStreams(*session, config, bufferManagerType, halBufManagedStreamIds, halStreams);
+
ASSERT_TRUE(ret.isOk());
- if (*useHalBufManager) {
+ if (halBufManagedStreamIds->size() != 0) {
std::vector<Stream> ss(1);
std::vector<HalStream> hs(1);
ss[0] = streams[0];
@@ -3348,6 +3495,21 @@
return false;
}
+bool CameraAidlTest::supportsStreamUseCaseCap(const camera_metadata_t* staticMeta) {
+ camera_metadata_ro_entry entry;
+ int retcode = find_camera_metadata_ro_entry(staticMeta, ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
+ &entry);
+ bool hasStreamUseCaseCap = false;
+ if ((0 == retcode) && (entry.count > 0)) {
+ if (std::find(entry.data.u8, entry.data.u8 + entry.count,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE) !=
+ entry.data.u8 + entry.count) {
+ hasStreamUseCaseCap = true;
+ }
+ }
+ return hasStreamUseCaseCap;
+}
+
bool CameraAidlTest::isPerFrameControl(const camera_metadata_t* staticMeta) {
camera_metadata_ro_entry syncLatencyEntry;
int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_SYNC_MAX_LATENCY,
@@ -3398,7 +3560,7 @@
const AvailableStream* threshold, std::shared_ptr<ICameraDeviceSession>* session,
Stream* stream, std::vector<HalStream>* halStreams, bool* supportsPartialResults,
int32_t* partialResultCount, std::shared_ptr<DeviceCb>* outCb, int32_t* jpegBufferSize,
- bool* useHalBufManager) {
+ std::set<int32_t>* halBufManagedStreamIds) {
ASSERT_NE(nullptr, session);
ASSERT_NE(nullptr, halStreams);
ASSERT_NE(nullptr, stream);
@@ -3406,7 +3568,7 @@
ASSERT_NE(nullptr, partialResultCount);
ASSERT_NE(nullptr, outCb);
ASSERT_NE(nullptr, jpegBufferSize);
- ASSERT_NE(nullptr, useHalBufManager);
+ ASSERT_NE(nullptr, halBufManagedStreamIds);
std::vector<AvailableStream> outputStreams;
std::shared_ptr<ICameraDevice> cameraDevice;
@@ -3433,12 +3595,16 @@
*supportsPartialResults = (*partialResultCount > 1);
}
- *useHalBufManager = false;
+ BufferManagerType bufferManagerType = BufferManagerType::FRAMEWORK;
status = find_camera_metadata_ro_entry(
staticMeta, ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &entry);
if ((0 == status) && (entry.count == 1)) {
- *useHalBufManager = (entry.data.u8[0] ==
- ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
+ if (entry.data.u8[0] == ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5) {
+ bufferManagerType = BufferManagerType::HAL;
+ } else if (entry.data.u8[0] ==
+ ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE) {
+ bufferManagerType = BufferManagerType::SESSION;
+ }
}
auto st = getJpegBufferSize(staticMeta, jpegBufferSize);
@@ -3491,10 +3657,11 @@
StreamConfiguration config = {streams, StreamConfigurationMode::NORMAL_MODE, CameraMetadata()};
- (*session)->configureStreams(config, halStreams);
+ ret = configureStreams(*session, config, bufferManagerType, halBufManagedStreamIds, halStreams);
+
ASSERT_TRUE(ret.isOk());
- if (*useHalBufManager) {
+ if (halBufManagedStreamIds->size() != 0) {
(*outCb)->setCurrentStreamConfig(streams, *halStreams);
}
@@ -3597,7 +3764,7 @@
std::vector<HalStream> halStreams;
bool supportsPartialResults = false;
- bool useHalBufManager = false;
+ std::set<int32_t> halBufManagedStreamIds;
int32_t partialResultCount = 0;
Stream previewStream;
std::shared_ptr<DeviceCb> cb;
@@ -3606,7 +3773,7 @@
GRALLOC1_CONSUMER_USAGE_HWCOMPOSER);
configureStreams(name, mProvider, PixelFormat::IMPLEMENTATION_DEFINED, &mSession,
&previewStream, &halStreams, &supportsPartialResults, &partialResultCount,
- &useHalBufManager, &cb, 0,
+ &halBufManagedStreamIds, &cb, 0,
/*maxResolution*/ false, dynamicRangeProfile, colorSpace);
ASSERT_NE(mSession, nullptr);
@@ -3645,7 +3812,7 @@
auto bufferId = requestId + 1; // Buffer id value 0 is not valid
for (const auto& halStream : halStreams) {
buffer_handle_t buffer_handle;
- if (useHalBufManager) {
+ if (contains(halBufManagedStreamIds, halStream.id)) {
outputBuffers[k] = {halStream.id, 0,
NativeHandle(), BufferStatus::OK,
NativeHandle(), NativeHandle()};
@@ -3712,10 +3879,12 @@
}
}
- if (useHalBufManager) {
- std::vector<int32_t> streamIds(halStreams.size());
+ if (halBufManagedStreamIds.size() != 0) {
+ std::vector<int32_t> streamIds;
for (size_t i = 0; i < streamIds.size(); i++) {
- streamIds[i] = halStreams[i].id;
+ if (contains(halBufManagedStreamIds, halStreams[i].id)) {
+ streamIds.emplace_back(halStreams[i].id);
+ }
}
mSession->signalStreamFlush(streamIds, /*streamConfigCounter*/ 0);
cb->waitForBuffersReturned();
@@ -3926,3 +4095,12 @@
}
}
}
+
+void CameraAidlTest::validateDefaultRequestMetadata(RequestTemplate reqTemplate,
+ const CameraMetadata& rawMetadata) {
+ const camera_metadata_t* metadata = (camera_metadata_t*)rawMetadata.metadata.data();
+ size_t expectedSize = rawMetadata.metadata.size();
+ int result = validate_camera_metadata_structure(metadata, &expectedSize);
+ ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
+ verifyRequestTemplate(metadata, reqTemplate);
+}
diff --git a/camera/provider/aidl/vts/camera_aidl_test.h b/camera/provider/aidl/vts/camera_aidl_test.h
index 0ebd4ef..7bcf430 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.h
+++ b/camera/provider/aidl/vts/camera_aidl_test.h
@@ -64,6 +64,7 @@
using ::aidl::android::hardware::camera::device::BufferRequestStatus;
using ::aidl::android::hardware::camera::device::CameraMetadata;
using ::aidl::android::hardware::camera::device::CaptureResult;
+using ::aidl::android::hardware::camera::device::ConfigureStreamsRet;
using ::aidl::android::hardware::camera::device::ErrorCode;
using ::aidl::android::hardware::camera::device::HalStream;
using ::aidl::android::hardware::camera::device::ICameraDevice;
@@ -98,6 +99,11 @@
class DeviceCb; // Forward declare to break circular header dependency
+template <typename T>
+bool contains(const std::set<T>& container, T value) {
+ return container.find(value) != container.end();
+}
+
class CameraAidlTest : public ::testing::TestWithParam<std::string> {
public:
enum SystemCameraKind {
@@ -120,6 +126,8 @@
HIDDEN_SECURE_CAMERA
};
+ enum BufferManagerType { FRAMEWORK = 0, HAL, SESSION };
+
struct AvailableStream {
int32_t width;
int32_t height;
@@ -199,15 +207,22 @@
std::shared_ptr<ICameraDeviceSession>* session /*out*/, Stream* stream /*out*/,
std::vector<HalStream>* halStreams, bool* supportsPartialResults /*out*/,
int32_t* partialResultCount /*out*/, std::shared_ptr<DeviceCb>* outCb /*out*/,
- int32_t* jpegBufferSize /*out*/, bool* useHalBufManager /*out*/);
+ int32_t* jpegBufferSize /*out*/, std::set<int32_t>* halBufManagedStreamIds /*out*/);
+
+ ndk::ScopedAStatus configureStreams(std::shared_ptr<ICameraDeviceSession>& session,
+ const StreamConfiguration& config,
+ BufferManagerType bufferManagerType,
+ std::set<int32_t>* halBufManagedStreamIds,
+ std::vector<HalStream>* halStreams);
void configureStreams(
const std::string& name, const std::shared_ptr<ICameraProvider>& provider,
PixelFormat format, std::shared_ptr<ICameraDeviceSession>* session /*out*/,
Stream* previewStream /*out*/, std::vector<HalStream>* halStreams /*out*/,
bool* supportsPartialResults /*out*/, int32_t* partialResultCount /*out*/,
- bool* useHalBufManager /*out*/, std::shared_ptr<DeviceCb>* outCb /*out*/,
- uint32_t streamConfigCounter, bool maxResolution,
+ std::set<int32_t>* halBufManagedStreamIds /*out*/,
+ std::shared_ptr<DeviceCb>* outCb /*out*/, uint32_t streamConfigCounter,
+ bool maxResolution,
RequestAvailableDynamicRangeProfilesMap dynamicRangeProf =
RequestAvailableDynamicRangeProfilesMap::
ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
@@ -221,7 +236,7 @@
const std::unordered_set<std::string>& physicalIds,
std::shared_ptr<ICameraDeviceSession>* session /*out*/, Stream* previewStream /*out*/,
std::vector<HalStream>* halStreams /*out*/, bool* supportsPartialResults /*out*/,
- int32_t* partialResultCount /*out*/, bool* useHalBufManager /*out*/,
+ int32_t* partialResultCount /*out*/, std::set<int32_t>* halBufManagedStreamIds /*out*/,
std::shared_ptr<DeviceCb>* cb /*out*/, int32_t streamConfigCounter = 0,
bool allowUnsupport = false);
@@ -273,12 +288,15 @@
static void verifySettingsOverrideCharacteristics(const camera_metadata_t* metadata);
static void verifyStreamCombination(const std::shared_ptr<ICameraDevice>& device,
- const StreamConfiguration& config, bool expectedStatus,
- bool expectStreamCombQuery);
+ const StreamConfiguration& config, bool expectedStatus);
+
+ static void verifySessionCharacteristics(const CameraMetadata& chars);
static void verifyLogicalCameraResult(const camera_metadata_t* staticMetadata,
const std::vector<uint8_t>& resultMetadata);
+ static void verifyLensIntrinsicsResult(const std::vector<uint8_t>& resultMetadata);
+
static void verifyBuffersReturned(const std::shared_ptr<ICameraDeviceSession>& session,
int32_t streamId, const std::shared_ptr<DeviceCb>& cb,
uint32_t streamConfigCounter = 0);
@@ -421,7 +439,8 @@
int32_t frameCount, const bool *overrideSequence, const bool *expectedResults);
bool supportZoomSettingsOverride(const camera_metadata_t* staticMeta);
- bool supportsCroppedRawUseCase(const camera_metadata_t *staticMeta);
+ static bool supportsStreamUseCaseCap(const camera_metadata_t* staticMeta);
+ static bool supportsCroppedRawUseCase(const camera_metadata_t* staticMeta);
bool isPerFrameControl(const camera_metadata_t* staticMeta);
void getSupportedSizes(const camera_metadata_t* ch, uint32_t tag, int32_t format,
@@ -581,6 +600,9 @@
static void waitForReleaseFence(
std::vector<InFlightRequest::StreamBufferAndTimestamp>& resultOutputBuffers);
+ static void validateDefaultRequestMetadata(RequestTemplate reqTemplate,
+ const CameraMetadata& rawMetadata);
+
// Map from frame number to the in-flight request state
typedef std::unordered_map<uint32_t, std::shared_ptr<InFlightRequest>> InFlightMap;
@@ -617,6 +639,7 @@
// device@<major>.<minor>/<type>/id
const char* kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/\\s+/(.+)";
const std::string CAMERA_DEVICE_API_VERSION_1 = "1.1";
+const int32_t CAMERA_DEVICE_API_MINOR_VERSION_3 = 3;
const int32_t kMaxVideoWidth = 4096;
const int32_t kMaxVideoHeight = 2160;
diff --git a/camera/provider/aidl/vts/device_cb.cpp b/camera/provider/aidl/vts/device_cb.cpp
index 7e0969a..2c11d3f 100644
--- a/camera/provider/aidl/vts/device_cb.cpp
+++ b/camera/provider/aidl/vts/device_cb.cpp
@@ -388,15 +388,16 @@
// Verify logical camera result metadata
bool isLogicalCamera =
Status::OK == CameraAidlTest::isLogicalMultiCamera(staticMetadataBuffer);
+ camera_metadata_t* collectedMetadata =
+ const_cast<camera_metadata_t*>(request->collectedResult.getAndLock());
+ uint8_t* rawMetadata = reinterpret_cast<uint8_t*>(collectedMetadata);
+ std::vector metadata =
+ std::vector(rawMetadata, rawMetadata + get_camera_metadata_size(collectedMetadata));
if (isLogicalCamera) {
- camera_metadata_t* collectedMetadata =
- const_cast<camera_metadata_t*>(request->collectedResult.getAndLock());
- uint8_t* rawMetadata = reinterpret_cast<uint8_t*>(collectedMetadata);
- std::vector metadata = std::vector(
- rawMetadata, rawMetadata + get_camera_metadata_size(collectedMetadata));
CameraAidlTest::verifyLogicalCameraResult(staticMetadataBuffer, metadata);
- request->collectedResult.unlock(collectedMetadata);
}
+ CameraAidlTest::verifyLensIntrinsicsResult(metadata);
+ request->collectedResult.unlock(collectedMetadata);
}
uint32_t numBuffersReturned = results.outputBuffers.size();
diff --git a/camera/provider/default/Android.bp b/camera/provider/default/Android.bp
index ed45cbe..9d70c92 100644
--- a/camera/provider/default/Android.bp
+++ b/camera/provider/default/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_camera_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index 712f28a..dd502ba 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -22,19 +22,6 @@
}
vintf_compatibility_matrix {
- name: "framework_compatibility_matrix.4.xml",
- stem: "compatibility_matrix.4.xml",
- srcs: [
- "compatibility_matrix.4.xml",
- ],
- kernel_configs: [
- "kernel_config_q_4.14",
- "kernel_config_q_4.19",
- ],
- core_hals: "only",
-}
-
-vintf_compatibility_matrix {
name: "framework_compatibility_matrix.5.xml",
stem: "compatibility_matrix.5.xml",
srcs: [
@@ -45,7 +32,6 @@
"kernel_config_r_4.19",
"kernel_config_r_5.4",
],
- core_hals: "only",
}
vintf_compatibility_matrix {
@@ -59,7 +45,6 @@
"kernel_config_s_5.4",
"kernel_config_s_5.10",
],
- core_hals: "only",
}
vintf_compatibility_matrix {
@@ -72,7 +57,6 @@
"kernel_config_t_5.10",
"kernel_config_t_5.15",
],
- core_hals: "only",
}
vintf_compatibility_matrix {
@@ -85,18 +69,16 @@
"kernel_config_u_5.15",
"kernel_config_u_6.1",
],
- core_hals: "only",
}
vintf_compatibility_matrix {
- name: "framework_compatibility_matrix.9.xml",
- stem: "compatibility_matrix.9.xml",
+ name: "framework_compatibility_matrix.202404.xml",
+ stem: "compatibility_matrix.202404.xml",
srcs: [
- "compatibility_matrix.9.xml",
+ "compatibility_matrix.202404.xml",
],
kernel_configs: [
- "kernel_config_v_5.15",
"kernel_config_v_6.1",
+ "kernel_config_v_6.6",
],
- core_hals: "only",
}
diff --git a/compatibility_matrices/Android.mk b/compatibility_matrices/Android.mk
index c2ffb84..639abf9 100644
--- a/compatibility_matrices/Android.mk
+++ b/compatibility_matrices/Android.mk
@@ -101,7 +101,6 @@
endif # DEVICE_PRODUCT_COMPATIBILITY_MATRIX_FILE
my_system_matrix_deps := \
- framework_compatibility_matrix.4.xml \
framework_compatibility_matrix.5.xml \
framework_compatibility_matrix.6.xml \
framework_compatibility_matrix.7.xml \
@@ -112,7 +111,8 @@
# interfaces (in the `next` release configuration).
ifeq ($(RELEASE_AIDL_USE_UNFROZEN),true)
my_system_matrix_deps += \
- framework_compatibility_matrix.9.xml
+ framework_compatibility_matrix.202404.xml \
+
endif
my_framework_matrix_deps += \
diff --git a/compatibility_matrices/build/vintf_compatibility_matrix.go b/compatibility_matrices/build/vintf_compatibility_matrix.go
index 4f342b2..c72cbde 100644
--- a/compatibility_matrices/build/vintf_compatibility_matrix.go
+++ b/compatibility_matrices/build/vintf_compatibility_matrix.go
@@ -35,10 +35,10 @@
pctx = android.NewPackageContext("android/vintf")
assembleVintfRule = pctx.AndroidStaticRule("assemble_vintf", blueprint.RuleParams{
- Command: `${assembleVintfCmd} -i ${inputs} -o ${out} ${extraParams}`,
+ Command: `${assembleVintfCmd} -i ${inputs} -o ${out}`,
CommandDeps: []string{"${assembleVintfCmd}"},
Description: "assemble_vintf -i ${inputs}",
- }, "inputs", "extraParams")
+ }, "inputs")
xmllintXsd = pctx.AndroidStaticRule("xmllint-xsd", blueprint.RuleParams{
Command: `$XmlLintCmd --quiet --schema $xsd $in > /dev/null && touch -a $out`,
@@ -64,13 +64,6 @@
// list of kernel_config modules to be combined to final output
Kernel_configs []string
-
- // Default is "default" for compatibility matrices on /vendor
- // and /odm, and "disallow" for compatibility matrices on /system,
- // /product, and /system_ext.
- // If value is "only", only android.* HALs are allowed. If value
- // is "disallow", none of android.* HALs are allowed.
- Core_hals *string
}
type vintfCompatibilityMatrixRule struct {
@@ -173,8 +166,7 @@
Implicits: inputPaths,
Output: g.genFile,
Args: map[string]string{
- "inputs": strings.Join(inputPaths.Strings(), ":"),
- "extraParams": strings.Join(g.getExtraParams(), " "),
+ "inputs": strings.Join(inputPaths.Strings(), ":"),
},
})
g.generateValidateBuildAction(ctx, g.genFile, schema.Path())
@@ -199,23 +191,3 @@
},
}
}
-
-// Return extra parameters to assemble_vintf.
-func (g *vintfCompatibilityMatrixRule) getExtraParams() []string {
- var extraParams []string
-
- coreHalsStrategy := proptools.StringDefault(
- g.properties.Core_hals,
- g.defaultCoreHalsStrategy(),
- )
- extraParams = append(extraParams, "--core-hals", proptools.ShellEscape(coreHalsStrategy))
- return extraParams
-}
-
-func (g *vintfCompatibilityMatrixRule) defaultCoreHalsStrategy() string {
- // TODO(b/290408770): default to "disallow" for FCMs
-
- // For Device (vendor, odm) compatibility matrix, default is
- // to not check anything.
- return "default"
-}
diff --git a/compatibility_matrices/bump.py b/compatibility_matrices/bump.py
index 88b7a42..a5a453b 100755
--- a/compatibility_matrices/bump.py
+++ b/compatibility_matrices/bump.py
@@ -16,8 +16,6 @@
#
"""
Creates the next compatibility matrix.
-
-Requires libvintf Level.h to be updated before executing this script.
"""
import argparse
@@ -44,44 +42,33 @@
self.top = pathlib.Path(os.environ["ANDROID_BUILD_TOP"])
self.interfaces_dir = self.top / "hardware/interfaces"
- self.current_level = cmdline_args.current
+ self.current_level = cmdline_args.current_level
+ self.current_letter = cmdline_args.current_letter
self.current_module_name = f"framework_compatibility_matrix.{self.current_level}.xml"
self.current_xml = self.interfaces_dir / f"compatibility_matrices/compatibility_matrix.{self.current_level}.xml"
+ self.device_module_name = "framework_compatibility_matrix.device.xml"
- self.next_level = cmdline_args.next
+ self.next_level = cmdline_args.next_level
+ self.next_letter = cmdline_args.next_letter
self.next_module_name = f"framework_compatibility_matrix.{self.next_level}.xml"
self.next_xml = self.interfaces_dir / f"compatibility_matrices/compatibility_matrix.{self.next_level}.xml"
- self.level_to_letter = self.get_level_to_letter_mapping()
- print("Found level mapping in libvintf Level.h:", self.level_to_letter)
-
def run(self):
self.bump_kernel_configs()
self.copy_matrix()
self.edit_android_bp()
self.edit_android_mk()
- def get_level_to_letter_mapping(self):
- levels_file = self.top / "system/libvintf/include/vintf/Level.h"
- with open(levels_file) as f:
- lines = f.readlines()
- pairs = [
- line.split("=", maxsplit=2) for line in lines if "=" in line
- ]
- return {
- level.strip().removesuffix(","): letter.strip()
- for letter, level in pairs
- }
-
def bump_kernel_configs(self):
check_call([
self.top / "kernel/configs/tools/bump.py",
- self.level_to_letter[self.current_level].lower(),
- self.level_to_letter[self.next_level].lower(),
+ self.current_letter,
+ self.next_letter,
])
def copy_matrix(self):
- shutil.copyfile(self.current_xml, self.next_xml)
+ with open(self.current_xml) as f_current, open(self.next_xml, "w") as f_next:
+ f_next.write(f_current.read().replace(f"level=\"{self.current_level}\"", f"level=\"{self.next_level}\""))
def edit_android_bp(self):
android_bp = self.interfaces_dir / "compatibility_matrices/Android.bp"
@@ -100,7 +87,7 @@
next_kernel_configs = check_output(
"""grep -rh name: | sed -E 's/^.*"(.*)".*/\\1/g'""",
cwd=self.top / "kernel/configs" /
- self.level_to_letter[self.next_level].lower(),
+ self.next_letter,
text=True,
shell=True,
).splitlines()
@@ -124,31 +111,38 @@
def edit_android_mk(self):
android_mk = self.interfaces_dir / "compatibility_matrices/Android.mk"
+ lines = []
with open(android_mk) as f:
if self.next_module_name in f.read():
return
f.seek(0)
- lines = f.readlines()
- current_module_line_number = None
- for line_number, line in enumerate(lines):
- if self.current_module_name in line:
- current_module_line_number = line_number
- break
- assert current_module_line_number is not None
- lines.insert(current_module_line_number + 1,
- f" {self.next_module_name} \\\n")
+ for line in f:
+ if f" {self.device_module_name} \\\n" in line:
+ lines.append(f" {self.current_module_name} \\\n")
+
+ if self.current_module_name in line:
+ lines.append(f" {self.next_module_name} \\\n")
+ else:
+ lines.append(line)
+
with open(android_mk, "w") as f:
f.write("".join(lines))
def main():
parser = argparse.ArgumentParser(description=__doc__)
- parser.add_argument("current",
+ parser.add_argument("current_level",
type=str,
help="VINTF level of the current version (e.g. 9)")
- parser.add_argument("next",
+ parser.add_argument("next_level",
type=str,
help="VINTF level of the next version (e.g. 10)")
+ parser.add_argument("current_letter",
+ type=str,
+ help="Letter of the API level of the current version (e.g. v)")
+ parser.add_argument("next_letter",
+ type=str,
+ help="Letter of the API level of the next version (e.g. w)")
cmdline_args = parser.parse_args()
Bump(cmdline_args).run()
diff --git a/compatibility_matrices/compatibility_matrix.9.xml b/compatibility_matrices/compatibility_matrix.202404.xml
similarity index 79%
rename from compatibility_matrices/compatibility_matrix.9.xml
rename to compatibility_matrices/compatibility_matrix.202404.xml
index acfcf01..cf7de22 100644
--- a/compatibility_matrices/compatibility_matrix.9.xml
+++ b/compatibility_matrices/compatibility_matrix.202404.xml
@@ -1,23 +1,5 @@
-<compatibility-matrix version="1.0" type="framework" level="9">
- <hal format="hidl" optional="true">
- <name>android.hardware.audio</name>
- <version>6.0</version>
- <version>7.0-1</version>
- <interface>
- <name>IDevicesFactory</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.audio.effect</name>
- <version>6.0</version>
- <version>7.0</version>
- <interface>
- <name>IEffectsFactory</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="aidl" optional="true">
+<compatibility-matrix version="1.0" type="framework" level="202404">
+ <hal format="aidl">
<name>android.hardware.audio.core</name>
<version>1-2</version>
<interface>
@@ -36,7 +18,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.audio.effect</name>
<version>1-2</version>
<interface>
@@ -44,7 +26,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.audio.sounddose</name>
<version>1-2</version>
<interface>
@@ -52,7 +34,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.authsecret</name>
<version>1</version>
<interface>
@@ -60,7 +42,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.automotive.audiocontrol</name>
<version>2-4</version>
<interface>
@@ -68,7 +50,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.automotive.can</name>
<version>1</version>
<interface>
@@ -76,7 +58,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.automotive.evs</name>
<version>1-2</version>
<interface>
@@ -84,7 +66,15 @@
<regex-instance>[a-z]+/[0-9]+</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
+ <name>android.hardware.macsec</name>
+ <version>1</version>
+ <interface>
+ <name>IMacsecPskPlugin</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="aidl">
<name>android.hardware.automotive.occupant_awareness</name>
<version>1</version>
<interface>
@@ -92,7 +82,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.automotive.vehicle</name>
<version>1-3</version>
<interface>
@@ -100,7 +90,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.automotive.remoteaccess</name>
<version>1-2</version>
<interface>
@@ -108,14 +98,14 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.automotive.ivn</name>
<interface>
<name>IIvnAndroidDevice</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.biometrics.face</name>
<version>3-4</version>
<interface>
@@ -124,23 +114,23 @@
<instance>virtual</instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.biometrics.fingerprint</name>
- <version>3</version>
+ <version>3-4</version>
<interface>
<name>IFingerprint</name>
<instance>default</instance>
<instance>virtual</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.bluetooth</name>
<interface>
<name>IBluetoothHci</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.bluetooth.audio</name>
<version>3-4</version>
<interface>
@@ -148,14 +138,38 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
+ <name>android.hardware.bluetooth.ranging</name>
+ <version>1</version>
+ <interface>
+ <name>IBluetoothChannelSounding</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="aidl">
+ <name>android.hardware.bluetooth.finder</name>
+ <version>1</version>
+ <interface>
+ <name>IBluetoothFinder</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="aidl">
+ <name>android.hardware.bluetooth.lmp_event</name>
+ <version>1</version>
+ <interface>
+ <name>IBluetoothLmpEvent</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="aidl">
<name>android.hardware.boot</name>
<interface>
<name>IBootControl</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.broadcastradio</name>
<version>1-2</version>
<interface>
@@ -163,22 +177,22 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.camera.provider</name>
- <version>1-2</version>
+ <version>1-3</version>
<interface>
<name>ICameraProvider</name>
<regex-instance>[^/]+/[0-9]+</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.cas</name>
<interface>
<name>IMediaCasService</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.confirmationui</name>
<version>1</version>
<interface>
@@ -186,7 +200,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.contexthub</name>
<version>3</version>
<interface>
@@ -194,7 +208,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.drm</name>
<version>1</version>
<interface>
@@ -202,14 +216,14 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.dumpstate</name>
<interface>
<name>IDumpstateDevice</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.gatekeeper</name>
<version>1</version>
<interface>
@@ -217,7 +231,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.gnss</name>
<version>2-4</version>
<interface>
@@ -225,7 +239,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.graphics.allocator</name>
<version>1-2</version>
<interface>
@@ -233,7 +247,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.graphics.composer3</name>
<version>3</version>
<interface>
@@ -241,15 +255,15 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.health</name>
- <version>1-2</version>
+ <version>3</version>
<interface>
<name>IHealth</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.health.storage</name>
<version>1</version>
<interface>
@@ -257,7 +271,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.identity</name>
<version>1-5</version>
<interface>
@@ -265,14 +279,14 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.net.nlinterceptor</name>
<interface>
<name>IInterceptor</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.oemlock</name>
<version>1</version>
<interface>
@@ -280,7 +294,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.ir</name>
<version>1</version>
<interface>
@@ -288,7 +302,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.input.processor</name>
<version>1</version>
<interface>
@@ -296,7 +310,16 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl">
+ <name>android.hardware.security.secretkeeper</name>
+ <version>1</version>
+ <interface>
+ <name>ISecretkeeper</name>
+ <instance>default</instance>
+ <instance>nonsecure</instance>
+ </interface>
+ </hal>
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.security.keymint</name>
<version>1-3</version>
<interface>
@@ -305,7 +328,7 @@
<instance>strongbox</instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.security.keymint</name>
<version>1-3</version>
<interface>
@@ -314,7 +337,7 @@
<instance>strongbox</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.light</name>
<version>2</version>
<interface>
@@ -322,26 +345,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.media.c2</name>
- <version>1.0-2</version>
- <interface>
- <name>IComponentStore</name>
- <instance>software</instance>
- <regex-instance>default[0-9]*</regex-instance>
- <regex-instance>vendor[0-9]*_software</regex-instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.media.c2</name>
- <version>1.0</version>
- <interface>
- <name>IConfigurable</name>
- <instance>default</instance>
- <instance>software</instance>
- </interface>
- </hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.media.c2</name>
<version>1</version>
<interface>
@@ -350,7 +354,7 @@
<regex-instance>vendor[0-9]*_software</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.memtrack</name>
<version>1</version>
<interface>
@@ -358,7 +362,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.neuralnetworks</name>
<version>1-4</version>
<interface>
@@ -366,14 +370,14 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.nfc</name>
<interface>
<name>INfc</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.power</name>
<version>5</version>
<interface>
@@ -381,7 +385,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.power.stats</name>
<version>2</version>
<interface>
@@ -389,7 +393,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.config</name>
<version>3</version>
<interface>
@@ -397,7 +401,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.data</name>
<version>3</version>
<interface>
@@ -407,7 +411,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.messaging</name>
<version>3</version>
<interface>
@@ -417,7 +421,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.modem</name>
<version>3</version>
<interface>
@@ -427,7 +431,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.network</name>
<version>3</version>
<interface>
@@ -437,7 +441,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.sim</name>
<version>3</version>
<interface>
@@ -447,7 +451,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.sap</name>
<version>1</version>
<interface>
@@ -457,7 +461,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.voice</name>
<version>3</version>
<interface>
@@ -467,7 +471,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.ims</name>
<version>2</version>
<interface>
@@ -477,7 +481,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.ims.media</name>
<version>2</version>
<interface>
@@ -485,7 +489,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.rebootescrow</name>
<version>1</version>
<interface>
@@ -493,7 +497,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.secure_element</name>
<version>1</version>
<interface>
@@ -502,7 +506,7 @@
<regex-instance>SIM[1-9][0-9]*</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.security.authgraph</name>
<version>1</version>
<interface>
@@ -510,7 +514,7 @@
<instance>nonsecure</instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.security.secureclock</name>
<version>1</version>
<interface>
@@ -518,7 +522,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.security.sharedsecret</name>
<version>1</version>
<interface>
@@ -527,7 +531,7 @@
<instance>strongbox</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.sensors</name>
<version>2</version>
<interface>
@@ -535,7 +539,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.soundtrigger3</name>
<version>1-2</version>
<interface>
@@ -543,7 +547,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.tetheroffload</name>
<version>1</version>
<interface>
@@ -551,15 +555,15 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.thermal</name>
- <version>1</version>
+ <version>2</version>
<interface>
<name>IThermal</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.threadnetwork</name>
<version>1</version>
<interface>
@@ -567,7 +571,7 @@
<regex-instance>chip[0-9]+</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.tv.hdmi.cec</name>
<version>1</version>
<interface>
@@ -575,7 +579,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.tv.hdmi.earc</name>
<version>1</version>
<interface>
@@ -583,7 +587,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.tv.hdmi.connection</name>
<version>1</version>
<interface>
@@ -591,7 +595,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.tv.tuner</name>
<version>1-2</version>
<interface>
@@ -599,7 +603,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.tv.input</name>
<version>1-2</version>
<interface>
@@ -607,7 +611,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.usb</name>
<version>1-3</version>
<interface>
@@ -615,14 +619,14 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.usb.gadget</name>
<interface>
<name>IUsbGadget</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.vibrator</name>
<version>1-2</version>
<interface>
@@ -630,7 +634,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.vibrator</name>
<version>1-2</version>
<interface>
@@ -638,7 +642,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.weaver</name>
<version>2</version>
<interface>
@@ -646,7 +650,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.wifi</name>
<version>1-2</version>
<interface>
@@ -654,7 +658,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.uwb</name>
<version>1</version>
<interface>
@@ -662,15 +666,15 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.wifi.hostapd</name>
- <version>1</version>
+ <version>1-2</version>
<interface>
<name>IHostapd</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.wifi.supplicant</name>
<version>2-3</version>
<interface>
@@ -679,7 +683,7 @@
</interface>
</hal>
<!-- The native mapper HAL must exist on the device -->
- <hal format="native" optional="true">
+ <hal format="native">
<name>mapper</name>
<version>5.0</version>
<interface>
diff --git a/compatibility_matrices/compatibility_matrix.4.xml b/compatibility_matrices/compatibility_matrix.4.xml
deleted file mode 100644
index bb7637a..0000000
--- a/compatibility_matrices/compatibility_matrix.4.xml
+++ /dev/null
@@ -1,525 +0,0 @@
-<compatibility-matrix version="1.0" type="framework" level="4">
- <hal format="hidl" optional="true">
- <name>android.hardware.atrace</name>
- <version>1.0</version>
- <interface>
- <name>IAtraceDevice</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.audio</name>
- <version>5.0</version>
- <interface>
- <name>IDevicesFactory</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.audio.effect</name>
- <version>5.0</version>
- <interface>
- <name>IEffectsFactory</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.authsecret</name>
- <version>1.0</version>
- <interface>
- <name>IAuthSecret</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.automotive.audiocontrol</name>
- <version>1.0</version>
- <interface>
- <name>IAudioControl</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.automotive.evs</name>
- <version>1.0</version>
- <interface>
- <name>IEvsEnumerator</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.automotive.vehicle</name>
- <version>2.0</version>
- <interface>
- <name>IVehicle</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.biometrics.face</name>
- <version>1.0</version>
- <interface>
- <name>IBiometricsFace</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.biometrics.fingerprint</name>
- <version>2.1</version>
- <interface>
- <name>IBiometricsFingerprint</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.bluetooth</name>
- <version>1.0</version>
- <interface>
- <name>IBluetoothHci</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.bluetooth.audio</name>
- <version>2.0</version>
- <interface>
- <name>IBluetoothAudioProvidersFactory</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.boot</name>
- <version>1.0</version>
- <interface>
- <name>IBootControl</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.broadcastradio</name>
- <version>1.0-1</version>
- <interface>
- <name>IBroadcastRadioFactory</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.broadcastradio</name>
- <version>2.0</version>
- <interface>
- <name>IBroadcastRadio</name>
- <regex-instance>.*</regex-instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.camera.provider</name>
- <version>2.4-5</version>
- <interface>
- <name>ICameraProvider</name>
- <regex-instance>[^/]+/[0-9]+</regex-instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.cas</name>
- <version>1.1</version>
- <interface>
- <name>IMediaCasService</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.configstore</name>
- <version>1.1</version>
- <interface>
- <name>ISurfaceFlingerConfigs</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.confirmationui</name>
- <version>1.0</version>
- <interface>
- <name>IConfirmationUI</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.contexthub</name>
- <version>1.0</version>
- <interface>
- <name>IContexthub</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.drm</name>
- <version>1.0-2</version>
- <interface>
- <name>ICryptoFactory</name>
- <regex-instance>.*</regex-instance>
- </interface>
- <interface>
- <name>IDrmFactory</name>
- <regex-instance>.*</regex-instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.dumpstate</name>
- <version>1.0</version>
- <interface>
- <name>IDumpstateDevice</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.gatekeeper</name>
- <version>1.0</version>
- <interface>
- <name>IGatekeeper</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.gnss</name>
- <version>2.0</version>
- <interface>
- <name>IGnss</name>
- <instance>default</instance>
- </interface>
- </hal>
- <!-- Either the AIDL or the HIDL allocator HAL must exist on the device.
- If the HIDL composer HAL exists, it must be at least version 2.0.
- See DeviceManifestTest.GrallocHal -->
- <hal format="hidl" optional="true">
- <name>android.hardware.graphics.allocator</name>
- <version>2.0</version>
- <version>3.0</version>
- <interface>
- <name>IAllocator</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.graphics.composer</name>
- <version>2.1-3</version>
- <interface>
- <name>IComposer</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.graphics.mapper</name>
- <version>2.1</version>
- <version>3.0</version>
- <interface>
- <name>IMapper</name>
- <instance>default</instance>
- </interface>
- </hal>
- <!-- Either the AIDL or the HIDL health HAL must exist on the device.
- If the HIDL health HAL exists, it must be at least version 2.0.
- See DeviceManifestTest.HealthHal -->
- <hal format="hidl" optional="true">
- <name>android.hardware.health</name>
- <version>2.0</version>
- <interface>
- <name>IHealth</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.health.storage</name>
- <version>1.0</version>
- <interface>
- <name>IStorage</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.ir</name>
- <version>1.0</version>
- <interface>
- <name>IConsumerIr</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.input.classifier</name>
- <version>1.0</version>
- <interface>
- <name>IInputClassifier</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.keymaster</name>
- <version>3.0</version>
- <version>4.0</version>
- <interface>
- <name>IKeymasterDevice</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.keymaster</name>
- <version>4.0</version>
- <interface>
- <name>IKeymasterDevice</name>
- <instance>strongbox</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.light</name>
- <version>2.0</version>
- <interface>
- <name>ILight</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.media.c2</name>
- <version>1.0</version>
- <interface>
- <name>IComponentStore</name>
- <instance>software</instance>
- <regex-instance>default[0-9]*</regex-instance>
- <regex-instance>vendor[0-9]*_software</regex-instance>
- </interface>
- <interface>
- <name>IConfigurable</name>
- <instance>default</instance>
- <instance>software</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.media.omx</name>
- <version>1.0</version>
- <interface>
- <name>IOmx</name>
- <instance>default</instance>
- </interface>
- <interface>
- <name>IOmxStore</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.memtrack</name>
- <version>1.0</version>
- <interface>
- <name>IMemtrack</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.neuralnetworks</name>
- <version>1.0-2</version>
- <interface>
- <name>IDevice</name>
- <regex-instance>.*</regex-instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.nfc</name>
- <version>1.2</version>
- <interface>
- <name>INfc</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.oemlock</name>
- <version>1.0</version>
- <interface>
- <name>IOemLock</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.power</name>
- <version>1.0-3</version>
- <interface>
- <name>IPower</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.power.stats</name>
- <version>1.0</version>
- <interface>
- <name>IPowerStats</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.radio</name>
- <version>1.4</version>
- <interface>
- <name>IRadio</name>
- <instance>slot1</instance>
- <instance>slot2</instance>
- <instance>slot3</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.radio</name>
- <version>1.2</version>
- <interface>
- <name>ISap</name>
- <instance>slot1</instance>
- <instance>slot2</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.radio.config</name>
- <!--
- Note: Devices launching with target-level 4, if implementing the
- radio config HAL, must provide an implementation of 1.1 IRadioConfig
- that can handle version 1.2 of IRadioConfigResponse and
- IRadioConfigIndication.
- -->
- <version>1.1</version>
- <interface>
- <name>IRadioConfig</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.renderscript</name>
- <version>1.0</version>
- <interface>
- <name>IDevice</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.secure_element</name>
- <version>1.0</version>
- <interface>
- <name>ISecureElement</name>
- <regex-instance>eSE[1-9][0-9]*</regex-instance>
- <regex-instance>SIM[1-9][0-9]*</regex-instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.sensors</name>
- <version>1.0</version>
- <version>2.0</version>
- <interface>
- <name>ISensors</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.soundtrigger</name>
- <version>2.0-2</version>
- <interface>
- <name>ISoundTriggerHw</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.tetheroffload.config</name>
- <version>1.0</version>
- <interface>
- <name>IOffloadConfig</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.tetheroffload.control</name>
- <version>1.0</version>
- <interface>
- <name>IOffloadControl</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.thermal</name>
- <version>2.0</version>
- <interface>
- <name>IThermal</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.tv.cec</name>
- <version>1.0</version>
- <interface>
- <name>IHdmiCec</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.tv.input</name>
- <version>1.0</version>
- <interface>
- <name>ITvInput</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.usb</name>
- <version>1.0-2</version>
- <interface>
- <name>IUsb</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.usb.gadget</name>
- <version>1.0</version>
- <interface>
- <name>IUsbGadget</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.vibrator</name>
- <version>1.0-3</version>
- <interface>
- <name>IVibrator</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.vr</name>
- <version>1.0</version>
- <interface>
- <name>IVr</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.weaver</name>
- <version>1.0</version>
- <interface>
- <name>IWeaver</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.wifi</name>
- <version>1.0-3</version>
- <interface>
- <name>IWifi</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.wifi.hostapd</name>
- <version>1.0-1</version>
- <interface>
- <name>IHostapd</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.wifi.supplicant</name>
- <version>1.0-2</version>
- <interface>
- <name>ISupplicant</name>
- <instance>default</instance>
- </interface>
- </hal>
-</compatibility-matrix>
diff --git a/compatibility_matrices/compatibility_matrix.5.xml b/compatibility_matrices/compatibility_matrix.5.xml
index dad1558..1cf98b0 100644
--- a/compatibility_matrices/compatibility_matrix.5.xml
+++ b/compatibility_matrices/compatibility_matrix.5.xml
@@ -1,5 +1,5 @@
<compatibility-matrix version="1.0" type="framework" level="5">
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.atrace</name>
<version>1.0</version>
<interface>
@@ -7,7 +7,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.audio</name>
<version>6.0</version>
<interface>
@@ -15,7 +15,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.audio.effect</name>
<version>6.0</version>
<interface>
@@ -23,7 +23,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.authsecret</name>
<version>1.0</version>
<interface>
@@ -31,7 +31,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.automotive.audiocontrol</name>
<version>1.0</version>
<version>2.0</version>
@@ -40,7 +40,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.automotive.can</name>
<version>1.0</version>
<interface>
@@ -52,7 +52,7 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.automotive.evs</name>
<version>1.0-1</version>
<interface>
@@ -61,14 +61,14 @@
<regex-instance>[a-z]+/[0-9]+</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.automotive.occupant_awareness</name>
<interface>
<name>IOccupantAwareness</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.automotive.sv</name>
<version>1.0</version>
<interface>
@@ -76,7 +76,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.automotive.vehicle</name>
<version>2.0</version>
<interface>
@@ -84,7 +84,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.biometrics.face</name>
<version>1.0</version>
<interface>
@@ -92,7 +92,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.biometrics.fingerprint</name>
<version>2.1-2</version>
<interface>
@@ -100,7 +100,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.bluetooth</name>
<version>1.0-1</version>
<interface>
@@ -108,7 +108,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.bluetooth.audio</name>
<version>2.0</version>
<interface>
@@ -116,7 +116,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.boot</name>
<version>1.1</version>
<interface>
@@ -124,7 +124,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.broadcastradio</name>
<version>1.0-1</version>
<interface>
@@ -132,7 +132,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.broadcastradio</name>
<version>2.0</version>
<interface>
@@ -140,7 +140,7 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.camera.provider</name>
<version>2.4-6</version>
<interface>
@@ -148,7 +148,7 @@
<regex-instance>[^/]+/[0-9]+</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.cas</name>
<version>1.1-2</version>
<interface>
@@ -156,7 +156,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.confirmationui</name>
<version>1.0</version>
<interface>
@@ -164,7 +164,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.contexthub</name>
<version>1.0-1</version>
<interface>
@@ -172,7 +172,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.drm</name>
<version>1.3</version>
<interface>
@@ -184,7 +184,7 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.dumpstate</name>
<version>1.1</version>
<interface>
@@ -192,7 +192,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.gatekeeper</name>
<version>1.0</version>
<interface>
@@ -200,7 +200,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.gnss</name>
<version>2.0-1</version>
<interface>
@@ -211,7 +211,7 @@
<!-- Either the AIDL or the HIDL allocator HAL must exist on the device.
If the HIDL composer HAL exists, it must be at least version 2.0.
See DeviceManifestTest.GrallocHal -->
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.graphics.allocator</name>
<!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
<version>2.0</version>
@@ -222,7 +222,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.graphics.composer</name>
<version>2.1-4</version>
<interface>
@@ -230,7 +230,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.graphics.mapper</name>
<!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
<version>2.1</version>
@@ -244,7 +244,7 @@
<!-- Either the AIDL or the HIDL health HAL must exist on the device.
If the HIDL health HAL exists, it must be at least version 2.1.
See DeviceManifestTest.HealthHal -->
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.health</name>
<version>2.1</version>
<interface>
@@ -252,7 +252,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.health.storage</name>
<version>1.0</version>
<interface>
@@ -260,7 +260,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.identity</name>
<!--
b/178458001: identity V2 is introduced in R, but Android R VINTF does not support AIDL
@@ -274,7 +274,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.ir</name>
<version>1.0</version>
<interface>
@@ -282,7 +282,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.input.classifier</name>
<version>1.0</version>
<interface>
@@ -290,7 +290,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.keymaster</name>
<version>3.0</version>
<version>4.0-1</version>
@@ -299,7 +299,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.keymaster</name>
<version>4.0-1</version>
<interface>
@@ -307,14 +307,14 @@
<instance>strongbox</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.light</name>
<interface>
<name>ILights</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.media.c2</name>
<version>1.0-1</version>
<interface>
@@ -324,7 +324,7 @@
<regex-instance>vendor[0-9]*_software</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.media.c2</name>
<version>1.0</version>
<interface>
@@ -333,7 +333,7 @@
<instance>software</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.media.omx</name>
<version>1.0</version>
<interface>
@@ -345,7 +345,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.memtrack</name>
<version>1.0</version>
<interface>
@@ -353,7 +353,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.neuralnetworks</name>
<version>1.0-3</version>
<interface>
@@ -361,7 +361,7 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.nfc</name>
<version>1.2</version>
<interface>
@@ -369,7 +369,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.oemlock</name>
<version>1.0</version>
<interface>
@@ -377,14 +377,14 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.power</name>
<interface>
<name>IPower</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.power.stats</name>
<version>1.0</version>
<interface>
@@ -392,7 +392,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.radio</name>
<version>1.4</version>
<version>1.5</version>
@@ -403,7 +403,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.radio</name>
<version>1.2</version>
<interface>
@@ -412,7 +412,7 @@
<instance>slot2</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.radio.config</name>
<!--
See compatibility_matrix.4.xml on versioning of radio config HAL.
@@ -423,7 +423,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.renderscript</name>
<version>1.0</version>
<interface>
@@ -431,14 +431,14 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.rebootescrow</name>
<interface>
<name>IRebootEscrow</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.secure_element</name>
<version>1.0-2</version>
<interface>
@@ -447,7 +447,7 @@
<regex-instance>SIM[1-9][0-9]*</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.sensors</name>
<version>1.0</version>
<version>2.0-1</version>
@@ -456,7 +456,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.soundtrigger</name>
<version>2.0-3</version>
<interface>
@@ -464,7 +464,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.tetheroffload.config</name>
<version>1.0</version>
<interface>
@@ -472,7 +472,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.tetheroffload.control</name>
<version>1.0</version>
<interface>
@@ -480,7 +480,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.thermal</name>
<version>2.0</version>
<interface>
@@ -488,7 +488,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.tv.cec</name>
<version>1.0</version>
<interface>
@@ -496,7 +496,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.tv.input</name>
<version>1.0</version>
<interface>
@@ -504,7 +504,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.tv.tuner</name>
<version>1.0</version>
<interface>
@@ -512,7 +512,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.usb</name>
<version>1.0-2</version>
<interface>
@@ -520,7 +520,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.usb.gadget</name>
<version>1.0-1</version>
<interface>
@@ -528,14 +528,14 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.vibrator</name>
<interface>
<name>IVibrator</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.vr</name>
<version>1.0</version>
<interface>
@@ -543,7 +543,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.weaver</name>
<version>1.0</version>
<interface>
@@ -551,7 +551,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.wifi</name>
<version>1.0-4</version>
<interface>
@@ -559,7 +559,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.wifi.hostapd</name>
<version>1.0-2</version>
<interface>
@@ -567,7 +567,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.wifi.supplicant</name>
<version>1.0-3</version>
<interface>
diff --git a/compatibility_matrices/compatibility_matrix.6.xml b/compatibility_matrices/compatibility_matrix.6.xml
index 23f634d..fdd7952 100644
--- a/compatibility_matrices/compatibility_matrix.6.xml
+++ b/compatibility_matrices/compatibility_matrix.6.xml
@@ -1,5 +1,5 @@
<compatibility-matrix version="1.0" type="framework" level="6">
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.atrace</name>
<version>1.0</version>
<interface>
@@ -7,7 +7,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.audio</name>
<version>6.0</version>
<version>7.0</version>
@@ -16,7 +16,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.audio.effect</name>
<version>6.0</version>
<version>7.0</version>
@@ -25,7 +25,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.authsecret</name>
<version>1</version>
<interface>
@@ -33,7 +33,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.authsecret</name>
<version>1.0</version>
<interface>
@@ -41,14 +41,14 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.automotive.audiocontrol</name>
<interface>
<name>IAudioControl</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.automotive.can</name>
<version>1.0</version>
<interface>
@@ -60,7 +60,7 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.automotive.evs</name>
<version>1.0-1</version>
<interface>
@@ -69,7 +69,7 @@
<regex-instance>[a-z]+/[0-9]+</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.automotive.occupant_awareness</name>
<version>1</version>
<interface>
@@ -77,7 +77,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.automotive.sv</name>
<version>1.0</version>
<interface>
@@ -85,7 +85,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.automotive.vehicle</name>
<version>2.0</version>
<interface>
@@ -93,7 +93,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.biometrics.face</name>
<version>1.0</version>
<interface>
@@ -101,14 +101,14 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.biometrics.face</name>
<interface>
<name>IFace</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.biometrics.fingerprint</name>
<version>2.1-3</version>
<interface>
@@ -116,14 +116,14 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.biometrics.fingerprint</name>
<interface>
<name>IFingerprint</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.bluetooth</name>
<version>1.0-1</version>
<interface>
@@ -131,7 +131,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.bluetooth.audio</name>
<version>2.0-1</version>
<interface>
@@ -139,7 +139,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.boot</name>
<version>1.2</version>
<interface>
@@ -147,7 +147,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.broadcastradio</name>
<version>1.0-1</version>
<interface>
@@ -155,7 +155,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.broadcastradio</name>
<version>2.0</version>
<interface>
@@ -163,7 +163,7 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.camera.provider</name>
<version>2.4-7</version>
<interface>
@@ -171,7 +171,7 @@
<regex-instance>[^/]+/[0-9]+</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.cas</name>
<version>1.1-2</version>
<interface>
@@ -179,7 +179,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.confirmationui</name>
<version>1.0</version>
<interface>
@@ -187,7 +187,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.contexthub</name>
<version>1.2</version>
<interface>
@@ -195,7 +195,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.drm</name>
<version>1.3-4</version>
<interface>
@@ -207,7 +207,7 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.dumpstate</name>
<version>1.1</version>
<interface>
@@ -215,7 +215,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.gatekeeper</name>
<version>1.0</version>
<interface>
@@ -223,7 +223,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.gnss</name>
<version>2.0-1</version>
<interface>
@@ -231,7 +231,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.gnss</name>
<interface>
<name>IGnss</name>
@@ -241,7 +241,7 @@
<!-- Either the AIDL or the HIDL allocator HAL must exist on the device.
If the HIDL composer HAL exists, it must be at least version 2.0.
See DeviceManifestTest.GrallocHal -->
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.graphics.allocator</name>
<!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
<version>2.0</version>
@@ -252,7 +252,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.graphics.composer</name>
<version>2.1-4</version>
<interface>
@@ -260,7 +260,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.graphics.mapper</name>
<!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
<version>2.1</version>
@@ -274,7 +274,7 @@
<!-- Either the AIDL or the HIDL health HAL must exist on the device.
If the HIDL health HAL exists, it must be at least version 2.1.
See DeviceManifestTest.HealthHal -->
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.health</name>
<version>2.1</version>
<interface>
@@ -282,7 +282,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.health.storage</name>
<version>1</version>
<interface>
@@ -290,7 +290,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.identity</name>
<version>1-3</version>
<interface>
@@ -298,7 +298,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.oemlock</name>
<version>1</version>
<interface>
@@ -306,7 +306,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.ir</name>
<version>1.0</version>
<interface>
@@ -314,7 +314,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.input.classifier</name>
<version>1.0</version>
<interface>
@@ -322,7 +322,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.keymaster</name>
<version>3.0</version>
<version>4.0-1</version>
@@ -331,7 +331,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.keymaster</name>
<version>4.0-1</version>
<interface>
@@ -339,7 +339,7 @@
<instance>strongbox</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.security.keymint</name>
<version>1</version>
<interface>
@@ -348,14 +348,14 @@
<instance>strongbox</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.security.keymint</name>
<interface>
<name>IRemotelyProvisionedComponent</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.light</name>
<version>1</version>
<interface>
@@ -363,7 +363,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.media.c2</name>
<version>1.0-2</version>
<interface>
@@ -373,7 +373,7 @@
<regex-instance>vendor[0-9]*_software</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.media.c2</name>
<version>1.0</version>
<interface>
@@ -382,7 +382,7 @@
<instance>software</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.media.omx</name>
<version>1.0</version>
<interface>
@@ -394,7 +394,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.memtrack</name>
<version>1</version>
<interface>
@@ -402,7 +402,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.neuralnetworks</name>
<version>1.0-3</version>
<interface>
@@ -410,14 +410,14 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.neuralnetworks</name>
<interface>
<name>IDevice</name>
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.nfc</name>
<version>1.2</version>
<interface>
@@ -425,7 +425,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.oemlock</name>
<version>1.0</version>
<interface>
@@ -433,7 +433,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.power</name>
<version>1-2</version>
<interface>
@@ -441,14 +441,14 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.power.stats</name>
<interface>
<name>IPowerStats</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.radio</name>
<version>1.6</version>
<interface>
@@ -458,7 +458,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.radio</name>
<version>1.2</version>
<interface>
@@ -467,7 +467,7 @@
<instance>slot2</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.radio.config</name>
<!--
See compatibility_matrix.4.xml on versioning of radio config HAL.
@@ -478,7 +478,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.radio.config</name>
<version>1.3</version>
<interface>
@@ -486,7 +486,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.renderscript</name>
<version>1.0</version>
<interface>
@@ -494,7 +494,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.rebootescrow</name>
<version>1</version>
<interface>
@@ -502,7 +502,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.secure_element</name>
<version>1.0-2</version>
<interface>
@@ -511,7 +511,7 @@
<regex-instance>SIM[1-9][0-9]*</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.security.secureclock</name>
<version>1</version>
<interface>
@@ -519,7 +519,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.security.sharedsecret</name>
<version>1</version>
<interface>
@@ -528,7 +528,7 @@
<instance>strongbox</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.sensors</name>
<version>1.0</version>
<version>2.0-1</version>
@@ -537,7 +537,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.soundtrigger</name>
<version>2.3</version>
<interface>
@@ -545,7 +545,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.tetheroffload.config</name>
<version>1.0</version>
<interface>
@@ -553,7 +553,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.tetheroffload.control</name>
<version>1.1</version>
<interface>
@@ -561,7 +561,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.thermal</name>
<version>2.0</version>
<interface>
@@ -569,7 +569,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.tv.cec</name>
<version>1.0-1</version>
<interface>
@@ -577,7 +577,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.tv.input</name>
<version>1.0</version>
<interface>
@@ -585,7 +585,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.tv.tuner</name>
<version>1.0-1</version>
<interface>
@@ -593,7 +593,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.usb</name>
<version>1.0-3</version>
<interface>
@@ -601,7 +601,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.usb.gadget</name>
<version>1.0-2</version>
<interface>
@@ -609,7 +609,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.vibrator</name>
<version>1-2</version>
<interface>
@@ -617,7 +617,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.vibrator</name>
<version>1-2</version>
<interface>
@@ -625,7 +625,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.weaver</name>
<version>1.0</version>
<interface>
@@ -633,7 +633,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.weaver</name>
<version>1</version>
<interface>
@@ -641,7 +641,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.wifi</name>
<version>1.3-5</version>
<interface>
@@ -649,7 +649,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.wifi.hostapd</name>
<version>1.0-3</version>
<interface>
@@ -657,7 +657,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.wifi.supplicant</name>
<version>1.2-4</version>
<interface>
diff --git a/compatibility_matrices/compatibility_matrix.7.xml b/compatibility_matrices/compatibility_matrix.7.xml
index fe424bd..8dcc4ae 100644
--- a/compatibility_matrices/compatibility_matrix.7.xml
+++ b/compatibility_matrices/compatibility_matrix.7.xml
@@ -1,5 +1,5 @@
<compatibility-matrix version="1.0" type="framework" level="7">
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.atrace</name>
<version>1.0</version>
<interface>
@@ -7,7 +7,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.audio</name>
<version>6.0</version>
<version>7.0-1</version>
@@ -16,7 +16,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.audio.effect</name>
<version>6.0</version>
<version>7.0</version>
@@ -25,7 +25,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.authsecret</name>
<version>1</version>
<interface>
@@ -33,7 +33,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.authsecret</name>
<version>1.0</version>
<interface>
@@ -41,7 +41,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.automotive.audiocontrol</name>
<version>1-2</version>
<interface>
@@ -49,7 +49,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.automotive.can</name>
<version>1.0</version>
<interface>
@@ -61,7 +61,7 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.automotive.evs</name>
<interface>
<name>IEvsEnumerator</name>
@@ -69,7 +69,7 @@
<regex-instance>[a-z]+/[0-9]+</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.automotive.evs</name>
<version>1.0-1</version>
<interface>
@@ -78,7 +78,7 @@
<regex-instance>[a-z]+/[0-9]+</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.automotive.occupant_awareness</name>
<version>1</version>
<interface>
@@ -86,14 +86,14 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.automotive.vehicle</name>
<interface>
<name>IVehicle</name>
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.automotive.vehicle</name>
<version>2.0</version>
<interface>
@@ -101,7 +101,7 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.biometrics.face</name>
<version>1.0</version>
<interface>
@@ -109,7 +109,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.biometrics.face</name>
<version>2</version>
<interface>
@@ -117,7 +117,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.biometrics.fingerprint</name>
<version>2.1-3</version>
<interface>
@@ -125,7 +125,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.biometrics.fingerprint</name>
<version>2</version>
<interface>
@@ -133,7 +133,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.bluetooth</name>
<version>1.0-1</version>
<interface>
@@ -141,7 +141,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.bluetooth.audio</name>
<version>2</version>
<interface>
@@ -149,7 +149,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.boot</name>
<version>1.2</version>
<interface>
@@ -157,7 +157,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.broadcastradio</name>
<version>1.0-1</version>
<interface>
@@ -165,7 +165,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.broadcastradio</name>
<version>2.0</version>
<interface>
@@ -173,7 +173,7 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.camera.provider</name>
<version>2.4-7</version>
<interface>
@@ -181,7 +181,7 @@
<regex-instance>[^/]+/[0-9]+</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.camera.provider</name>
<version>1</version>
<interface>
@@ -189,7 +189,7 @@
<regex-instance>[^/]+/[0-9]+</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.cas</name>
<version>1.1-2</version>
<interface>
@@ -197,7 +197,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.confirmationui</name>
<version>1.0</version>
<interface>
@@ -205,14 +205,14 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.contexthub</name>
<interface>
<name>IContextHub</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.drm</name>
<version>1</version>
<interface>
@@ -220,7 +220,7 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.drm</name>
<version>1.3-4</version>
<interface>
@@ -232,14 +232,14 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.dumpstate</name>
<interface>
<name>IDumpstateDevice</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.gatekeeper</name>
<version>1.0</version>
<interface>
@@ -247,7 +247,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.gnss</name>
<version>2.0-1</version>
<interface>
@@ -255,7 +255,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.gnss</name>
<version>2</version>
<interface>
@@ -263,7 +263,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.graphics.allocator</name>
<!-- New, non-Go devices should use 4.0 or the AIDL hal. -->
<version>2.0</version>
@@ -274,7 +274,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.graphics.allocator</name>
<version>1</version>
<interface>
@@ -285,7 +285,7 @@
<!-- Either the AIDL or the HIDL composer HAL must exist on the device.
If the HIDL composer HAL exists, it must be at least version 2.1.
See DeviceManifestTest.ComposerHal -->
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.graphics.composer</name>
<version>2.1-4</version>
<interface>
@@ -293,7 +293,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.graphics.composer3</name>
<version>1</version>
<interface>
@@ -301,7 +301,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.graphics.mapper</name>
<!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
<version>2.1</version>
@@ -312,7 +312,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.health</name>
<version>1</version>
<interface>
@@ -320,7 +320,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.health.storage</name>
<version>1</version>
<interface>
@@ -328,7 +328,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.identity</name>
<version>1-4</version>
<interface>
@@ -336,14 +336,14 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.net.nlinterceptor</name>
<interface>
<name>IInterceptor</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.oemlock</name>
<version>1</version>
<interface>
@@ -351,7 +351,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.ir</name>
<version>1</version>
<interface>
@@ -359,7 +359,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.input.processor</name>
<version>1</version>
<interface>
@@ -367,7 +367,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.keymaster</name>
<version>3.0</version>
<version>4.0-1</version>
@@ -376,7 +376,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.keymaster</name>
<version>4.0-1</version>
<interface>
@@ -384,7 +384,7 @@
<instance>strongbox</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.security.keymint</name>
<version>1-2</version>
<interface>
@@ -393,7 +393,7 @@
<instance>strongbox</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.security.keymint</name>
<version>1-2</version>
<interface>
@@ -402,7 +402,7 @@
<instance>strongbox</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.light</name>
<version>1-2</version>
<interface>
@@ -410,7 +410,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.media.c2</name>
<version>1.0-2</version>
<interface>
@@ -420,7 +420,7 @@
<regex-instance>vendor[0-9]*_software</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.media.c2</name>
<version>1.0</version>
<interface>
@@ -429,7 +429,7 @@
<instance>software</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.media.omx</name>
<version>1.0</version>
<interface>
@@ -441,7 +441,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.memtrack</name>
<version>1</version>
<interface>
@@ -449,7 +449,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.neuralnetworks</name>
<version>1.0-3</version>
<interface>
@@ -457,7 +457,7 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.neuralnetworks</name>
<version>1-4</version>
<interface>
@@ -465,7 +465,7 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.nfc</name>
<version>1.2</version>
<interface>
@@ -473,14 +473,14 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.nfc</name>
<interface>
<name>INfc</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.oemlock</name>
<version>1.0</version>
<interface>
@@ -488,7 +488,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.power</name>
<version>2-3</version>
<interface>
@@ -496,14 +496,14 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.power.stats</name>
<interface>
<name>IPowerStats</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.config</name>
<version>1</version>
<interface>
@@ -511,7 +511,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.data</name>
<version>1</version>
<interface>
@@ -521,7 +521,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.messaging</name>
<version>1</version>
<interface>
@@ -531,7 +531,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.modem</name>
<version>1</version>
<interface>
@@ -541,7 +541,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.network</name>
<version>1</version>
<interface>
@@ -551,7 +551,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.sim</name>
<version>1</version>
<interface>
@@ -561,7 +561,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.voice</name>
<version>1</version>
<interface>
@@ -571,7 +571,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.radio</name>
<version>1.2</version>
<interface>
@@ -580,7 +580,7 @@
<instance>slot2</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.renderscript</name>
<version>1.0</version>
<interface>
@@ -588,7 +588,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.rebootescrow</name>
<version>1</version>
<interface>
@@ -596,7 +596,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.secure_element</name>
<version>1.0-2</version>
<interface>
@@ -605,7 +605,7 @@
<regex-instance>SIM[1-9][0-9]*</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.security.secureclock</name>
<version>1</version>
<interface>
@@ -613,7 +613,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.security.sharedsecret</name>
<version>1</version>
<interface>
@@ -622,14 +622,14 @@
<instance>strongbox</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.sensors</name>
<interface>
<name>ISensors</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.sensors</name>
<version>1.0</version>
<version>2.0-1</version>
@@ -638,7 +638,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.soundtrigger</name>
<version>2.3</version>
<interface>
@@ -646,7 +646,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.soundtrigger3</name>
<version>1</version>
<interface>
@@ -654,7 +654,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.tetheroffload.config</name>
<version>1.0</version>
<interface>
@@ -662,7 +662,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.tetheroffload.control</name>
<version>1.1</version>
<interface>
@@ -670,7 +670,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.thermal</name>
<version>2.0</version>
<interface>
@@ -678,7 +678,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.tv.cec</name>
<version>1.0-1</version>
<interface>
@@ -686,7 +686,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.tv.input</name>
<version>1.0</version>
<interface>
@@ -694,7 +694,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.tv.tuner</name>
<version>1.0-1</version>
<interface>
@@ -702,7 +702,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.tv.tuner</name>
<version>1</version>
<interface>
@@ -710,7 +710,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.usb</name>
<version>1.0-3</version>
<interface>
@@ -718,14 +718,14 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.usb</name>
<interface>
<name>IUsb</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.usb.gadget</name>
<version>1.0-2</version>
<interface>
@@ -733,7 +733,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.vibrator</name>
<version>1-2</version>
<interface>
@@ -741,7 +741,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.vibrator</name>
<version>1-2</version>
<interface>
@@ -749,7 +749,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.weaver</name>
<version>1.0</version>
<interface>
@@ -757,7 +757,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.weaver</name>
<version>1</version>
<interface>
@@ -765,7 +765,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.wifi</name>
<version>1.3-6</version>
<interface>
@@ -773,7 +773,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.uwb</name>
<version>1</version>
<interface>
@@ -781,7 +781,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.wifi.hostapd</name>
<version>1</version>
<interface>
@@ -789,7 +789,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.wifi.supplicant</name>
<interface>
<name>ISupplicant</name>
diff --git a/compatibility_matrices/compatibility_matrix.8.xml b/compatibility_matrices/compatibility_matrix.8.xml
index 9057788..7054bfa 100644
--- a/compatibility_matrices/compatibility_matrix.8.xml
+++ b/compatibility_matrices/compatibility_matrix.8.xml
@@ -1,5 +1,5 @@
<compatibility-matrix version="1.0" type="framework" level="8">
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.audio</name>
<version>6.0</version>
<version>7.0-1</version>
@@ -8,7 +8,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.audio.effect</name>
<version>6.0</version>
<version>7.0</version>
@@ -17,7 +17,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.audio.core</name>
<version>1</version>
<interface>
@@ -36,7 +36,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.audio.effect</name>
<version>1</version>
<interface>
@@ -44,7 +44,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.audio.sounddose</name>
<version>1</version>
<interface>
@@ -52,7 +52,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.authsecret</name>
<version>1</version>
<interface>
@@ -60,7 +60,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.automotive.audiocontrol</name>
<version>2-3</version>
<interface>
@@ -68,7 +68,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.automotive.can</name>
<version>1</version>
<interface>
@@ -76,7 +76,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.automotive.evs</name>
<version>1-2</version>
<interface>
@@ -84,7 +84,7 @@
<regex-instance>[a-z]+/[0-9]+</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.automotive.occupant_awareness</name>
<version>1</version>
<interface>
@@ -92,7 +92,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.automotive.vehicle</name>
<version>1-2</version>
<interface>
@@ -100,30 +100,30 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.automotive.remoteaccess</name>
<interface>
<name>IRemoteAccess</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.automotive.ivn</name>
<interface>
<name>IIvnAndroidDevice</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.biometrics.face</name>
- <version>3</version>
+ <version>3-4</version>
<interface>
<name>IFace</name>
<instance>default</instance>
<instance>virtual</instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.biometrics.fingerprint</name>
<version>3</version>
<interface>
@@ -132,7 +132,7 @@
<instance>virtual</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.bluetooth</name>
<version>1.0-1</version>
<interface>
@@ -140,14 +140,14 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.bluetooth</name>
<interface>
<name>IBluetoothHci</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.bluetooth.audio</name>
<version>3</version>
<interface>
@@ -155,21 +155,21 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.boot</name>
<interface>
<name>IBootControl</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.broadcastradio</name>
<interface>
<name>IBroadcastRadio</name>
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.camera.provider</name>
<version>1-2</version>
<interface>
@@ -177,14 +177,14 @@
<regex-instance>[^/]+/[0-9]+</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.cas</name>
<interface>
<name>IMediaCasService</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.confirmationui</name>
<version>1</version>
<interface>
@@ -192,7 +192,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.contexthub</name>
<version>2</version>
<interface>
@@ -200,7 +200,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.drm</name>
<version>1</version>
<interface>
@@ -208,14 +208,14 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.dumpstate</name>
<interface>
<name>IDumpstateDevice</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.gatekeeper</name>
<version>1</version>
<interface>
@@ -223,7 +223,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.gnss</name>
<version>2-3</version>
<interface>
@@ -231,7 +231,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.graphics.allocator</name>
<version>1-2</version>
<interface>
@@ -239,7 +239,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.graphics.composer3</name>
<version>2</version>
<interface>
@@ -248,7 +248,7 @@
</interface>
</hal>
<!-- Either the native or the HIDL mapper HAL must exist on the device -->
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.graphics.mapper</name>
<!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
<version>2.1</version>
@@ -259,7 +259,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.health</name>
<version>1-2</version>
<interface>
@@ -267,7 +267,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.health.storage</name>
<version>1</version>
<interface>
@@ -275,7 +275,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.identity</name>
<version>1-5</version>
<interface>
@@ -283,14 +283,14 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.net.nlinterceptor</name>
<interface>
<name>IInterceptor</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.oemlock</name>
<version>1</version>
<interface>
@@ -298,7 +298,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.ir</name>
<version>1</version>
<interface>
@@ -306,7 +306,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.input.processor</name>
<version>1</version>
<interface>
@@ -314,7 +314,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.security.keymint</name>
<version>1-3</version>
<interface>
@@ -323,7 +323,7 @@
<instance>strongbox</instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.security.keymint</name>
<version>1-3</version>
<interface>
@@ -333,7 +333,7 @@
<instance>widevine</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.light</name>
<version>2</version>
<interface>
@@ -341,7 +341,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.media.c2</name>
<version>1.0-2</version>
<interface>
@@ -351,7 +351,7 @@
<regex-instance>vendor[0-9]*_software</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.media.c2</name>
<version>1.0</version>
<interface>
@@ -360,7 +360,7 @@
<instance>software</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.media.omx</name>
<version>1.0</version>
<interface>
@@ -372,7 +372,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.memtrack</name>
<version>1</version>
<interface>
@@ -380,7 +380,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.neuralnetworks</name>
<version>1-4</version>
<interface>
@@ -388,14 +388,14 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.nfc</name>
<interface>
<name>INfc</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.power</name>
<version>4</version>
<interface>
@@ -403,7 +403,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.power.stats</name>
<version>2</version>
<interface>
@@ -411,7 +411,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.config</name>
<version>2</version>
<interface>
@@ -419,7 +419,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.data</name>
<version>2</version>
<interface>
@@ -429,7 +429,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.messaging</name>
<version>2</version>
<interface>
@@ -439,7 +439,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.modem</name>
<version>2</version>
<interface>
@@ -449,7 +449,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.network</name>
<version>2</version>
<interface>
@@ -459,7 +459,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.sim</name>
<version>2</version>
<interface>
@@ -469,7 +469,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.sap</name>
<version>1</version>
<interface>
@@ -479,7 +479,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.voice</name>
<version>2</version>
<interface>
@@ -489,7 +489,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.ims</name>
<version>1</version>
<interface>
@@ -499,7 +499,7 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.radio.ims.media</name>
<version>1</version>
<interface>
@@ -507,7 +507,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.renderscript</name>
<version>1.0</version>
<interface>
@@ -515,7 +515,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.rebootescrow</name>
<version>1</version>
<interface>
@@ -523,7 +523,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.secure_element</name>
<version>1</version>
<interface>
@@ -532,7 +532,7 @@
<regex-instance>SIM[1-9][0-9]*</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.security.secureclock</name>
<version>1</version>
<interface>
@@ -540,7 +540,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.security.sharedsecret</name>
<version>1</version>
<interface>
@@ -549,7 +549,7 @@
<instance>strongbox</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.sensors</name>
<version>2</version>
<interface>
@@ -557,7 +557,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.soundtrigger</name>
<version>2.3</version>
<interface>
@@ -565,7 +565,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.soundtrigger3</name>
<version>1</version>
<interface>
@@ -573,7 +573,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.tetheroffload.config</name>
<version>1.0</version>
<interface>
@@ -581,7 +581,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="hidl">
<name>android.hardware.tetheroffload.control</name>
<version>1.1</version>
<interface>
@@ -589,7 +589,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.tetheroffload</name>
<version>1</version>
<interface>
@@ -597,7 +597,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.thermal</name>
<version>1</version>
<interface>
@@ -605,7 +605,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.tv.hdmi.cec</name>
<version>1</version>
<interface>
@@ -613,7 +613,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.tv.hdmi.earc</name>
<version>1</version>
<interface>
@@ -621,7 +621,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.tv.hdmi.connection</name>
<version>1</version>
<interface>
@@ -629,7 +629,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.tv.tuner</name>
<version>1-2</version>
<interface>
@@ -637,7 +637,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.tv.input</name>
<version>1</version>
<interface>
@@ -645,7 +645,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.usb</name>
<version>1-2</version>
<interface>
@@ -653,14 +653,14 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.usb.gadget</name>
<interface>
<name>IUsbGadget</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.vibrator</name>
<version>1-2</version>
<interface>
@@ -668,7 +668,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.vibrator</name>
<version>1-2</version>
<interface>
@@ -676,7 +676,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.weaver</name>
<version>2</version>
<interface>
@@ -684,7 +684,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.wifi</name>
<version>1</version>
<interface>
@@ -692,7 +692,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true" updatable-via-apex="true">
+ <hal format="aidl" updatable-via-apex="true">
<name>android.hardware.uwb</name>
<version>1</version>
<interface>
@@ -700,7 +700,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.wifi.hostapd</name>
<version>1</version>
<interface>
@@ -708,7 +708,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl">
<name>android.hardware.wifi.supplicant</name>
<version>2</version>
<interface>
@@ -717,7 +717,7 @@
</interface>
</hal>
<!-- Either the native or the HIDL mapper HAL must exist on the device -->
- <hal format="native" optional="true">
+ <hal format="native">
<name>mapper</name>
<version>5.0</version>
<interface>
diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp
index 46f0e03..08ef49b 100644
--- a/compatibility_matrices/exclude/fcm_exclude.cpp
+++ b/compatibility_matrices/exclude/fcm_exclude.cpp
@@ -84,6 +84,26 @@
"android.hardware.thermal@1.0",
"android.hardware.thermal@1.1",
"android.hardware.wifi.offload@1.0",
+
+ // b/279809679 for HALS deprecated in Q
+ "android.hardware.audio.effect@5.0",
+ "android.hardware.audio@5.0",
+ "android.hardware.boot@1.0",
+ "android.hardware.configstore@1.1",
+ "android.hardware.drm@1.0",
+ "android.hardware.drm@1.1",
+ "android.hardware.drm@1.2",
+ "android.hardware.dumpstate@1.0",
+ "android.hardware.health@2.0",
+ "android.hardware.light@2.0",
+ "android.hardware.power@1.0",
+ "android.hardware.power@1.1",
+ "android.hardware.power@1.2",
+ "android.hardware.power@1.3",
+ "android.hardware.vibrator@1.0",
+ "android.hardware.vibrator@1.1",
+ "android.hardware.vibrator@1.2",
+ "android.hardware.vibrator@1.3",
};
auto package_has_prefix = [&](const std::string& prefix) {
diff --git a/contexthub/OWNERS b/contexthub/OWNERS
index d5cfc2e..ee25833 100644
--- a/contexthub/OWNERS
+++ b/contexthub/OWNERS
@@ -1,4 +1,3 @@
# Bug component: 156070
arthuri@google.com
bduddie@google.com
-stange@google.com
diff --git a/contexthub/aidl/Android.bp b/contexthub/aidl/Android.bp
index cf10529..5905c8c 100644
--- a/contexthub/aidl/Android.bp
+++ b/contexthub/aidl/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_context_hub",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/ContextHubInfo.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/ContextHubInfo.aidl
index e573556..c99169e 100644
--- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/ContextHubInfo.aidl
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/ContextHubInfo.aidl
@@ -45,4 +45,5 @@
byte chreApiMinorVersion;
char chrePatchVersion;
String[] supportedPermissions;
+ boolean supportsReliableMessages;
}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/ContextHubMessage.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/ContextHubMessage.aidl
index e38c251..a6951a8 100644
--- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/ContextHubMessage.aidl
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/ContextHubMessage.aidl
@@ -39,4 +39,6 @@
int messageType;
byte[] messageBody;
String[] permissions;
+ boolean isReliable;
+ int messageSequenceNumber;
}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/ErrorCode.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/ErrorCode.aidl
new file mode 100644
index 0000000..8924658
--- /dev/null
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/ErrorCode.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.contexthub;
+@Backing(type="byte") @VintfStability
+enum ErrorCode {
+ OK = 0,
+ TRANSIENT_ERROR,
+ PERMANENT_ERROR,
+ PERMISSION_DENIED,
+ DESTINATION_NOT_FOUND,
+}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl
index de8d752..7341e0e 100644
--- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl
@@ -48,5 +48,6 @@
long[] getPreloadedNanoappIds(in int contextHubId);
void onNanSessionStateChanged(in android.hardware.contexthub.NanSessionStateUpdate update);
void setTestMode(in boolean enable);
+ void sendMessageDeliveryStatusToHub(in int contextHubId, in android.hardware.contexthub.MessageDeliveryStatus messageDeliveryStatus);
const int EX_CONTEXT_HUB_UNSPECIFIED = (-1) /* -1 */;
}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHubCallback.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHubCallback.aidl
index d0099ff..70f69c6 100644
--- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHubCallback.aidl
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHubCallback.aidl
@@ -39,6 +39,8 @@
void handleContextHubAsyncEvent(in android.hardware.contexthub.AsyncEventType evt);
void handleTransactionResult(in int transactionId, in boolean success);
void handleNanSessionRequest(in android.hardware.contexthub.NanSessionRequest request);
+ void handleMessageDeliveryStatus(in char hostEndpointId, in android.hardware.contexthub.MessageDeliveryStatus messageDeliveryStatus);
byte[16] getUuid();
+ String getName();
const int CONTEXTHUB_NAN_TRANSACTION_TIMEOUT_MS = 10000;
}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/MessageDeliveryStatus.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/MessageDeliveryStatus.aidl
new file mode 100644
index 0000000..40dac13
--- /dev/null
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/MessageDeliveryStatus.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.contexthub;
+@VintfStability
+parcelable MessageDeliveryStatus {
+ int messageSequenceNumber;
+ android.hardware.contexthub.ErrorCode errorCode;
+}
diff --git a/contexthub/aidl/android/hardware/contexthub/ContextHubInfo.aidl b/contexthub/aidl/android/hardware/contexthub/ContextHubInfo.aidl
index c0fa702..42dba10 100644
--- a/contexthub/aidl/android/hardware/contexthub/ContextHubInfo.aidl
+++ b/contexthub/aidl/android/hardware/contexthub/ContextHubInfo.aidl
@@ -33,7 +33,9 @@
/** Peak MIPs this platform can deliver */
float peakMips;
- /** The maximum length in bytes of the message that can be sent to the Context Hub. */
+ /**
+ * The maximum length in bytes of a message sent to the Context Hub.
+ */
int maxSupportedMessageLengthBytes;
/**
@@ -61,4 +63,11 @@
* are granted in order to communicate with them.
*/
String[] supportedPermissions;
+
+ /**
+ * True if the Context Hub supports reliable messages. False otherwise, in which case
+ * ContextHubMessage.isReliable must always be set to false. See
+ * ContextHubMessage.isReliable for more information.
+ */
+ boolean supportsReliableMessages;
}
diff --git a/contexthub/aidl/android/hardware/contexthub/ContextHubMessage.aidl b/contexthub/aidl/android/hardware/contexthub/ContextHubMessage.aidl
index 95d478e..3cd20ca 100644
--- a/contexthub/aidl/android/hardware/contexthub/ContextHubMessage.aidl
+++ b/contexthub/aidl/android/hardware/contexthub/ContextHubMessage.aidl
@@ -50,4 +50,35 @@
* of the permissions that the sending nanoapp is using.
*/
String[] permissions;
+
+ /**
+ * Whether the message is reliable.
+ *
+ * For reliable messages, the receiver is expected to acknowledge the reception of
+ * the message by sending a message delivery status back to the sender. Acknowledgment of
+ * the message must be returned within 1 second.
+ *
+ * For reliable messages sent by the host, the Context Hub invokes
+ * IContextHubCallback#handleMessageDeliveryStatus to report the status.
+ *
+ * For reliable messages sent by the Context Hub, the host calls
+ * IContextHub#sendMessageDeliveryStatusToHub to report the status.
+ */
+ boolean isReliable;
+
+ /**
+ * The sequence number for a reliable message. For less than 2^32 messages, each message sent
+ * from a Context Hub will have a unique sequence number generated by the Context Hub, and the
+ * sequence numbers are guaranteed to not be reused for unacknowledged messages. For messages
+ * sent to the Context Hub, sequence numbers are only guaranteed to be unique within the scope
+ * of a given hostEndPoint. The sequence number may be reused if more than 2^32 messages are
+ * sent, due to the size limit of int.
+ *
+ * The sequence number is used only for reliable messages. There is no guarantee of strict
+ * ordering of messages. The recipient may receive messages with gaps between the sequence
+ * numbers. This is not an indication of a missed message.
+ *
+ * See isReliable for more information.
+ */
+ int messageSequenceNumber;
}
diff --git a/contexthub/aidl/android/hardware/contexthub/ErrorCode.aidl b/contexthub/aidl/android/hardware/contexthub/ErrorCode.aidl
new file mode 100644
index 0000000..22e7ea1
--- /dev/null
+++ b/contexthub/aidl/android/hardware/contexthub/ErrorCode.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.contexthub;
+
+@VintfStability
+@Backing(type="byte")
+enum ErrorCode {
+ /**
+ * No Error.
+ */
+ OK = 0,
+
+ /**
+ * A generic transient error. The sender may retry the
+ * operation, but there is no guarantee of success.
+ */
+ TRANSIENT_ERROR,
+
+ /**
+ * A generic permanent error. The sender should not retry the operation.
+ */
+ PERMANENT_ERROR,
+
+ /**
+ * The request failed because the sender does not have necessary permissions.
+ * The sender should not retry the operation.
+ */
+ PERMISSION_DENIED,
+
+ /**
+ * The request failed because the destination was not found.
+ * The sender should not retry the operation.
+ */
+ DESTINATION_NOT_FOUND,
+}
diff --git a/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl b/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
index 9683d2d..b146ff8 100644
--- a/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
+++ b/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
@@ -20,6 +20,7 @@
import android.hardware.contexthub.ContextHubMessage;
import android.hardware.contexthub.HostEndpointInfo;
import android.hardware.contexthub.IContextHubCallback;
+import android.hardware.contexthub.MessageDeliveryStatus;
import android.hardware.contexthub.NanSessionStateUpdate;
import android.hardware.contexthub.NanoappBinary;
import android.hardware.contexthub.NanoappInfo;
@@ -147,7 +148,7 @@
/**
* Register a callback for the HAL implementation to send asynchronous messages to the service
- * from a Context hub. There can only be one callback registered for a single Context Hub ID.
+ * from a Context hub. Each HAL client can only have one callback for each Context Hub ID.
*
* A call to this function when a callback has already been registered must override the
* previous registration.
@@ -236,6 +237,21 @@
void setTestMode(in boolean enable);
/**
+ * Sends a message delivery status to the Context Hub in response to receiving a
+ * ContextHubMessage with isReliable=true. Each reliable message should have a
+ * messageDeliveryStatus response. This method sends the message delivery status
+ * back to the Context Hub.
+ *
+ * @param contextHubId The identifier of the Context Hub.
+ * @param messageDeliveryStatus The status to be sent.
+ *
+ * @throws EX_UNSUPPORTED_OPERATION if ContextHubInfo.supportsReliableMessages is false for
+ * this hub.
+ */
+ void sendMessageDeliveryStatusToHub(
+ in int contextHubId, in MessageDeliveryStatus messageDeliveryStatus);
+
+ /**
* Error codes that are used as service specific errors with the AIDL return
* value EX_SERVICE_SPECIFIC.
*/
diff --git a/contexthub/aidl/android/hardware/contexthub/IContextHubCallback.aidl b/contexthub/aidl/android/hardware/contexthub/IContextHubCallback.aidl
index 41fb266..1aa0776 100644
--- a/contexthub/aidl/android/hardware/contexthub/IContextHubCallback.aidl
+++ b/contexthub/aidl/android/hardware/contexthub/IContextHubCallback.aidl
@@ -18,6 +18,7 @@
import android.hardware.contexthub.AsyncEventType;
import android.hardware.contexthub.ContextHubMessage;
+import android.hardware.contexthub.MessageDeliveryStatus;
import android.hardware.contexthub.NanSessionRequest;
import android.hardware.contexthub.NanoappInfo;
@@ -91,14 +92,35 @@
void handleNanSessionRequest(in NanSessionRequest request);
/**
+ * This callback is passed by the Contexthub service to the HAL
+ * implementation to allow the HAL to send the response for a reliable message.
+ * The response is the message delivery status of a recently sent message. See
+ * sendMessageDeliveryStatusToHub() for more details.
+ *
+ * @param hostEndPointId The ID of the host endpoint associated with this message delivery
+ * status.
+ * @param messageDeliveryStatus The status to be sent.
+ */
+ void handleMessageDeliveryStatus(
+ in char hostEndpointId, in MessageDeliveryStatus messageDeliveryStatus);
+
+ /**
* This callback is passed to the HAL implementation to allow the HAL to request a UUID that
- * uniquely identifies an IContextHubCallback.
+ * uniquely identifies a client.
*
* @return a byte array representating the UUID
*/
byte[16] getUuid();
/**
+ * This callback gets the name of a client implementing this IContextHubCallback interface,
+ * which must be a hard-coded string and does not change at runtime.
+ *
+ * <p>The name provides a human-readable way to identify a client for troubleshooting purpose.
+ */
+ String getName();
+
+ /**
* Amount of time, in milliseconds, that a handleNanSessionRequest can be pending before the
* Contexthub service must respond.
*/
diff --git a/contexthub/aidl/android/hardware/contexthub/MessageDeliveryStatus.aidl b/contexthub/aidl/android/hardware/contexthub/MessageDeliveryStatus.aidl
new file mode 100644
index 0000000..ae425b3
--- /dev/null
+++ b/contexthub/aidl/android/hardware/contexthub/MessageDeliveryStatus.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.contexthub;
+
+import android.hardware.contexthub.ErrorCode;
+
+@VintfStability
+parcelable MessageDeliveryStatus {
+ /**
+ * The messageSequenceNumber of the ContextHubMessage to which this status applies.
+ */
+ int messageSequenceNumber;
+
+ /**
+ * The error code associated with this status.
+ */
+ ErrorCode errorCode;
+}
diff --git a/contexthub/aidl/default/Android.bp b/contexthub/aidl/default/Android.bp
index 03213bc..2960746 100644
--- a/contexthub/aidl/default/Android.bp
+++ b/contexthub/aidl/default/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_context_hub",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/contexthub/aidl/default/ContextHub.cpp b/contexthub/aidl/default/ContextHub.cpp
index 5272957..bd483d7 100644
--- a/contexthub/aidl/default/ContextHub.cpp
+++ b/contexthub/aidl/default/ContextHub.cpp
@@ -16,10 +16,7 @@
#include "contexthub-impl/ContextHub.h"
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace contexthub {
+namespace aidl::android::hardware::contexthub {
using ::ndk::ScopedAStatus;
@@ -34,10 +31,11 @@
hub.chrePlatformId = UINT64_C(0x476f6f6754000000);
hub.chreApiMajorVersion = 1;
hub.chreApiMinorVersion = 6;
+ hub.supportsReliableMessages = false;
out_contextHubInfos->push_back(hub);
- return ndk::ScopedAStatus::ok();
+ return ScopedAStatus::ok();
}
// We don't expose any nanoapps for the default impl, therefore all nanoapp-related APIs fail.
@@ -63,14 +61,14 @@
}
ScopedAStatus ContextHub::onSettingChanged(Setting /* in_setting */, bool /*in_enabled */) {
- return ndk::ScopedAStatus::ok();
+ return ScopedAStatus::ok();
}
ScopedAStatus ContextHub::queryNanoapps(int32_t in_contextHubId) {
if (in_contextHubId == kMockHubId && mCallback != nullptr) {
std::vector<NanoappInfo> nanoapps;
mCallback->handleNanoappInfo(nanoapps);
- return ndk::ScopedAStatus::ok();
+ return ScopedAStatus::ok();
} else {
return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
@@ -85,18 +83,18 @@
for (uint64_t i = 0; i < 10; ++i) {
out_preloadedNanoappIds->push_back(i);
}
- return ndk::ScopedAStatus::ok();
+ return ScopedAStatus::ok();
}
ScopedAStatus ContextHub::onNanSessionStateChanged(const NanSessionStateUpdate& /*in_update*/) {
- return ndk::ScopedAStatus::ok();
+ return ScopedAStatus::ok();
}
ScopedAStatus ContextHub::registerCallback(int32_t in_contextHubId,
const std::shared_ptr<IContextHubCallback>& in_cb) {
if (in_contextHubId == kMockHubId) {
mCallback = in_cb;
- return ndk::ScopedAStatus::ok();
+ return ScopedAStatus::ok();
} else {
return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
@@ -108,20 +106,20 @@
// Return true here to indicate that the HAL has accepted the message.
// Successful delivery of the message to a nanoapp should be handled at
// a higher level protocol.
- return ndk::ScopedAStatus::ok();
+ return ScopedAStatus::ok();
} else {
return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
}
ScopedAStatus ContextHub::setTestMode(bool /* enable */) {
- return ndk::ScopedAStatus::ok();
+ return ScopedAStatus::ok();
}
ScopedAStatus ContextHub::onHostEndpointConnected(const HostEndpointInfo& in_info) {
mConnectedHostEndpoints.insert(in_info.hostEndpointId);
- return ndk::ScopedAStatus::ok();
+ return ScopedAStatus::ok();
}
ScopedAStatus ContextHub::onHostEndpointDisconnected(char16_t in_hostEndpointId) {
@@ -129,10 +127,13 @@
mConnectedHostEndpoints.erase(in_hostEndpointId);
}
- return ndk::ScopedAStatus::ok();
+ return ScopedAStatus::ok();
}
-} // namespace contexthub
-} // namespace hardware
-} // namespace android
-} // namespace aidl
+ScopedAStatus ContextHub::sendMessageDeliveryStatusToHub(
+ int32_t /* in_contextHubId */,
+ const MessageDeliveryStatus& /* in_messageDeliveryStatus */) {
+ return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+} // namespace aidl::android::hardware::contexthub
diff --git a/contexthub/aidl/default/include/contexthub-impl/ContextHub.h b/contexthub/aidl/default/include/contexthub-impl/ContextHub.h
index 7a2cfd1..72e8b3b 100644
--- a/contexthub/aidl/default/include/contexthub-impl/ContextHub.h
+++ b/contexthub/aidl/default/include/contexthub-impl/ContextHub.h
@@ -49,6 +49,9 @@
::ndk::ScopedAStatus onHostEndpointDisconnected(char16_t in_hostEndpointId) override;
::ndk::ScopedAStatus onNanSessionStateChanged(const NanSessionStateUpdate& in_update) override;
+ ::ndk::ScopedAStatus sendMessageDeliveryStatusToHub(
+ int32_t in_contextHubId,
+ const MessageDeliveryStatus& in_messageDeliveryStatus) override;
private:
static constexpr uint32_t kMockHubId = 0;
diff --git a/contexthub/aidl/vts/Android.bp b/contexthub/aidl/vts/Android.bp
index b166baf..62a319e 100644
--- a/contexthub/aidl/vts/Android.bp
+++ b/contexthub/aidl/vts/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_context_hub",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
index e780857..fa427a5 100644
--- a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
+++ b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
@@ -36,9 +36,11 @@
using ::android::hardware::contexthub::AsyncEventType;
using ::android::hardware::contexthub::ContextHubInfo;
using ::android::hardware::contexthub::ContextHubMessage;
+using ::android::hardware::contexthub::ErrorCode;
using ::android::hardware::contexthub::HostEndpointInfo;
using ::android::hardware::contexthub::IContextHub;
using ::android::hardware::contexthub::IContextHubCallbackDefault;
+using ::android::hardware::contexthub::MessageDeliveryStatus;
using ::android::hardware::contexthub::NanoappBinary;
using ::android::hardware::contexthub::NanoappInfo;
using ::android::hardware::contexthub::NanoappRpcService;
@@ -49,8 +51,9 @@
using ::android::hardware::contexthub::vts_utils::waitForCallback;
// 6612b522-b717-41c8-b48d-c0b1cc64e142
-const std::array<uint8_t, 16> kUuid = {0x66, 0x12, 0xb5, 0x22, 0xb7, 0x17, 0x41, 0xc8,
- 0xb4, 0x8d, 0xc0, 0xb1, 0xcc, 0x64, 0xe1, 0x42};
+constexpr std::array<uint8_t, 16> kUuid = {0x66, 0x12, 0xb5, 0x22, 0xb7, 0x17, 0x41, 0xc8,
+ 0xb4, 0x8d, 0xc0, 0xb1, 0xcc, 0x64, 0xe1, 0x42};
+const String16 kName{"VtsAidlHalContextHubTargetTest"};
class ContextHubAidl : public testing::TestWithParam<std::tuple<std::string, int32_t>> {
public:
@@ -131,10 +134,21 @@
return Status::ok();
}
+ Status handleMessageDeliveryStatus(
+ char16_t /* hostEndPointId */,
+ const MessageDeliveryStatus& /* messageDeliveryStatus */) override {
+ return Status::ok();
+ }
+
Status getUuid(std::array<uint8_t, 16>* out_uuid) override {
*out_uuid = kUuid;
return Status::ok();
}
+
+ Status getName(::android::String16* out_name) override {
+ *out_name = kName;
+ return Status::ok();
+ }
};
TEST_P(ContextHubAidl, TestRegisterCallback) {
@@ -166,11 +180,22 @@
return Status::ok();
}
+ Status handleMessageDeliveryStatus(
+ char16_t /* hostEndPointId */,
+ const MessageDeliveryStatus& /* messageDeliveryStatus */) override {
+ return Status::ok();
+ }
+
Status getUuid(std::array<uint8_t, 16>* out_uuid) override {
*out_uuid = kUuid;
return Status::ok();
}
+ Status getName(::android::String16* out_name) override {
+ *out_name = kName;
+ return Status::ok();
+ }
+
std::promise<std::vector<NanoappInfo>> promise;
};
@@ -237,11 +262,22 @@
return Status::ok();
}
+ Status handleMessageDeliveryStatus(
+ char16_t /* hostEndPointId */,
+ const MessageDeliveryStatus& /* messageDeliveryStatus */) override {
+ return Status::ok();
+ }
+
Status getUuid(std::array<uint8_t, 16>* out_uuid) override {
*out_uuid = kUuid;
return Status::ok();
}
+ Status getName(::android::String16* out_name) override {
+ *out_name = kName;
+ return Status::ok();
+ }
+
uint32_t expectedTransactionId = 0;
std::promise<bool> promise;
};
@@ -385,7 +421,7 @@
return tuples;
}
-TEST_P(ContextHubAidl, TestHostConnection) {
+TEST_P(ContextHubTransactionTest, TestHostConnection) {
constexpr char16_t kHostEndpointId = 1;
HostEndpointInfo hostEndpointInfo;
hostEndpointInfo.type = HostEndpointInfo::Type::NATIVE;
@@ -395,13 +431,13 @@
ASSERT_TRUE(contextHub->onHostEndpointDisconnected(kHostEndpointId).isOk());
}
-TEST_P(ContextHubAidl, TestInvalidHostConnection) {
+TEST_P(ContextHubTransactionTest, TestInvalidHostConnection) {
constexpr char16_t kHostEndpointId = 1;
ASSERT_TRUE(contextHub->onHostEndpointDisconnected(kHostEndpointId).isOk());
}
-TEST_P(ContextHubAidl, TestNanSessionStateChange) {
+TEST_P(ContextHubTransactionTest, TestNanSessionStateChange) {
NanSessionStateUpdate update;
update.state = true;
Status status = contextHub->onNanSessionStateChanged(update);
@@ -415,6 +451,20 @@
}
}
+TEST_P(ContextHubAidl, TestSendMessageDeliveryStatusToHub) {
+ MessageDeliveryStatus messageDeliveryStatus;
+ messageDeliveryStatus.messageSequenceNumber = 123;
+ messageDeliveryStatus.errorCode = ErrorCode::OK;
+
+ Status status = contextHub->sendMessageDeliveryStatusToHub(getHubId(), messageDeliveryStatus);
+ if (status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
+ status.transactionError() == android::UNKNOWN_TRANSACTION) {
+ GTEST_SKIP() << "Not supported -> old API; or not implemented";
+ } else {
+ EXPECT_TRUE(status.isOk());
+ }
+}
+
std::string PrintGeneratedTest(const testing::TestParamInfo<ContextHubAidl::ParamType>& info) {
return std::string("CONTEXT_HUB_ID_") + std::to_string(std::get<1>(info.param));
}
diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl
index aaafe7f..8a22d6e 100644
--- a/gnss/aidl/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl
@@ -217,6 +217,10 @@
* Starts a location output stream using the IGnssCallback gnssLocationCb(), following the
* settings from the most recent call to setPositionMode().
*
+ * When a location output stream is in progress, calling setPositionMode() does not change the
+ * settings of the current location output stream. stop() and start() must be called to make the
+ * new settings effective.
+ *
* This output must operate independently of any GNSS location batching operations,
* see the IGnssBatching for details.
*/
@@ -306,6 +310,10 @@
/**
* Sets the GnssPositionMode parameter, its associated recurrence value, the time between fixes,
* requested fix accuracy, time to first fix.
+ *
+ * If a location output stream is in progress, calling this method does not affect the settings
+ * of current location output stream. stop() and start() must be called to make the new settings
+ * effective.
*/
void setPositionMode(in PositionModeOptions options);
diff --git a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
index 0200625..522d44e 100644
--- a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
@@ -136,14 +136,14 @@
*
* - GNSS: 1-32
* - SBAS: 120-151, 183-192
- * - GLONASS: 1-24, the orbital slot number (OSN), if known. Or, if not:
+ * - GLONASS: 1-25, the orbital slot number (OSN), if known. Or, if not:
* 93-106, the frequency channel number (FCN) (-7 to +6) offset by
* + 100
* i.e. report an FCN of -7 as 93, FCN of 0 as 100, and FCN of +6
* as 106.
- * - QZSS: 193-200
+ * - QZSS: 183-206
* - Galileo: 1-36
- * - Beidou: 1-37
+ * - Beidou: 1-63
* - IRNSS: 1-14
*/
int svid;
diff --git a/graphics/allocator/2.0/Android.bp b/graphics/allocator/2.0/Android.bp
index 40db81d..36158e9 100644
--- a/graphics/allocator/2.0/Android.bp
+++ b/graphics/allocator/2.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/allocator/2.0/default/Android.bp b/graphics/allocator/2.0/default/Android.bp
index 4d17dc3..2ca9c86 100644
--- a/graphics/allocator/2.0/default/Android.bp
+++ b/graphics/allocator/2.0/default/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/allocator/2.0/utils/gralloc1-adapter/Android.bp b/graphics/allocator/2.0/utils/gralloc1-adapter/Android.bp
index bc42099..1ef32ef 100644
--- a/graphics/allocator/2.0/utils/gralloc1-adapter/Android.bp
+++ b/graphics/allocator/2.0/utils/gralloc1-adapter/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -11,9 +12,15 @@
name: "libgralloc1-adapter",
defaults: ["hidl_defaults"],
vendor: true,
- srcs: ["gralloc1-adapter.cpp", "Gralloc1On0Adapter.cpp"],
+ srcs: [
+ "gralloc1-adapter.cpp",
+ "Gralloc1On0Adapter.cpp",
+ ],
include_dirs: ["system/core/libsync/include"],
export_include_dirs: ["."],
whole_static_libs: ["libgrallocusage"],
- shared_libs: ["libhardware", "liblog"],
+ shared_libs: [
+ "libhardware",
+ "liblog",
+ ],
}
diff --git a/graphics/allocator/2.0/utils/hal/Android.bp b/graphics/allocator/2.0/utils/hal/Android.bp
index 6bb9a0f..a2ddafd 100644
--- a/graphics/allocator/2.0/utils/hal/Android.bp
+++ b/graphics/allocator/2.0/utils/hal/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/allocator/2.0/utils/passthrough/Android.bp b/graphics/allocator/2.0/utils/passthrough/Android.bp
index f5ac5a6..fe00518 100644
--- a/graphics/allocator/2.0/utils/passthrough/Android.bp
+++ b/graphics/allocator/2.0/utils/passthrough/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/allocator/3.0/Android.bp b/graphics/allocator/3.0/Android.bp
index 800632c..0100f6f 100644
--- a/graphics/allocator/3.0/Android.bp
+++ b/graphics/allocator/3.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/allocator/4.0/Android.bp b/graphics/allocator/4.0/Android.bp
index 5c5fb37..5d7a4a9 100644
--- a/graphics/allocator/4.0/Android.bp
+++ b/graphics/allocator/4.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/allocator/aidl/Android.bp b/graphics/allocator/aidl/Android.bp
index 03628b0..6e24edc 100644
--- a/graphics/allocator/aidl/Android.bp
+++ b/graphics/allocator/aidl/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/allocator/aidl/vts/Android.bp b/graphics/allocator/aidl/vts/Android.bp
index 630ab2a..b2ed821 100644
--- a/graphics/allocator/aidl/vts/Android.bp
+++ b/graphics/allocator/aidl/vts/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/allocator/aidl/vts/VtsHalGraphicsAllocatorAidl_TargetTest.cpp b/graphics/allocator/aidl/vts/VtsHalGraphicsAllocatorAidl_TargetTest.cpp
index 4778020..0430ea7 100644
--- a/graphics/allocator/aidl/vts/VtsHalGraphicsAllocatorAidl_TargetTest.cpp
+++ b/graphics/allocator/aidl/vts/VtsHalGraphicsAllocatorAidl_TargetTest.cpp
@@ -144,7 +144,8 @@
auto status = mAllocator->getIMapperLibrarySuffix(&mapperSuffix);
ASSERT_TRUE(status.isOk());
std::string lib_name = "mapper." + mapperSuffix + ".so";
- void* so = android_load_sphal_library(lib_name.c_str(), RTLD_LOCAL | RTLD_NOW);
+ void* so = AServiceManager_openDeclaredPassthroughHal("mapper", mapperSuffix.c_str(),
+ RTLD_LOCAL | RTLD_NOW);
ASSERT_NE(nullptr, so) << "Failed to load " << lib_name;
auto loadIMapper = (AIMapper_loadIMapperFn)dlsym(so, "AIMapper_loadIMapper");
ASSERT_NE(nullptr, loadIMapper) << "AIMapper_locaIMapper missing from " << lib_name;
diff --git a/graphics/bufferqueue/1.0/Android.bp b/graphics/bufferqueue/1.0/Android.bp
index 82c71f1..fe46b5e 100644
--- a/graphics/bufferqueue/1.0/Android.bp
+++ b/graphics/bufferqueue/1.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/bufferqueue/2.0/Android.bp b/graphics/bufferqueue/2.0/Android.bp
index 3067e24..c2b0985 100644
--- a/graphics/bufferqueue/2.0/Android.bp
+++ b/graphics/bufferqueue/2.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/common/1.0/Android.bp b/graphics/common/1.0/Android.bp
index 3288583..786953b 100644
--- a/graphics/common/1.0/Android.bp
+++ b/graphics/common/1.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/common/1.1/Android.bp b/graphics/common/1.1/Android.bp
index 5d07eae..d857f80 100644
--- a/graphics/common/1.1/Android.bp
+++ b/graphics/common/1.1/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/common/1.2/Android.bp b/graphics/common/1.2/Android.bp
index 4aa4af5..17d0c20 100644
--- a/graphics/common/1.2/Android.bp
+++ b/graphics/common/1.2/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/common/aidl/Android.bp b/graphics/common/aidl/Android.bp
index f177a41..605299f 100644
--- a/graphics/common/aidl/Android.bp
+++ b/graphics/common/aidl/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/1/.hash b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/1/.hash
index 66b5d13..babbf24 100644
--- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/1/.hash
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/1/.hash
@@ -1 +1,2 @@
f5bdf5724a941dc7e5e7d0ebe9dfe028f7bcc25f
+71da13748094aa53237dd6eeac04f0f9add80aa1
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/1/android/hardware/graphics/common/BufferUsage.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/1/android/hardware/graphics/common/BufferUsage.aidl
index 58eefc4..cb5bc9e 100644
--- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/1/android/hardware/graphics/common/BufferUsage.aidl
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/1/android/hardware/graphics/common/BufferUsage.aidl
@@ -42,6 +42,6 @@
GPU_MIPMAP_COMPLETE = 67108864,
HW_IMAGE_ENCODER = 134217728,
GPU_DATA_BUFFER = 16777216,
- VENDOR_MASK = -268435456,
+ VENDOR_MASK = 4026531840,
VENDOR_MASK_HI = -281474976710656,
}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/.hash b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/.hash
index 167ed0e..54f8f32 100644
--- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/.hash
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/.hash
@@ -1 +1,2 @@
bd2f5e2ab1d5112dfe982f64012e425f544c9d60
+4279f88ef38c8fdeea6797410b464ae29df34e72
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/BufferUsage.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/BufferUsage.aidl
index b4ef451..5e23bcc 100644
--- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/BufferUsage.aidl
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/BufferUsage.aidl
@@ -58,6 +58,6 @@
GPU_MIPMAP_COMPLETE = 67108864,
HW_IMAGE_ENCODER = 134217728,
GPU_DATA_BUFFER = 16777216,
- VENDOR_MASK = -268435456,
+ VENDOR_MASK = 4026531840,
VENDOR_MASK_HI = -281474976710656,
}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/3/.hash b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/3/.hash
index dfda68f..53eb6bd 100644
--- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/3/.hash
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/3/.hash
@@ -1 +1,2 @@
e7e8b0bd7cd27ab4f1998700ef19ebc82e022d87
+37aa15ac89ae27f3f89099d79609f5aaa1717de5
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/3/android/hardware/graphics/common/BufferUsage.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/3/android/hardware/graphics/common/BufferUsage.aidl
index d3ab44f..f91625f 100644
--- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/3/android/hardware/graphics/common/BufferUsage.aidl
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/3/android/hardware/graphics/common/BufferUsage.aidl
@@ -60,6 +60,6 @@
GPU_MIPMAP_COMPLETE = 67108864,
HW_IMAGE_ENCODER = 134217728,
FRONT_BUFFER = 4294967296,
- VENDOR_MASK = -268435456,
+ VENDOR_MASK = 4026531840,
VENDOR_MASK_HI = -281474976710656,
}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/.hash b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/.hash
index ef17b34..fe20ff9 100644
--- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/.hash
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/.hash
@@ -1 +1,2 @@
9bcf4b83485ce912dc39108201504f77b8c96cef
+adb71c34ba271f87c6431845b310777c1e611ebf
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/BufferUsage.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/BufferUsage.aidl
index d42a6d5..52b2a56 100644
--- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/BufferUsage.aidl
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/BufferUsage.aidl
@@ -60,6 +60,6 @@
GPU_MIPMAP_COMPLETE = (1 << 26) /* 67108864 */,
HW_IMAGE_ENCODER = (1 << 27) /* 134217728 */,
FRONT_BUFFER = (1L << 32) /* 4294967296 */,
- VENDOR_MASK = (0xf << 28) /* -268435456 */,
+ VENDOR_MASK = (0xfL << 28) /* 4026531840 */,
VENDOR_MASK_HI = ((1L * 0xffff) << 48) /* -281474976710656 */,
}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/BufferUsage.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/BufferUsage.aidl
index d42a6d5..52b2a56 100644
--- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/BufferUsage.aidl
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/BufferUsage.aidl
@@ -60,6 +60,6 @@
GPU_MIPMAP_COMPLETE = (1 << 26) /* 67108864 */,
HW_IMAGE_ENCODER = (1 << 27) /* 134217728 */,
FRONT_BUFFER = (1L << 32) /* 4294967296 */,
- VENDOR_MASK = (0xf << 28) /* -268435456 */,
+ VENDOR_MASK = (0xfL << 28) /* 4026531840 */,
VENDOR_MASK_HI = ((1L * 0xffff) << 48) /* -281474976710656 */,
}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/DisplayHotplugEvent.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/DisplayHotplugEvent.aidl
new file mode 100644
index 0000000..63dca0a
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/DisplayHotplugEvent.aidl
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.graphics.common;
+@Backing(type="int") @VintfStability
+enum DisplayHotplugEvent {
+ CONNECTED = 0,
+ DISCONNECTED = 1,
+ ERROR_UNKNOWN = (-1) /* -1 */,
+ ERROR_INCOMPATIBLE_CABLE = (-2) /* -2 */,
+ ERROR_TOO_MANY_DISPLAYS = (-3) /* -3 */,
+}
diff --git a/graphics/common/aidl/android/hardware/graphics/common/BufferUsage.aidl b/graphics/common/aidl/android/hardware/graphics/common/BufferUsage.aidl
index 0d1a094..7d39d95 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/BufferUsage.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/BufferUsage.aidl
@@ -150,7 +150,7 @@
FRONT_BUFFER = 1L << 32,
/** bits 28-31 are reserved for vendor extensions */
- VENDOR_MASK = 0xf << 28,
+ VENDOR_MASK = 0xfL << 28,
/** bits 33-47 must be zero and are reserved for future versions */
/** bits 48-63 are reserved for vendor extensions */
diff --git a/graphics/common/aidl/android/hardware/graphics/common/DisplayHotplugEvent.aidl b/graphics/common/aidl/android/hardware/graphics/common/DisplayHotplugEvent.aidl
new file mode 100644
index 0000000..b35ada5
--- /dev/null
+++ b/graphics/common/aidl/android/hardware/graphics/common/DisplayHotplugEvent.aidl
@@ -0,0 +1,46 @@
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.common;
+
+/**
+ * Display hotplug events through onHotplugEvent callback.
+ */
+@VintfStability
+@Backing(type="int")
+enum DisplayHotplugEvent {
+ /**
+ * Display is successfully connected.
+ * Connected may be called more than once and the behavior of subsequent
+ * calls is that SurfaceFlinger queries the display properties again.
+ */
+ CONNECTED = 0,
+
+ /** Display is successfully disconnected */
+ DISCONNECTED = 1,
+
+ /** Display is plugged in, but an unknown error occurred */
+ ERROR_UNKNOWN = -1,
+
+ /** Display is plugged in, but incompatible cable error detected */
+ ERROR_INCOMPATIBLE_CABLE = -2,
+
+ /**
+ * Display is plugged in, but exceeds the max number of
+ * displays that can be simultaneously connected
+ */
+ ERROR_TOO_MANY_DISPLAYS = -3,
+}
diff --git a/graphics/composer/2.1/Android.bp b/graphics/composer/2.1/Android.bp
index 2e41208..3c3575d 100644
--- a/graphics/composer/2.1/Android.bp
+++ b/graphics/composer/2.1/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.1/default/Android.bp b/graphics/composer/2.1/default/Android.bp
index 96fea4e..91d9b0d 100644
--- a/graphics/composer/2.1/default/Android.bp
+++ b/graphics/composer/2.1/default/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.1/utils/command-buffer/Android.bp b/graphics/composer/2.1/utils/command-buffer/Android.bp
index 07dea31..224cea5 100644
--- a/graphics/composer/2.1/utils/command-buffer/Android.bp
+++ b/graphics/composer/2.1/utils/command-buffer/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.1/utils/hal/Android.bp b/graphics/composer/2.1/utils/hal/Android.bp
index 874be84..9622c58 100644
--- a/graphics/composer/2.1/utils/hal/Android.bp
+++ b/graphics/composer/2.1/utils/hal/Android.bp
@@ -14,6 +14,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp b/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp
index 3527cca..fd00297 100644
--- a/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp
+++ b/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp b/graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp
index d613ba9..ecf6201 100644
--- a/graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp
+++ b/graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.1/utils/passthrough/Android.bp b/graphics/composer/2.1/utils/passthrough/Android.bp
index 67f5163..7bc32c0 100644
--- a/graphics/composer/2.1/utils/passthrough/Android.bp
+++ b/graphics/composer/2.1/utils/passthrough/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.1/utils/resources/Android.bp b/graphics/composer/2.1/utils/resources/Android.bp
index 4052003..776bf28 100644
--- a/graphics/composer/2.1/utils/resources/Android.bp
+++ b/graphics/composer/2.1/utils/resources/Android.bp
@@ -14,6 +14,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.1/utils/vts/Android.bp b/graphics/composer/2.1/utils/vts/Android.bp
index 3bc127f..9064475 100644
--- a/graphics/composer/2.1/utils/vts/Android.bp
+++ b/graphics/composer/2.1/utils/vts/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.1/vts/functional/Android.bp b/graphics/composer/2.1/vts/functional/Android.bp
index 0706341..57a85d6 100644
--- a/graphics/composer/2.1/vts/functional/Android.bp
+++ b/graphics/composer/2.1/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
index b67cfc2..a1992b9 100644
--- a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
+++ b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
@@ -315,6 +315,8 @@
* required client targets.
*/
TEST_P(GraphicsComposerHidlTest, GetClientTargetSupport) {
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setPowerMode(mPrimaryDisplay, IComposerClient::PowerMode::ON));
std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
for (auto config : configs) {
int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
diff --git a/graphics/composer/2.2/Android.bp b/graphics/composer/2.2/Android.bp
index e44a236..1f28ea3 100644
--- a/graphics/composer/2.2/Android.bp
+++ b/graphics/composer/2.2/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.2/utils/command-buffer/Android.bp b/graphics/composer/2.2/utils/command-buffer/Android.bp
index d55145e..eae2242 100644
--- a/graphics/composer/2.2/utils/command-buffer/Android.bp
+++ b/graphics/composer/2.2/utils/command-buffer/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.2/utils/hal/Android.bp b/graphics/composer/2.2/utils/hal/Android.bp
index 4e028e0..9194aa1 100644
--- a/graphics/composer/2.2/utils/hal/Android.bp
+++ b/graphics/composer/2.2/utils/hal/Android.bp
@@ -14,6 +14,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.2/utils/passthrough/Android.bp b/graphics/composer/2.2/utils/passthrough/Android.bp
index b700344..10e0b73 100644
--- a/graphics/composer/2.2/utils/passthrough/Android.bp
+++ b/graphics/composer/2.2/utils/passthrough/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.2/utils/resources/Android.bp b/graphics/composer/2.2/utils/resources/Android.bp
index 9e45ef2..d1bf8c5 100644
--- a/graphics/composer/2.2/utils/resources/Android.bp
+++ b/graphics/composer/2.2/utils/resources/Android.bp
@@ -14,6 +14,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.2/utils/vts/Android.bp b/graphics/composer/2.2/utils/vts/Android.bp
index a923923..7157862 100644
--- a/graphics/composer/2.2/utils/vts/Android.bp
+++ b/graphics/composer/2.2/utils/vts/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -37,6 +38,7 @@
],
shared_libs: [
"libui",
+ "server_configurable_flags",
],
static_libs: [
"android.hardware.graphics.composer@2.1-vts",
@@ -47,6 +49,7 @@
"libnativewindow",
"librenderengine",
"libshaders",
+ "libsurfaceflinger_common",
"libtonemap",
],
export_static_lib_headers: [
diff --git a/graphics/composer/2.2/vts/functional/Android.bp b/graphics/composer/2.2/vts/functional/Android.bp
index a781712..bda4198 100644
--- a/graphics/composer/2.2/vts/functional/Android.bp
+++ b/graphics/composer/2.2/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -53,6 +54,7 @@
"libsync",
"libui",
"android.hardware.common-V2-ndk",
+ "server_configurable_flags",
],
static_libs: [
"android.hardware.graphics.common@1.1",
@@ -65,6 +67,7 @@
"librenderengine",
"libshaders",
"libtonemap",
+ "libsurfaceflinger_common",
],
header_libs: [
"android.hardware.graphics.composer@2.1-command-buffer",
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
index 2bd287b..cd4cb58 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
@@ -256,6 +256,8 @@
* required client targets.
*/
TEST_P(GraphicsComposerHidlTest, GetClientTargetSupport_2_2) {
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setPowerMode_2_2(mPrimaryDisplay, IComposerClient::PowerMode::ON));
std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
for (auto config : configs) {
int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
diff --git a/graphics/composer/2.3/Android.bp b/graphics/composer/2.3/Android.bp
index 3c52b6f..47a0965 100644
--- a/graphics/composer/2.3/Android.bp
+++ b/graphics/composer/2.3/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.3/default/Android.bp b/graphics/composer/2.3/default/Android.bp
index f801fba..bffe632 100644
--- a/graphics/composer/2.3/default/Android.bp
+++ b/graphics/composer/2.3/default/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.3/utils/command-buffer/Android.bp b/graphics/composer/2.3/utils/command-buffer/Android.bp
index ca7d136..1694509 100644
--- a/graphics/composer/2.3/utils/command-buffer/Android.bp
+++ b/graphics/composer/2.3/utils/command-buffer/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.3/utils/hal/Android.bp b/graphics/composer/2.3/utils/hal/Android.bp
index b475757..eb854c3 100644
--- a/graphics/composer/2.3/utils/hal/Android.bp
+++ b/graphics/composer/2.3/utils/hal/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.3/utils/passthrough/Android.bp b/graphics/composer/2.3/utils/passthrough/Android.bp
index 68b706c..7bf54e5 100644
--- a/graphics/composer/2.3/utils/passthrough/Android.bp
+++ b/graphics/composer/2.3/utils/passthrough/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.3/utils/vts/Android.bp b/graphics/composer/2.3/utils/vts/Android.bp
index 99429db..7695523 100644
--- a/graphics/composer/2.3/utils/vts/Android.bp
+++ b/graphics/composer/2.3/utils/vts/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.3/vts/functional/Android.bp b/graphics/composer/2.3/vts/functional/Android.bp
index 0d3c27d..db0326e 100644
--- a/graphics/composer/2.3/vts/functional/Android.bp
+++ b/graphics/composer/2.3/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
index c072ef0..f99c72d 100644
--- a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
+++ b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
@@ -274,6 +274,8 @@
* Test IComposerClient::getClientTargetSupport_2_3
*/
TEST_P(GraphicsComposerHidlTest, GetClientTargetSupport_2_3) {
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setPowerMode_2_2(mPrimaryDisplay, IComposerClient::PowerMode::ON));
std::vector<V2_1::Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
for (auto config : configs) {
int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
diff --git a/graphics/composer/2.4/Android.bp b/graphics/composer/2.4/Android.bp
index e6b238b..748faf6 100644
--- a/graphics/composer/2.4/Android.bp
+++ b/graphics/composer/2.4/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.4/default/Android.bp b/graphics/composer/2.4/default/Android.bp
index 7a91ec1..a9b6d4e 100644
--- a/graphics/composer/2.4/default/Android.bp
+++ b/graphics/composer/2.4/default/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.4/utils/command-buffer/Android.bp b/graphics/composer/2.4/utils/command-buffer/Android.bp
index c966fc4..608b004 100644
--- a/graphics/composer/2.4/utils/command-buffer/Android.bp
+++ b/graphics/composer/2.4/utils/command-buffer/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.4/utils/hal/Android.bp b/graphics/composer/2.4/utils/hal/Android.bp
index abf8e04..c90a79d 100644
--- a/graphics/composer/2.4/utils/hal/Android.bp
+++ b/graphics/composer/2.4/utils/hal/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.4/utils/passthrough/Android.bp b/graphics/composer/2.4/utils/passthrough/Android.bp
index a851c0a..867f8cb 100644
--- a/graphics/composer/2.4/utils/passthrough/Android.bp
+++ b/graphics/composer/2.4/utils/passthrough/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.4/utils/vts/Android.bp b/graphics/composer/2.4/utils/vts/Android.bp
index c39b5eb1..d2f4297 100644
--- a/graphics/composer/2.4/utils/vts/Android.bp
+++ b/graphics/composer/2.4/utils/vts/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/2.4/vts/functional/Android.bp b/graphics/composer/2.4/vts/functional/Android.bp
index 52624b4..225c73b 100644
--- a/graphics/composer/2.4/vts/functional/Android.bp
+++ b/graphics/composer/2.4/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/aidl/Android.bp b/graphics/composer/aidl/Android.bp
index 5699895..d60f8c4 100644
--- a/graphics/composer/aidl/Android.bp
+++ b/graphics/composer/aidl/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Capability.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Capability.aidl
index f02f8aa..ee004d6 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Capability.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Capability.aidl
@@ -45,4 +45,5 @@
BOOT_DISPLAY_CONFIG = 5,
HDR_OUTPUT_CONVERSION_CONFIG = 6,
REFRESH_RATE_CHANGED_CALLBACK_DEBUG = 7,
+ LAYER_LIFECYCLE_BATCH_COMMAND = 8,
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ClientTarget.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ClientTarget.aidl
index 7632707..06ed922 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ClientTarget.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ClientTarget.aidl
@@ -37,4 +37,5 @@
android.hardware.graphics.composer3.Buffer buffer;
android.hardware.graphics.common.Dataspace dataspace;
android.hardware.graphics.common.Rect[] damage;
+ float hdrSdrRatio = 1.0f;
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
index 00598eb..e6db116 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
@@ -37,12 +37,12 @@
long display;
int mask;
android.hardware.graphics.composer3.DisplayRequest.LayerRequest[] layerRequests;
- const int FLIP_CLIENT_TARGET = (1 << 0);
- const int WRITE_CLIENT_TARGET_TO_OUTPUT = (1 << 1);
+ const int FLIP_CLIENT_TARGET = (1 << 0) /* 1 */;
+ const int WRITE_CLIENT_TARGET_TO_OUTPUT = (1 << 1) /* 2 */;
@VintfStability
parcelable LayerRequest {
long layer;
int mask;
- const int CLEAR_CLIENT_TARGET = (1 << 0);
+ const int CLEAR_CLIENT_TARGET = (1 << 0) /* 1 */;
}
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FormatColorComponent.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FormatColorComponent.aidl
index 1990350..89dae83 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FormatColorComponent.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FormatColorComponent.aidl
@@ -34,8 +34,8 @@
package android.hardware.graphics.composer3;
@Backing(type="byte") @VintfStability
enum FormatColorComponent {
- FORMAT_COMPONENT_0 = (1 << 0),
- FORMAT_COMPONENT_1 = (1 << 1),
- FORMAT_COMPONENT_2 = (1 << 2),
- FORMAT_COMPONENT_3 = (1 << 3),
+ FORMAT_COMPONENT_0 = (1 << 0) /* 1 */,
+ FORMAT_COMPONENT_1 = (1 << 1) /* 2 */,
+ FORMAT_COMPONENT_2 = (1 << 2) /* 4 */,
+ FORMAT_COMPONENT_3 = (1 << 3) /* 8 */,
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerCallback.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerCallback.aidl
index 2c08cbe..e64bd52 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerCallback.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerCallback.aidl
@@ -34,6 +34,9 @@
package android.hardware.graphics.composer3;
@VintfStability
interface IComposerCallback {
+ /**
+ * @deprecated : Use instead onHotplugEvent
+ */
void onHotplug(long display, boolean connected);
oneway void onRefresh(long display);
oneway void onSeamlessPossible(long display);
@@ -41,4 +44,5 @@
oneway void onVsyncPeriodTimingChanged(long display, in android.hardware.graphics.composer3.VsyncPeriodChangeTimeline updatedTimeline);
oneway void onVsyncIdle(long display);
oneway void onRefreshRateChangedDebug(in android.hardware.graphics.composer3.RefreshRateChangedDebugData data);
+ void onHotplugEvent(long display, android.hardware.graphics.common.DisplayHotplugEvent event);
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl
index 6d32218..87c8c18 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl
@@ -55,4 +55,6 @@
@nullable android.hardware.graphics.composer3.PerFrameMetadataBlob[] perFrameMetadataBlob;
@nullable android.hardware.graphics.common.Rect[] blockingRegion;
@nullable int[] bufferSlotsToClear;
+ android.hardware.graphics.composer3.LayerLifecycleBatchCommandType layerLifecycleBatchCommandType;
+ int newBufferSlotCount;
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerLifecycleBatchCommandType.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerLifecycleBatchCommandType.aidl
new file mode 100644
index 0000000..ac78cd5
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerLifecycleBatchCommandType.aidl
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.graphics.composer3;
+@Backing(type="int") @VintfStability
+enum LayerLifecycleBatchCommandType {
+ MODIFY = 0,
+ CREATE = 1,
+ DESTROY = 2,
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/RefreshRateChangedDebugData.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/RefreshRateChangedDebugData.aidl
index 2b9801a..e9305e1 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/RefreshRateChangedDebugData.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/RefreshRateChangedDebugData.aidl
@@ -36,4 +36,5 @@
parcelable RefreshRateChangedDebugData {
long display;
int vsyncPeriodNanos;
+ int refreshPeriodNanos;
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/VrrConfig.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/VrrConfig.aidl
index bb2569f..7377b4b 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/VrrConfig.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/VrrConfig.aidl
@@ -42,7 +42,7 @@
int averageRefreshPeriodNs;
}
parcelable NotifyExpectedPresentConfig {
- int notifyExpectedPresentHeadsUpNs;
- int notifyExpectedPresentTimeoutNs;
+ int headsUpNs;
+ int timeoutNs;
}
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Capability.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/Capability.aidl
index 4638610..1dfc074 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/Capability.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/Capability.aidl
@@ -86,4 +86,14 @@
* @see IComposerCallback.onRefreshRateChangedDebug
*/
REFRESH_RATE_CHANGED_CALLBACK_DEBUG = 7,
+
+ /**
+ * Specifies that the device HAL supports the batching of layer creation and destruction
+ * for better performance.
+ *
+ * @see IComposerClient.executeCommands
+ * @see LayerCommand.layerLifecycleBatchCommandType
+ * @see LayerCommand.newBufferSlotCount
+ */
+ LAYER_LIFECYCLE_BATCH_COMMAND = 8,
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTarget.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTarget.aidl
index 56488d5..bc9f63a 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTarget.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTarget.aidl
@@ -36,4 +36,14 @@
* The surface damage regions.
*/
Rect[] damage;
+
+ /**
+ * The HDR/SDR ratio.
+ * Only meaningful for extended_range client targets to communicate the amount of HDR heaedroom
+ * inside the client target. For floating point client targets, this means that for each color
+ * channel the maximum SDR luminance is 1.0, and the maximum display relative luminance is
+ * the hdrSdrRatio.
+ * Note that this ratio is meant to be >= 1.0.
+ */
+ float hdrSdrRatio = 1.0f;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl
index f4384b7..96eccd7 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl
@@ -16,6 +16,7 @@
package android.hardware.graphics.composer3;
+import android.hardware.graphics.common.DisplayHotplugEvent;
import android.hardware.graphics.composer3.RefreshRateChangedDebugData;
import android.hardware.graphics.composer3.VsyncPeriodChangeTimeline;
@@ -38,6 +39,7 @@
* @param display is the display that triggers the hotplug event.
* @param connected indicates whether the display is connected or
* disconnected.
+ * @deprecated: Use instead onHotplugEvent
*/
void onHotplug(long display, boolean connected);
@@ -118,4 +120,23 @@
* @param data is the data for the callback when refresh rate changed.
*/
oneway void onRefreshRateChangedDebug(in RefreshRateChangedDebugData data);
+
+ /**
+ * Notifies the client that a DisplayHotplugEvent has occurred for the
+ * given display. Every active display (even a built-in physical display)
+ * must trigger at least one hotplug notification, even if it only occurs
+ * immediately after callback registration.
+ *
+ * Displays which have been connected are assumed to be in PowerMode.OFF,
+ * and the onVsync callback should not be called for a display until vsync
+ * has been enabled with setVsyncEnabled.
+ *
+ * The client may call back into the device while the callback is in
+ * progress. The device must serialize calls to this callback such that
+ * only one thread is calling it at a time.
+ *
+ * @param display is the display that triggers the hotplug event.
+ * @param event is the type of event that occurred.
+ */
+ void onHotplugEvent(long display, DisplayHotplugEvent event);
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
index 725c947..213e8e9 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -895,9 +895,9 @@
*
* The framework will call this function based on the parameters specified in
* DisplayConfiguration.VrrConfig:
- * - notifyExpectedPresentTimeoutNs specifies the idle time from the previous present command
- * where the framework must send the early hint for the next frame.
- * - notifyExpectedPresentHeadsUpNs specifies minimal time that framework must send
+ * - notifyExpectedPresentConfig.timeoutNs specifies the idle time from the previous
+ * present command where the framework must send the early hint for the next frame.
+ * - notifyExpectedPresentConfig.headsUpNs specifies minimal time that framework must send
* the early hint before the next frame.
*
* The framework can omit calling this API when the next present command matches
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
index fd50be9..e961c48 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
@@ -23,6 +23,7 @@
import android.hardware.graphics.composer3.Buffer;
import android.hardware.graphics.composer3.Color;
import android.hardware.graphics.composer3.LayerBrightness;
+import android.hardware.graphics.composer3.LayerLifecycleBatchCommandType;
import android.hardware.graphics.composer3.ParcelableBlendMode;
import android.hardware.graphics.composer3.ParcelableComposition;
import android.hardware.graphics.composer3.ParcelableDataspace;
@@ -265,4 +266,17 @@
* be freed.
*/
@nullable int[] bufferSlotsToClear;
+
+ /**
+ * Specifies if this layer command is on type modify, create or destroy.
+ * This command is replacing the older IComposerClient.createLayer and destroyLayer
+ * and making it more efficient with reduced aidls to the HAL.
+ * The HAL will report the errors by setting CommandResultPayload::CommandError.
+ */
+ LayerLifecycleBatchCommandType layerLifecycleBatchCommandType;
+
+ /**
+ * Specifies the number of buffer slot to be reserved.
+ */
+ int newBufferSlotCount;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerLifecycleBatchCommandType.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerLifecycleBatchCommandType.aidl
new file mode 100644
index 0000000..e619712
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerLifecycleBatchCommandType.aidl
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.composer3;
+
+/**
+ * Possible batch command types for a given layer.
+ */
+@VintfStability
+@Backing(type="int")
+enum LayerLifecycleBatchCommandType {
+ /**
+ * Layer attributes are being modified for already created layer.
+ */
+ MODIFY = 0,
+ /**
+ * This indicates that the current LayerCommand should also create the layer,
+ * before processing the other attributes in the LayerCommand.
+ */
+ CREATE = 1,
+ /**
+ * This indicates that the current LayerCommand should also destroy the layer,
+ * before processing the other attributes in the LayerCommand.
+ */
+ DESTROY = 2,
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/RefreshRateChangedDebugData.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/RefreshRateChangedDebugData.aidl
index c1f78d6..11c0112 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/RefreshRateChangedDebugData.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/RefreshRateChangedDebugData.aidl
@@ -27,4 +27,15 @@
* The display vsync period in nanoseconds.
*/
int vsyncPeriodNanos;
+
+ /**
+ * The refresh period of the display in nanoseconds.
+ * On VRR (Variable Refresh Rate) displays, refreshPeriodNanos can be different from the
+ * vsyncPeriodNanos because not every vsync cycle of the display is a refresh cycle.
+ * This should be set to the current refresh period.
+ * On non-VRR displays this value should be equal to vsyncPeriodNanos
+ *
+ * @see vsyncPeriodNanos
+ */
+ int refreshPeriodNanos;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/VrrConfig.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/VrrConfig.aidl
index 3b241ba..99c1c62 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/VrrConfig.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/VrrConfig.aidl
@@ -45,15 +45,16 @@
* The minimal time in nanoseconds that IComposerClient.notifyExpectedPresent needs to be
* called ahead of an expectedPresentTime provided on a presentDisplay command.
*/
- int notifyExpectedPresentHeadsUpNs;
+ int headsUpNs;
/**
* The time in nanoseconds that represents a timeout from the previous presentDisplay, which
* after this point the display needs a call to IComposerClient.notifyExpectedPresent before
- * sending the next frame. If set to 0, there is no need to call
+ * sending the next frame.
+ * If set to 0, hint is sent for every frame.
* IComposerClient.notifyExpectedPresent for timeout.
*/
- int notifyExpectedPresentTimeoutNs;
+ int timeoutNs;
}
/**
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
index 92ed6d3..a1ccbfe 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
@@ -29,6 +29,7 @@
#include <aidl/android/hardware/graphics/composer3/Composition.h>
#include <aidl/android/hardware/graphics/composer3/DisplayBrightness.h>
#include <aidl/android/hardware/graphics/composer3/LayerBrightness.h>
+#include <aidl/android/hardware/graphics/composer3/LayerLifecycleBatchCommandType.h>
#include <aidl/android/hardware/graphics/composer3/PerFrameMetadata.h>
#include <aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h>
@@ -83,11 +84,13 @@
}
void setClientTarget(int64_t display, uint32_t slot, const native_handle_t* target,
- int acquireFence, Dataspace dataspace, const std::vector<Rect>& damage) {
+ int acquireFence, Dataspace dataspace, const std::vector<Rect>& damage,
+ float hdrSdrRatio) {
ClientTarget clientTargetCommand;
clientTargetCommand.buffer = getBufferCommand(slot, target, acquireFence);
clientTargetCommand.dataspace = dataspace;
clientTargetCommand.damage.assign(damage.begin(), damage.end());
+ clientTargetCommand.hdrSdrRatio = hdrSdrRatio;
getDisplayCommand(display).clientTarget.emplace(std::move(clientTargetCommand));
}
@@ -97,6 +100,15 @@
getBufferCommand(slot, buffer, releaseFence));
}
+ void setLayerLifecycleBatchCommandType(int64_t display, int64_t layer,
+ LayerLifecycleBatchCommandType cmd) {
+ getLayerCommand(display, layer).layerLifecycleBatchCommandType = cmd;
+ }
+
+ void setNewBufferSlotCount(int64_t display, int64_t layer, int32_t newBufferSlotToCount) {
+ getLayerCommand(display, layer).newBufferSlotCount = newBufferSlotToCount;
+ }
+
void validateDisplay(int64_t display,
std::optional<ClockMonotonicTimestamp> expectedPresentTime,
int32_t frameIntervalNs) {
diff --git a/graphics/composer/aidl/vts/Android.bp b/graphics/composer/aidl/vts/Android.bp
index d71999d..3464fe9 100644
--- a/graphics/composer/aidl/vts/Android.bp
+++ b/graphics/composer/aidl/vts/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -55,6 +56,7 @@
"libhidlbase",
"libprocessgroup",
"libvndksupport",
+ "server_configurable_flags",
],
header_libs: [
"android.hardware.graphics.composer3-command-buffer",
@@ -73,6 +75,7 @@
"libshaders",
"libsync",
"libtonemap",
+ "libsurfaceflinger_common",
],
cflags: [
"-Wconversion",
diff --git a/graphics/composer/aidl/vts/GraphicsComposerCallback.cpp b/graphics/composer/aidl/vts/GraphicsComposerCallback.cpp
index 7b3a2b4..544f692 100644
--- a/graphics/composer/aidl/vts/GraphicsComposerCallback.cpp
+++ b/graphics/composer/aidl/vts/GraphicsComposerCallback.cpp
@@ -17,6 +17,7 @@
#include "GraphicsComposerCallback.h"
#include <log/log_main.h>
#include <utils/Timers.h>
+#include <cinttypes>
#pragma push_macro("LOG_TAG")
#undef LOG_TAG
@@ -193,4 +194,18 @@
return ::ndk::ScopedAStatus::ok();
}
+::ndk::ScopedAStatus GraphicsComposerCallback::onHotplugEvent(int64_t in_display,
+ common::DisplayHotplugEvent event) {
+ switch (event) {
+ case common::DisplayHotplugEvent::CONNECTED:
+ return onHotplug(in_display, true);
+ case common::DisplayHotplugEvent::DISCONNECTED:
+ return onHotplug(in_display, false);
+ default:
+ ALOGE("%s(): display:%" PRIu64 ", event:%d", __func__, in_display,
+ static_cast<int32_t>(event));
+ return ::ndk::ScopedAStatus::ok();
+ }
+}
+
} // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/vts/GraphicsComposerCallback.h b/graphics/composer/aidl/vts/GraphicsComposerCallback.h
index 13e992a..7a8d4a3 100644
--- a/graphics/composer/aidl/vts/GraphicsComposerCallback.h
+++ b/graphics/composer/aidl/vts/GraphicsComposerCallback.h
@@ -63,6 +63,8 @@
virtual ::ndk::ScopedAStatus onVsyncIdle(int64_t in_display) override;
virtual ::ndk::ScopedAStatus onRefreshRateChangedDebug(
const RefreshRateChangedDebugData&) override;
+ virtual ::ndk::ScopedAStatus onHotplugEvent(int64_t in_display,
+ common::DisplayHotplugEvent) override;
mutable std::mutex mMutex;
// the set of all currently connected displays
diff --git a/graphics/composer/aidl/vts/ReadbackVts.cpp b/graphics/composer/aidl/vts/ReadbackVts.cpp
index 8605628..c72ec69 100644
--- a/graphics/composer/aidl/vts/ReadbackVts.cpp
+++ b/graphics/composer/aidl/vts/ReadbackVts.cpp
@@ -293,8 +293,8 @@
TestBufferLayer::TestBufferLayer(const std::shared_ptr<VtsComposerClient>& client,
TestRenderEngine& renderEngine, int64_t display, uint32_t width,
uint32_t height, common::PixelFormat format,
- Composition composition)
- : TestLayer{client, display}, mRenderEngine(renderEngine) {
+ ComposerClientWriter& writer, Composition composition)
+ : TestLayer{client, display, writer}, mRenderEngine(renderEngine) {
mComposition = composition;
mWidth = width;
mHeight = height;
diff --git a/graphics/composer/aidl/vts/ReadbackVts.h b/graphics/composer/aidl/vts/ReadbackVts.h
index ee20573..8ac0f4b 100644
--- a/graphics/composer/aidl/vts/ReadbackVts.h
+++ b/graphics/composer/aidl/vts/ReadbackVts.h
@@ -50,9 +50,10 @@
class TestLayer {
public:
- TestLayer(const std::shared_ptr<VtsComposerClient>& client, int64_t display)
+ TestLayer(const std::shared_ptr<VtsComposerClient>& client, int64_t display,
+ ComposerClientWriter& writer)
: mDisplay(display) {
- const auto& [status, layer] = client->createLayer(display, kBufferSlotCount);
+ const auto& [status, layer] = client->createLayer(display, kBufferSlotCount, &writer);
EXPECT_TRUE(status.isOk());
mLayer = layer;
}
@@ -108,8 +109,9 @@
class TestColorLayer : public TestLayer {
public:
- TestColorLayer(const std::shared_ptr<VtsComposerClient>& client, int64_t display)
- : TestLayer{client, display} {}
+ TestColorLayer(const std::shared_ptr<VtsComposerClient>& client, int64_t display,
+ ComposerClientWriter& writer)
+ : TestLayer{client, display, writer} {}
void write(ComposerClientWriter& writer) override;
@@ -125,7 +127,7 @@
public:
TestBufferLayer(const std::shared_ptr<VtsComposerClient>& client,
TestRenderEngine& renderEngine, int64_t display, uint32_t width,
- uint32_t height, common::PixelFormat format,
+ uint32_t height, common::PixelFormat format, ComposerClientWriter& writer,
Composition composition = Composition::DEVICE);
void write(ComposerClientWriter& writer) override;
diff --git a/graphics/composer/aidl/vts/VtsComposerClient.cpp b/graphics/composer/aidl/vts/VtsComposerClient.cpp
index 11b995e..89ba2e6 100644
--- a/graphics/composer/aidl/vts/VtsComposerClient.cpp
+++ b/graphics/composer/aidl/vts/VtsComposerClient.cpp
@@ -33,6 +33,14 @@
mComposer = IComposer::fromBinder(binder);
ALOGE_IF(mComposer == nullptr, "Failed to acquire the composer from the binder");
}
+
+ const auto& [status, capabilities] = getCapabilities();
+ EXPECT_TRUE(status.isOk());
+ if (std::any_of(capabilities.begin(), capabilities.end(), [&](const Capability& cap) {
+ return cap == Capability::LAYER_LIFECYCLE_BATCH_COMMAND;
+ })) {
+ mSupportsBatchedCreateLayer = true;
+ }
}
ScopedAStatus VtsComposerClient::createClient() {
@@ -54,12 +62,15 @@
return mComposerClient->registerCallback(mComposerCallback);
}
-bool VtsComposerClient::tearDown() {
- return verifyComposerCallbackParams() && destroyAllLayers();
+bool VtsComposerClient::tearDown(ComposerClientWriter* writer) {
+ return verifyComposerCallbackParams() && destroyAllLayers(writer);
}
std::pair<ScopedAStatus, int32_t> VtsComposerClient::getInterfaceVersion() const {
int32_t version = 1;
+ if (!mComposerClient) {
+ return {ScopedAStatus{nullptr}, version};
+ }
auto status = mComposerClient->getInterfaceVersion(&version);
return {std::move(status), version};
}
@@ -86,7 +97,16 @@
}
std::pair<ScopedAStatus, int64_t> VtsComposerClient::createLayer(int64_t display,
- int32_t bufferSlotCount) {
+ int32_t bufferSlotCount,
+ ComposerClientWriter* writer) {
+ if (mSupportsBatchedCreateLayer) {
+ int64_t layer = mNextLayerHandle++;
+ writer->setLayerLifecycleBatchCommandType(display, layer,
+ LayerLifecycleBatchCommandType::CREATE);
+ writer->setNewBufferSlotCount(display, layer, bufferSlotCount);
+ return {addLayerToDisplayResources(display, layer), layer};
+ }
+
int64_t outLayer;
auto status = mComposerClient->createLayer(display, bufferSlotCount, &outLayer);
@@ -96,14 +116,20 @@
return {addLayerToDisplayResources(display, outLayer), outLayer};
}
-ScopedAStatus VtsComposerClient::destroyLayer(int64_t display, int64_t layer) {
- auto status = mComposerClient->destroyLayer(display, layer);
-
- if (!status.isOk()) {
- return status;
+ScopedAStatus VtsComposerClient::destroyLayer(int64_t display, int64_t layer,
+ ComposerClientWriter* writer) {
+ if (mSupportsBatchedCreateLayer) {
+ writer->setLayerLifecycleBatchCommandType(display, layer,
+ LayerLifecycleBatchCommandType::DESTROY);
+ } else {
+ auto status = mComposerClient->destroyLayer(display, layer);
+ if (!status.isOk()) {
+ return status;
+ }
}
+
removeLayerFromDisplayResources(display, layer);
- return status;
+ return ScopedAStatus::ok();
}
std::pair<ScopedAStatus, int32_t> VtsComposerClient::getActiveConfig(int64_t display) {
@@ -517,7 +543,8 @@
void VtsComposerClient::addDisplayConfigs(VtsDisplay* vtsDisplay,
const std::vector<DisplayConfiguration>& configs) {
for (const auto& config : configs) {
- vtsDisplay->addDisplayConfig(config.configId, {config.vsyncPeriod, config.configGroup});
+ vtsDisplay->addDisplayConfig(config.configId,
+ {config.vsyncPeriod, config.configGroup, config.vrrConfig});
}
}
@@ -631,7 +658,7 @@
return interfaceVersion >= 3;
}
-bool VtsComposerClient::destroyAllLayers() {
+bool VtsComposerClient::destroyAllLayers(ComposerClientWriter* writer) {
std::unordered_map<int64_t, DisplayResource> physicalDisplays;
while (!mDisplayResources.empty()) {
const auto& it = mDisplayResources.begin();
@@ -639,7 +666,7 @@
while (!resource.layers.empty()) {
auto layer = *resource.layers.begin();
- const auto status = destroyLayer(display, layer);
+ const auto status = destroyLayer(display, layer, writer);
if (!status.isOk()) {
ALOGE("Unable to destroy all the layers, failed at layer %" PRId64 " with error %s",
layer, status.getDescription().c_str());
diff --git a/graphics/composer/aidl/vts/VtsComposerClient.h b/graphics/composer/aidl/vts/VtsComposerClient.h
index b45c71f..fabc82a 100644
--- a/graphics/composer/aidl/vts/VtsComposerClient.h
+++ b/graphics/composer/aidl/vts/VtsComposerClient.h
@@ -25,6 +25,7 @@
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <android/hardware/graphics/composer3/ComposerClientReader.h>
+#include <android/hardware/graphics/composer3/ComposerClientWriter.h>
#include <binder/ProcessState.h>
#include <gtest/gtest.h>
#include <ui/Fence.h>
@@ -59,7 +60,7 @@
ScopedAStatus createClient();
- bool tearDown();
+ bool tearDown(ComposerClientWriter*);
std::pair<ScopedAStatus, int32_t> getInterfaceVersion() const;
@@ -69,9 +70,10 @@
ScopedAStatus destroyVirtualDisplay(int64_t display);
- std::pair<ScopedAStatus, int64_t> createLayer(int64_t display, int32_t bufferSlotCount);
+ std::pair<ScopedAStatus, int64_t> createLayer(int64_t display, int32_t bufferSlotCount,
+ ComposerClientWriter*);
- ScopedAStatus destroyLayer(int64_t display, int64_t layer);
+ ScopedAStatus destroyLayer(int64_t display, int64_t layer, ComposerClientWriter*);
std::pair<ScopedAStatus, int32_t> getActiveConfig(int64_t display);
@@ -211,7 +213,7 @@
void removeLayerFromDisplayResources(int64_t display, int64_t layer);
- bool destroyAllLayers();
+ bool destroyAllLayers(ComposerClientWriter*);
bool verifyComposerCallbackParams();
@@ -229,6 +231,8 @@
std::shared_ptr<IComposerClient> mComposerClient;
std::shared_ptr<GraphicsComposerCallback> mComposerCallback;
std::unordered_map<int64_t, DisplayResource> mDisplayResources;
+ bool mSupportsBatchedCreateLayer = false;
+ std::atomic<int64_t> mNextLayerHandle = 1;
};
class VtsDisplay {
@@ -253,10 +257,14 @@
int32_t getDisplayHeight() const { return mDisplayHeight; }
struct DisplayConfig {
- DisplayConfig(int32_t vsyncPeriod_, int32_t configGroup_)
- : vsyncPeriod(vsyncPeriod_), configGroup(configGroup_) {}
+ DisplayConfig(int32_t vsyncPeriod_, int32_t configGroup_,
+ std::optional<VrrConfig> vrrConfig_ = {})
+ : vsyncPeriod(vsyncPeriod_),
+ configGroup(configGroup_),
+ vrrConfig(std::move(vrrConfig_)) {}
int32_t vsyncPeriod;
int32_t configGroup;
+ std::optional<VrrConfig> vrrConfig;
};
void addDisplayConfig(int32_t config, DisplayConfig displayConfig) {
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
index 58eca6e..3f82925 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
@@ -85,8 +85,9 @@
}
void TearDown() override {
+ ASSERT_FALSE(mDisplays.empty());
ASSERT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
- ASSERT_TRUE(mComposerClient->tearDown());
+ ASSERT_TRUE(mComposerClient->tearDown(mWriter.get()));
mComposerClient.reset();
const auto errors = mReader.takeErrors();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -201,7 +202,8 @@
return;
}
- auto layer = std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+ auto layer =
+ std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
common::Rect coloredSquare({0, 0, getDisplayWidth(), getDisplayHeight()});
layer->setColor(BLUE);
layer->setDisplayFrame(coloredSquare);
@@ -270,7 +272,7 @@
auto layer = std::make_shared<TestBufferLayer>(
mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
- getDisplayHeight(), common::PixelFormat::RGBA_8888);
+ getDisplayHeight(), common::PixelFormat::RGBA_8888, *mWriter);
layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
layer->setZOrder(10);
layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
@@ -315,7 +317,8 @@
return;
}
- auto layer = std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+ auto layer =
+ std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
common::Rect coloredSquare({0, 0, getDisplayWidth(), getDisplayHeight()});
layer->setColor(BLUE);
layer->setDisplayFrame(coloredSquare);
@@ -454,9 +457,9 @@
expectedColors, getDisplayWidth(),
{0, getDisplayHeight() / 2, getDisplayWidth(), getDisplayHeight()}, BLUE);
- auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
- getPrimaryDisplayId(), getDisplayWidth(),
- getDisplayHeight(), PixelFormat::RGBA_FP16);
+ auto layer = std::make_shared<TestBufferLayer>(
+ mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
+ getDisplayHeight(), PixelFormat::RGBA_FP16, *mWriter);
layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
layer->setZOrder(10);
layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
@@ -500,7 +503,7 @@
const auto unlockStatus = graphicBuffer->unlockAsync(&clientFence);
ASSERT_EQ(::android::OK, unlockStatus);
mWriter->setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, buffer, clientFence,
- clientDataspace, std::vector<common::Rect>(1, damage));
+ clientDataspace, std::vector<common::Rect>(1, damage), 1.f);
layer->setToClientComposition(*mWriter);
mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
VtsComposerClient::kNoFrameIntervalNs);
@@ -550,7 +553,7 @@
auto deviceLayer = std::make_shared<TestBufferLayer>(
mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
- getDisplayHeight() / 2, PixelFormat::RGBA_8888);
+ getDisplayHeight() / 2, PixelFormat::RGBA_8888, *mWriter);
std::vector<Color> deviceColors(deviceLayer->getWidth() * deviceLayer->getHeight());
ReadbackHelper::fillColorsArea(deviceColors, static_cast<int32_t>(deviceLayer->getWidth()),
{0, 0, static_cast<int32_t>(deviceLayer->getWidth()),
@@ -574,7 +577,7 @@
auto clientLayer = std::make_shared<TestBufferLayer>(
mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), clientWidth,
- clientHeight, PixelFormat::RGBA_FP16, Composition::DEVICE);
+ clientHeight, PixelFormat::RGBA_FP16, *mWriter, Composition::DEVICE);
common::Rect clientFrame = {0, getDisplayHeight() / 2, getDisplayWidth(),
getDisplayHeight()};
clientLayer->setDisplayFrame(clientFrame);
@@ -608,7 +611,7 @@
const auto unlockStatus = graphicBuffer->unlockAsync(&clientFence);
ASSERT_EQ(::android::OK, unlockStatus);
mWriter->setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, buffer, clientFence,
- clientDataspace, std::vector<common::Rect>(1, clientFrame));
+ clientDataspace, std::vector<common::Rect>(1, clientFrame), 1.f);
clientLayer->setToClientComposition(*mWriter);
mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
VtsComposerClient::kNoFrameIntervalNs);
@@ -643,9 +646,9 @@
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), redRect, RED);
- auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
- getPrimaryDisplayId(), getDisplayWidth(),
- getDisplayHeight(), PixelFormat::RGBA_8888);
+ auto layer = std::make_shared<TestBufferLayer>(
+ mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
+ getDisplayHeight(), PixelFormat::RGBA_8888, *mWriter);
layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
layer->setZOrder(10);
layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
@@ -714,7 +717,8 @@
return;
}
- auto layer = std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+ auto layer =
+ std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
layer->setColor(RED);
layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
layer->setZOrder(10);
@@ -774,9 +778,9 @@
expectedColors, getDisplayWidth(),
{0, getDisplayHeight() / 2, getDisplayWidth(), getDisplayHeight()}, BLUE);
- auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
- getPrimaryDisplayId(), getDisplayWidth(),
- getDisplayHeight(), PixelFormat::RGBA_8888);
+ auto layer = std::make_shared<TestBufferLayer>(
+ mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
+ getDisplayHeight(), PixelFormat::RGBA_8888, *mWriter);
layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
layer->setZOrder(10);
layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
@@ -828,11 +832,13 @@
common::Rect redRect = {0, 0, getDisplayWidth(), getDisplayHeight() / 2};
common::Rect blueRect = {0, getDisplayHeight() / 4, getDisplayWidth(), getDisplayHeight()};
- auto redLayer = std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+ auto redLayer =
+ std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
redLayer->setColor(RED);
redLayer->setDisplayFrame(redRect);
- auto blueLayer = std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+ auto blueLayer =
+ std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
blueLayer->setColor(BLUE);
blueLayer->setDisplayFrame(blueRect);
blueLayer->setZOrder(5);
@@ -914,14 +920,14 @@
static constexpr float kMaxBrightnessNits = 300.f;
const auto redLayer =
- std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+ std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
redLayer->setColor(RED);
redLayer->setDisplayFrame(redRect);
redLayer->setWhitePointNits(kMaxBrightnessNits);
redLayer->setBrightness(1.f);
const auto dimmerRedLayer =
- std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+ std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
dimmerRedLayer->setColor(RED);
dimmerRedLayer->setDisplayFrame(dimmerRedRect);
// Intentionally use a small dimming ratio as some implementations may be more likely to
@@ -992,14 +998,14 @@
mTopLayerColor);
auto backgroundLayer =
- std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+ std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
backgroundLayer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
backgroundLayer->setZOrder(0);
backgroundLayer->setColor(mBackgroundColor);
- auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
- getPrimaryDisplayId(), getDisplayWidth(),
- getDisplayHeight(), PixelFormat::RGBA_8888);
+ auto layer = std::make_shared<TestBufferLayer>(
+ mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
+ getDisplayHeight(), PixelFormat::RGBA_8888, *mWriter);
layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
layer->setZOrder(10);
layer->setDataspace(Dataspace::UNKNOWN);
@@ -1190,7 +1196,7 @@
GraphicsCompositionTest::SetUp();
auto backgroundLayer =
- std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+ std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
backgroundLayer->setColor({0.0f, 0.0f, 0.0f, 0.0f});
backgroundLayer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
backgroundLayer->setZOrder(0);
@@ -1202,7 +1208,7 @@
mLayer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
getPrimaryDisplayId(), mSideLength, mSideLength,
- PixelFormat::RGBA_8888);
+ PixelFormat::RGBA_8888, *mWriter);
mLayer->setDisplayFrame({0, 0, mSideLength, mSideLength});
mLayer->setZOrder(10);
@@ -1388,7 +1394,7 @@
void makeLayer() {
mLayer = std::make_shared<TestBufferLayer>(
mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
- getDisplayHeight(), common::PixelFormat::RGBA_8888);
+ getDisplayHeight(), common::PixelFormat::RGBA_8888, *mWriter);
mLayer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
mLayer->setZOrder(10);
mLayer->setAlpha(1.f);
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
index c135298..f72cf55 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -70,7 +70,7 @@
}
void TearDown() override {
- ASSERT_TRUE(mComposerClient->tearDown());
+ ASSERT_TRUE(mComposerClient->tearDown(nullptr));
mComposerClient.reset();
}
@@ -832,36 +832,58 @@
}
TEST_P(GraphicsComposerAidlTest, CreateLayer) {
+ if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+ GTEST_SKIP() << "Create layer will be tested in GraphicsComposerAidlBatchedCommandTest";
+ return;
+ }
+
const auto& [status, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, nullptr);
EXPECT_TRUE(status.isOk());
- EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer).isOk());
+ EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, nullptr).isOk());
}
TEST_P(GraphicsComposerAidlTest, CreateLayer_BadDisplay) {
- const auto& [status, _] = mComposerClient->createLayer(getInvalidDisplayId(), kBufferSlotCount);
+ if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+ GTEST_SKIP() << "Create layer will be tested in GraphicsComposerAidlBatchedCommandTest";
+ return;
+ }
+
+ const auto& [status, _] =
+ mComposerClient->createLayer(getInvalidDisplayId(), kBufferSlotCount, nullptr);
EXPECT_FALSE(status.isOk());
EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
}
TEST_P(GraphicsComposerAidlTest, DestroyLayer_BadDisplay) {
+ if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+ GTEST_SKIP() << "Destroy layer will be tested in GraphicsComposerAidlBatchedCommandTest";
+ return;
+ }
+
const auto& [status, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, nullptr);
EXPECT_TRUE(status.isOk());
- const auto& destroyStatus = mComposerClient->destroyLayer(getInvalidDisplayId(), layer);
+ const auto& destroyStatus =
+ mComposerClient->destroyLayer(getInvalidDisplayId(), layer, nullptr);
EXPECT_FALSE(destroyStatus.isOk());
EXPECT_NO_FATAL_FAILURE(
assertServiceSpecificError(destroyStatus, IComposerClient::EX_BAD_DISPLAY));
- ASSERT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer).isOk());
+ ASSERT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, nullptr).isOk());
}
TEST_P(GraphicsComposerAidlTest, DestroyLayer_BadLayerError) {
+ if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+ GTEST_SKIP() << "Destroy layer will be tested in GraphicsComposerAidlBatchedCommandTest";
+ return;
+ }
+
// We haven't created any layers yet, so any id should be invalid
- const auto& status = mComposerClient->destroyLayer(getPrimaryDisplayId(), /*layer*/ 1);
+ const auto& status = mComposerClient->destroyLayer(getPrimaryDisplayId(), /*layer*/ 1, nullptr);
EXPECT_FALSE(status.isOk());
EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_LAYER));
@@ -1171,6 +1193,12 @@
}
}
+TEST_P(GraphicsComposerAidlTest, LayerLifecycleCapabilityNotSupportedOnOldVersions) {
+ if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+ EXPECT_GE(getInterfaceVersion(), 3);
+ }
+}
+
class GraphicsComposerAidlV2Test : public GraphicsComposerAidlTest {
protected:
void SetUp() override {
@@ -1263,6 +1291,9 @@
frameIntervalPowerHints.cend());
EXPECT_LE(minFrameInterval->frameIntervalNs,
VtsComposerClient::kMaxFrameIntervalNs);
+ const auto maxFrameInterval = *max_element(frameIntervalPowerHints.cbegin(),
+ frameIntervalPowerHints.cend());
+ EXPECT_GE(maxFrameInterval->frameIntervalNs, vrrConfig.minFrameIntervalNs);
EXPECT_TRUE(std::all_of(frameIntervalPowerHints.cbegin(),
frameIntervalPowerHints.cend(),
@@ -1275,8 +1306,8 @@
if (vrrConfig.notifyExpectedPresentConfig) {
const auto& notifyExpectedPresentConfig =
*vrrConfig.notifyExpectedPresentConfig;
- EXPECT_GT(0, notifyExpectedPresentConfig.notifyExpectedPresentHeadsUpNs);
- EXPECT_GE(0, notifyExpectedPresentConfig.notifyExpectedPresentTimeoutNs);
+ EXPECT_GE(notifyExpectedPresentConfig.headsUpNs, 0);
+ EXPECT_GE(notifyExpectedPresentConfig.timeoutNs, 0);
}
}
}
@@ -1357,25 +1388,15 @@
}
}
-// TODO(b/291792736) Add detailed VTS test cases for NotifyExpectedPresent
-TEST_P(GraphicsComposerAidlV3Test, NotifyExpectedPresent) {
- for (const auto& display : mDisplays) {
- EXPECT_TRUE(mComposerClient
- ->notifyExpectedPresent(display.getDisplayId(),
- ClockMonotonicTimestamp{0},
- std::chrono::nanoseconds{8ms}.count())
- .isOk());
- }
-}
-
// Tests for Command.
class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest {
protected:
void TearDown() override {
- const auto errors = mReader.takeErrors();
+ ASSERT_FALSE(mDisplays.empty());
ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_TRUE(mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty());
+ ASSERT_TRUE(mComposerClient->tearDown(&getWriter(getPrimaryDisplayId())));
ASSERT_NO_FATAL_FAILURE(GraphicsComposerAidlTest::TearDown());
}
@@ -1463,10 +1484,10 @@
RenderIntent::COLORIMETRIC)
.isOk());
- const auto& [status, layer] =
- mComposerClient->createLayer(display.getDisplayId(), kBufferSlotCount);
- EXPECT_TRUE(status.isOk());
auto& writer = getWriter(display.getDisplayId());
+ const auto& [status, layer] =
+ mComposerClient->createLayer(display.getDisplayId(), kBufferSlotCount, &writer);
+ EXPECT_TRUE(status.isOk());
{
const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ASSERT_NE(nullptr, buffer);
@@ -1506,22 +1527,24 @@
execute();
}
- EXPECT_TRUE(mComposerClient->destroyLayer(display.getDisplayId(), layer).isOk());
+ EXPECT_TRUE(mComposerClient->destroyLayer(display.getDisplayId(), layer, &writer).isOk());
}
sp<::android::Fence> presentAndGetFence(
- std::optional<ClockMonotonicTimestamp> expectedPresentTime) {
- auto& writer = getWriter(getPrimaryDisplayId());
- writer.validateDisplay(getPrimaryDisplayId(), expectedPresentTime,
- VtsComposerClient::kNoFrameIntervalNs);
+ std::optional<ClockMonotonicTimestamp> expectedPresentTime,
+ std::optional<int64_t> displayIdOpt = {},
+ int32_t frameIntervalNs = VtsComposerClient::kNoFrameIntervalNs) {
+ const auto displayId = displayIdOpt.value_or(getPrimaryDisplayId());
+ auto& writer = getWriter(displayId);
+ writer.validateDisplay(displayId, expectedPresentTime, frameIntervalNs);
execute();
EXPECT_TRUE(mReader.takeErrors().empty());
- writer.presentDisplay(getPrimaryDisplayId());
+ writer.presentDisplay(displayId);
execute();
EXPECT_TRUE(mReader.takeErrors().empty());
- auto presentFence = mReader.takePresentFence(getPrimaryDisplayId());
+ auto presentFence = mReader.takePresentFence(displayId);
// take ownership
const int fenceOwner = presentFence.get();
*presentFence.getR() = -1;
@@ -1540,17 +1563,17 @@
return vsyncPeriod;
}
- int64_t createOnScreenLayer(Composition composition = Composition::DEVICE) {
+ int64_t createOnScreenLayer(const VtsDisplay& display,
+ Composition composition = Composition::DEVICE) {
+ auto& writer = getWriter(display.getDisplayId());
const auto& [status, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+ mComposerClient->createLayer(display.getDisplayId(), kBufferSlotCount, &writer);
EXPECT_TRUE(status.isOk());
- Rect displayFrame{0, 0, getPrimaryDisplay().getDisplayWidth(),
- getPrimaryDisplay().getDisplayHeight()};
- FRect cropRect{0, 0, (float)getPrimaryDisplay().getDisplayWidth(),
- (float)getPrimaryDisplay().getDisplayHeight()};
- configureLayer(getPrimaryDisplay(), layer, composition, displayFrame, cropRect);
- auto& writer = getWriter(getPrimaryDisplayId());
- writer.setLayerDataspace(getPrimaryDisplayId(), layer, common::Dataspace::UNKNOWN);
+ Rect displayFrame{0, 0, display.getDisplayWidth(), display.getDisplayHeight()};
+ FRect cropRect{0, 0, (float)display.getDisplayWidth(), (float)display.getDisplayHeight()};
+ configureLayer(display, layer, composition, displayFrame, cropRect);
+
+ writer.setLayerDataspace(display.getDisplayId(), layer, common::Dataspace::UNKNOWN);
return layer;
}
@@ -1662,7 +1685,7 @@
ASSERT_NE(nullptr, buffer1);
ASSERT_NE(nullptr, buffer2);
- const auto layer = createOnScreenLayer();
+ const auto layer = createOnScreenLayer(getPrimaryDisplay());
auto& writer = getWriter(getPrimaryDisplayId());
writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer1->handle,
/*acquireFence*/ -1);
@@ -1695,6 +1718,38 @@
ASSERT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
}
+ void forEachNotifyExpectedPresentConfig(
+ std::function<void(VtsDisplay&, const DisplayConfiguration&)> func) {
+ for (VtsDisplay& display : mDisplays) {
+ const auto displayId = display.getDisplayId();
+ EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
+ const auto& [status, displayConfigurations] =
+ mComposerClient->getDisplayConfigurations(displayId);
+ EXPECT_TRUE(status.isOk());
+ EXPECT_FALSE(displayConfigurations.empty());
+ for (const auto& config : displayConfigurations) {
+ if (config.vrrConfig && config.vrrConfig->notifyExpectedPresentConfig) {
+ const auto [vsyncPeriodStatus, oldVsyncPeriod] =
+ mComposerClient->getDisplayVsyncPeriod(displayId);
+ ASSERT_TRUE(vsyncPeriodStatus.isOk());
+ const auto& [timelineStatus, timeline] =
+ mComposerClient->setActiveConfigWithConstraints(
+ &display, config.configId,
+ VsyncPeriodChangeConstraints{.seamlessRequired = false});
+ ASSERT_TRUE(timelineStatus.isOk());
+ if (timeline.refreshRequired) {
+ sendRefreshFrame(display, &timeline);
+ }
+ waitForVsyncPeriodChange(displayId, timeline, systemTime(), oldVsyncPeriod,
+ config.vsyncPeriod);
+ func(display, config);
+ }
+ }
+ EXPECT_TRUE(
+ mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
+ }
+ }
+
void configureLayer(const VtsDisplay& display, int64_t layer, Composition composition,
const Rect& displayFrame, const FRect& cropRect) {
auto& writer = getWriter(display.getDisplayId());
@@ -1758,10 +1813,10 @@
}
TEST_P(GraphicsComposerAidlCommandTest, SetLayerColorTransform) {
- const auto& [status, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
- EXPECT_TRUE(status.isOk());
auto& writer = getWriter(getPrimaryDisplayId());
+ const auto& [status, layer] =
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
+ EXPECT_TRUE(status.isOk());
writer.setLayerColorTransform(getPrimaryDisplayId(), layer, kIdentity.data());
execute();
@@ -1773,6 +1828,7 @@
}
TEST_P(GraphicsComposerAidlCommandTest, SetDisplayBrightness) {
+ EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
const auto& [status, capabilities] =
mComposerClient->getDisplayCapabilities(getPrimaryDisplayId());
ASSERT_TRUE(status.isOk());
@@ -1828,7 +1884,7 @@
auto& writer = getWriter(getPrimaryDisplayId());
writer.setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, nullptr, /*acquireFence*/ -1,
- Dataspace::UNKNOWN, std::vector<Rect>());
+ Dataspace::UNKNOWN, std::vector<Rect>(), 1.0f);
execute();
}
@@ -1899,7 +1955,7 @@
ASSERT_NE(nullptr, handle);
const auto& [layerStatus, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
EXPECT_TRUE(layerStatus.isOk());
Rect displayFrame{0, 0, getPrimaryDisplay().getDisplayWidth(),
@@ -1936,15 +1992,15 @@
}
TEST_P(GraphicsComposerAidlCommandTest, SetLayerCursorPosition) {
+ auto& writer = getWriter(getPrimaryDisplayId());
const auto& [layerStatus, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
EXPECT_TRUE(layerStatus.isOk());
const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
const auto handle = buffer->handle;
ASSERT_NE(nullptr, handle);
- auto& writer = getWriter(getPrimaryDisplayId());
writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle, /*acquireFence*/ -1);
Rect displayFrame{0, 0, getPrimaryDisplay().getDisplayWidth(),
@@ -1980,19 +2036,19 @@
const auto handle = buffer->handle;
ASSERT_NE(nullptr, handle);
- const auto& [layerStatus, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
- EXPECT_TRUE(layerStatus.isOk());
auto& writer = getWriter(getPrimaryDisplayId());
+ const auto& [layerStatus, layer] =
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
+ EXPECT_TRUE(layerStatus.isOk());
writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle, /*acquireFence*/ -1);
execute();
}
TEST_P(GraphicsComposerAidlCommandTest, SetLayerBufferMultipleTimes) {
- const auto& [layerStatus, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
- EXPECT_TRUE(layerStatus.isOk());
auto& writer = getWriter(getPrimaryDisplayId());
+ const auto& [layerStatus, layer] =
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
+ EXPECT_TRUE(layerStatus.isOk());
// Setup 3 buffers in the buffer cache, with the last buffer being active. Then, emulate the
// Android platform code that clears all 3 buffer slots by setting all but the active buffer
@@ -2040,14 +2096,14 @@
}
TEST_P(GraphicsComposerAidlCommandTest, SetLayerSurfaceDamage) {
+ auto& writer = getWriter(getPrimaryDisplayId());
const auto& [layerStatus, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
EXPECT_TRUE(layerStatus.isOk());
Rect empty{0, 0, 0, 0};
Rect unit{0, 0, 1, 1};
- auto& writer = getWriter(getPrimaryDisplayId());
writer.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2062,14 +2118,14 @@
}
TEST_P(GraphicsComposerAidlCommandTest, SetLayerBlockingRegion) {
+ auto& writer = getWriter(getPrimaryDisplayId());
const auto& [layerStatus, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
EXPECT_TRUE(layerStatus.isOk());
Rect empty{0, 0, 0, 0};
Rect unit{0, 0, 1, 1};
- auto& writer = getWriter(getPrimaryDisplayId());
writer.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2084,11 +2140,11 @@
}
TEST_P(GraphicsComposerAidlCommandTest, SetLayerBlendMode) {
+ auto& writer = getWriter(getPrimaryDisplayId());
const auto& [layerStatus, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
EXPECT_TRUE(layerStatus.isOk());
- auto& writer = getWriter(getPrimaryDisplayId());
writer.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::NONE);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2103,11 +2159,11 @@
}
TEST_P(GraphicsComposerAidlCommandTest, SetLayerColor) {
+ auto& writer = getWriter(getPrimaryDisplayId());
const auto& [layerStatus, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
EXPECT_TRUE(layerStatus.isOk());
- auto& writer = getWriter(getPrimaryDisplayId());
writer.setLayerColor(getPrimaryDisplayId(), layer, Color{1.0f, 1.0f, 1.0f, 1.0f});
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2118,11 +2174,11 @@
}
TEST_P(GraphicsComposerAidlCommandTest, SetLayerCompositionType) {
+ auto& writer = getWriter(getPrimaryDisplayId());
const auto& [layerStatus, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
EXPECT_TRUE(layerStatus.isOk());
- auto& writer = getWriter(getPrimaryDisplayId());
writer.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::CLIENT);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2141,8 +2197,9 @@
TEST_P(GraphicsComposerAidlCommandTest, DisplayDecoration) {
for (VtsDisplay& display : mDisplays) {
+ auto& writer = getWriter(display.getDisplayId());
const auto [layerStatus, layer] =
- mComposerClient->createLayer(display.getDisplayId(), kBufferSlotCount);
+ mComposerClient->createLayer(display.getDisplayId(), kBufferSlotCount, &writer);
EXPECT_TRUE(layerStatus.isOk());
const auto [error, support] =
@@ -2165,8 +2222,7 @@
}
configureLayer(display, layer, Composition::DISPLAY_DECORATION, display.getFrameRect(),
- display.getCrop());
- auto& writer = getWriter(display.getDisplayId());
+ display.getCrop());
writer.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, decorBuffer->handle,
/*acquireFence*/ -1);
writer.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp,
@@ -2183,31 +2239,31 @@
}
TEST_P(GraphicsComposerAidlCommandTest, SetLayerDataspace) {
+ auto& writer = getWriter(getPrimaryDisplayId());
const auto& [layerStatus, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
EXPECT_TRUE(layerStatus.isOk());
- auto& writer = getWriter(getPrimaryDisplayId());
writer.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
execute();
}
TEST_P(GraphicsComposerAidlCommandTest, SetLayerDisplayFrame) {
+ auto& writer = getWriter(getPrimaryDisplayId());
const auto& [layerStatus, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
EXPECT_TRUE(layerStatus.isOk());
- auto& writer = getWriter(getPrimaryDisplayId());
writer.setLayerDisplayFrame(getPrimaryDisplayId(), layer, Rect{0, 0, 1, 1});
execute();
}
TEST_P(GraphicsComposerAidlCommandTest, SetLayerPlaneAlpha) {
+ auto& writer = getWriter(getPrimaryDisplayId());
const auto& [layerStatus, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
EXPECT_TRUE(layerStatus.isOk());
- auto& writer = getWriter(getPrimaryDisplayId());
writer.setLayerPlaneAlpha(getPrimaryDisplayId(), layer, /*alpha*/ 0.0f);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2227,31 +2283,31 @@
const auto handle = buffer->handle;
ASSERT_NE(nullptr, handle);
+ auto& writer = getWriter(getPrimaryDisplayId());
const auto& [layerStatus, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
EXPECT_TRUE(layerStatus.isOk());
- auto& writer = getWriter(getPrimaryDisplayId());
writer.setLayerSidebandStream(getPrimaryDisplayId(), layer, handle);
execute();
}
TEST_P(GraphicsComposerAidlCommandTest, SetLayerSourceCrop) {
+ auto& writer = getWriter(getPrimaryDisplayId());
const auto& [layerStatus, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
EXPECT_TRUE(layerStatus.isOk());
- auto& writer = getWriter(getPrimaryDisplayId());
writer.setLayerSourceCrop(getPrimaryDisplayId(), layer, FRect{0.0f, 0.0f, 1.0f, 1.0f});
execute();
}
TEST_P(GraphicsComposerAidlCommandTest, SetLayerTransform) {
+ auto& writer = getWriter(getPrimaryDisplayId());
const auto& [layerStatus, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
EXPECT_TRUE(layerStatus.isOk());
- auto& writer = getWriter(getPrimaryDisplayId());
writer.setLayerTransform(getPrimaryDisplayId(), layer, static_cast<Transform>(0));
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2290,14 +2346,14 @@
}
TEST_P(GraphicsComposerAidlCommandTest, SetLayerVisibleRegion) {
+ auto& writer = getWriter(getPrimaryDisplayId());
const auto& [layerStatus, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
EXPECT_TRUE(layerStatus.isOk());
Rect empty{0, 0, 0, 0};
Rect unit{0, 0, 1, 1};
- auto& writer = getWriter(getPrimaryDisplayId());
writer.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2312,11 +2368,12 @@
}
TEST_P(GraphicsComposerAidlCommandTest, SetLayerZOrder) {
+ auto& writer = getWriter(getPrimaryDisplayId());
+
const auto& [layerStatus, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
EXPECT_TRUE(layerStatus.isOk());
- auto& writer = getWriter(getPrimaryDisplayId());
writer.setLayerZOrder(getPrimaryDisplayId(), layer, /*z*/ 10);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2327,8 +2384,9 @@
}
TEST_P(GraphicsComposerAidlCommandTest, SetLayerPerFrameMetadata) {
+ auto& writer = getWriter(getPrimaryDisplayId());
const auto& [layerStatus, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
EXPECT_TRUE(layerStatus.isOk());
/**
@@ -2343,7 +2401,6 @@
* white (D65) 0.3127 0.3290
*/
- auto& writer = getWriter(getPrimaryDisplayId());
std::vector<PerFrameMetadata> aidlMetadata;
aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X, 0.680f});
aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y, 0.320f});
@@ -2363,18 +2420,19 @@
const auto errors = mReader.takeErrors();
if (errors.size() == 1 && errors[0].errorCode == EX_UNSUPPORTED_OPERATION) {
GTEST_SUCCEED() << "SetLayerPerFrameMetadata is not supported";
- EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer).isOk());
+ EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, &writer).isOk());
return;
}
- EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer).isOk());
+ EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, &writer).isOk());
}
TEST_P(GraphicsComposerAidlCommandTest, setLayerBrightness) {
- const auto& [layerStatus, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
-
auto& writer = getWriter(getPrimaryDisplayId());
+
+ const auto& [layerStatus, layer] =
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
+
writer.setLayerBrightness(getPrimaryDisplayId(), layer, 0.2f);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2559,7 +2617,7 @@
const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ASSERT_NE(nullptr, buffer->handle);
- const auto layer = createOnScreenLayer();
+ const auto layer = createOnScreenLayer(getPrimaryDisplay());
auto& writer = getWriter(getPrimaryDisplayId());
writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer->handle,
/*acquireFence*/ -1);
@@ -2603,12 +2661,12 @@
}
TEST_P(GraphicsComposerAidlCommandV2Test, SetLayerBufferSlotsToClear) {
+ auto& writer = getWriter(getPrimaryDisplayId());
// Older HAL versions use a backwards compatible way of clearing buffer slots
// HAL at version 1 or lower does not have LayerCommand::bufferSlotsToClear
const auto& [layerStatus, layer] =
- mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
EXPECT_TRUE(layerStatus.isOk());
- auto& writer = getWriter(getPrimaryDisplayId());
// setup 3 buffers in the buffer cache, with the last buffer being active
// then emulate the Android platform code that clears all 3 buffer slots
@@ -2664,26 +2722,40 @@
return;
}
- const auto displayId = getPrimaryDisplayId();
- EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
- // Enable the callback
- ASSERT_TRUE(mComposerClient
- ->setRefreshRateChangedCallbackDebugEnabled(displayId,
- /*enabled*/ true)
- .isOk());
- std::this_thread::sleep_for(100ms);
+ for (VtsDisplay& display : mDisplays) {
+ const auto displayId = display.getDisplayId();
+ EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
+ // Enable the callback
+ ASSERT_TRUE(mComposerClient
+ ->setRefreshRateChangedCallbackDebugEnabled(displayId,
+ /*enabled*/ true)
+ .isOk());
+ std::this_thread::sleep_for(100ms);
- const auto displayFilter = [displayId](auto refreshRateChangedDebugData) {
- return displayId == refreshRateChangedDebugData.display;
- };
+ const auto [status, configId] = mComposerClient->getActiveConfig(display.getDisplayId());
+ EXPECT_TRUE(status.isOk());
- // Check that we immediately got a callback
- EXPECT_TRUE(checkIfCallbackRefreshRateChangedDebugEnabledReceived(displayFilter));
+ const auto displayFilter = [&](auto refreshRateChangedDebugData) {
+ bool nonVrrRateMatching = true;
+ if (std::optional<VrrConfig> vrrConfigOpt =
+ display.getDisplayConfig(configId).vrrConfig;
+ getInterfaceVersion() >= 3 && !vrrConfigOpt) {
+ nonVrrRateMatching = refreshRateChangedDebugData.refreshPeriodNanos ==
+ refreshRateChangedDebugData.vsyncPeriodNanos;
+ }
+ const bool isDisplaySame =
+ display.getDisplayId() == refreshRateChangedDebugData.display;
+ return nonVrrRateMatching && isDisplaySame;
+ };
- ASSERT_TRUE(mComposerClient
- ->setRefreshRateChangedCallbackDebugEnabled(displayId,
- /*enabled*/ false)
- .isOk());
+ // Check that we immediately got a callback
+ EXPECT_TRUE(checkIfCallbackRefreshRateChangedDebugEnabledReceived(displayFilter));
+
+ ASSERT_TRUE(mComposerClient
+ ->setRefreshRateChangedCallbackDebugEnabled(displayId,
+ /*enabled*/ false)
+ .isOk());
+ }
}
TEST_P(GraphicsComposerAidlCommandV2Test,
@@ -2731,8 +2803,8 @@
}
// Send the REFRESH_RATE_INDICATOR update
- ASSERT_NO_FATAL_FAILURE(
- sendBufferUpdate(createOnScreenLayer(Composition::REFRESH_RATE_INDICATOR)));
+ ASSERT_NO_FATAL_FAILURE(sendBufferUpdate(
+ createOnScreenLayer(getPrimaryDisplay(), Composition::REFRESH_RATE_INDICATOR)));
std::this_thread::sleep_for(1s);
EXPECT_FALSE(checkIfCallbackRefreshRateChangedDebugEnabledReceived(displayFilter))
<< "A callback should not be received for REFRESH_RATE_INDICATOR";
@@ -2853,7 +2925,8 @@
EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
- const auto& [status, layer] = mComposerClient->createLayer(displayId, kBufferSlotCount);
+ const auto& [status, layer] =
+ mComposerClient->createLayer(displayId, kBufferSlotCount, &writer);
const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ASSERT_NE(nullptr, buffer);
ASSERT_EQ(::android::OK, buffer->initCheck());
@@ -2903,7 +2976,8 @@
}
for (auto& [displayId, layer] : layers) {
- EXPECT_TRUE(mComposerClient->destroyLayer(displayId, layer).isOk());
+ auto& writer = getWriter(displayId);
+ EXPECT_TRUE(mComposerClient->destroyLayer(displayId, layer, &writer).isOk());
}
std::lock_guard guard{readersMutex};
@@ -2913,6 +2987,254 @@
}
}
+class GraphicsComposerAidlCommandV3Test : public GraphicsComposerAidlCommandTest {
+ protected:
+ void SetUp() override {
+ GraphicsComposerAidlTest::SetUp();
+ if (getInterfaceVersion() <= 2) {
+ GTEST_SKIP() << "Device interface version is expected to be >= 3";
+ }
+ }
+};
+
+TEST_P(GraphicsComposerAidlCommandV3Test, CreateBatchedCommand) {
+ if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+ GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
+ return;
+ }
+
+ auto& writer = getWriter(getPrimaryDisplayId());
+ int64_t layer = 5;
+ writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
+ LayerLifecycleBatchCommandType::CREATE);
+ writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
+ writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
+ VtsComposerClient::kNoFrameIntervalNs);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+}
+
+TEST_P(GraphicsComposerAidlCommandV3Test, CreateBatchedCommand_BadDisplay) {
+ if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+ GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
+ return;
+ }
+
+ auto& writer = getWriter(getPrimaryDisplayId());
+ int64_t layer = 5;
+ writer.setLayerLifecycleBatchCommandType(getInvalidDisplayId(), layer,
+ LayerLifecycleBatchCommandType::CREATE);
+ writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
+ writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
+ VtsComposerClient::kNoFrameIntervalNs);
+ execute();
+ const auto errors = mReader.takeErrors();
+ ASSERT_TRUE(errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_BAD_DISPLAY);
+}
+
+TEST_P(GraphicsComposerAidlCommandV3Test, DestroyBatchedCommand) {
+ if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+ GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
+ return;
+ }
+
+ auto& writer = getWriter(getPrimaryDisplayId());
+ int64_t layer = 5;
+ writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
+ LayerLifecycleBatchCommandType::CREATE);
+ writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
+ writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
+ VtsComposerClient::kNoFrameIntervalNs);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
+ LayerLifecycleBatchCommandType::DESTROY);
+ layer++;
+ writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
+ LayerLifecycleBatchCommandType::CREATE);
+ writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
+
+ execute();
+ const auto errors = mReader.takeErrors();
+ ASSERT_TRUE(errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_BAD_DISPLAY);
+}
+
+TEST_P(GraphicsComposerAidlCommandV3Test, DestroyBatchedCommand_BadDisplay) {
+ if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+ GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
+ return;
+ }
+
+ auto& writer = getWriter(getPrimaryDisplayId());
+ int64_t layer = 5;
+ writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
+ LayerLifecycleBatchCommandType::CREATE);
+ writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
+ writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
+ VtsComposerClient::kNoFrameIntervalNs);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ writer.setLayerLifecycleBatchCommandType(getInvalidDisplayId(), layer,
+ LayerLifecycleBatchCommandType::DESTROY);
+ layer++;
+ writer.setLayerLifecycleBatchCommandType(getInvalidDisplayId(), layer,
+ LayerLifecycleBatchCommandType::CREATE);
+ writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
+
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+}
+
+TEST_P(GraphicsComposerAidlCommandV3Test, NoCreateDestroyBatchedCommandIncorrectLayer) {
+ if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+ GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
+ return;
+ }
+
+ auto& writer = getWriter(getPrimaryDisplayId());
+ int64_t layer = 5;
+ writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
+ LayerLifecycleBatchCommandType::DESTROY);
+ execute();
+ const auto errors = mReader.takeErrors();
+ ASSERT_TRUE(errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_BAD_LAYER);
+}
+
+TEST_P(GraphicsComposerAidlCommandV3Test, notifyExpectedPresentTimeout) {
+ if (hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
+ GTEST_SUCCEED() << "Device has unreliable present fences capability, skipping";
+ return;
+ }
+ forEachNotifyExpectedPresentConfig([&](VtsDisplay& display,
+ const DisplayConfiguration& config) {
+ const auto displayId = display.getDisplayId();
+ auto minFrameIntervalNs = config.vrrConfig->minFrameIntervalNs;
+ const auto timeoutNs = config.vrrConfig->notifyExpectedPresentConfig->timeoutNs;
+
+ const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+ ASSERT_NE(nullptr, buffer);
+ const auto layer = createOnScreenLayer(display);
+ auto& writer = getWriter(displayId);
+ writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
+ /*acquireFence*/ -1);
+ sp<::android::Fence> presentFence = presentAndGetFence(ComposerClientWriter::kNoTimestamp,
+ displayId, minFrameIntervalNs);
+ presentFence->waitForever(LOG_TAG);
+ auto lastPresentTimeNs = presentFence->getSignalTime();
+
+ // Frame presents 30ms after timeout
+ const auto timeout = static_cast<const std::chrono::nanoseconds>(timeoutNs);
+ const auto vsyncPeriod = config.vsyncPeriod;
+ int32_t frameAfterTimeoutNs =
+ vsyncPeriod * static_cast<int32_t>((timeout + 30ms).count() / vsyncPeriod);
+ auto expectedPresentTimestamp =
+ ClockMonotonicTimestamp{lastPresentTimeNs + frameAfterTimeoutNs};
+ std::this_thread::sleep_for(timeout);
+ mComposerClient->notifyExpectedPresent(displayId, expectedPresentTimestamp,
+ minFrameIntervalNs);
+ presentFence = presentAndGetFence(expectedPresentTimestamp, displayId, minFrameIntervalNs);
+ presentFence->waitForever(LOG_TAG);
+ lastPresentTimeNs = presentFence->getSignalTime();
+ ASSERT_GE(lastPresentTimeNs, expectedPresentTimestamp.timestampNanos - vsyncPeriod / 2);
+ mComposerClient->destroyLayer(displayId, layer, &writer);
+ });
+}
+
+TEST_P(GraphicsComposerAidlCommandV3Test, notifyExpectedPresentFrameIntervalChange) {
+ if (hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
+ GTEST_SUCCEED() << "Device has unreliable present fences capability, skipping";
+ return;
+ }
+ forEachNotifyExpectedPresentConfig([&](VtsDisplay& display,
+ const DisplayConfiguration& config) {
+ const auto displayId = display.getDisplayId();
+ const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+ ASSERT_NE(nullptr, buffer);
+ const auto layer = createOnScreenLayer(display);
+ auto& writer = getWriter(displayId);
+ writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
+ /*acquireFence*/ -1);
+ auto minFrameIntervalNs = config.vrrConfig->minFrameIntervalNs;
+ sp<::android::Fence> presentFence = presentAndGetFence(ComposerClientWriter::kNoTimestamp,
+ displayId, minFrameIntervalNs);
+ presentFence->waitForever(LOG_TAG);
+ auto lastPresentTimeNs = presentFence->getSignalTime();
+
+ auto vsyncPeriod = config.vsyncPeriod;
+ int32_t highestDivisor = VtsComposerClient::kMaxFrameIntervalNs / vsyncPeriod;
+ int32_t lowestDivisor = minFrameIntervalNs / vsyncPeriod;
+ const auto headsUpNs = config.vrrConfig->notifyExpectedPresentConfig->headsUpNs;
+ float totalDivisorsPassed = 0.f;
+ for (int divisor = lowestDivisor; divisor <= highestDivisor; divisor++) {
+ const auto frameIntervalNs = vsyncPeriod * divisor;
+ const auto frameAfterHeadsUp = frameIntervalNs * (headsUpNs / frameIntervalNs);
+ auto presentTime = lastPresentTimeNs + frameIntervalNs + frameAfterHeadsUp;
+ const auto expectedPresentTimestamp = ClockMonotonicTimestamp{presentTime};
+ ASSERT_TRUE(mComposerClient
+ ->notifyExpectedPresent(displayId, expectedPresentTimestamp,
+ frameIntervalNs)
+ .isOk());
+ presentFence = presentAndGetFence(expectedPresentTimestamp, displayId, frameIntervalNs);
+ presentFence->waitForever(LOG_TAG);
+ lastPresentTimeNs = presentFence->getSignalTime();
+ if (lastPresentTimeNs >= expectedPresentTimestamp.timestampNanos - vsyncPeriod / 2) {
+ ++totalDivisorsPassed;
+ }
+ }
+ EXPECT_TRUE(totalDivisorsPassed >
+ (static_cast<float>(highestDivisor - lowestDivisor)) * 0.75f);
+ mComposerClient->destroyLayer(displayId, layer, &writer);
+ });
+}
+
+TEST_P(GraphicsComposerAidlCommandV3Test, frameIntervalChangeAtPresentFrame) {
+ if (hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
+ GTEST_SUCCEED() << "Device has unreliable present fences capability, skipping";
+ return;
+ }
+ forEachNotifyExpectedPresentConfig([&](VtsDisplay& display,
+ const DisplayConfiguration& config) {
+ const auto displayId = display.getDisplayId();
+ const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+ ASSERT_NE(nullptr, buffer);
+ const auto layer = createOnScreenLayer(display);
+ auto& writer = getWriter(displayId);
+ writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
+ /*acquireFence*/ -1);
+ auto minFrameIntervalNs = config.vrrConfig->minFrameIntervalNs;
+
+ auto vsyncPeriod = config.vsyncPeriod;
+ int32_t highestDivisor = VtsComposerClient::kMaxFrameIntervalNs / vsyncPeriod;
+ int32_t lowestDivisor = minFrameIntervalNs / vsyncPeriod;
+ const auto headsUpNs = config.vrrConfig->notifyExpectedPresentConfig->headsUpNs;
+ float totalDivisorsPassed = 0.f;
+ int divisor = lowestDivisor;
+ auto frameIntervalNs = vsyncPeriod * divisor;
+ sp<::android::Fence> presentFence =
+ presentAndGetFence(ComposerClientWriter::kNoTimestamp, displayId, frameIntervalNs);
+ presentFence->waitForever(LOG_TAG);
+ auto lastPresentTimeNs = presentFence->getSignalTime();
+ do {
+ frameIntervalNs = vsyncPeriod * divisor;
+ ++divisor;
+ const auto nextFrameIntervalNs = vsyncPeriod * divisor;
+ const auto frameAfterHeadsUp = frameIntervalNs * (headsUpNs / frameIntervalNs);
+ auto presentTime = lastPresentTimeNs + frameIntervalNs + frameAfterHeadsUp;
+ const auto expectedPresentTimestamp = ClockMonotonicTimestamp{presentTime};
+ presentFence =
+ presentAndGetFence(expectedPresentTimestamp, displayId, nextFrameIntervalNs);
+ presentFence->waitForever(LOG_TAG);
+ lastPresentTimeNs = presentFence->getSignalTime();
+ if (lastPresentTimeNs >= expectedPresentTimestamp.timestampNanos - vsyncPeriod / 2) {
+ ++totalDivisorsPassed;
+ }
+ } while (divisor < highestDivisor);
+ EXPECT_TRUE(totalDivisorsPassed >
+ (static_cast<float>(highestDivisor - lowestDivisor)) * 0.75f);
+ mComposerClient->destroyLayer(displayId, layer, &writer);
+ });
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandTest);
INSTANTIATE_TEST_SUITE_P(
PerInstance, GraphicsComposerAidlCommandTest,
@@ -2938,7 +3260,11 @@
PerInstance, GraphicsComposerAidlCommandV2Test,
testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
::android::PrintInstanceNameToString);
-
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandV3Test);
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, GraphicsComposerAidlCommandV3Test,
+ testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
+ ::android::PrintInstanceNameToString);
} // namespace aidl::android::hardware::graphics::composer3::vts
int main(int argc, char** argv) {
diff --git a/graphics/mapper/2.0/Android.bp b/graphics/mapper/2.0/Android.bp
index 6c3ef54..81040ab 100644
--- a/graphics/mapper/2.0/Android.bp
+++ b/graphics/mapper/2.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/mapper/2.0/default/Android.bp b/graphics/mapper/2.0/default/Android.bp
index fffea3b..337e29e 100644
--- a/graphics/mapper/2.0/default/Android.bp
+++ b/graphics/mapper/2.0/default/Android.bp
@@ -14,6 +14,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -29,7 +30,7 @@
relative_install_path: "hw",
srcs: ["passthrough.cpp"],
header_libs: [
- "android.hardware.graphics.mapper@2.0-passthrough"
+ "android.hardware.graphics.mapper@2.0-passthrough",
],
shared_libs: [
"android.hardware.graphics.mapper@2.0",
diff --git a/graphics/mapper/2.0/utils/hal/Android.bp b/graphics/mapper/2.0/utils/hal/Android.bp
index f5d4506..c4a0b11 100644
--- a/graphics/mapper/2.0/utils/hal/Android.bp
+++ b/graphics/mapper/2.0/utils/hal/Android.bp
@@ -14,6 +14,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/mapper/2.0/utils/passthrough/Android.bp b/graphics/mapper/2.0/utils/passthrough/Android.bp
index 23450fb..257eab9 100644
--- a/graphics/mapper/2.0/utils/passthrough/Android.bp
+++ b/graphics/mapper/2.0/utils/passthrough/Android.bp
@@ -14,6 +14,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/mapper/2.0/utils/vts/Android.bp b/graphics/mapper/2.0/utils/vts/Android.bp
index 03f925d..4fb78db 100644
--- a/graphics/mapper/2.0/utils/vts/Android.bp
+++ b/graphics/mapper/2.0/utils/vts/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/mapper/2.0/vts/functional/Android.bp b/graphics/mapper/2.0/vts/functional/Android.bp
index 43e6156..01bb615 100644
--- a/graphics/mapper/2.0/vts/functional/Android.bp
+++ b/graphics/mapper/2.0/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -33,5 +34,8 @@
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@2.0-vts",
],
- test_suites: ["general-tests", "vts"],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
}
diff --git a/graphics/mapper/2.1/Android.bp b/graphics/mapper/2.1/Android.bp
index cc74156..1308a6c 100644
--- a/graphics/mapper/2.1/Android.bp
+++ b/graphics/mapper/2.1/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/mapper/2.1/default/Android.bp b/graphics/mapper/2.1/default/Android.bp
index 4f080c4..8dfdbbd 100644
--- a/graphics/mapper/2.1/default/Android.bp
+++ b/graphics/mapper/2.1/default/Android.bp
@@ -14,6 +14,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/mapper/2.1/utils/hal/Android.bp b/graphics/mapper/2.1/utils/hal/Android.bp
index aff497c..47f7971 100644
--- a/graphics/mapper/2.1/utils/hal/Android.bp
+++ b/graphics/mapper/2.1/utils/hal/Android.bp
@@ -14,6 +14,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/mapper/2.1/utils/passthrough/Android.bp b/graphics/mapper/2.1/utils/passthrough/Android.bp
index d46041b..ddfc57d 100644
--- a/graphics/mapper/2.1/utils/passthrough/Android.bp
+++ b/graphics/mapper/2.1/utils/passthrough/Android.bp
@@ -14,6 +14,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/mapper/2.1/utils/vts/Android.bp b/graphics/mapper/2.1/utils/vts/Android.bp
index 5c67df9..a095733 100644
--- a/graphics/mapper/2.1/utils/vts/Android.bp
+++ b/graphics/mapper/2.1/utils/vts/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -25,7 +26,10 @@
cc_library_static {
name: "android.hardware.graphics.mapper@2.1-vts",
- defaults: ["hidl_defaults", "VtsHalTargetTestDefaults"],
+ defaults: [
+ "hidl_defaults",
+ "VtsHalTargetTestDefaults",
+ ],
srcs: ["MapperVts.cpp"],
cflags: [
"-O0",
diff --git a/graphics/mapper/2.1/vts/functional/Android.bp b/graphics/mapper/2.1/vts/functional/Android.bp
index 7bbc9a4..acfd52a 100644
--- a/graphics/mapper/2.1/vts/functional/Android.bp
+++ b/graphics/mapper/2.1/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -35,5 +36,8 @@
"android.hardware.graphics.mapper@2.0-vts",
"android.hardware.graphics.mapper@2.1-vts",
],
- test_suites: ["general-tests", "vts"],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
}
diff --git a/graphics/mapper/3.0/Android.bp b/graphics/mapper/3.0/Android.bp
index 88992a3..b49806f 100644
--- a/graphics/mapper/3.0/Android.bp
+++ b/graphics/mapper/3.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/mapper/3.0/utils/vts/Android.bp b/graphics/mapper/3.0/utils/vts/Android.bp
index c0d56de..d4b8035 100644
--- a/graphics/mapper/3.0/utils/vts/Android.bp
+++ b/graphics/mapper/3.0/utils/vts/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/mapper/3.0/vts/functional/Android.bp b/graphics/mapper/3.0/vts/functional/Android.bp
index e837027..57cd09b 100644
--- a/graphics/mapper/3.0/vts/functional/Android.bp
+++ b/graphics/mapper/3.0/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -35,5 +36,8 @@
"android.hardware.graphics.mapper@3.0",
"android.hardware.graphics.mapper@3.0-vts",
],
- test_suites: ["general-tests", "vts"],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
}
diff --git a/graphics/mapper/4.0/Android.bp b/graphics/mapper/4.0/Android.bp
index 0cffce4..c07f73c 100644
--- a/graphics/mapper/4.0/Android.bp
+++ b/graphics/mapper/4.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/mapper/4.0/utils/vts/Android.bp b/graphics/mapper/4.0/utils/vts/Android.bp
index 7815d41..c5f124c 100644
--- a/graphics/mapper/4.0/utils/vts/Android.bp
+++ b/graphics/mapper/4.0/utils/vts/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/mapper/4.0/vts/functional/Android.bp b/graphics/mapper/4.0/vts/functional/Android.bp
index 6208ae9..181408b 100644
--- a/graphics/mapper/4.0/vts/functional/Android.bp
+++ b/graphics/mapper/4.0/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/mapper/stable-c/Android.bp b/graphics/mapper/stable-c/Android.bp
index 1d01a02..40486fd 100644
--- a/graphics/mapper/stable-c/Android.bp
+++ b/graphics/mapper/stable-c/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_core_graphics_stack",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp b/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
index b329de2..1e0c427 100644
--- a/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
+++ b/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
@@ -166,7 +166,8 @@
auto status = mAllocator->getIMapperLibrarySuffix(&mapperSuffix);
ASSERT_TRUE(status.isOk()) << "Failed to get IMapper library suffix";
std::string lib_name = "mapper." + mapperSuffix + ".so";
- void* so = android_load_sphal_library(lib_name.c_str(), RTLD_LOCAL | RTLD_NOW);
+ void* so = AServiceManager_openDeclaredPassthroughHal("mapper", mapperSuffix.c_str(),
+ RTLD_LOCAL | RTLD_NOW);
ASSERT_NE(nullptr, so) << "Failed to load " << lib_name;
mIMapperLoader = (AIMapper_loadIMapperFn)dlsym(so, "AIMapper_loadIMapper");
ASSERT_NE(nullptr, mIMapperLoader) << "AIMapper_locaIMapper missing from " << lib_name;
diff --git a/health/2.0/README.md b/health/2.0/README.md
index 8a7c922..1c636c7 100644
--- a/health/2.0/README.md
+++ b/health/2.0/README.md
@@ -1,181 +1,7 @@
-# Implement the 2.1 HAL instead!
+# Deprecated.
-It is strongly recommended that you implement the 2.1 HAL directly. See
-`hardware/interfaces/health/2.1/README.md` for more details.
+Health HIDL HAL 2.0 is deprecated and subject to removal. Please
+implement the Health AIDL HAL instead.
-# Upgrading from Health 1.0 HAL
-
-1. Remove `android.hardware.health@1.0*` from `PRODUCT_PACKAGES`
- in `device/<manufacturer>/<device>/device.mk`
-
-1. If the device does not have a vendor-specific `libhealthd` AND does not
- implement storage-related APIs, just do the following:
-
- ```mk
- PRODUCT_PACKAGES += android.hardware.health@2.0-service
- ```
-
- Otherwise, continue to the next step.
-
-1. Create directory
- `device/<manufacturer>/<device>/health`
-
-1. Create `device/<manufacturer>/<device>/health/Android.bp`
- (or equivalent `device/<manufacturer>/<device>/health/Android.mk`)
-
- ```bp
- cc_binary {
- name: "android.hardware.health@2.0-service.<device>",
- init_rc: ["android.hardware.health@2.0-service.<device>.rc"],
- proprietary: true,
- relative_install_path: "hw",
- srcs: [
- "HealthService.cpp",
- ],
-
- cflags: [
- "-Wall",
- "-Werror",
- ],
-
- static_libs: [
- "android.hardware.health@2.0-impl",
- "android.hardware.health@1.0-convert",
- "libhealthservice",
- "libbatterymonitor",
- ],
-
- shared_libs: [
- "libbase",
- "libcutils",
- "libhidlbase",
- "libutils",
- "android.hardware.health@2.0",
- ],
-
- header_libs: ["libhealthd_headers"],
-
- overrides: [
- "healthd",
- ],
- }
- ```
-
- 1. (recommended) To remove `healthd` from the build, keep "overrides" section.
- 1. To keep `healthd` in the build, remove "overrides" section.
-
-1. Create `device/<manufacturer>/<device>/health/android.hardware.health@2.0-service.<device>.rc`
-
- ```rc
- service vendor.health-hal-2-0 /vendor/bin/hw/android.hardware.health@2.0-service.<device>
- class hal
- user system
- group system
- capabilities WAKE_ALARM
- file /dev/kmsg w
- ```
-
-1. Create `device/<manufacturer>/<device>/health/HealthService.cpp`:
-
- ```c++
- #include <health2/service.h>
- int main() { return health_service_main(); }
- ```
-
-1. `libhealthd` dependency:
-
- 1. If the device has a vendor-specific `libhealthd.<soc>`, add it to static_libs.
-
- 1. If the device does not have a vendor-specific `libhealthd`, add the following
- lines to `HealthService.cpp`:
-
- ```c++
- #include <healthd/healthd.h>
- void healthd_board_init(struct healthd_config*) {}
-
- int healthd_board_battery_update(struct android::BatteryProperties*) {
- // return 0 to log periodic polled battery status to kernel log
- return 0;
- }
- ```
-
-1. Storage related APIs:
-
- 1. If the device does not implement `IHealth.getDiskStats` and
- `IHealth.getStorageInfo`, add `libhealthstoragedefault` to `static_libs`.
-
- 1. If the device implements one of these two APIs, add and implement the
- following functions in `HealthService.cpp`:
-
- ```c++
- void get_storage_info(std::vector<struct StorageInfo>& info) {
- // ...
- }
- void get_disk_stats(std::vector<struct DiskStats>& stats) {
- // ...
- }
- ```
-
-1. Update necessary SELinux permissions. For example,
-
- ```
- # device/<manufacturer>/<device>/sepolicy/vendor/file_contexts
- /vendor/bin/hw/android\.hardware\.health@2\.0-service\.<device> u:object_r:hal_health_default_exec:s0
-
- # device/<manufacturer>/<device>/sepolicy/vendor/hal_health_default.te
- # Add device specific permissions to hal_health_default domain, especially
- # if a device-specific libhealthd is used and/or device-specific storage related
- # APIs are implemented.
- ```
-
-1. Implementing health HAL in recovery. The health HAL is used for battery
-status checks during OTA for non-A/B devices. If the health HAL is not
-implemented in recovery, `is_battery_ok()` will always return `true`.
-
- 1. If the device does not have a vendor-specific `libhealthd`, nothing needs to
- be done. A "backup" implementation is provided in
- `android.hardware.health@2.0-impl-default`, which is always installed to recovery
- image by default.
-
- 1. If the device does have a vendor-specific `libhealthd`, implement the following
- module and include it in `PRODUCT_PACKAGES` (replace `<device>` with appropriate
- strings):
-
- ```bp
- // Android.bp
- cc_library_shared {
- name: "android.hardware.health@2.0-impl-<device>",
- recovery_available: true,
- relative_install_path: "hw",
- static_libs: [
- "android.hardware.health@2.0-impl",
- "libhealthd.<device>"
- // Include the following or implement device-specific storage APIs
- "libhealthstoragedefault",
- ],
- srcs: [
- "HealthImpl.cpp",
- ],
- overrides: [
- "android.hardware.health@2.0-impl-default",
- ],
- }
- ```
-
- ```c++
- // HealthImpl.cpp
- #include <health2/Health.h>
- #include <healthd/healthd.h>
- using android::hardware::health::V2_0::IHealth;
- using android::hardware::health::V2_0::implementation::Health;
- extern "C" IHealth* HIDL_FETCH_IHealth(const char* name) {
- const static std::string providedInstance{"default"};
- if (providedInstance != name) return nullptr;
- return Health::initInstance(&gHealthdConfig).get();
- }
- ```
-
- ```mk
- # device.mk
- PRODUCT_PACKAGES += android.hardware.health@2.0-impl-<device>
- ```
+See [`hardware/interfaces/health/aidl/README.md`](../aidl/README.md) for
+details.
diff --git a/health/2.0/default/Android.bp b/health/2.0/default/Android.bp
deleted file mode 100644
index 73cd553..0000000
--- a/health/2.0/default/Android.bp
+++ /dev/null
@@ -1,72 +0,0 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "hardware_interfaces_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-cc_defaults {
- name: "android.hardware.health@2.0-impl_defaults",
-
- recovery_available: true,
- cflags: [
- "-Wall",
- "-Werror",
- ],
-
- shared_libs: [
- "libbase",
- "libhidlbase",
- "liblog",
- "libutils",
- "libcutils",
- "android.hardware.health@2.0",
- ],
-
- static_libs: [
- "libbatterymonitor",
- "android.hardware.health@1.0-convert",
- ],
-}
-
-// Helper library for implementing health HAL. It is recommended that a health
-// service or passthrough HAL link to this library.
-cc_library_static {
- name: "android.hardware.health@2.0-impl",
- defaults: ["android.hardware.health@2.0-impl_defaults"],
-
- vendor_available: true,
- srcs: [
- "Health.cpp",
- "healthd_common_adapter.cpp",
- ],
-
- whole_static_libs: [
- "libhealthloop",
- ],
-
- export_include_dirs: ["include"],
-}
-
-// Default passthrough implementation for recovery. Vendors can implement
-// android.hardware.health@2.0-impl-recovery-<device> to customize the behavior
-// of the HAL in recovery.
-// The implementation does NOT start the uevent loop for polling.
-cc_library_shared {
- name: "android.hardware.health@2.0-impl-default",
- defaults: ["android.hardware.health@2.0-impl_defaults"],
-
- recovery_available: true,
- relative_install_path: "hw",
-
- static_libs: [
- "android.hardware.health@2.0-impl",
- "libhealthstoragedefault",
- ],
-
- srcs: [
- "HealthImplDefault.cpp",
- ],
-}
diff --git a/health/2.0/default/Health.cpp b/health/2.0/default/Health.cpp
deleted file mode 100644
index 65eada8..0000000
--- a/health/2.0/default/Health.cpp
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define LOG_TAG "android.hardware.health@2.0-impl"
-#include <android-base/logging.h>
-
-#include <android-base/file.h>
-#include <android/hardware/health/2.0/types.h>
-#include <health2/Health.h>
-
-#include <hal_conversion.h>
-#include <hidl/HidlTransportSupport.h>
-
-using HealthInfo_1_0 = android::hardware::health::V1_0::HealthInfo;
-using android::hardware::health::V1_0::hal_conversion::convertFromHealthInfo;
-
-extern void healthd_battery_update_internal(bool);
-
-namespace android {
-namespace hardware {
-namespace health {
-namespace V2_0 {
-namespace implementation {
-
-sp<Health> Health::instance_;
-
-Health::Health(struct healthd_config* c) {
- // TODO(b/69268160): remove when libhealthd is removed.
- healthd_board_init(c);
- battery_monitor_ = std::make_unique<BatteryMonitor>();
- battery_monitor_->init(c);
-}
-
-// Methods from IHealth follow.
-Return<Result> Health::registerCallback(const sp<IHealthInfoCallback>& callback) {
- if (callback == nullptr) {
- return Result::SUCCESS;
- }
-
- {
- std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
- callbacks_.push_back(callback);
- // unlock
- }
-
- auto linkRet = callback->linkToDeath(this, 0u /* cookie */);
- if (!linkRet.withDefault(false)) {
- LOG(WARNING) << __func__ << "Cannot link to death: "
- << (linkRet.isOk() ? "linkToDeath returns false" : linkRet.description());
- // ignore the error
- }
-
- return updateAndNotify(callback);
-}
-
-bool Health::unregisterCallbackInternal(const sp<IBase>& callback) {
- if (callback == nullptr) return false;
-
- bool removed = false;
- std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
- for (auto it = callbacks_.begin(); it != callbacks_.end();) {
- if (interfacesEqual(*it, callback)) {
- it = callbacks_.erase(it);
- removed = true;
- } else {
- ++it;
- }
- }
- (void)callback->unlinkToDeath(this).isOk(); // ignore errors
- return removed;
-}
-
-Return<Result> Health::unregisterCallback(const sp<IHealthInfoCallback>& callback) {
- return unregisterCallbackInternal(callback) ? Result::SUCCESS : Result::NOT_FOUND;
-}
-
-template <typename T>
-void getProperty(const std::unique_ptr<BatteryMonitor>& monitor, int id, T defaultValue,
- const std::function<void(Result, T)>& callback) {
- struct BatteryProperty prop;
- T ret = defaultValue;
- Result result = Result::SUCCESS;
- status_t err = monitor->getProperty(static_cast<int>(id), &prop);
- if (err != OK) {
- LOG(DEBUG) << "getProperty(" << id << ")"
- << " fails: (" << err << ") " << strerror(-err);
- } else {
- ret = static_cast<T>(prop.valueInt64);
- }
- switch (err) {
- case OK:
- result = Result::SUCCESS;
- break;
- case NAME_NOT_FOUND:
- result = Result::NOT_SUPPORTED;
- break;
- default:
- result = Result::UNKNOWN;
- break;
- }
- callback(result, static_cast<T>(ret));
-}
-
-Return<void> Health::getChargeCounter(getChargeCounter_cb _hidl_cb) {
- getProperty<int32_t>(battery_monitor_, BATTERY_PROP_CHARGE_COUNTER, 0, _hidl_cb);
- return Void();
-}
-
-Return<void> Health::getCurrentNow(getCurrentNow_cb _hidl_cb) {
- getProperty<int32_t>(battery_monitor_, BATTERY_PROP_CURRENT_NOW, 0, _hidl_cb);
- return Void();
-}
-
-Return<void> Health::getCurrentAverage(getCurrentAverage_cb _hidl_cb) {
- getProperty<int32_t>(battery_monitor_, BATTERY_PROP_CURRENT_AVG, 0, _hidl_cb);
- return Void();
-}
-
-Return<void> Health::getCapacity(getCapacity_cb _hidl_cb) {
- getProperty<int32_t>(battery_monitor_, BATTERY_PROP_CAPACITY, 0, _hidl_cb);
- return Void();
-}
-
-Return<void> Health::getEnergyCounter(getEnergyCounter_cb _hidl_cb) {
- getProperty<int64_t>(battery_monitor_, BATTERY_PROP_ENERGY_COUNTER, 0, _hidl_cb);
- return Void();
-}
-
-Return<void> Health::getChargeStatus(getChargeStatus_cb _hidl_cb) {
- getProperty(battery_monitor_, BATTERY_PROP_BATTERY_STATUS, BatteryStatus::UNKNOWN, _hidl_cb);
- return Void();
-}
-
-Return<Result> Health::update() {
- if (!healthd_mode_ops || !healthd_mode_ops->battery_update) {
- LOG(WARNING) << "health@2.0: update: not initialized. "
- << "update() should not be called in charger";
- return Result::UNKNOWN;
- }
-
- // Retrieve all information and call healthd_mode_ops->battery_update, which calls
- // notifyListeners.
- battery_monitor_->updateValues();
- const HealthInfo_1_0& health_info = battery_monitor_->getHealthInfo_1_0();
- struct BatteryProperties props;
- convertFromHealthInfo(health_info, &props);
- bool log = (healthd_board_battery_update(&props) == 0);
- if (log) {
- battery_monitor_->logValues();
- }
- healthd_mode_ops->battery_update(&props);
- bool chargerOnline = battery_monitor_->isChargerOnline();
-
- // adjust uevent / wakealarm periods
- healthd_battery_update_internal(chargerOnline);
-
- return Result::SUCCESS;
-}
-
-Return<Result> Health::updateAndNotify(const sp<IHealthInfoCallback>& callback) {
- std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
- std::vector<sp<IHealthInfoCallback>> storedCallbacks{std::move(callbacks_)};
- callbacks_.clear();
- if (callback != nullptr) {
- callbacks_.push_back(callback);
- }
- Return<Result> result = update();
- callbacks_ = std::move(storedCallbacks);
- return result;
-}
-
-void Health::notifyListeners(HealthInfo* healthInfo) {
- std::vector<StorageInfo> info;
- get_storage_info(info);
-
- std::vector<DiskStats> stats;
- get_disk_stats(stats);
-
- int32_t currentAvg = 0;
-
- struct BatteryProperty prop;
- status_t ret = battery_monitor_->getProperty(BATTERY_PROP_CURRENT_AVG, &prop);
- if (ret == OK) {
- currentAvg = static_cast<int32_t>(prop.valueInt64);
- }
-
- healthInfo->batteryCurrentAverage = currentAvg;
- healthInfo->diskStats = stats;
- healthInfo->storageInfos = info;
-
- std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
- for (auto it = callbacks_.begin(); it != callbacks_.end();) {
- auto ret = (*it)->healthInfoChanged(*healthInfo);
- if (!ret.isOk() && ret.isDeadObject()) {
- it = callbacks_.erase(it);
- } else {
- ++it;
- }
- }
-}
-
-Return<void> Health::debug(const hidl_handle& handle, const hidl_vec<hidl_string>&) {
- if (handle != nullptr && handle->numFds >= 1) {
- int fd = handle->data[0];
- battery_monitor_->dumpState(fd);
-
- getHealthInfo([fd](auto res, const auto& info) {
- android::base::WriteStringToFd("\ngetHealthInfo -> ", fd);
- if (res == Result::SUCCESS) {
- android::base::WriteStringToFd(toString(info), fd);
- } else {
- android::base::WriteStringToFd(toString(res), fd);
- }
- android::base::WriteStringToFd("\n", fd);
- });
-
- fsync(fd);
- }
- return Void();
-}
-
-Return<void> Health::getStorageInfo(getStorageInfo_cb _hidl_cb) {
- std::vector<struct StorageInfo> info;
- get_storage_info(info);
- hidl_vec<struct StorageInfo> info_vec(info);
- if (!info.size()) {
- _hidl_cb(Result::NOT_SUPPORTED, info_vec);
- } else {
- _hidl_cb(Result::SUCCESS, info_vec);
- }
- return Void();
-}
-
-Return<void> Health::getDiskStats(getDiskStats_cb _hidl_cb) {
- std::vector<struct DiskStats> stats;
- get_disk_stats(stats);
- hidl_vec<struct DiskStats> stats_vec(stats);
- if (!stats.size()) {
- _hidl_cb(Result::NOT_SUPPORTED, stats_vec);
- } else {
- _hidl_cb(Result::SUCCESS, stats_vec);
- }
- return Void();
-}
-
-Return<void> Health::getHealthInfo(getHealthInfo_cb _hidl_cb) {
- using android::hardware::health::V1_0::hal_conversion::convertToHealthInfo;
-
- updateAndNotify(nullptr);
- HealthInfo healthInfo = battery_monitor_->getHealthInfo_2_0();
-
- std::vector<StorageInfo> info;
- get_storage_info(info);
-
- std::vector<DiskStats> stats;
- get_disk_stats(stats);
-
- int32_t currentAvg = 0;
-
- struct BatteryProperty prop;
- status_t ret = battery_monitor_->getProperty(BATTERY_PROP_CURRENT_AVG, &prop);
- if (ret == OK) {
- currentAvg = static_cast<int32_t>(prop.valueInt64);
- }
-
- healthInfo.batteryCurrentAverage = currentAvg;
- healthInfo.diskStats = stats;
- healthInfo.storageInfos = info;
-
- _hidl_cb(Result::SUCCESS, healthInfo);
- return Void();
-}
-
-void Health::serviceDied(uint64_t /* cookie */, const wp<IBase>& who) {
- (void)unregisterCallbackInternal(who.promote());
-}
-
-sp<IHealth> Health::initInstance(struct healthd_config* c) {
- if (instance_ == nullptr) {
- instance_ = new Health(c);
- }
- return instance_;
-}
-
-sp<Health> Health::getImplementation() {
- CHECK(instance_ != nullptr);
- return instance_;
-}
-
-} // namespace implementation
-} // namespace V2_0
-} // namespace health
-} // namespace hardware
-} // namespace android
diff --git a/health/2.0/default/HealthImplDefault.cpp b/health/2.0/default/HealthImplDefault.cpp
deleted file mode 100644
index 08fee9e..0000000
--- a/health/2.0/default/HealthImplDefault.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <health2/Health.h>
-#include <healthd/healthd.h>
-
-using android::hardware::health::V2_0::IHealth;
-using android::hardware::health::V2_0::implementation::Health;
-
-static struct healthd_config gHealthdConfig = {
- .energyCounter = nullptr,
- .boot_min_cap = 0,
- .screen_on = nullptr};
-
-void healthd_board_init(struct healthd_config*) {
- // use defaults
-}
-
-int healthd_board_battery_update(struct android::BatteryProperties*) {
- // return 0 to log periodic polled battery status to kernel log
- return 0;
-}
-
-void healthd_mode_default_impl_init(struct healthd_config*) {
- // noop
-}
-
-int healthd_mode_default_impl_preparetowait(void) {
- return -1;
-}
-
-void healthd_mode_default_impl_heartbeat(void) {
- // noop
-}
-
-void healthd_mode_default_impl_battery_update(struct android::BatteryProperties*) {
- // noop
-}
-
-static struct healthd_mode_ops healthd_mode_default_impl_ops = {
- .init = healthd_mode_default_impl_init,
- .preparetowait = healthd_mode_default_impl_preparetowait,
- .heartbeat = healthd_mode_default_impl_heartbeat,
- .battery_update = healthd_mode_default_impl_battery_update,
-};
-
-extern "C" IHealth* HIDL_FETCH_IHealth(const char* name) {
- const static std::string providedInstance{"backup"};
- healthd_mode_ops = &healthd_mode_default_impl_ops;
- if (providedInstance == name) {
- // use defaults
- // Health class stores static instance
- return Health::initInstance(&gHealthdConfig).get();
- }
- return nullptr;
-}
diff --git a/health/2.0/default/healthd_common_adapter.cpp b/health/2.0/default/healthd_common_adapter.cpp
deleted file mode 100644
index 0b5d869..0000000
--- a/health/2.0/default/healthd_common_adapter.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Support legacy functions in healthd/healthd.h using healthd_mode_ops.
-// New code should use HealthLoop directly instead.
-
-#include <memory>
-
-#include <cutils/klog.h>
-#include <health/HealthLoop.h>
-#include <health2/Health.h>
-#include <healthd/healthd.h>
-
-using android::hardware::health::HealthLoop;
-using android::hardware::health::V2_0::implementation::Health;
-
-struct healthd_mode_ops* healthd_mode_ops = nullptr;
-
-// Adapter of HealthLoop to use legacy healthd_mode_ops.
-class HealthLoopAdapter : public HealthLoop {
- public:
- // Expose internal functions, assuming clients calls them in the same thread
- // where StartLoop is called.
- int RegisterEvent(int fd, BoundFunction func, EventWakeup wakeup) {
- return HealthLoop::RegisterEvent(fd, func, wakeup);
- }
- void AdjustWakealarmPeriods(bool charger_online) {
- return HealthLoop::AdjustWakealarmPeriods(charger_online);
- }
- protected:
- void Init(healthd_config* config) override { healthd_mode_ops->init(config); }
- void Heartbeat() override { healthd_mode_ops->heartbeat(); }
- int PrepareToWait() override { return healthd_mode_ops->preparetowait(); }
- void ScheduleBatteryUpdate() override { Health::getImplementation()->update(); }
-};
-static std::unique_ptr<HealthLoopAdapter> health_loop;
-
-int healthd_register_event(int fd, void (*handler)(uint32_t), EventWakeup wakeup) {
- if (!health_loop) return -1;
-
- auto wrapped_handler = [handler](auto*, uint32_t epevents) { handler(epevents); };
- return health_loop->RegisterEvent(fd, wrapped_handler, wakeup);
-}
-
-void healthd_battery_update_internal(bool charger_online) {
- if (!health_loop) return;
- health_loop->AdjustWakealarmPeriods(charger_online);
-}
-
-int healthd_main() {
- if (!healthd_mode_ops) {
- KLOG_ERROR("healthd ops not set, exiting\n");
- exit(1);
- }
-
- health_loop = std::make_unique<HealthLoopAdapter>();
-
- int ret = health_loop->StartLoop();
-
- // Should not reach here. The following will exit().
- health_loop.reset();
-
- return ret;
-}
diff --git a/health/2.0/default/include/health2/Health.h b/health/2.0/default/include/health2/Health.h
deleted file mode 100644
index 6410474..0000000
--- a/health/2.0/default/include/health2/Health.h
+++ /dev/null
@@ -1,79 +0,0 @@
-#ifndef ANDROID_HARDWARE_HEALTH_V2_0_HEALTH_H
-#define ANDROID_HARDWARE_HEALTH_V2_0_HEALTH_H
-
-#include <memory>
-#include <vector>
-
-#include <android/hardware/health/1.0/types.h>
-#include <android/hardware/health/2.0/IHealth.h>
-#include <healthd/BatteryMonitor.h>
-#include <hidl/Status.h>
-
-using android::hardware::health::V2_0::StorageInfo;
-using android::hardware::health::V2_0::DiskStats;
-
-void get_storage_info(std::vector<struct StorageInfo>& info);
-void get_disk_stats(std::vector<struct DiskStats>& stats);
-
-namespace android {
-namespace hardware {
-namespace health {
-namespace V2_0 {
-namespace implementation {
-
-using V1_0::BatteryStatus;
-
-using ::android::hidl::base::V1_0::IBase;
-
-struct Health : public IHealth, hidl_death_recipient {
- public:
- static sp<IHealth> initInstance(struct healthd_config* c);
- // Should only be called by implementation itself (-impl, -service).
- // Clients should not call this function. Instead, initInstance() initializes and returns the
- // global instance that has fewer functions.
- static sp<Health> getImplementation();
-
- Health(struct healthd_config* c);
-
- void notifyListeners(HealthInfo* info);
-
- // Methods from IHealth follow.
- Return<Result> registerCallback(const sp<IHealthInfoCallback>& callback) override;
- Return<Result> unregisterCallback(const sp<IHealthInfoCallback>& callback) override;
- Return<Result> update() override;
- Return<void> getChargeCounter(getChargeCounter_cb _hidl_cb) override;
- Return<void> getCurrentNow(getCurrentNow_cb _hidl_cb) override;
- Return<void> getCurrentAverage(getCurrentAverage_cb _hidl_cb) override;
- Return<void> getCapacity(getCapacity_cb _hidl_cb) override;
- Return<void> getEnergyCounter(getEnergyCounter_cb _hidl_cb) override;
- Return<void> getChargeStatus(getChargeStatus_cb _hidl_cb) override;
- Return<void> getStorageInfo(getStorageInfo_cb _hidl_cb) override;
- Return<void> getDiskStats(getDiskStats_cb _hidl_cb) override;
- Return<void> getHealthInfo(getHealthInfo_cb _hidl_cb) override;
-
- // Methods from ::android::hidl::base::V1_0::IBase follow.
- Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) override;
-
- void serviceDied(uint64_t cookie, const wp<IBase>& /* who */) override;
-
- private:
- static sp<Health> instance_;
-
- std::recursive_mutex callbacks_lock_;
- std::vector<sp<IHealthInfoCallback>> callbacks_;
- std::unique_ptr<BatteryMonitor> battery_monitor_;
-
- bool unregisterCallbackInternal(const sp<IBase>& cb);
-
- // update() and only notify the given callback, but none of the other callbacks.
- // If cb is null, do not notify any callback at all.
- Return<Result> updateAndNotify(const sp<IHealthInfoCallback>& cb);
-};
-
-} // namespace implementation
-} // namespace V2_0
-} // namespace health
-} // namespace hardware
-} // namespace android
-
-#endif // ANDROID_HARDWARE_HEALTH_V2_0_HEALTH_H
diff --git a/health/2.0/utils/README.md b/health/2.0/utils/README.md
index c59b3f3..3fc8dab 100644
--- a/health/2.0/utils/README.md
+++ b/health/2.0/utils/README.md
@@ -6,25 +6,3 @@
calling `IHealth::getService()` directly.
Its Java equivalent can be found in `BatteryService.HealthServiceWrapper`.
-
-# libhealthservice
-
-Common code for all (hwbinder) services of the health HAL, including healthd and
-vendor health service `android.hardware.health@2.0-service(.<vendor>)`. `main()` in
-those binaries calls `health_service_main()` directly.
-
-# libhealthstoragedefault
-
-Default implementation for storage related APIs for (hwbinder) services of the
-health HAL. If an implementation of the health HAL do not wish to provide any
-storage info, include this library. Otherwise, it should implement the following
-two functions:
-
-```c++
-void get_storage_info(std::vector<struct StorageInfo>& info) {
- // ...
-}
-void get_disk_stats(std::vector<struct DiskStats>& stats) {
- // ...
-}
-```
diff --git a/health/2.0/utils/libhealthhalutils/HealthHalUtils.cpp b/health/2.0/utils/libhealthhalutils/HealthHalUtils.cpp
index 3c353e6..67f0ecc 100644
--- a/health/2.0/utils/libhealthhalutils/HealthHalUtils.cpp
+++ b/health/2.0/utils/libhealthhalutils/HealthHalUtils.cpp
@@ -24,34 +24,14 @@
namespace health {
namespace V2_0 {
+// Deprecated. Kept to minimize migration cost.
+// The function can be removed once Health 2.1 is removed
+// (i.e. compatibility_matrix.7.xml is the lowest supported level).
sp<IHealth> get_health_service() {
- // For the core and vendor variant, the "backup" instance points to healthd,
- // which is removed.
- // For the recovery variant, the "backup" instance has a different
- // meaning. It points to android.hardware.health@2.0-impl-default.recovery
- // which was assumed by OEMs to be always installed when a
- // vendor-specific libhealthd is not necessary. Hence, its behavior
- // is kept. See health/2.0/README.md.
- // android.hardware.health@2.0-impl-default.recovery, and subsequently the
- // special handling of recovery mode below, can be removed once health@2.1
- // is the minimum required version (i.e. compatibility matrix level 5 is the
- // minimum supported level). Health 2.1 requires OEMs to install the
+ // Health 2.1 requires OEMs to install the
// implementation to the recovery partition when it is necessary (i.e. on
// non-A/B devices, where IsBatteryOk() is needed in recovery).
- for (auto&& instanceName :
-#ifdef __ANDROID_RECOVERY__
- { "default", "backup" }
-#else
- {"default"}
-#endif
- ) {
- auto ret = IHealth::getService(instanceName);
- if (ret != nullptr) {
- return ret;
- }
- LOG(INFO) << "health: cannot get " << instanceName << " service";
- }
- return nullptr;
+ return IHealth::getService();
}
} // namespace V2_0
diff --git a/health/2.0/utils/libhealthservice/Android.bp b/health/2.0/utils/libhealthservice/Android.bp
deleted file mode 100644
index 8023692..0000000
--- a/health/2.0/utils/libhealthservice/Android.bp
+++ /dev/null
@@ -1,38 +0,0 @@
-// Reasonable defaults for android.hardware.health@2.0-service.<device>.
-// Vendor service can customize by implementing functions defined in
-// libhealthd and libhealthstoragedefault.
-
-
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "hardware_interfaces_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-cc_library_static {
- name: "libhealthservice",
- vendor_available: true,
- srcs: ["HealthServiceCommon.cpp"],
-
- export_include_dirs: ["include"],
-
- cflags: [
- "-Wall",
- "-Werror",
- ],
- shared_libs: [
- "android.hardware.health@2.0",
- ],
- static_libs: [
- "android.hardware.health@2.0-impl",
- "android.hardware.health@1.0-convert",
- ],
- export_static_lib_headers: [
- "android.hardware.health@1.0-convert",
- ],
- header_libs: ["libhealthd_headers"],
- export_header_lib_headers: ["libhealthd_headers"],
-}
diff --git a/health/2.0/utils/libhealthservice/HealthServiceCommon.cpp b/health/2.0/utils/libhealthservice/HealthServiceCommon.cpp
deleted file mode 100644
index 039570a..0000000
--- a/health/2.0/utils/libhealthservice/HealthServiceCommon.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "health@2.0/"
-#include <android-base/logging.h>
-
-#include <android/hardware/health/1.0/types.h>
-#include <hal_conversion.h>
-#include <health2/Health.h>
-#include <health2/service.h>
-#include <healthd/healthd.h>
-#include <hidl/HidlTransportSupport.h>
-#include <hwbinder/IPCThreadState.h>
-
-using android::hardware::IPCThreadState;
-using android::hardware::configureRpcThreadpool;
-using android::hardware::handleTransportPoll;
-using android::hardware::setupTransportPolling;
-using android::hardware::health::V2_0::HealthInfo;
-using android::hardware::health::V1_0::hal_conversion::convertToHealthInfo;
-using android::hardware::health::V2_0::IHealth;
-using android::hardware::health::V2_0::implementation::Health;
-
-extern int healthd_main(void);
-
-static int gBinderFd = -1;
-static std::string gInstanceName;
-
-static void binder_event(uint32_t /*epevents*/) {
- if (gBinderFd >= 0) handleTransportPoll(gBinderFd);
-}
-
-void healthd_mode_service_2_0_init(struct healthd_config* config) {
- LOG(INFO) << LOG_TAG << gInstanceName << " Hal is starting up...";
-
- gBinderFd = setupTransportPolling();
-
- if (gBinderFd >= 0) {
- if (healthd_register_event(gBinderFd, binder_event))
- LOG(ERROR) << LOG_TAG << gInstanceName << ": Register for binder events failed";
- }
-
- android::sp<IHealth> service = Health::initInstance(config);
- CHECK_EQ(service->registerAsService(gInstanceName), android::OK)
- << LOG_TAG << gInstanceName << ": Failed to register HAL";
-
- LOG(INFO) << LOG_TAG << gInstanceName << ": Hal init done";
-}
-
-int healthd_mode_service_2_0_preparetowait(void) {
- IPCThreadState::self()->flushCommands();
- return -1;
-}
-
-void healthd_mode_service_2_0_heartbeat(void) {
- // noop
-}
-
-void healthd_mode_service_2_0_battery_update(struct android::BatteryProperties* prop) {
- HealthInfo info;
- convertToHealthInfo(prop, info.legacy);
- Health::getImplementation()->notifyListeners(&info);
-}
-
-static struct healthd_mode_ops healthd_mode_service_2_0_ops = {
- .init = healthd_mode_service_2_0_init,
- .preparetowait = healthd_mode_service_2_0_preparetowait,
- .heartbeat = healthd_mode_service_2_0_heartbeat,
- .battery_update = healthd_mode_service_2_0_battery_update,
-};
-
-int health_service_main(const char* instance) {
- gInstanceName = instance;
- if (gInstanceName.empty()) {
- gInstanceName = "default";
- }
- healthd_mode_ops = &healthd_mode_service_2_0_ops;
- LOG(INFO) << LOG_TAG << gInstanceName << ": Hal starting main loop...";
- return healthd_main();
-}
diff --git a/health/2.0/utils/libhealthservice/include/health2/service.h b/health/2.0/utils/libhealthservice/include/health2/service.h
deleted file mode 100644
index d260568..0000000
--- a/health/2.0/utils/libhealthservice/include/health2/service.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_HEALTH_V2_0_SERVICE_COMMON
-#define ANDROID_HARDWARE_HEALTH_V2_0_SERVICE_COMMON
-
-int health_service_main(const char* instance = "");
-
-#endif // ANDROID_HARDWARE_HEALTH_V2_0_SERVICE_COMMON
diff --git a/health/2.0/utils/libhealthstoragedefault/include/StorageHealthDefault.h b/health/2.0/utils/libhealthstoragedefault/include/StorageHealthDefault.h
deleted file mode 100644
index 85eb210..0000000
--- a/health/2.0/utils/libhealthstoragedefault/include/StorageHealthDefault.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef ANDROID_HARDWARE_HEALTH_V2_0_STORAGE_HEALTH_H
-#define ANDROID_HARDWARE_HEALTH_V2_0_STORAGE_HEALTH_H
-
-#include <android/hardware/health/2.0/types.h>
-
-using android::hardware::health::V2_0::StorageInfo;
-using android::hardware::health::V2_0::DiskStats;
-
-/*
- * Get storage information.
- */
-void get_storage_info(std::vector<struct StorageInfo>& info);
-
-/*
- * Get disk statistics.
- */
-void get_disk_stats(std::vector<struct DiskStats>& stats);
-
-#endif // ANDROID_HARDWARE_HEALTH_V2_0_STORAGE_HEALTH_H
diff --git a/health/OWNERS b/health/OWNERS
index 1d4d086..e540d55 100644
--- a/health/OWNERS
+++ b/health/OWNERS
@@ -1,6 +1,6 @@
# Bug component: 30545
apelosi@google.com
-elsk@google.com
+dvander@google.com
smoreland@google.com
wjack@google.com
diff --git a/health/aidl/Android.bp b/health/aidl/Android.bp
index e288f17..4691dd6 100644
--- a/health/aidl/Android.bp
+++ b/health/aidl/Android.bp
@@ -48,7 +48,7 @@
},
],
- frozen: true,
+ frozen: false,
}
@@ -80,7 +80,7 @@
name: "android.hardware.health-translate-ndk",
defaults: ["android.hardware.health-translate-ndk_defaults"],
shared_libs: [
- "android.hardware.health-V2-ndk",
+ "android.hardware.health-V3-ndk",
],
}
@@ -97,7 +97,7 @@
name: "android.hardware.health-translate-java",
srcs: ["android/hardware/health/Translate.java"],
libs: [
- "android.hardware.health-V2-java",
+ "android.hardware.health-V3-java",
"android.hardware.health-V2.0-java",
"android.hardware.health-V2.1-java",
],
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl
index 2dd01b1..089c8ac 100644
--- a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl
@@ -37,4 +37,6 @@
long batteryManufacturingDateSeconds;
long batteryFirstUsageSeconds;
long batteryStateOfHealth;
+ @nullable String batterySerialNumber;
+ android.hardware.health.BatteryPartStatus batteryPartStatus = android.hardware.health.BatteryPartStatus.UNSUPPORTED;
}
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryPartStatus.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryPartStatus.aidl
new file mode 100644
index 0000000..e013e31
--- /dev/null
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryPartStatus.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.health;
+@Backing(type="int") @VintfStability
+enum BatteryPartStatus {
+ UNSUPPORTED,
+ ORIGINAL,
+ REPLACED,
+}
diff --git a/health/aidl/android/hardware/health/BatteryHealthData.aidl b/health/aidl/android/hardware/health/BatteryHealthData.aidl
index 594bcce..7245298 100644
--- a/health/aidl/android/hardware/health/BatteryHealthData.aidl
+++ b/health/aidl/android/hardware/health/BatteryHealthData.aidl
@@ -16,6 +16,8 @@
package android.hardware.health;
+import android.hardware.health.BatteryPartStatus;
+
/*
* Battery health data
*/
@@ -36,4 +38,14 @@
* Otherwise, value must be in the range 0 to 100.
*/
long batteryStateOfHealth;
+ /**
+ * Serial number of the battery. Null if not supported. If supported, a string of at least 6
+ * alphanumeric characters. Characters may either be upper or lower case, but for comparison
+ * and uniqueness purposes, must be treated as case-insensitive.
+ */
+ @nullable String batterySerialNumber;
+ /**
+ * Indicator for part originality of the battery.
+ */
+ BatteryPartStatus batteryPartStatus = BatteryPartStatus.UNSUPPORTED;
}
diff --git a/health/aidl/android/hardware/health/BatteryPartStatus.aidl b/health/aidl/android/hardware/health/BatteryPartStatus.aidl
new file mode 100644
index 0000000..6c2060a
--- /dev/null
+++ b/health/aidl/android/hardware/health/BatteryPartStatus.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.health;
+
+/**
+ * Possible values for BatteryPartStatus.
+ * Note: These are currently in sync with BatteryManager and must not
+ * be extended / altered.
+ */
+@VintfStability
+@Backing(type="int")
+enum BatteryPartStatus {
+ /**
+ * Device cannot differentiate an original battery from a replaced battery.
+ */
+ UNSUPPORTED = 0,
+ /**
+ * Device has the original battery it was manufactured with.
+ */
+ ORIGINAL = 1,
+ /**
+ * Device has a replaced battery.
+ */
+ REPLACED = 2,
+}
diff --git a/health/aidl/default/Android.bp b/health/aidl/default/Android.bp
index b51e4f3..2071f08 100644
--- a/health/aidl/default/Android.bp
+++ b/health/aidl/default/Android.bp
@@ -29,7 +29,7 @@
"libcutils",
"liblog",
"libutils",
- "android.hardware.health-V2-ndk",
+ "android.hardware.health-V3-ndk",
// TODO(b/177269435): remove when BatteryMonitor works with AIDL HealthInfo.
"libhidlbase",
@@ -48,7 +48,7 @@
name: "libhealth_aidl_charger_defaults",
shared_libs: [
// common
- "android.hardware.health-V2-ndk",
+ "android.hardware.health-V3-ndk",
"libbase",
"libcutils",
"liblog",
@@ -195,7 +195,7 @@
"service_fuzzer_defaults",
],
static_libs: [
- "android.hardware.health-V2-ndk",
+ "android.hardware.health-V3-ndk",
"libbase",
"liblog",
"fuzz_libhealth_aidl_impl",
diff --git a/health/aidl/default/Health.cpp b/health/aidl/default/Health.cpp
index 4ad8f50..37662ea 100644
--- a/health/aidl/default/Health.cpp
+++ b/health/aidl/default/Health.cpp
@@ -36,6 +36,11 @@
LinkedCallback* linked = reinterpret_cast<LinkedCallback*>(cookie);
linked->OnCallbackDied();
}
+// Delete the owned cookie.
+void onCallbackUnlinked(void* cookie) {
+ LinkedCallback* linked = reinterpret_cast<LinkedCallback*>(cookie);
+ delete linked;
+}
} // namespace
/*
@@ -57,11 +62,24 @@
: instance_name_(instance_name),
healthd_config_(std::move(config)),
death_recipient_(AIBinder_DeathRecipient_new(&OnCallbackDiedWrapped)) {
+ AIBinder_DeathRecipient_setOnUnlinked(death_recipient_.get(), onCallbackUnlinked);
battery_monitor_.init(healthd_config_.get());
}
Health::~Health() {}
+static inline ndk::ScopedAStatus TranslateStatus(::android::status_t err) {
+ switch (err) {
+ case ::android::OK:
+ return ndk::ScopedAStatus::ok();
+ case ::android::NAME_NOT_FOUND:
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ default:
+ return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ IHealth::STATUS_UNKNOWN, ::android::statusToString(err).c_str());
+ }
+}
+
//
// Getters.
//
@@ -78,16 +96,7 @@
LOG(DEBUG) << "getProperty(" << id << ")"
<< " fails: (" << err << ") " << ::android::statusToString(err);
}
-
- switch (err) {
- case ::android::OK:
- return ndk::ScopedAStatus::ok();
- case ::android::NAME_NOT_FOUND:
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
- default:
- return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
- IHealth::STATUS_UNKNOWN, ::android::statusToString(err).c_str());
- }
+ return TranslateStatus(err);
}
ndk::ScopedAStatus Health::getChargeCounterUah(int32_t* out) {
@@ -153,6 +162,21 @@
!res.isOk()) {
LOG(WARNING) << "Cannot get Battery_state_of_health: " << res.getDescription();
}
+ if (auto res = battery_monitor_.getSerialNumber(&out->batterySerialNumber);
+ res != ::android::OK) {
+ LOG(WARNING) << "Cannot get Battery_serial_number: "
+ << TranslateStatus(res).getDescription();
+ }
+
+ int64_t part_status = static_cast<int64_t>(BatteryPartStatus::UNSUPPORTED);
+ if (auto res = GetProperty<int64_t>(&battery_monitor_, ::android::BATTERY_PROP_PART_STATUS,
+ static_cast<int64_t>(BatteryPartStatus::UNSUPPORTED),
+ &part_status);
+ !res.isOk()) {
+ LOG(WARNING) << "Cannot get Battery_part_status: " << res.getDescription();
+ }
+ out->batteryPartStatus = static_cast<BatteryPartStatus>(part_status);
+
return ndk::ScopedAStatus::ok();
}
@@ -236,15 +260,6 @@
return healthd_config_->screen_on(&props);
}
-namespace {
-bool IsDeadObjectLogged(const ndk::ScopedAStatus& ret) {
- if (ret.isOk()) return false;
- if (ret.getStatus() == ::STATUS_DEAD_OBJECT) return true;
- LOG(ERROR) << "Cannot call healthInfoChanged on callback: " << ret.getDescription();
- return false;
-}
-} // namespace
-
//
// Subclass helpers / overrides
//
@@ -277,7 +292,7 @@
if (!linked_callback_result.ok()) {
return ndk::ScopedAStatus::fromStatus(-linked_callback_result.error().code());
}
- callbacks_.emplace_back(std::move(*linked_callback_result));
+ callbacks_[*linked_callback_result] = callback;
// unlock
}
@@ -288,8 +303,10 @@
return ndk::ScopedAStatus::ok();
}
- if (auto res = callback->healthInfoChanged(health_info); IsDeadObjectLogged(res)) {
- (void)unregisterCallback(callback);
+ auto res = callback->healthInfoChanged(health_info);
+ if (!res.isOk()) {
+ LOG(DEBUG) << "Cannot call healthInfoChanged:" << res.getDescription()
+ << ". Do nothing here if callback is dead as it will be cleaned up later.";
}
return ndk::ScopedAStatus::ok();
}
@@ -303,12 +320,24 @@
std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
- auto matches = [callback](const auto& linked) {
- return linked->callback()->asBinder() == callback->asBinder(); // compares binder object
+ auto matches = [callback](const auto& cb) {
+ return cb->asBinder() == callback->asBinder(); // compares binder object
};
- auto it = std::remove_if(callbacks_.begin(), callbacks_.end(), matches);
- bool removed = (it != callbacks_.end());
- callbacks_.erase(it, callbacks_.end()); // calls unlinkToDeath on deleted callbacks.
+ bool removed = false;
+ for (auto it = callbacks_.begin(); it != callbacks_.end();) {
+ if (it->second->asBinder() == callback->asBinder()) {
+ auto status = AIBinder_unlinkToDeath(callback->asBinder().get(), death_recipient_.get(),
+ reinterpret_cast<void*>(it->first));
+ if (status != STATUS_OK && status != STATUS_DEAD_OBJECT) {
+ LOG(WARNING) << __func__
+ << "Cannot unlink to death: " << ::android::statusToString(status);
+ }
+ it = callbacks_.erase(it);
+ removed = true;
+ } else {
+ it++;
+ }
+ }
return removed ? ndk::ScopedAStatus::ok()
: ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
@@ -336,13 +365,13 @@
void Health::OnHealthInfoChanged(const HealthInfo& health_info) {
// Notify all callbacks
std::unique_lock<decltype(callbacks_lock_)> lock(callbacks_lock_);
- // is_dead notifies a callback and return true if it is dead.
- auto is_dead = [&](const auto& linked) {
- auto res = linked->callback()->healthInfoChanged(health_info);
- return IsDeadObjectLogged(res);
- };
- auto it = std::remove_if(callbacks_.begin(), callbacks_.end(), is_dead);
- callbacks_.erase(it, callbacks_.end()); // calls unlinkToDeath on deleted callbacks.
+ for (const auto& [_, callback] : callbacks_) {
+ auto res = callback->healthInfoChanged(health_info);
+ if (!res.isOk()) {
+ LOG(DEBUG) << "Cannot call healthInfoChanged:" << res.getDescription()
+ << ". Do nothing here if callback is dead as it will be cleaned up later.";
+ }
+ }
lock.unlock();
// Let HalHealthLoop::OnHealthInfoChanged() adjusts uevent / wakealarm periods
diff --git a/health/aidl/default/LinkedCallback.cpp b/health/aidl/default/LinkedCallback.cpp
index 26e99f9..df471a3 100644
--- a/health/aidl/default/LinkedCallback.cpp
+++ b/health/aidl/default/LinkedCallback.cpp
@@ -24,35 +24,24 @@
namespace aidl::android::hardware::health {
-::android::base::Result<std::unique_ptr<LinkedCallback>> LinkedCallback::Make(
+::android::base::Result<LinkedCallback*> LinkedCallback::Make(
std::shared_ptr<Health> service, std::shared_ptr<IHealthInfoCallback> callback) {
- std::unique_ptr<LinkedCallback> ret(new LinkedCallback());
+ LinkedCallback* ret(new LinkedCallback());
+ // pass ownership of this object to the death recipient
binder_status_t linkRet =
AIBinder_linkToDeath(callback->asBinder().get(), service->death_recipient_.get(),
- reinterpret_cast<void*>(ret.get()));
+ reinterpret_cast<void*>(ret));
if (linkRet != ::STATUS_OK) {
LOG(WARNING) << __func__ << "Cannot link to death: " << linkRet;
return ::android::base::Error(-linkRet);
}
ret->service_ = service;
- ret->callback_ = std::move(callback);
+ ret->callback_ = callback;
return ret;
}
LinkedCallback::LinkedCallback() = default;
-LinkedCallback::~LinkedCallback() {
- if (callback_ == nullptr) {
- return;
- }
- auto status =
- AIBinder_unlinkToDeath(callback_->asBinder().get(), service()->death_recipient_.get(),
- reinterpret_cast<void*>(this));
- if (status != STATUS_OK && status != STATUS_DEAD_OBJECT) {
- LOG(WARNING) << __func__ << "Cannot unlink to death: " << ::android::statusToString(status);
- }
-}
-
std::shared_ptr<Health> LinkedCallback::service() {
auto service_sp = service_.lock();
CHECK_NE(nullptr, service_sp);
@@ -60,7 +49,10 @@
}
void LinkedCallback::OnCallbackDied() {
- service()->unregisterCallback(callback_);
+ auto sCb = callback_.lock();
+ if (sCb) {
+ service()->unregisterCallback(sCb);
+ }
}
} // namespace aidl::android::hardware::health
diff --git a/health/aidl/default/LinkedCallback.h b/health/aidl/default/LinkedCallback.h
index da494c9..8c9c997 100644
--- a/health/aidl/default/LinkedCallback.h
+++ b/health/aidl/default/LinkedCallback.h
@@ -32,19 +32,10 @@
class LinkedCallback {
public:
// Automatically linkToDeath upon construction with the returned object as the cookie.
- // service->death_reciepient() should be from CreateDeathRecipient().
- // Not using a strong reference to |service| to avoid circular reference. The lifetime
- // of |service| must be longer than this LinkedCallback object.
- static ::android::base::Result<std::unique_ptr<LinkedCallback>> Make(
+ // The deathRecipient owns the LinkedCallback object and will delete it with
+ // cookie when it's unlinked.
+ static ::android::base::Result<LinkedCallback*> Make(
std::shared_ptr<Health> service, std::shared_ptr<IHealthInfoCallback> callback);
-
- // Automatically unlinkToDeath upon destruction. So, it is always safe to reinterpret_cast
- // the cookie back to the LinkedCallback object.
- ~LinkedCallback();
-
- // The wrapped IHealthInfoCallback object.
- const std::shared_ptr<IHealthInfoCallback>& callback() const { return callback_; }
-
// On callback died, unreigster it from the service.
void OnCallbackDied();
@@ -55,7 +46,7 @@
std::shared_ptr<Health> service();
std::weak_ptr<Health> service_;
- std::shared_ptr<IHealthInfoCallback> callback_;
+ std::weak_ptr<IHealthInfoCallback> callback_;
};
} // namespace aidl::android::hardware::health
diff --git a/health/aidl/default/android.hardware.health-service.example.xml b/health/aidl/default/android.hardware.health-service.example.xml
index 1fe9b8d..2acaaba 100644
--- a/health/aidl/default/android.hardware.health-service.example.xml
+++ b/health/aidl/default/android.hardware.health-service.example.xml
@@ -1,7 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.health</name>
- <version>2</version>
+ <version>3</version>
<fqname>IHealth/default</fqname>
</hal>
</manifest>
diff --git a/health/aidl/default/include/health-impl/Health.h b/health/aidl/default/include/health-impl/Health.h
index dc3a0ef..429ae2a 100644
--- a/health/aidl/default/include/health-impl/Health.h
+++ b/health/aidl/default/include/health-impl/Health.h
@@ -16,6 +16,7 @@
#pragma once
+#include <map>
#include <memory>
#include <optional>
@@ -112,7 +113,7 @@
ndk::ScopedAIBinder_DeathRecipient death_recipient_;
int binder_fd_ = -1;
std::mutex callbacks_lock_;
- std::vector<std::unique_ptr<LinkedCallback>> callbacks_;
+ std::map<LinkedCallback*, std::shared_ptr<IHealthInfoCallback>> callbacks_;
};
} // namespace aidl::android::hardware::health
diff --git a/health/aidl/vts/functional/Android.bp b/health/aidl/vts/functional/Android.bp
index b735a87..6d2b530 100644
--- a/health/aidl/vts/functional/Android.bp
+++ b/health/aidl/vts/functional/Android.bp
@@ -39,7 +39,7 @@
"libbinder_ndk",
],
static_libs: [
- "android.hardware.health-V2-ndk",
+ "android.hardware.health-V3-ndk",
"libgmock",
],
header_libs: [
diff --git a/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp b/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
index 783ce11..9360789 100644
--- a/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
+++ b/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
@@ -84,6 +84,21 @@
return AnyOfArray(enum_range<T>().begin(), enum_range<T>().end());
}
+MATCHER(IsValidSerialNumber, "") {
+ if (!arg) {
+ return true;
+ }
+ if (arg->size() < 6) {
+ return false;
+ }
+ for (const auto& c : *arg) {
+ if (!isalnum(c)) {
+ return false;
+ }
+ }
+ return true;
+}
+
class HealthAidl : public testing::TestWithParam<std::string> {
public:
void SetUp() override {
@@ -270,7 +285,7 @@
ASSERT_THAT(static_cast<int>(value), AnyOf(Eq(1), Eq(4)));
}
-MATCHER(IsValidHealthData, "") {
+MATCHER_P(IsValidHealthData, version, "") {
*result_listener << "value is " << arg.toString() << ".";
if (!ExplainMatchResult(Ge(-1), arg.batteryManufacturingDateSeconds, result_listener)) {
*result_listener << " for batteryManufacturingDateSeconds.";
@@ -284,6 +299,15 @@
*result_listener << " for batteryStateOfHealth.";
return false;
}
+ if (!ExplainMatchResult(IsValidSerialNumber(), arg.batterySerialNumber, result_listener)) {
+ *result_listener << " for batterySerialNumber.";
+ return false;
+ }
+ if (!ExplainMatchResult(IsValidEnum<BatteryPartStatus>(), arg.batteryPartStatus,
+ result_listener)) {
+ *result_listener << " for batteryPartStatus.";
+ return false;
+ }
return true;
}
@@ -303,7 +327,7 @@
status = health->getBatteryHealthData(&value);
ASSERT_THAT(status, AnyOf(IsOk(), ExceptionIs(EX_UNSUPPORTED_OPERATION)));
if (!status.isOk()) return;
- ASSERT_THAT(value, IsValidHealthData());
+ ASSERT_THAT(value, IsValidHealthData(version));
}
MATCHER(IsValidStorageInfo, "") {
diff --git a/health/utils/libhealthshim/Android.bp b/health/utils/libhealthshim/Android.bp
index 14c32ae..b0ea743 100644
--- a/health/utils/libhealthshim/Android.bp
+++ b/health/utils/libhealthshim/Android.bp
@@ -34,7 +34,7 @@
"-Werror",
],
static_libs: [
- "android.hardware.health-V2-ndk",
+ "android.hardware.health-V3-ndk",
"android.hardware.health-translate-ndk",
"android.hardware.health@1.0",
"android.hardware.health@2.0",
diff --git a/health/utils/libhealthshim/shim.cpp b/health/utils/libhealthshim/shim.cpp
index 6a5f512..a5ba919 100644
--- a/health/utils/libhealthshim/shim.cpp
+++ b/health/utils/libhealthshim/shim.cpp
@@ -230,6 +230,7 @@
ScopedAStatus HealthShim::getBatteryHealthData(BatteryHealthData* out) {
out->batteryManufacturingDateSeconds = 0;
out->batteryFirstUsageSeconds = 0;
+ out->batteryPartStatus = BatteryPartStatus::UNSUPPORTED;
return ResultToStatus(Result::NOT_SUPPORTED);
}
diff --git a/input/classifier/1.0/default/Android.bp b/input/classifier/1.0/default/Android.bp
index 8ab2ba8..264292b 100644
--- a/input/classifier/1.0/default/Android.bp
+++ b/input/classifier/1.0/default/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_input_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/input/classifier/1.0/vts/functional/Android.bp b/input/classifier/1.0/vts/functional/Android.bp
index 22346ed..dcf68b9 100644
--- a/input/classifier/1.0/vts/functional/Android.bp
+++ b/input/classifier/1.0/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_input_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/input/common/1.0/Android.bp b/input/common/1.0/Android.bp
index ed0ab98..ffa3441 100644
--- a/input/common/1.0/Android.bp
+++ b/input/common/1.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_input_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/input/common/aidl/Android.bp b/input/common/aidl/Android.bp
index f23f270..0759d2e 100644
--- a/input/common/aidl/Android.bp
+++ b/input/common/aidl/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_input_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/input/processor/aidl/Android.bp b/input/processor/aidl/Android.bp
index f1a73d2..68adf32 100644
--- a/input/processor/aidl/Android.bp
+++ b/input/processor/aidl/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_input_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/input/processor/aidl/default/Android.bp b/input/processor/aidl/default/Android.bp
index bdd27e2..f5163a7 100644
--- a/input/processor/aidl/default/Android.bp
+++ b/input/processor/aidl/default/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_input_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/ir/aidl/default/android.hardware.ir-service.example.rc b/ir/aidl/default/android.hardware.ir-service.example.rc
index 1a721da..d27f282 100644
--- a/ir/aidl/default/android.hardware.ir-service.example.rc
+++ b/ir/aidl/default/android.hardware.ir-service.example.rc
@@ -1,4 +1,4 @@
-service vendor.ir-default /apex/com.android.hardware.ir/bin/hw/android.hardware.ir-service.example
+service vendor.ir-default /vendor/bin/hw/android.hardware.ir-service.example
class hal
user system
group system
diff --git a/keymaster/4.0/vts/functional/HmacKeySharingTest.cpp b/keymaster/4.0/vts/functional/HmacKeySharingTest.cpp
index 1bff076..a076438 100644
--- a/keymaster/4.0/vts/functional/HmacKeySharingTest.cpp
+++ b/keymaster/4.0/vts/functional/HmacKeySharingTest.cpp
@@ -51,7 +51,7 @@
};
using KeymasterVec = std::vector<sp<IKeymasterDevice>>;
- using ByteString = std::basic_string<uint8_t>;
+ using ByteString = std::vector<uint8_t>;
// using NonceVec = std::vector<HidlBuf>;
GetParamsResult getHmacSharingParameters(IKeymasterDevice& keymaster) {
@@ -98,7 +98,7 @@
std::vector<ByteString> copyNonces(const hidl_vec<HmacSharingParameters>& paramsVec) {
std::vector<ByteString> nonces;
for (auto& param : paramsVec) {
- nonces.emplace_back(param.nonce.data(), param.nonce.size());
+ nonces.emplace_back(param.nonce.data(), param.nonce.data() + param.nonce.size());
}
return nonces;
}
diff --git a/light/aidl/default/main.rs b/light/aidl/default/main.rs
index 8f32470..b5452d6 100644
--- a/light/aidl/default/main.rs
+++ b/light/aidl/default/main.rs
@@ -23,11 +23,11 @@
const LOG_TAG: &str = "lights_service_example_rust";
-use log::Level;
+use log::LevelFilter;
fn main() {
let logger_success = logger::init(
- logger::Config::default().with_tag_on_device(LOG_TAG).with_min_level(Level::Trace),
+ logger::Config::default().with_tag_on_device(LOG_TAG).with_max_level(LevelFilter::Trace),
);
if !logger_success {
panic!("{LOG_TAG}: Failed to start logger.");
diff --git a/macsec/OWNERS b/macsec/OWNERS
new file mode 100644
index 0000000..6934f86
--- /dev/null
+++ b/macsec/OWNERS
@@ -0,0 +1 @@
+keithmok@google.com
diff --git a/macsec/aidl/Android.bp b/macsec/aidl/Android.bp
new file mode 100644
index 0000000..5e47999
--- /dev/null
+++ b/macsec/aidl/Android.bp
@@ -0,0 +1,40 @@
+//
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+aidl_interface {
+ name: "android.hardware.macsec",
+ vendor_available: true,
+ srcs: ["android/hardware/macsec/*.aidl"],
+ stability: "vintf",
+ host_supported: true,
+ backend: {
+ java: {
+ enabled: false,
+ },
+ rust: {
+ enabled: false,
+ },
+ },
+}
diff --git a/macsec/aidl/aidl_api/android.hardware.macsec/current/android/hardware/macsec/IMacsecPskPlugin.aidl b/macsec/aidl/aidl_api/android.hardware.macsec/current/android/hardware/macsec/IMacsecPskPlugin.aidl
new file mode 100644
index 0000000..6a93919
--- /dev/null
+++ b/macsec/aidl/aidl_api/android.hardware.macsec/current/android/hardware/macsec/IMacsecPskPlugin.aidl
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.macsec;
+
+/**
+ * MACSEC (IEEE 802.1AE) pre-shared key plugin for wpa_supplicant
+ *
+ * The goal of this service is to provide function for using the MACSEC CAK
+ *
+ */
+@VintfStability
+interface IMacsecPskPlugin {
+ /**
+ * For xTS test only inject a key to verify implementation correctness, not called in production
+ *
+ * @param keyId is key id to add
+ * @param Connectivity Association Keys (CAK) to set
+ * @param Connectivity Association Key Name (CKN) to set
+ *
+ */
+ void addTestKey(in byte[] keyId, in byte[] CAK, in byte[] CKN);
+
+ /**
+ * Use ICV key do AES CMAC
+ * same as ieee802_1x_icv_aes_cmac in wpa_supplicant
+ *
+ * @param keyId is key id to be used for AES CMAC
+ * @param data, a data pointer to the buffer for calculate the ICV
+ *
+ * @return Integrity check value (ICV).
+ */
+ byte[] calcIcv(in byte[] keyId, in byte[] data);
+
+ /**
+ * KDF with CAK key to generate Secure Association Key (SAK)
+ * same as ieee802_1x_sak_aes_cmac in wpa_supplicant
+ *
+ * @param keyId is key id to be used for KDF
+ * @param data is key seed (random number)
+ * @param sakLength generated SAK length (16 or 32)
+ *
+ * @return Secure Association Key (SAK).
+ */
+ byte[] generateSak(in byte[] keyId, in byte[] data, in int sakLength);
+
+ /**
+ * Encrypt using KEK key, this is same as aes_wrap with kek.key in wpa_supplicant
+ * which used to wrap a SAK key
+ *
+ * @param keyId is key id to be used for encryption
+ * @param sak is the SAK key (16 or 32 bytes) to be wrapped.
+ *
+ * @return wrapped data using Key Encrypting Key (KEK).
+ */
+ byte[] wrapSak(in byte[] keyId, in byte[] sak);
+
+ /**
+ * Decrypt using KEK key, this is same as aes_unwrap with kek.key in wpa_supplicant
+ * which used to unwrap a SAK key
+ *
+ * @param keyId is key id to be used for decryption
+ * @param sak is wrapped SAK key.
+ *
+ * @return unwrapped data using KEK key.
+ */
+ byte[] unwrapSak(in byte[] keyId, in byte[] sak);
+}
diff --git a/macsec/aidl/android/hardware/macsec/IMacsecPskPlugin.aidl b/macsec/aidl/android/hardware/macsec/IMacsecPskPlugin.aidl
new file mode 100644
index 0000000..a98cfa6
--- /dev/null
+++ b/macsec/aidl/android/hardware/macsec/IMacsecPskPlugin.aidl
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.macsec;
+
+/**
+ * MACSEC (IEEE 802.1AE) pre-shared key plugin for wpa_supplicant
+ *
+ * The goal of this service is to provide function for using the MACSEC CAK
+ *
+ */
+@VintfStability
+interface IMacsecPskPlugin {
+ /**
+ * For xTS test only inject a key to verify implementation correctness, not called in production
+ *
+ * @param keyId is key id to add
+ * @param Connectivity Association Keys (CAK) to set
+ * @param Connectivity Association Key Name (CKN) to set
+ * @throws EX_ILLEGAL_ARGUMENT If CAK size is not 16 or 32 or keyID size not equals to CAK size
+ */
+ void addTestKey(in byte[] keyId, in byte[] CAK, in byte[] CKN);
+
+ /**
+ * Use ICV key do AES CMAC
+ * same as ieee802_1x_icv_aes_cmac in wpa_supplicant
+ *
+ * @param keyId is key id to be used for AES CMAC
+ * @param data, a data pointer to the buffer for calculate the ICV
+ *
+ * @return Integrity check value (ICV).
+ * @throws EX_ILLEGAL_ARGUMENT If keyId does not exist
+ */
+ byte[] calcIcv(in byte[] keyId, in byte[] data);
+
+ /**
+ * KDF with CAK key to generate Secure Association Key (SAK)
+ * same as ieee802_1x_sak_aes_cmac in wpa_supplicant
+ *
+ * @param keyId is key id to be used for KDF
+ * @param data is key seed (random number)
+ * @param sakLength generated SAK length (16 or 32)
+ *
+ * @return Secure Association Key (SAK).
+ * @throws EX_ILLEGAL_ARGUMENT In the following cases:
+ * - If keyId does not exist
+ * - sakLength != 16 or 32
+ * - data length < sakLength
+ */
+ byte[] generateSak(in byte[] keyId, in byte[] data, in int sakLength);
+
+ /**
+ * Encrypt using KEK key, this is same as aes_wrap with kek.key in wpa_supplicant
+ * which used to wrap a SAK key
+ *
+ * @param keyId is key id to be used for encryption
+ * @param sak is the SAK key (16 or 32 bytes) to be wrapped.
+ *
+ * @return wrapped data using Key Encrypting Key (KEK).
+ * @throws EX_ILLEGAL_ARGUMENT In the following cases:
+ * - If keyId does not exist
+ * - sak size eqauls to 0 or not multiples of 8
+ */
+ byte[] wrapSak(in byte[] keyId, in byte[] sak);
+
+ /**
+ * Decrypt using KEK key, this is same as aes_unwrap with kek.key in wpa_supplicant
+ * which used to unwrap a SAK key
+ *
+ * @param keyId is key id to be used for decryption
+ * @param sak is wrapped SAK key.
+ *
+ * @return unwrapped data using KEK key.
+ * @throws EX_ILLEGAL_ARGUMENT In the following cases:
+ * - If keyId does not exist
+ * - sak size <= 8 or not multiples of 8
+ */
+ byte[] unwrapSak(in byte[] keyId, in byte[] sak);
+}
diff --git a/macsec/aidl/default/Android.bp b/macsec/aidl/default/Android.bp
new file mode 100644
index 0000000..7c7346f
--- /dev/null
+++ b/macsec/aidl/default/Android.bp
@@ -0,0 +1,64 @@
+//
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_binary {
+ name: "android.hardware.macsec-service",
+ init_rc: ["android.hardware.macsec.rc"],
+ vendor: true,
+ relative_install_path: "hw",
+ srcs: [
+ "MacsecPskPlugin.cpp",
+ "service.cpp",
+ ],
+ shared_libs: [
+ "android.hardware.macsec-V1-ndk",
+ "libcrypto",
+ "libbase",
+ "libbinder_ndk",
+ ],
+ vintf_fragments: ["android.hardware.macsec.xml"],
+}
+
+cc_fuzz {
+ name: "android.hardware.macsec@V1-default-service.aidl_fuzzer",
+ vendor: true,
+ srcs: [
+ "MacsecPskPlugin.cpp",
+ "fuzzer/fuzzer.cpp",
+ ],
+ shared_libs: [
+ "android.hardware.macsec-V1-ndk",
+ "libcrypto",
+ "liblog",
+ ],
+ defaults: [
+ "service_fuzzer_defaults",
+ ],
+ fuzz_config: {
+ cc: [
+ "keithmok@google.com",
+ ],
+ },
+}
diff --git a/macsec/aidl/default/MacsecPskPlugin.cpp b/macsec/aidl/default/MacsecPskPlugin.cpp
new file mode 100644
index 0000000..82d2545
--- /dev/null
+++ b/macsec/aidl/default/MacsecPskPlugin.cpp
@@ -0,0 +1,308 @@
+/*
+ * Copyright 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MacsecPskPlugin.h"
+#include <openssl/cipher.h>
+#include <openssl/mem.h>
+
+#include <android-base/format.h>
+#include <android-base/logging.h>
+
+namespace aidl::android::hardware::macsec {
+
+constexpr auto ok = &ndk::ScopedAStatus::ok;
+
+// vendor should hide the key in TEE/TA
+// CAK key can be either 16 / 32 bytes
+const std::vector<uint8_t> CAK_ID_1 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
+const std::vector<uint8_t> CAK_KEY_1 = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
+std::vector<uint8_t> CKN_1 = {0x31, 0x32, 0x33, 0x34}; // maximum 16 bytes
+
+const std::vector<uint8_t> CAK_ID_2 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02};
+const std::vector<uint8_t> CAK_KEY_2 = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
+std::vector<uint8_t> CKN_2 = {0x35, 0x36, 0x37, 0x38}; // maximum 16 bytes
+
+static ndk::ScopedAStatus resultToStatus(binder_exception_t res, const std::string& msg = "") {
+ if (msg.empty()) {
+ return ndk::ScopedAStatus::fromExceptionCode(res);
+ }
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(res, msg.c_str());
+}
+
+static int omac1_aes(CMAC_CTX* ctx, const uint8_t* data, size_t data_len,
+ uint8_t* mac /* 16 bytes */) {
+ size_t outlen;
+
+ // Just reuse same key in ctx
+ if (!CMAC_Reset(ctx)) {
+ return -1;
+ }
+
+ if (!CMAC_Update(ctx, data, data_len)) {
+ return -1;
+ }
+
+ if (!CMAC_Final(ctx, mac, &outlen) || outlen != 16) {
+ return -1;
+ }
+ return 0;
+}
+
+static void put_be16(uint8_t* addr, uint16_t value) {
+ *addr++ = value >> 8;
+ *addr = value & 0xff;
+}
+
+/* IEEE Std 802.1X-2010, 6.2.1 KDF */
+static int aes_kdf(CMAC_CTX* ctx, const char* label, const uint8_t* context, int ctx_bits,
+ int ret_bits, uint8_t* ret) {
+ const int h = 128;
+ const int r = 8;
+ int i, n;
+ int lab_len, ctx_len, ret_len, buf_len;
+ uint8_t* buf;
+
+ lab_len = strlen(label);
+ ctx_len = (ctx_bits + 7) / 8;
+ ret_len = ((ret_bits & 0xffff) + 7) / 8;
+ buf_len = lab_len + ctx_len + 4;
+
+ memset(ret, 0, ret_len);
+
+ n = (ret_bits + h - 1) / h;
+ if (n > ((0x1 << r) - 1)) return -1;
+
+ buf = (uint8_t*)calloc(1, buf_len);
+ if (buf == NULL) return -1;
+
+ memcpy(buf + 1, label, lab_len);
+ memcpy(buf + lab_len + 2, context, ctx_len);
+ put_be16(&buf[buf_len - 2], ret_bits);
+
+ for (i = 0; i < n; i++) {
+ int res;
+
+ buf[0] = (uint8_t)(i + 1);
+ res = omac1_aes(ctx, buf, buf_len, ret);
+ if (res) {
+ free(buf);
+ return -1;
+ }
+ ret = ret + h / 8;
+ }
+ free(buf);
+ return 0;
+}
+
+MacsecPskPlugin::MacsecPskPlugin() {
+ // always make sure ckn is 16 bytes, zero padded
+ CKN_1.resize(16);
+ CKN_2.resize(16);
+
+ addTestKey(CAK_ID_1, CAK_KEY_1, CKN_1);
+ addTestKey(CAK_ID_2, CAK_KEY_2, CKN_2);
+}
+
+MacsecPskPlugin::~MacsecPskPlugin() {
+ for (auto s : mKeys) {
+ OPENSSL_cleanse(&s.kekEncCtx, sizeof(AES_KEY));
+ OPENSSL_cleanse(&s.kekDecCtx, sizeof(AES_KEY));
+ CMAC_CTX_free(s.ickCtx);
+ CMAC_CTX_free(s.cakCtx);
+ }
+}
+
+ndk::ScopedAStatus MacsecPskPlugin::addTestKey(const std::vector<uint8_t>& keyId,
+ const std::vector<uint8_t>& CAK,
+ const std::vector<uint8_t>& CKN) {
+ if (CAK.size() != 16 && CAK.size() != 32) {
+ return resultToStatus(EX_ILLEGAL_ARGUMENT, "CAK length must be 16 or 32 bytes");
+ }
+
+ if (keyId.size() != CAK.size()) {
+ return resultToStatus(EX_ILLEGAL_ARGUMENT, "Key ID must be same as CAK length");
+ }
+
+ std::vector<uint8_t> ckn;
+ ckn = CKN;
+ ckn.resize(16); // make sure it is always zero padded with maximum length of
+ // 16 bytes
+
+ AES_KEY kekEncCtx;
+ AES_KEY kekDecCtx;
+ CMAC_CTX* ickCtx;
+ CMAC_CTX* cakCtx;
+
+ // Create the CAK openssl context
+ cakCtx = CMAC_CTX_new();
+
+ CMAC_Init(cakCtx, CAK.data(), CAK.size(),
+ CAK.size() == 16 ? EVP_aes_128_cbc() : EVP_aes_256_cbc(), NULL);
+
+ // derive KEK from CAK (ieee802_1x_kek_aes_cmac)
+ std::vector<uint8_t> kek;
+ kek.resize(CAK.size());
+
+ aes_kdf(cakCtx, "IEEE8021 KEK", (const uint8_t*)ckn.data(), ckn.size() * 8, 8 * kek.size(),
+ kek.data());
+
+ AES_set_encrypt_key(kek.data(), kek.size() << 3, &kekEncCtx);
+ AES_set_decrypt_key(kek.data(), kek.size() << 3, &kekDecCtx);
+
+ // derive ICK from CAK (ieee802_1x_ick_aes_cmac)
+ std::vector<uint8_t> ick;
+ ick.resize(CAK.size());
+
+ aes_kdf(cakCtx, "IEEE8021 ICK", (const uint8_t*)CKN.data(), CKN.size() * 8, 8 * ick.size(),
+ ick.data());
+
+ ickCtx = CMAC_CTX_new();
+
+ CMAC_Init(ickCtx, ick.data(), ick.size(),
+ ick.size() == 16 ? EVP_aes_128_cbc() : EVP_aes_256_cbc(), NULL);
+
+ mKeys.push_back({keyId, kekEncCtx, kekDecCtx, ickCtx, cakCtx});
+
+ return ok();
+}
+
+ndk::ScopedAStatus MacsecPskPlugin::calcIcv(const std::vector<uint8_t>& keyId,
+ const std::vector<uint8_t>& data,
+ std::vector<uint8_t>* out) {
+ CMAC_CTX* ctx = NULL;
+
+ for (auto s : mKeys) {
+ if (s.keyId == keyId) {
+ ctx = s.ickCtx;
+ break;
+ }
+ }
+
+ if (ctx == NULL) {
+ return resultToStatus(EX_ILLEGAL_ARGUMENT, "Key not exist");
+ }
+
+ out->resize(16);
+ if (omac1_aes(ctx, data.data(), data.size(), out->data()) != 0) {
+ return resultToStatus(EX_SERVICE_SPECIFIC, "Internal error");
+ }
+
+ return ok();
+}
+
+ndk::ScopedAStatus MacsecPskPlugin::generateSak(const std::vector<uint8_t>& keyId,
+ const std::vector<uint8_t>& data,
+ const int sakLength, std::vector<uint8_t>* out) {
+ CMAC_CTX* ctx = NULL;
+
+ if ((sakLength != 16) && (sakLength != 32)) {
+ return resultToStatus(EX_ILLEGAL_ARGUMENT, "Invalid SAK length");
+ }
+
+ if (data.size() < sakLength) {
+ return resultToStatus(EX_ILLEGAL_ARGUMENT, "Invalid data length");
+ }
+
+ for (auto s : mKeys) {
+ if (s.keyId == keyId) {
+ ctx = s.cakCtx;
+ break;
+ }
+ }
+
+ if (ctx == NULL) {
+ return resultToStatus(EX_ILLEGAL_ARGUMENT, "Key not exist");
+ }
+
+ out->resize(sakLength);
+
+ if (aes_kdf(ctx, "IEEE8021 SAK", data.data(), data.size() * 8, out->size() * 8, out->data()) !=
+ 0) {
+ return resultToStatus(EX_SERVICE_SPECIFIC, "Internal error");
+ }
+
+ return ok();
+}
+
+ndk::ScopedAStatus MacsecPskPlugin::wrapSak(const std::vector<uint8_t>& keyId,
+ const std::vector<uint8_t>& sak,
+ std::vector<uint8_t>* out) {
+ if (sak.size() == 0 || sak.size() % 8 != 0) {
+ return resultToStatus(EX_ILLEGAL_ARGUMENT,
+ "SAK length not multiple of 8 or greater than 0");
+ }
+
+ AES_KEY* ctx = NULL;
+
+ for (auto s : mKeys) {
+ if (s.keyId == keyId) {
+ ctx = &s.kekEncCtx;
+ break;
+ }
+ }
+
+ if (ctx == NULL) {
+ return resultToStatus(EX_ILLEGAL_ARGUMENT, "Key not exist");
+ }
+
+ out->resize(sak.size() + 8);
+
+ if (AES_wrap_key(ctx, NULL, out->data(), sak.data(), sak.size()) > 0) {
+ return ok();
+ }
+
+ return resultToStatus(EX_SERVICE_SPECIFIC, "Internal error");
+}
+
+ndk::ScopedAStatus MacsecPskPlugin::unwrapSak(const std::vector<uint8_t>& keyId,
+ const std::vector<uint8_t>& sak,
+ std::vector<uint8_t>* out) {
+ if (sak.size() <= 8 || sak.size() % 8 != 0) {
+ return resultToStatus(EX_ILLEGAL_ARGUMENT,
+ "SAK length not multiple of 8 or greater than 0");
+ }
+
+ AES_KEY* ctx = NULL;
+
+ for (auto s : mKeys) {
+ if (s.keyId == keyId) {
+ ctx = &s.kekDecCtx;
+ break;
+ }
+ }
+
+ if (ctx == NULL) {
+ return resultToStatus(EX_ILLEGAL_ARGUMENT, "Key not exist");
+ }
+
+ out->resize(sak.size() - 8);
+
+ if (AES_unwrap_key(ctx, NULL, out->data(), sak.data(), sak.size()) > 0) {
+ return ok();
+ }
+
+ return resultToStatus(EX_SERVICE_SPECIFIC, "Internal error");
+}
+
+} // namespace aidl::android::hardware::macsec
diff --git a/macsec/aidl/default/MacsecPskPlugin.h b/macsec/aidl/default/MacsecPskPlugin.h
new file mode 100644
index 0000000..0b056e3
--- /dev/null
+++ b/macsec/aidl/default/MacsecPskPlugin.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/macsec/BnMacsecPskPlugin.h>
+
+#include <openssl/aes.h>
+#include <openssl/cmac.h>
+
+namespace aidl::android::hardware::macsec {
+
+struct keys {
+ std::vector<uint8_t> keyId;
+ AES_KEY kekEncCtx;
+ AES_KEY kekDecCtx;
+ CMAC_CTX* ickCtx;
+ CMAC_CTX* cakCtx;
+};
+
+class MacsecPskPlugin : public BnMacsecPskPlugin {
+ public:
+ MacsecPskPlugin();
+ ~MacsecPskPlugin();
+ ndk::ScopedAStatus addTestKey(const std::vector<uint8_t>& keyId,
+ const std::vector<uint8_t>& CAK,
+ const std::vector<uint8_t>& CKN) override;
+ ndk::ScopedAStatus calcIcv(const std::vector<uint8_t>& keyId, const std::vector<uint8_t>& data,
+ std::vector<uint8_t>* out) override;
+
+ ndk::ScopedAStatus generateSak(const std::vector<uint8_t>& keyId,
+ const std::vector<uint8_t>& data, const int sakLength,
+ std::vector<uint8_t>* out);
+
+ ndk::ScopedAStatus wrapSak(const std::vector<uint8_t>& keyId, const std::vector<uint8_t>& sak,
+ std::vector<uint8_t>* out) override;
+
+ ndk::ScopedAStatus unwrapSak(const std::vector<uint8_t>& keyId, const std::vector<uint8_t>& sak,
+ std::vector<uint8_t>* out) override;
+
+ private:
+ std::vector<struct keys> mKeys;
+};
+} // namespace aidl::android::hardware::macsec
diff --git a/macsec/aidl/default/android.hardware.macsec.rc b/macsec/aidl/default/android.hardware.macsec.rc
new file mode 100644
index 0000000..0ff0e53
--- /dev/null
+++ b/macsec/aidl/default/android.hardware.macsec.rc
@@ -0,0 +1,3 @@
+service android.hardware.macsec /vendor/bin/hw/android.hardware.macsec-service
+ class early_hal
+ user nobody
diff --git a/macsec/aidl/default/android.hardware.macsec.xml b/macsec/aidl/default/android.hardware.macsec.xml
new file mode 100644
index 0000000..9cf9e5a
--- /dev/null
+++ b/macsec/aidl/default/android.hardware.macsec.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.macsec</name>
+ <version>1</version>
+ <interface>
+ <name>IMacsecPskPlugin</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/macsec/aidl/default/fuzzer/fuzzer.cpp b/macsec/aidl/default/fuzzer/fuzzer.cpp
new file mode 100644
index 0000000..d912a67
--- /dev/null
+++ b/macsec/aidl/default/fuzzer/fuzzer.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include "MacsecPskPlugin.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ std::shared_ptr<aidl::android::hardware::macsec::MacsecPskPlugin> service =
+ ndk::SharedRefBase::make<aidl::android::hardware::macsec::MacsecPskPlugin>();
+ android::fuzzService(service->asBinder().get(), FuzzedDataProvider(data, size));
+
+ return 0;
+}
diff --git a/macsec/aidl/default/service.cpp b/macsec/aidl/default/service.cpp
new file mode 100644
index 0000000..faf3a09
--- /dev/null
+++ b/macsec/aidl/default/service.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MacsecPskPlugin.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+namespace android::hardware::macsec {
+
+using namespace std::string_literals;
+using ::aidl::android::hardware::macsec::MacsecPskPlugin;
+
+extern "C" int main() {
+ base::SetDefaultTag("MacsecPskPlugin");
+ base::SetMinimumLogSeverity(base::VERBOSE);
+
+ LOG(VERBOSE) << "Starting up...";
+ auto service = ndk::SharedRefBase::make<MacsecPskPlugin>();
+ const auto instance = MacsecPskPlugin::descriptor + "/default"s;
+ const auto status = AServiceManager_addService(service->asBinder().get(), instance.c_str());
+ CHECK_EQ(status, STATUS_OK) << "Failed to add service " << instance;
+ LOG(VERBOSE) << "Started successfully!";
+
+ ABinderProcess_joinThreadPool();
+ LOG(FATAL) << "MacsecPskPlugin exited unexpectedly!";
+ return EXIT_FAILURE;
+}
+} // namespace android::hardware::macsec
diff --git a/macsec/aidl/vts/functional/Android.bp b/macsec/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..0c8f43d
--- /dev/null
+++ b/macsec/aidl/vts/functional/Android.bp
@@ -0,0 +1,48 @@
+//
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+ name: "VtsHalMacsecPskPluginV1Test",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ cpp_std: "experimental",
+ srcs: [
+ "MacsecAidlTest.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ ],
+ static_libs: [
+ "android.hardware.macsec-V1-ndk",
+ "libgmock",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
diff --git a/macsec/aidl/vts/functional/MacsecAidlTest.cpp b/macsec/aidl/vts/functional/MacsecAidlTest.cpp
new file mode 100644
index 0000000..e94c049
--- /dev/null
+++ b/macsec/aidl/vts/functional/MacsecAidlTest.cpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/macsec/IMacsecPskPlugin.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <gtest/gtest.h>
+
+#include <chrono>
+#include <thread>
+
+using aidl::android::hardware::macsec::IMacsecPskPlugin;
+using namespace std::chrono_literals;
+using namespace std::string_literals;
+
+const std::vector<uint8_t> CAK_ID_1 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01};
+const std::vector<uint8_t> CAK_KEY_1 = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
+const std::vector<uint8_t> CKN_1 = {0x31, 0x32, 0x33, 0x34}; // maximum 16 bytes
+const std::vector<uint8_t> SAK_DATA_1 = {0x31, 0x32, 0x33, 0x34, 0x11, 0x12, 0x12, 0x14,
+ 0x31, 0x32, 0x33, 0x34, 0x11, 0x12, 0x12, 0x14};
+const std::vector<uint8_t> SAK_1 = {0x13, 0xD9, 0xEE, 0x5B, 0x26, 0x8B, 0x44, 0xFB,
+ 0x37, 0x63, 0x3D, 0x41, 0xC8, 0xE7, 0x0D, 0x93};
+const std::vector<uint8_t> WRAPPED_SAK_1 = {0x3B, 0x39, 0xAB, 0x4C, 0xD8, 0xDA, 0x2E, 0xC5,
+ 0xD1, 0x38, 0x6A, 0x13, 0x9D, 0xE3, 0x78, 0xD9,
+ 0x93, 0xD2, 0xA0, 0x70, 0x88, 0xCB, 0xF5, 0xEC};
+const std::vector<uint8_t> DATA_1 = {0x31, 0x32, 0x33, 0x34, 0x31, 0x32, 0x34, 0x29,
+ 0x51, 0x52, 0x53, 0x54, 0x51, 0x35, 0x54, 0x59};
+const std::vector<uint8_t> ICV_1 = {0xDF, 0x54, 0xFF, 0xCD, 0xE0, 0xA9, 0x78, 0x10,
+ 0x6B, 0x7B, 0xD2, 0xBF, 0xEF, 0xD9, 0x0C, 0x81};
+
+const std::vector<uint8_t> CAK_ID_2 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02};
+const std::vector<uint8_t> CAK_KEY_2 = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
+const std::vector<uint8_t> CKN_2 = {0x35, 0x36, 0x37, 0x38}; // maximum 16 bytes
+const std::vector<uint8_t> SAK_DATA_2 = {0x31, 0x32, 0x33, 0x34, 0x31, 0x32, 0x33, 0x34,
+ 0x31, 0x32, 0x33, 0x34, 0x31, 0x32, 0x33, 0x34,
+ 0x31, 0x32, 0x33, 0x34, 0x31, 0x32, 0x33, 0x34,
+ 0x31, 0x32, 0x33, 0x34, 0x31, 0x32, 0x33, 0x34};
+const std::vector<uint8_t> SAK_2 = {0x39, 0x09, 0x36, 0x60, 0x18, 0x07, 0x2B, 0x5D,
+ 0xF0, 0x81, 0x81, 0x45, 0xCD, 0x71, 0xC6, 0xBA,
+ 0x1D, 0x2B, 0x87, 0xC4, 0xEF, 0x79, 0x68, 0x82,
+ 0x28, 0xD0, 0x25, 0x86, 0xD3, 0x63, 0xFF, 0x89};
+const std::vector<uint8_t> WRAPPED_SAK_2 = {
+ 0x2f, 0x6a, 0x22, 0x29, 0x68, 0x0e, 0x6e, 0x35, 0x91, 0x64, 0x05, 0x4a, 0x31, 0x8d,
+ 0x35, 0xea, 0x95, 0x85, 0x40, 0xc6, 0xea, 0x55, 0xe5, 0xc5, 0x68, 0x40, 0xae, 0x4d,
+ 0x6f, 0xeb, 0x73, 0xcd, 0x4e, 0x2a, 0x43, 0xb1, 0xda, 0x49, 0x4f, 0x0a};
+const std::vector<uint8_t> DATA_2 = {0x71, 0x82, 0x13, 0x24, 0x31, 0x82, 0xA4, 0x2F,
+ 0x51, 0x52, 0x53, 0x44, 0x21, 0x35, 0x54, 0x59};
+const std::vector<uint8_t> ICV_2 = {0x8D, 0xF1, 0x1D, 0x6E, 0xAC, 0x62, 0xC1, 0x2A,
+ 0xE8, 0xF8, 0x4E, 0xB1, 0x00, 0x45, 0x9A, 0xAD};
+
+class MacsecAidlTest : public ::testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ android::base::SetDefaultTag("MACSEC_HAL_VTS");
+ android::base::SetMinimumLogSeverity(android::base::VERBOSE);
+ const auto instance = IMacsecPskPlugin::descriptor + "/default"s;
+ mMacsecPskPluginService = IMacsecPskPlugin::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService(instance.c_str())));
+
+ ASSERT_NE(mMacsecPskPluginService, nullptr);
+ auto aidlStatus = mMacsecPskPluginService->addTestKey(CAK_ID_1, CAK_KEY_1, CKN_1);
+ ASSERT_TRUE(aidlStatus.isOk());
+ aidlStatus = mMacsecPskPluginService->addTestKey(CAK_ID_2, CAK_KEY_2, CKN_2);
+ ASSERT_TRUE(aidlStatus.isOk());
+ }
+ virtual void TearDown() override {}
+
+ std::shared_ptr<IMacsecPskPlugin> mMacsecPskPluginService;
+};
+
+TEST_P(MacsecAidlTest, calcIcv) {
+ std::vector<uint8_t> out;
+ auto aidlStatus = mMacsecPskPluginService->calcIcv(CAK_ID_1, DATA_1, &out);
+ ASSERT_TRUE(aidlStatus.isOk()) << "calcIcv KEY 1 failed: " << aidlStatus.getMessage();
+ EXPECT_EQ(out, ICV_1);
+
+ aidlStatus = mMacsecPskPluginService->calcIcv(CAK_ID_2, DATA_2, &out);
+ ASSERT_TRUE(aidlStatus.isOk()) << "calcIcv KEY 2 failed: " << aidlStatus.getMessage();
+ EXPECT_EQ(out, ICV_2);
+}
+
+TEST_P(MacsecAidlTest, generateSak) {
+ std::vector<uint8_t> out;
+ auto aidlStatus = mMacsecPskPluginService->generateSak(CAK_ID_1, SAK_DATA_1, 16, &out);
+ ASSERT_TRUE(aidlStatus.isOk()) << "generateSak KEY 1 failed: " << aidlStatus.getMessage();
+ EXPECT_EQ(out, SAK_1);
+
+ aidlStatus = mMacsecPskPluginService->generateSak(CAK_ID_2, SAK_DATA_2, 32, &out);
+ ASSERT_TRUE(aidlStatus.isOk()) << "generateSak KEY 2 failed: " << aidlStatus.getMessage();
+ EXPECT_EQ(out, SAK_2);
+}
+
+TEST_P(MacsecAidlTest, wrapSak) {
+ std::vector<uint8_t> out;
+ auto aidlStatus = mMacsecPskPluginService->wrapSak(CAK_ID_1, SAK_1, &out);
+ ASSERT_TRUE(aidlStatus.isOk()) << "wrapSak KEY 1 failed: " << aidlStatus.getMessage();
+ EXPECT_EQ(out, WRAPPED_SAK_1);
+
+ aidlStatus = mMacsecPskPluginService->wrapSak(CAK_ID_2, SAK_2, &out);
+ ASSERT_TRUE(aidlStatus.isOk()) << "wrapSak KEY 2 failed: " << aidlStatus.getMessage();
+ EXPECT_EQ(out, WRAPPED_SAK_2);
+}
+
+TEST_P(MacsecAidlTest, unwrapSak) {
+ std::vector<uint8_t> out;
+ auto aidlStatus = mMacsecPskPluginService->unwrapSak(CAK_ID_1, WRAPPED_SAK_1, &out);
+ ASSERT_TRUE(aidlStatus.isOk()) << "unwrapSak KEY 1 failed: " << aidlStatus.getMessage();
+ EXPECT_EQ(out, SAK_1);
+
+ aidlStatus = mMacsecPskPluginService->unwrapSak(CAK_ID_2, WRAPPED_SAK_2, &out);
+ ASSERT_TRUE(aidlStatus.isOk()) << "unwrapSak KEY 2 failed: " << aidlStatus.getMessage();
+ EXPECT_EQ(out, SAK_2);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MacsecAidlTest);
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, MacsecAidlTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IMacsecPskPlugin::descriptor)),
+ android::PrintInstanceNameToString);
diff --git a/macsec/aidl/vts/functional/OWNERS b/macsec/aidl/vts/functional/OWNERS
new file mode 100644
index 0000000..5009a88
--- /dev/null
+++ b/macsec/aidl/vts/functional/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 533426
+keithmok@google.com
diff --git a/media/bufferpool/1.0/Android.bp b/media/bufferpool/1.0/Android.bp
index 175b8a5..60bcf7b 100644
--- a/media/bufferpool/1.0/Android.bp
+++ b/media/bufferpool/1.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_media_codec_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/media/bufferpool/2.0/Android.bp b/media/bufferpool/2.0/Android.bp
index 56597db..fd6f08b 100644
--- a/media/bufferpool/2.0/Android.bp
+++ b/media/bufferpool/2.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_android_media_codec_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/media/bufferpool/aidl/Android.bp b/media/bufferpool/aidl/Android.bp
index 8e013e0..010c7cd 100644
--- a/media/bufferpool/aidl/Android.bp
+++ b/media/bufferpool/aidl/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_android_media_codec_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -26,6 +27,9 @@
vendor_available: true,
double_loadable: true,
srcs: ["android/hardware/media/bufferpool2/*.aidl"],
+ headers: [
+ "HardwareBuffer_aidl",
+ ],
imports: [
"android.hardware.common-V2",
"android.hardware.common.fmq-V1",
@@ -44,10 +48,13 @@
"//apex_available:platform",
"com.android.media.swcodec",
],
+ additional_shared_libraries: [
+ "libnativewindow",
+ ],
min_sdk_version: "29",
},
rust: {
- enabled: true,
+ enabled: false,
},
},
versions_with_info: [
@@ -59,6 +66,6 @@
],
},
],
- frozen: true,
+ frozen: false,
}
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/Buffer.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/Buffer.aidl
index 4ea0bba..85a78ad 100644
--- a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/Buffer.aidl
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/Buffer.aidl
@@ -35,5 +35,6 @@
@VintfStability
parcelable Buffer {
int id;
- android.hardware.common.NativeHandle buffer;
+ @nullable android.hardware.common.NativeHandle buffer;
+ @nullable android.hardware.HardwareBuffer hwbBuffer;
}
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IClientManager.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IClientManager.aidl
index 5899a40..298cb13 100644
--- a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IClientManager.aidl
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IClientManager.aidl
@@ -35,6 +35,7 @@
@VintfStability
interface IClientManager {
android.hardware.media.bufferpool2.IClientManager.Registration registerSender(in android.hardware.media.bufferpool2.IAccessor bufferPool);
+ android.hardware.media.bufferpool2.IClientManager.Registration registerPassiveSender(in android.hardware.media.bufferpool2.IAccessor bufferPool);
@VintfStability
parcelable Registration {
long connectionId;
diff --git a/media/bufferpool/aidl/android/hardware/media/bufferpool2/Buffer.aidl b/media/bufferpool/aidl/android/hardware/media/bufferpool2/Buffer.aidl
index 976f674..79b3f23 100644
--- a/media/bufferpool/aidl/android/hardware/media/bufferpool2/Buffer.aidl
+++ b/media/bufferpool/aidl/android/hardware/media/bufferpool2/Buffer.aidl
@@ -17,6 +17,7 @@
package android.hardware.media.bufferpool2;
import android.hardware.common.NativeHandle;
+import android.hardware.HardwareBuffer;
/**
* Generic buffer for fast recycling for media/stagefright.
@@ -26,10 +27,14 @@
* by a buffer pool, and are recycled to the buffer pool when they are
* no longer referenced by the clients.
*
+ * Initially all buffers in media HAL should be NativeHandle(actually native_handle_t).
+ * HardwareBuffer(actually AHardwareBuffer) for GraphicBuffer is added from V2.
+ *
* E.g. ion or gralloc buffer
*/
@VintfStability
parcelable Buffer {
int id;
- NativeHandle buffer;
+ @nullable NativeHandle buffer;
+ @nullable HardwareBuffer hwbBuffer;
}
diff --git a/media/bufferpool/aidl/android/hardware/media/bufferpool2/IClientManager.aidl b/media/bufferpool/aidl/android/hardware/media/bufferpool2/IClientManager.aidl
index a3054cb..2bc77bc 100644
--- a/media/bufferpool/aidl/android/hardware/media/bufferpool2/IClientManager.aidl
+++ b/media/bufferpool/aidl/android/hardware/media/bufferpool2/IClientManager.aidl
@@ -40,7 +40,8 @@
/**
* Sets up a buffer receiving communication node for the specified
* buffer pool. A manager must create a IConnection to the buffer
- * pool if it does not already have a connection.
+ * pool if it does not already have a connection. To transfer buffers
+ * using the interface, the sender must initiates transfer.
*
* @param bufferPool a buffer pool which is specified with the IAccessor.
* The specified buffer pool is the owner of received buffers.
@@ -52,4 +53,21 @@
* ResultStatus::CRITICAL_ERROR - Other errors.
*/
Registration registerSender(in IAccessor bufferPool);
+
+ /**
+ * Sets up a buffer receiving communication node for the specified
+ * buffer pool. A manager must create a IConnection to the buffer
+ * pool if it does not already have a connection. To transfer buffers
+ * using the interface, the receiver must initiates transfer(on demand).
+ *
+ * @param bufferPool a buffer pool which is specified with the IAccessor.
+ * The specified buffer pool is the owner of received buffers.
+ * @return the Id of the communication node to the buffer pool.
+ * This id is used in FMQ to notify IAccessor that a buffer has been
+ * sent to that connection during transfers.
+ * @throws ServiceSpecificException with one of the following values:
+ * ResultStatus::NO_MEMORY - Memory allocation failure occurred.
+ * ResultStatus::CRITICAL_ERROR - Other errors.
+ */
+ Registration registerPassiveSender(in IAccessor bufferPool);
}
diff --git a/media/bufferpool/aidl/default/Android.bp b/media/bufferpool/aidl/default/Android.bp
index 11a6163..72cd903 100644
--- a/media/bufferpool/aidl/default/Android.bp
+++ b/media/bufferpool/aidl/default/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_media_codec_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "frameworks_av_license"
@@ -33,15 +34,16 @@
"libcutils",
"libfmq",
"liblog",
+ "libnativewindow",
"libutils",
- "android.hardware.media.bufferpool2-V1-ndk",
+ "android.hardware.media.bufferpool2-V2-ndk",
],
static_libs: [
"libaidlcommonsupport",
],
export_shared_lib_headers: [
"libfmq",
- "android.hardware.media.bufferpool2-V1-ndk",
+ "android.hardware.media.bufferpool2-V2-ndk",
],
double_loadable: true,
cflags: [
diff --git a/media/bufferpool/aidl/default/BufferPoolClient.cpp b/media/bufferpool/aidl/default/BufferPoolClient.cpp
index e9777d8..ce4ad8e 100644
--- a/media/bufferpool/aidl/default/BufferPoolClient.cpp
+++ b/media/bufferpool/aidl/default/BufferPoolClient.cpp
@@ -297,7 +297,7 @@
mLastEvictCacheMs(::android::elapsedRealtime()) {
IAccessor::ConnectionInfo conInfo;
bool valid = false;
- if(accessor->connect(observer, &conInfo).isOk()) {
+ if (accessor && accessor->connect(observer, &conInfo).isOk()) {
auto channel = std::make_unique<BufferStatusChannel>(conInfo.toFmqDesc);
auto observer = std::make_unique<BufferInvalidationListener>(conInfo.fromFmqDesc);
@@ -757,7 +757,13 @@
return svcSpecific ? svcSpecific : ResultStatus::CRITICAL_ERROR;
}
if (results[0].getTag() == FetchResult::buffer) {
- *handle = ::android::dupFromAidl(results[0].get<FetchResult::buffer>().buffer);
+ if (results[0].get<FetchResult::buffer>().buffer.has_value()) {
+ *handle = ::android::dupFromAidl(results[0].get<FetchResult::buffer>().buffer.value());
+ } else {
+ // TODO: Support HardwareBuffer
+ ALOGW("handle nullptr");
+ *handle = nullptr;
+ }
return ResultStatus::OK;
}
return results[0].get<FetchResult::failure>();
diff --git a/media/bufferpool/aidl/default/ClientManager.cpp b/media/bufferpool/aidl/default/ClientManager.cpp
index de1db50..138790d 100644
--- a/media/bufferpool/aidl/default/ClientManager.cpp
+++ b/media/bufferpool/aidl/default/ClientManager.cpp
@@ -422,6 +422,14 @@
return ::ndk::ScopedAStatus::ok();
}
+::ndk::ScopedAStatus ClientManager::registerPassiveSender(
+ const std::shared_ptr<IAccessor>& in_bufferPool, Registration* _aidl_return) {
+ // TODO
+ (void) in_bufferPool;
+ (void) _aidl_return;
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(ResultStatus::NOT_FOUND);
+}
+
// Methods for local use.
std::shared_ptr<ClientManager> ClientManager::sInstance;
std::mutex ClientManager::sInstanceLock;
diff --git a/media/bufferpool/aidl/default/include/bufferpool2/ClientManager.h b/media/bufferpool/aidl/default/include/bufferpool2/ClientManager.h
index bff75ba..4b0916f 100644
--- a/media/bufferpool/aidl/default/include/bufferpool2/ClientManager.h
+++ b/media/bufferpool/aidl/default/include/bufferpool2/ClientManager.h
@@ -34,6 +34,11 @@
::aidl::android::hardware::media::bufferpool2::IClientManager::Registration* _aidl_return)
override;
+ ::ndk::ScopedAStatus registerPassiveSender(
+ const std::shared_ptr<IAccessor>& in_bufferPool,
+ ::aidl::android::hardware::media::bufferpool2::IClientManager::Registration* _aidl_return)
+ override;
+
/** Gets an instance. */
static std::shared_ptr<ClientManager> getInstance();
diff --git a/media/bufferpool/aidl/default/tests/Android.bp b/media/bufferpool/aidl/default/tests/Android.bp
index 549af57..46aa4da 100644
--- a/media/bufferpool/aidl/default/tests/Android.bp
+++ b/media/bufferpool/aidl/default/tests/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_media_codec_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "frameworks_av_license"
@@ -36,12 +37,13 @@
"libcutils",
"libfmq",
"liblog",
+ "libnativewindow",
"libutils",
- "android.hardware.media.bufferpool2-V1-ndk",
+ "android.hardware.media.bufferpool2-V2-ndk",
],
static_libs: [
"libaidlcommonsupport",
- "libstagefright_aidl_bufferpool2"
+ "libstagefright_aidl_bufferpool2",
],
compile_multilib: "both",
}
@@ -59,12 +61,13 @@
"libcutils",
"libfmq",
"liblog",
+ "libnativewindow",
"libutils",
- "android.hardware.media.bufferpool2-V1-ndk",
+ "android.hardware.media.bufferpool2-V2-ndk",
],
static_libs: [
"libaidlcommonsupport",
- "libstagefright_aidl_bufferpool2"
+ "libstagefright_aidl_bufferpool2",
],
compile_multilib: "both",
}
@@ -82,12 +85,13 @@
"libcutils",
"libfmq",
"liblog",
+ "libnativewindow",
"libutils",
- "android.hardware.media.bufferpool2-V1-ndk",
+ "android.hardware.media.bufferpool2-V2-ndk",
],
static_libs: [
"libaidlcommonsupport",
- "libstagefright_aidl_bufferpool2"
+ "libstagefright_aidl_bufferpool2",
],
compile_multilib: "both",
}
diff --git a/media/c2/aidl/Android.bp b/media/c2/aidl/Android.bp
index 3c0915d..2eaeb01 100644
--- a/media/c2/aidl/Android.bp
+++ b/media/c2/aidl/Android.bp
@@ -20,7 +20,10 @@
],
imports: [
"android.hardware.common-V2",
- "android.hardware.media.bufferpool2-V1",
+ "android.hardware.media.bufferpool2-V2",
+ ],
+ include_dirs: [
+ "frameworks/native/aidl/gui",
],
stability: "vintf",
backend: {
@@ -42,11 +45,8 @@
],
},
rust: {
- min_sdk_version: "31",
- enabled: true,
- additional_rustlibs: [
- "libnativewindow_rs",
- ],
+ // No users, and no rust implementation of android.os.Surface yet
+ enabled: false,
},
},
}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponent.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponent.aidl
index 7d58340..0a7e3c4 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponent.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponent.aidl
@@ -45,16 +45,24 @@
void reset();
void start();
void stop();
+ android.hardware.media.c2.IInputSurfaceConnection connectToInputSurface(in android.hardware.media.c2.IInputSurface inputSurface);
+ android.hardware.media.c2.IInputSink asInputSink();
parcelable BlockPool {
long blockPoolId;
android.hardware.media.c2.IConfigurable configurable;
}
- parcelable C2AidlGbAllocator {
- android.hardware.media.c2.IGraphicBufferAllocator igba;
+ parcelable GbAllocator {
ParcelFileDescriptor waitableFd;
+ android.hardware.media.c2.IGraphicBufferAllocator igba;
}
- union BlockPoolAllocator {
+ parcelable PooledGbAllocator {
+ ParcelFileDescriptor waitableFd;
+ long receiverId;
+ android.hardware.media.c2.IPooledGraphicBufferAllocator ipgba;
+ }
+ parcelable BlockPoolAllocator {
int allocatorId;
- android.hardware.media.c2.IComponent.C2AidlGbAllocator allocator;
+ @nullable android.hardware.media.c2.IComponent.GbAllocator gbAllocator;
+ @nullable android.hardware.media.c2.IComponent.PooledGbAllocator pooledGbAllocator;
}
}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentStore.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentStore.aidl
index d1b5915..d7a4706 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentStore.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentStore.aidl
@@ -41,6 +41,7 @@
android.hardware.media.bufferpool2.IClientManager getPoolClientManager();
android.hardware.media.c2.StructDescriptor[] getStructDescriptors(in int[] indices);
android.hardware.media.c2.IComponentStore.ComponentTraits[] listComponents();
+ android.hardware.media.c2.IInputSurface createInputSurface();
@VintfStability
parcelable ComponentTraits {
String name;
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IConfigurable.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IConfigurable.aidl
index 32f5abd..04e776e 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IConfigurable.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IConfigurable.aidl
@@ -37,12 +37,23 @@
android.hardware.media.c2.IConfigurable.ConfigResult config(in android.hardware.media.c2.Params inParams, in boolean mayBlock);
int getId();
String getName();
- android.hardware.media.c2.Params query(in int[] indices, in boolean mayBlock);
+ android.hardware.media.c2.IConfigurable.QueryResult query(in int[] indices, in boolean mayBlock);
android.hardware.media.c2.ParamDescriptor[] querySupportedParams(in int start, in int count);
- android.hardware.media.c2.FieldSupportedValuesQueryResult[] querySupportedValues(in android.hardware.media.c2.FieldSupportedValuesQuery[] inFields, in boolean mayBlock);
+ android.hardware.media.c2.IConfigurable.QuerySupportedValuesResult querySupportedValues(in android.hardware.media.c2.FieldSupportedValuesQuery[] inFields, in boolean mayBlock);
@VintfStability
parcelable ConfigResult {
android.hardware.media.c2.Params params;
android.hardware.media.c2.SettingResult[] failures;
+ android.hardware.media.c2.Status status;
+ }
+ @VintfStability
+ parcelable QueryResult {
+ android.hardware.media.c2.Params params;
+ android.hardware.media.c2.Status status;
+ }
+ @VintfStability
+ parcelable QuerySupportedValuesResult {
+ android.hardware.media.c2.FieldSupportedValuesQueryResult[] values;
+ android.hardware.media.c2.Status status;
}
}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IGraphicBufferAllocator.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IGraphicBufferAllocator.aidl
index 3e460dd..e13ba1f 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IGraphicBufferAllocator.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IGraphicBufferAllocator.aidl
@@ -39,7 +39,7 @@
ParcelFileDescriptor getWaitableFd();
parcelable Allocation {
android.hardware.HardwareBuffer buffer;
- ParcelFileDescriptor fence;
+ @nullable ParcelFileDescriptor fence;
}
parcelable Description {
int width;
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IInputSink.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IInputSink.aidl
new file mode 100644
index 0000000..e6ea4d5
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IInputSink.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.media.c2;
+@VintfStability
+interface IInputSink {
+ void queue(in android.hardware.media.c2.WorkBundle workBundle);
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IInputSurface.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IInputSurface.aidl
new file mode 100644
index 0000000..14455cb
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IInputSurface.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.media.c2;
+@VintfStability
+interface IInputSurface {
+ android.view.Surface getSurface();
+ android.hardware.media.c2.IConfigurable getConfigurable();
+ android.hardware.media.c2.IInputSurfaceConnection connect(in android.hardware.media.c2.IInputSink sink);
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IInputSurfaceConnection.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IInputSurfaceConnection.aidl
new file mode 100644
index 0000000..28fff65
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IInputSurfaceConnection.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.media.c2;
+@VintfStability
+interface IInputSurfaceConnection {
+ void disconnect();
+ void signalEndOfStream();
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IPooledGraphicBufferAllocator.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IPooledGraphicBufferAllocator.aidl
new file mode 100644
index 0000000..1a8c66d
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IPooledGraphicBufferAllocator.aidl
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.media.c2;
+@VintfStability
+interface IPooledGraphicBufferAllocator {
+ android.hardware.media.c2.IPooledGraphicBufferAllocator.Allocation allocate(in android.hardware.media.c2.IPooledGraphicBufferAllocator.Description desc);
+ boolean deallocate(in int id);
+ parcelable Allocation {
+ int bufferId;
+ @nullable ParcelFileDescriptor fence;
+ }
+ parcelable Description {
+ int widthPixels;
+ int heightPixels;
+ int format;
+ long usage;
+ }
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/IComponent.aidl b/media/c2/aidl/android/hardware/media/c2/IComponent.aidl
index fc923ab..387d70a 100644
--- a/media/c2/aidl/android/hardware/media/c2/IComponent.aidl
+++ b/media/c2/aidl/android/hardware/media/c2/IComponent.aidl
@@ -21,6 +21,10 @@
import android.hardware.media.c2.IComponentInterface;
import android.hardware.media.c2.IConfigurable;
import android.hardware.media.c2.IGraphicBufferAllocator;
+import android.hardware.media.c2.IInputSink;
+import android.hardware.media.c2.IInputSurface;
+import android.hardware.media.c2.IInputSurfaceConnection;
+import android.hardware.media.c2.IPooledGraphicBufferAllocator;
import android.hardware.media.c2.WorkBundle;
import android.os.ParcelFileDescriptor;
@@ -54,20 +58,36 @@
* graphic blocks. the waitable fd is used to create a specific type of
* C2Fence which can be used for waiting until to allocate is not blocked.
*/
- parcelable C2AidlGbAllocator {
- IGraphicBufferAllocator igba;
+ parcelable GbAllocator {
ParcelFileDescriptor waitableFd;
+ IGraphicBufferAllocator igba;
}
/**
+ * C2AIDL allocator interface based on media.bufferpool2 along with a waitable fd.
+ *
+ * The interface is used from a specific type of C2BlockPool to allocate
+ * graphic blocks. the waitable fd is used to create a specific type of
+ * C2Fence which can be used for waiting until to allocate is not blocked.
+ * receiverId is id of receiver IConnection of media.bufferpool2.
+ */
+ parcelable PooledGbAllocator {
+ ParcelFileDescriptor waitableFd;
+ long receiverId;
+ IPooledGraphicBufferAllocator ipgba;
+ }
+
+
+ /**
* Allocator for C2BlockPool.
*
* C2BlockPool will use a C2Allocator which is specified by an id.
- * or C2AIDL allocator interface directly.
+ * Based on allocator id, allocator is specified.
*/
- union BlockPoolAllocator {
+ parcelable BlockPoolAllocator {
int allocatorId;
- C2AidlGbAllocator allocator;
+ @nullable GbAllocator gbAllocator;
+ @nullable PooledGbAllocator pooledGbAllocator;
}
/**
@@ -308,4 +328,32 @@
* - `Status::CORRUPTED` - Some unknown error occurred.
*/
void stop();
+
+ /**
+ * Starts using an input surface.
+ *
+ * The component must be in running state.
+ *
+ * @param inputSurface Input surface to connect to.
+ * @return connection `IInputSurfaceConnection` object, which can be used to
+ * query and configure properties of the connection. This cannot be
+ * null.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::CANNOT_DO` - The component does not support an input surface.
+ * - `Status::BAD_STATE` - The component is not in running state.
+ * - `Status::DUPLICATE` - The component is already connected to an input surface.
+ * - `Status::REFUSED` - The input surface is already in use.
+ * - `Status::NO_MEMORY` - Not enough memory to start the component.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ IInputSurfaceConnection connectToInputSurface(in IInputSurface inputSurface);
+
+ /**
+ * Returns an @ref IInputSink instance that has the component as the
+ * underlying implementation.
+ *
+ * @return sink `IInputSink` instance.
+ */
+ IInputSink asInputSink();
}
diff --git a/media/c2/aidl/android/hardware/media/c2/IComponentStore.aidl b/media/c2/aidl/android/hardware/media/c2/IComponentStore.aidl
index 1435a7e..019405d 100644
--- a/media/c2/aidl/android/hardware/media/c2/IComponentStore.aidl
+++ b/media/c2/aidl/android/hardware/media/c2/IComponentStore.aidl
@@ -21,6 +21,7 @@
import android.hardware.media.c2.IComponentInterface;
import android.hardware.media.c2.IComponentListener;
import android.hardware.media.c2.IConfigurable;
+import android.hardware.media.c2.IInputSurface;
import android.hardware.media.c2.StructDescriptor;
/**
@@ -182,4 +183,16 @@
* - `Status::CORRUPTED` - Some unknown error occurred.
*/
ComponentTraits[] listComponents();
+
+ /**
+ * Creates a persistent input surface that can be used as an input surface
+ * for any IComponent instance
+ *
+ * @return IInputSurface A persistent input surface.
+ * @throws ServiceSpecificException with one of following values:
+ * - `Status::NO_MEMORY` - Not enough memory to complete this method.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ IInputSurface createInputSurface();
}
diff --git a/media/c2/aidl/android/hardware/media/c2/IConfigurable.aidl b/media/c2/aidl/android/hardware/media/c2/IConfigurable.aidl
index 7fdb825..1481c15 100644
--- a/media/c2/aidl/android/hardware/media/c2/IConfigurable.aidl
+++ b/media/c2/aidl/android/hardware/media/c2/IConfigurable.aidl
@@ -21,6 +21,7 @@
import android.hardware.media.c2.ParamDescriptor;
import android.hardware.media.c2.Params;
import android.hardware.media.c2.SettingResult;
+import android.hardware.media.c2.Status;
/**
* Generic configuration interface presented by all configurable Codec2 objects.
@@ -34,12 +35,42 @@
* Return parcelable for config() interface.
*
* This includes the successful config settings along with the failure reasons of
- * the specified setting.
+ * the specified setting. @p status is for the compatibility with HIDL interface.
+ * (The value is defined in Status.aidl, and possible values are enumerated
+ * in config() interface definition)
*/
@VintfStability
parcelable ConfigResult {
Params params;
SettingResult[] failures;
+ Status status;
+ }
+
+ /**
+ * Return parcelable for query() interface.
+ *
+ * @p params is the parameter descripion for queried configuration indices.
+ * @p status is for the compatibility with HIDL interface. (The value is defined in
+ * Status.aidl, and possible values are enumerated in query() interface definition)
+ */
+ @VintfStability
+ parcelable QueryResult {
+ Params params;
+ Status status;
+ }
+
+ /**
+ * Return parcelable for querySupportedValues() interface.
+ *
+ * @p values is the value descripion for queried configuration fields.
+ * @p status is for the compatibility with HIDL interface. (The value is defined in
+ * Status.aidl, and possible values are enumerated in querySupportedValues()
+ * interface definition)
+ */
+ @VintfStability
+ parcelable QuerySupportedValuesResult {
+ FieldSupportedValuesQueryResult[] values;
+ Status status;
}
/**
@@ -82,7 +113,8 @@
* @param mayBlock Whether this call may block or not.
* @return result of config. Params in the result should be in same order
* with @p inParams.
- * @throws ServiceSpecificException with one of the following values:
+ *
+ * Returned @p status will be one of the following.
* - `Status::NO_MEMORY` - Some supported parameters could not be updated
* successfully because they contained unsupported values.
* These are returned in @p failures.
@@ -146,17 +178,22 @@
*
* @param indices List of C2Param structure indices to query.
* @param mayBlock Whether this call may block or not.
- * @return Flattened representation of std::vector<C2Param> object.
- * Unsupported settings are skipped in the results. The order in @p indices
- * still be preserved except skipped settings.
- * @throws ServiceSpecificException with one of the following values:
+ * @return @p params is the flattened representation of std::vector<C2Param> object.
+ * Technically unsupported settings can be either skipped or invalidated.
+ * (Invalidated params will be skipped during unflattening to make these identical.)
+ * In the future we will want these to be invalidated to make it easier
+ * for the framework code.
+ *
+ * The order in @p indices still be preserved except skipped settings.
+ *
+ * Returned @p status will be one of the following.
* - `Status::NO_MEMORY` - Could not allocate memory for a supported parameter.
* - `Status::BLOCKING` - Querying some parameters requires blocking, but
* @p mayBlock is false.
* - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
* - `Status::CORRUPTED` - Some unknown error occurred.
*/
- Params query(in int[] indices, in boolean mayBlock);
+ QueryResult query(in int[] indices, in boolean mayBlock);
/**
* Returns a list of supported parameters within a selected range of C2Param
@@ -197,9 +234,10 @@
*
* @param inFields List of field queries.
* @param mayBlock Whether this call may block or not.
- * @return List of supported values and results for the
+ * @return @p values is the list of supported values and results for the
* supplied queries.
- * @throws ServiceSpecificException with one of the following values:
+ *
+ * Returned @p status will be one of the following.
* - `Status::BLOCKING` - Querying some parameters requires blocking, but
* @p mayBlock is false.
* - `Status::NO_MEMORY` - Not enough memory to complete this method.
@@ -208,6 +246,6 @@
* - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
* - `Status::CORRUPTED` - Some unknown error occurred.
*/
- FieldSupportedValuesQueryResult[] querySupportedValues(
+ QuerySupportedValuesResult querySupportedValues(
in FieldSupportedValuesQuery[] inFields, in boolean mayBlock);
}
diff --git a/media/c2/aidl/android/hardware/media/c2/IGraphicBufferAllocator.aidl b/media/c2/aidl/android/hardware/media/c2/IGraphicBufferAllocator.aidl
index 49c4ea4..1710242 100644
--- a/media/c2/aidl/android/hardware/media/c2/IGraphicBufferAllocator.aidl
+++ b/media/c2/aidl/android/hardware/media/c2/IGraphicBufferAllocator.aidl
@@ -35,7 +35,7 @@
*/
parcelable Allocation {
HardwareBuffer buffer;
- ParcelFileDescriptor fence;
+ @nullable ParcelFileDescriptor fence;
}
/**
diff --git a/media/c2/aidl/android/hardware/media/c2/IInputSink.aidl b/media/c2/aidl/android/hardware/media/c2/IInputSink.aidl
new file mode 100644
index 0000000..eb8ad3d
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/IInputSink.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.WorkBundle;
+
+/**
+ * An `IInputSink` is a receiver of work items.
+ *
+ * An @ref IComponent instance can present itself as an `IInputSink` via a thin
+ * wrapper.
+ *
+ * @sa IInputSurface, IComponent.
+ */
+@VintfStability
+interface IInputSink {
+ /**
+ * Feeds work to the sink.
+ *
+ * @param workBundle `WorkBundle` object containing a list of `Work` objects
+ * to queue to the component.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::BAD_INDEX` - Some component id in some `Worklet` is not valid.
+ * - `Status::CANNOT_DO` - Tunneling has not been set up for this sink, but some
+ * `Work` object contains tunneling information.
+ * - `Status::NO_MEMORY` - Not enough memory to queue @p workBundle.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ void queue(in WorkBundle workBundle);
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/IInputSurface.aidl b/media/c2/aidl/android/hardware/media/c2/IInputSurface.aidl
new file mode 100644
index 0000000..77cb1fd
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/IInputSurface.aidl
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.IConfigurable;
+import android.hardware.media.c2.IInputSink;
+import android.hardware.media.c2.IInputSurfaceConnection;
+import android.view.Surface;
+
+/**
+ * Input surface for a Codec2 component.
+ *
+ * An <em>input surface</em> is an instance of `IInputSurface`, which may be
+ * created by calling IComponentStore::createInputSurface(). Once created, the
+ * client may
+ * 1. write data to it via the `NativeWindow` interface; and
+ * 2. use it as input to a Codec2 encoder.
+ *
+ * @sa IInputSurfaceConnection, IComponentStore::createInputSurface(),
+ * IComponent::connectToInputSurface().
+ */
+@VintfStability
+interface IInputSurface {
+ /**
+ * Returns the producer interface into the internal buffer queue.
+ *
+ * @return producer `Surface` instance(actually ANativeWindow). This must not
+ * be null.
+ */
+ Surface getSurface();
+
+ /**
+ * Returns the @ref IConfigurable instance associated to this input surface.
+ *
+ * @return configurable `IConfigurable` instance. This must not be null.
+ */
+ IConfigurable getConfigurable();
+
+ /**
+ * Connects the input surface to an input sink.
+ *
+ * This function is generally called from inside the implementation of
+ * IComponent::connectToInputSurface(), where @p sink is a thin wrapper of
+ * the component that consumes buffers from this surface.
+ *
+ * @param sink Input sink. See `IInputSink` for more information.
+ * @return connection `IInputSurfaceConnection` object. This must not be
+ * null if @p status is `OK`.
+ * @throws ServiceSpecificException with one of following values:
+ * - `Status::BAD_VALUE` - @p sink is invalid.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ IInputSurfaceConnection connect(in IInputSink sink);
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/IInputSurfaceConnection.aidl b/media/c2/aidl/android/hardware/media/c2/IInputSurfaceConnection.aidl
new file mode 100644
index 0000000..36524eb
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/IInputSurfaceConnection.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+/**
+ * Connection between an IInputSink and an IInpuSurface.
+ */
+@VintfStability
+interface IInputSurfaceConnection {
+ /**
+ * Destroys the connection between an input surface and a component.
+ *
+ * @throws ServiceSpecificException with one of following values:
+ * - `Status::BAD_STATE` - The component is not in running state.
+ * - `Status::NOT_FOUND` - The surface is not connected to a component.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ void disconnect();
+
+ /**
+ * Signal the end of stream.
+
+ * @throws ServiceSpecificException with one of following values:
+ * - `Status::BAD_STATE` - The component is not in running state.
+ */
+ void signalEndOfStream();
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/IPooledGraphicBufferAllocator.aidl b/media/c2/aidl/android/hardware/media/c2/IPooledGraphicBufferAllocator.aidl
new file mode 100644
index 0000000..b599d52
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/IPooledGraphicBufferAllocator.aidl
@@ -0,0 +1,77 @@
+/*
+ * 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.hardware.media.c2;
+
+import android.os.ParcelFileDescriptor;
+
+/**
+ * Interface for decoder output buffer allocator for HAL process
+ *
+ * A graphic buffer for decoder output is allocated by the interface.
+ */
+@VintfStability
+interface IPooledGraphicBufferAllocator {
+ /**
+ * A graphic buffer allocation.
+ *
+ * bufferId is id of buffer from a media.bufferpool2. The buffer is
+ * android.hardware.HardwareBuffer.
+ * fence is provided in order to signal readiness of the buffer I/O inside
+ * underlying Graphics subsystem. This is called a sync fence throughout Android framework.
+ */
+ parcelable Allocation {
+ int bufferId;
+ @nullable ParcelFileDescriptor fence;
+ }
+
+ /**
+ * Parameters for a graphic buffer allocation.
+ *
+ * Refer to AHardwareBuffer_Desc(libnativewindow) for details.
+ */
+ parcelable Description {
+ int widthPixels;
+ int heightPixels;
+ int format; // AHardwareBuffer_Format
+ long usage; // AHardwareBuffer_UsageFlags
+ }
+
+ /**
+ * Allocate a graphic buffer.
+ * deallocate() must be called after the allocated buffer is no longer needed.
+ *
+ * @param desc Allocation parameters.
+ * @return an id of a buffer, the id is created from media.bufferpool2 in order for
+ * caching and recycling,
+ * If underlying allocator is blocked, c2::Status::Blocked will be returned.
+ * Waitable fd must be obtained using the ndk object locally. The waitable fd must
+ * be passed to the receiver during BlockPool creation request via AIDL.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `c2::Status::BAD_STATE` - The client is not in running states.
+ * - `c2::Status::BLOCKED` - Underlying graphics system is blocked.
+ * - `c2::Status::CORRUPTED` - Some unknown error occurred.
+ */
+ Allocation allocate(in Description desc);
+
+ /**
+ * De-allocate a graphic buffer by graphic buffer's unique id.
+ *
+ * @param id buffer id.
+ * @return {@code true} when de-allocate happened, {@code false} otherwise.
+ */
+ boolean deallocate(in int id);
+}
diff --git a/media/omx/1.0/vts/functional/audio/Android.bp b/media/omx/1.0/vts/functional/audio/Android.bp
index a2733c9..1be82f8 100644
--- a/media/omx/1.0/vts/functional/audio/Android.bp
+++ b/media/omx/1.0/vts/functional/audio/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_media_codec_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/media/omx/1.0/vts/functional/common/Android.bp b/media/omx/1.0/vts/functional/common/Android.bp
index 12b6fb2..7c23d61 100644
--- a/media/omx/1.0/vts/functional/common/Android.bp
+++ b/media/omx/1.0/vts/functional/common/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_media_codec_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/media/omx/1.0/vts/functional/component/Android.bp b/media/omx/1.0/vts/functional/component/Android.bp
index 7b8ec9d..fddbb8e 100644
--- a/media/omx/1.0/vts/functional/component/Android.bp
+++ b/media/omx/1.0/vts/functional/component/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_media_codec_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/media/omx/1.0/vts/functional/store/Android.bp b/media/omx/1.0/vts/functional/store/Android.bp
index b34fff1..ebe4293 100644
--- a/media/omx/1.0/vts/functional/store/Android.bp
+++ b/media/omx/1.0/vts/functional/store/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_media_codec_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/media/omx/1.0/vts/functional/video/Android.bp b/media/omx/1.0/vts/functional/video/Android.bp
index 5454f16..0eac78e 100644
--- a/media/omx/1.0/vts/functional/video/Android.bp
+++ b/media/omx/1.0/vts/functional/video/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_media_codec_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
index f24c6d1..9a75e6e 100644
--- a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
+++ b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
@@ -630,10 +630,7 @@
if (error != android::NO_ERROR) return 1;
} else {
void* data;
- int32_t outBytesPerPixel;
- int32_t outBytesPerStride;
- error = gbmapper.lock(buff, buffer->omxBuffer.attr.anwBuffer.usage, rect, &data,
- &outBytesPerPixel, &outBytesPerStride);
+ error = gbmapper.lock(buff, buffer->omxBuffer.attr.anwBuffer.usage, rect, &data);
EXPECT_EQ(error, android::NO_ERROR);
if (error != android::NO_ERROR) return 1;
diff --git a/neuralnetworks/aidl/utils/src/Conversions.cpp b/neuralnetworks/aidl/utils/src/Conversions.cpp
index 47c72b4..9f920bb 100644
--- a/neuralnetworks/aidl/utils/src/Conversions.cpp
+++ b/neuralnetworks/aidl/utils/src/Conversions.cpp
@@ -421,7 +421,7 @@
return createSharedMemoryFromAHWB(ahwb, /*takeOwnership=*/true);
#else // __ANDROID__
- LOG(FATAL) << "GeneralResult<SharedMemory> unvalidatedConvert(const aidl_hal::Memory& "
+ LOG(ERROR) << "GeneralResult<SharedMemory> unvalidatedConvert(const aidl_hal::Memory& "
"memory): Not Available on Host Build";
return NN_ERROR() << "createFromHandle failed";
#endif // __ANDROID__
@@ -732,7 +732,7 @@
};
return Memory::make<Memory::Tag::hardwareBuffer>(std::move(hardwareBuffer));
#else // __ANDROID__
- LOG(FATAL) << "nn::GeneralResult<Memory> unvalidatedConvert(const nn::Memory::HardwareBuffer& "
+ LOG(ERROR) << "nn::GeneralResult<Memory> unvalidatedConvert(const nn::Memory::HardwareBuffer& "
"memory): Not Available on Host Build";
(void)memory;
return (NN_ERROR() << "unvalidatedConvert failed").operator nn::GeneralResult<Memory>();
diff --git a/nfc/1.0/vts/functional/Android.bp b/nfc/1.0/vts/functional/Android.bp
index 0d3f0c9..2e9a6fa 100644
--- a/nfc/1.0/vts/functional/Android.bp
+++ b/nfc/1.0/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_nfc",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -30,5 +31,8 @@
static_libs: [
"android.hardware.nfc@1.0",
],
- test_suites: ["general-tests", "vts"],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
}
diff --git a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
index 4d997e6..8210ff0 100644
--- a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
+++ b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
@@ -296,12 +296,6 @@
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
EXPECT_TRUE(res.no_timeout);
EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
- if (nci_version == NCI_VERSION_2 && res.args->last_data_.size() > 13 &&
- res.args->last_data_[13] == 0x00) {
- // Wait for CORE_CONN_CREDITS_NTF
- res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
- }
// Send an Error Data Packet
cmd = INVALID_COMMAND;
data = cmd;
@@ -360,13 +354,6 @@
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
EXPECT_TRUE(res.no_timeout);
EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
- if (nci_version == NCI_VERSION_2 && res.args->last_data_.size() > 13 &&
- res.args->last_data_[13] == 0x00) {
- // Wait for CORE_CONN_CREDITS_NTF
- res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
- }
-
cmd = CORE_CONN_CREATE_CMD;
data = cmd;
EXPECT_EQ(data.size(), nfc_->write(data));
diff --git a/nfc/1.1/vts/functional/Android.bp b/nfc/1.1/vts/functional/Android.bp
index 4439531..cffe84a 100644
--- a/nfc/1.1/vts/functional/Android.bp
+++ b/nfc/1.1/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_nfc",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -31,5 +32,8 @@
"android.hardware.nfc@1.0",
"android.hardware.nfc@1.1",
],
- test_suites: ["general-tests", "vts"],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
}
diff --git a/nfc/1.2/vts/functional/Android.bp b/nfc/1.2/vts/functional/Android.bp
index ff7bd3a..394dc26 100644
--- a/nfc/1.2/vts/functional/Android.bp
+++ b/nfc/1.2/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_nfc",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -32,5 +33,8 @@
"android.hardware.nfc@1.1",
"android.hardware.nfc@1.2",
],
- test_suites: ["general-tests", "vts"],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
}
diff --git a/nfc/aidl/Android.bp b/nfc/aidl/Android.bp
index dae9f29..ae68f17 100644
--- a/nfc/aidl/Android.bp
+++ b/nfc/aidl/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_fwk_nfc",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -34,7 +35,7 @@
sdk_version: "module_current",
enabled: false,
},
- ndk: {
+ ndk: {
enabled: true,
apex_available: [
"//apex_available:platform",
diff --git a/nfc/aidl/default/Android.bp b/nfc/aidl/default/Android.bp
index 6daebe5..0cda51d 100644
--- a/nfc/aidl/default/Android.bp
+++ b/nfc/aidl/default/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_fwk_nfc",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/nfc/aidl/vts/functional/Android.bp b/nfc/aidl/vts/functional/Android.bp
index 99eecd0..0dab2d8 100644
--- a/nfc/aidl/vts/functional/Android.bp
+++ b/nfc/aidl/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_nfc",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/power/aidl/Android.bp b/power/aidl/Android.bp
index 7643926..8900fb8 100644
--- a/power/aidl/Android.bp
+++ b/power/aidl/Android.bp
@@ -28,11 +28,20 @@
"android/hardware/power/*.aidl",
],
stability: "vintf",
+ imports: [
+ "android.hardware.common.fmq-V1",
+ "android.hardware.common-V2",
+ ],
backend: {
cpp: {
+ enabled: false,
+ },
+ ndk: {
enabled: true,
},
java: {
+ sdk_version: "module_current",
+ enabled: true,
platform_apis: true,
},
},
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/ChannelConfig.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/ChannelConfig.aidl
new file mode 100644
index 0000000..d3caca4
--- /dev/null
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/ChannelConfig.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.power;
+@VintfStability
+parcelable ChannelConfig {
+ android.hardware.common.fmq.MQDescriptor<android.hardware.power.ChannelMessage,android.hardware.common.fmq.SynchronizedReadWrite> channelDescriptor;
+ @nullable android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> eventFlagDescriptor;
+ int readFlagBitmask;
+ int writeFlagBitmask;
+}
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/ChannelMessage.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/ChannelMessage.aidl
new file mode 100644
index 0000000..ab38fcc
--- /dev/null
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/ChannelMessage.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.power;
+@FixedSize @VintfStability
+parcelable ChannelMessage {
+ int sessionID;
+ long timeStampNanos;
+ android.hardware.power.ChannelMessage.ChannelMessageContents data;
+ @FixedSize @VintfStability
+ union ChannelMessageContents {
+ long[16] reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ long targetDuration;
+ android.hardware.power.SessionHint hint;
+ android.hardware.power.ChannelMessage.ChannelMessageContents.SessionModeSetter mode;
+ android.hardware.power.WorkDurationFixedV1 workDuration;
+ @FixedSize @VintfStability
+ parcelable SessionModeSetter {
+ android.hardware.power.SessionMode modeInt;
+ boolean enabled;
+ }
+ }
+}
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl
index ae03313..8acdaf2 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl
@@ -40,4 +40,7 @@
boolean isBoostSupported(in android.hardware.power.Boost type);
android.hardware.power.IPowerHintSession createHintSession(in int tgid, in int uid, in int[] threadIds, in long durationNanos);
long getHintSessionPreferredRate();
+ android.hardware.power.IPowerHintSession createHintSessionWithConfig(in int tgid, in int uid, in int[] threadIds, in long durationNanos, in android.hardware.power.SessionTag tag, out android.hardware.power.SessionConfig config);
+ android.hardware.power.ChannelConfig getSessionChannel(in int tgid, in int uid);
+ oneway void closeSessionChannel(in int tgid, in int uid);
}
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl
index 6bc663e..010f815 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl
@@ -42,4 +42,5 @@
oneway void sendHint(android.hardware.power.SessionHint hint);
void setThreads(in int[] threadIds);
oneway void setMode(android.hardware.power.SessionMode type, boolean enabled);
+ android.hardware.power.SessionConfig getSessionConfig();
}
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Mode.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Mode.aidl
index b8a0710..46eca69 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Mode.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Mode.aidl
@@ -52,4 +52,5 @@
GAME,
GAME_LOADING,
DISPLAY_CHANGE,
+ AUTOMOTIVE_PROJECTION,
}
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionConfig.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionConfig.aidl
new file mode 100644
index 0000000..b03cfb2
--- /dev/null
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionConfig.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.power;
+@VintfStability
+parcelable SessionConfig {
+ long id;
+}
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionHint.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionHint.aidl
index 9c1f381..df31618 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionHint.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionHint.aidl
@@ -39,4 +39,7 @@
CPU_LOAD_RESET = 2,
CPU_LOAD_RESUME = 3,
POWER_EFFICIENCY = 4,
+ GPU_LOAD_UP = 5,
+ GPU_LOAD_DOWN = 6,
+ GPU_LOAD_RESET = 7,
}
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionTag.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionTag.aidl
new file mode 100644
index 0000000..862fbc5
--- /dev/null
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionTag.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.power;
+@Backing(type="int") @VintfStability
+enum SessionTag {
+ OTHER,
+ SURFACEFLINGER,
+ HWUI,
+ GAME,
+ APP,
+}
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDurationFixedV1.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDurationFixedV1.aidl
new file mode 100644
index 0000000..45310b8
--- /dev/null
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDurationFixedV1.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.power;
+@FixedSize @VintfStability
+parcelable WorkDurationFixedV1 {
+ long durationNanos;
+ long workPeriodStartTimestampNanos;
+ long cpuDurationNanos;
+ long gpuDurationNanos;
+}
diff --git a/power/aidl/android/hardware/power/ChannelConfig.aidl b/power/aidl/android/hardware/power/ChannelConfig.aidl
new file mode 100644
index 0000000..4da292e
--- /dev/null
+++ b/power/aidl/android/hardware/power/ChannelConfig.aidl
@@ -0,0 +1,52 @@
+
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.power;
+
+import android.hardware.common.fmq.MQDescriptor;
+import android.hardware.common.fmq.SynchronizedReadWrite;
+import android.hardware.power.ChannelMessage;
+
+@VintfStability
+parcelable ChannelConfig {
+ /**
+ * The message queue descriptor that provides the information necessary for
+ * a client to write to this channel.
+ */
+ MQDescriptor<ChannelMessage, SynchronizedReadWrite> channelDescriptor;
+
+ /**
+ * A message queue descriptor used to pass an optional event flag to clients,
+ * used to synchronize multiple message queues using the same flag. If not
+ * defined, the flag from the channelDescriptor should be used.
+ */
+ @nullable MQDescriptor<byte, SynchronizedReadWrite> eventFlagDescriptor;
+
+ /**
+ * The read flag bitmask to be used with the event flag, specifying the
+ * bits used by this channel to mark that the buffer has been read from.
+ * If set to 0, the default bitmask will be used.
+ */
+ int readFlagBitmask;
+
+ /**
+ * The write flag bitmask to be used with the event flag, specifying the
+ * bits used by this channel to mark that the buffer has been written to.
+ * If set to 0, the default bitmask will be used.
+ */
+ int writeFlagBitmask;
+}
diff --git a/power/aidl/android/hardware/power/ChannelMessage.aidl b/power/aidl/android/hardware/power/ChannelMessage.aidl
new file mode 100644
index 0000000..fa16911
--- /dev/null
+++ b/power/aidl/android/hardware/power/ChannelMessage.aidl
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.power;
+
+import android.hardware.power.SessionHint;
+import android.hardware.power.SessionMode;
+import android.hardware.power.WorkDurationFixedV1;
+
+/**
+ * Data sent through the FMQ must follow this structure. It's important to note
+ * that such data may come from the app itself, so the HAL must validate all
+ * data received through this interface, and reject any calls not guaranteed to be
+ * valid. Each of the types defined in the inner union maps to an equivalent call
+ * on IPowerHintSession, and is merely being used to expedite the use of that API
+ * in cases where it is safe to bypass the HintManagerService.
+ */
+@FixedSize
+@VintfStability
+parcelable ChannelMessage {
+ /**
+ * The ID of the specific session sending the hint, used to enable a single
+ * channel to be multiplexed across all sessions in a single process.
+ */
+ int sessionID;
+
+ /**
+ * Timestamp in nanoseconds based on CLOCK_MONOTONIC when the message was sent,
+ * used to ensure all messages can be processed in a coherent order.
+ */
+ long timeStampNanos;
+
+ /**
+ * A union defining the different messages that can be passed through the
+ * channel. Each type corresponds to a different call in IPowerHintSession.
+ */
+ ChannelMessageContents data;
+
+ @FixedSize
+ @VintfStability
+ union ChannelMessageContents {
+ /**
+ * Reserves the maximum fixed size for the ChannelMessage.
+ */
+ long[16] reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+ /**
+ * Setting this field will update the session’s target duration, equivalent
+ * to calling updateTargetWorkDuration(targetDuration).
+ */
+ long targetDuration;
+
+ /**
+ * Setting this field will send a hint to the session, equivalent to
+ * calling sendHint(hint).
+ */
+ SessionHint hint;
+
+ /**
+ * Setting this field will send a hint to the session, equivalent to
+ * calling setMode(mode.modeInt, mode.enabled).
+ */
+ SessionModeSetter mode;
+
+ /**
+ * Setting this field will update the session’s actual duration, equivalent
+ * to calling reportActualWorkDuration([workDuration]). Only one duration
+ * can be passed at a time; this API expects durations to be reported
+ * immediately each frame, since the overhead of this call is much lower.
+ */
+ WorkDurationFixedV1 workDuration;
+
+ /**
+ * This structure is used to fit both the mode and the state within one
+ * entry in the union.
+ */
+ @FixedSize
+ @VintfStability
+ parcelable SessionModeSetter {
+ SessionMode modeInt;
+ boolean enabled;
+ }
+ }
+}
diff --git a/power/aidl/android/hardware/power/IPower.aidl b/power/aidl/android/hardware/power/IPower.aidl
index ee8e5a3..e25714f 100644
--- a/power/aidl/android/hardware/power/IPower.aidl
+++ b/power/aidl/android/hardware/power/IPower.aidl
@@ -17,8 +17,11 @@
package android.hardware.power;
import android.hardware.power.Boost;
+import android.hardware.power.ChannelConfig;
import android.hardware.power.IPowerHintSession;
import android.hardware.power.Mode;
+import android.hardware.power.SessionConfig;
+import android.hardware.power.SessionTag;
@VintfStability
interface IPower {
@@ -103,4 +106,42 @@
* EX_UNSUPPORTED_OPERATION if hint session is not supported.
*/
long getHintSessionPreferredRate();
+
+ /**
+ * A version of createHintSession that returns an additional bundle of session
+ * data, useful to help the session immediately communicate via an FMQ channel
+ * for more efficient updates.
+ *
+ * @return the new session if it is supported on this device, otherwise return
+ * with EX_UNSUPPORTED_OPERATION error if hint session is not
+ * supported on this device.
+ * @param tgid The TGID to be associated with this session.
+ * @param uid The UID to be associated with this session.
+ * @param threadIds The list of threads to be associated with this session.
+ * @param durationNanos The desired duration in nanoseconds for this session.
+ * @param config Extra session metadata to be returned to the caller.
+ */
+ IPowerHintSession createHintSessionWithConfig(in int tgid, in int uid, in int[] threadIds,
+ in long durationNanos, in SessionTag tag, out SessionConfig config);
+
+ /**
+ * Used to get an FMQ channel, per-process. The channel should be unique to
+ * that process, and should return the same ChannelConfig if called multiple
+ * times from that same process.
+ *
+ * @return the channel config if hint sessions are supported on this device,
+ * otherwise return with EX_UNSUPPORTED_OPERATION.
+ * @param tgid The TGID to be associated with this channel.
+ * @param uid The UID to be associated with this channel.
+ */
+ ChannelConfig getSessionChannel(in int tgid, in int uid);
+
+ /**
+ * Used to close a channel once it is no longer needed by a process, or that
+ * process dies.
+ *
+ * @param tgid The TGID to be associated with this channel.
+ * @param uid The UID to be associated with this channel.
+ */
+ oneway void closeSessionChannel(in int tgid, in int uid);
}
diff --git a/power/aidl/android/hardware/power/IPowerHintSession.aidl b/power/aidl/android/hardware/power/IPowerHintSession.aidl
index 62263c8..9dd251f 100644
--- a/power/aidl/android/hardware/power/IPowerHintSession.aidl
+++ b/power/aidl/android/hardware/power/IPowerHintSession.aidl
@@ -16,6 +16,7 @@
package android.hardware.power;
+import android.hardware.power.SessionConfig;
import android.hardware.power.SessionHint;
import android.hardware.power.SessionMode;
import android.hardware.power.WorkDuration;
@@ -91,4 +92,11 @@
* @param enabled True to enable the mode, false to disable it
*/
oneway void setMode(SessionMode type, boolean enabled);
+
+ /**
+ * This method provides direct access to a session's config data.
+ *
+ * @return the config data for this session
+ */
+ SessionConfig getSessionConfig();
}
diff --git a/power/aidl/android/hardware/power/Mode.aidl b/power/aidl/android/hardware/power/Mode.aidl
index 78f0363..a8fba72 100644
--- a/power/aidl/android/hardware/power/Mode.aidl
+++ b/power/aidl/android/hardware/power/Mode.aidl
@@ -173,4 +173,10 @@
* or switching between inner and outer panels.
*/
DISPLAY_CHANGE,
+
+ /**
+ * This mode indicates that the device is rendering to a remote display in
+ * a vehicle (such as Android Auto projection screen).
+ */
+ AUTOMOTIVE_PROJECTION,
}
diff --git a/power/aidl/android/hardware/power/SessionConfig.aidl b/power/aidl/android/hardware/power/SessionConfig.aidl
new file mode 100644
index 0000000..93dc9a2
--- /dev/null
+++ b/power/aidl/android/hardware/power/SessionConfig.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.power;
+
+/**
+ * Additional session to be passed to the hint session during creation, or acquired
+ * after creation from the session directly.
+ */
+@VintfStability
+parcelable SessionConfig {
+ /**
+ * The session's unique ID, used to identify the session for debugging and
+ * for multiplexing on the per-process FMQ channel.
+ */
+ long id;
+}
diff --git a/power/aidl/android/hardware/power/SessionHint.aidl b/power/aidl/android/hardware/power/SessionHint.aidl
index a172e12..1a8c505 100644
--- a/power/aidl/android/hardware/power/SessionHint.aidl
+++ b/power/aidl/android/hardware/power/SessionHint.aidl
@@ -52,4 +52,24 @@
* power hint session is noncritical despite its CPU intensity.
*/
POWER_EFFICIENCY = 4,
+
+ /**
+ * This hint indicates an increase in GPU workload intensity. It means that
+ * this hint session needs extra GPU resources to meet the target duration.
+ * This hint must be sent before reporting the actual duration to the session.
+ */
+ GPU_LOAD_UP = 5,
+
+ /**
+ * This hint indicates a decrease in GPU workload intensity. It means that
+ * this hint session can reduce GPU resources and still meet the target duration.
+ */
+ GPU_LOAD_DOWN = 6,
+
+ /**
+ * This hint indicates an upcoming GPU workload that is completely changed and
+ * unknown. It means that the hint session should reset GPU resources to a known
+ * baseline to prepare for an arbitrary load, and must wake up if inactive.
+ */
+ GPU_LOAD_RESET = 7,
}
diff --git a/power/aidl/android/hardware/power/SessionTag.aidl b/power/aidl/android/hardware/power/SessionTag.aidl
new file mode 100644
index 0000000..27bf3e3
--- /dev/null
+++ b/power/aidl/android/hardware/power/SessionTag.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.power;
+
+@VintfStability
+@Backing(type="int")
+enum SessionTag {
+ /**
+ * This tag is used to mark uncategorized hint sessions.
+ */
+ OTHER,
+
+ /**
+ * This tag is used to mark the SurfaceFlinger hint session.
+ */
+ SURFACEFLINGER,
+
+ /**
+ * This tag is used to mark hint sessions created by HWUI.
+ */
+ HWUI,
+
+ /**
+ * This tag is used to mark hint sessions created by applications that are
+ * categorized as games.
+ */
+ GAME,
+
+ /**
+ * This tag is used to mark the hint session is created by the application.
+ * If an applications is categorized as game, then GAME should be used
+ * instead.
+ */
+ APP,
+}
diff --git a/power/aidl/android/hardware/power/WorkDurationFixedV1.aidl b/power/aidl/android/hardware/power/WorkDurationFixedV1.aidl
new file mode 100644
index 0000000..ef5c755
--- /dev/null
+++ b/power/aidl/android/hardware/power/WorkDurationFixedV1.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.power;
+
+@FixedSize
+@VintfStability
+parcelable WorkDurationFixedV1 {
+ /**
+ * Total work duration in nanoseconds.
+ */
+ long durationNanos;
+
+ /**
+ * Timestamp in nanoseconds based on CLOCK_MONOTONIC when the work starts.
+ * The work period start timestamp could be zero if the call is from
+ * the legacy SDK/NDK reportActualWorkDuration API.
+ */
+ long workPeriodStartTimestampNanos;
+
+ /**
+ * CPU work duration in nanoseconds.
+ * The CPU work duration could be the same as the total work duration if
+ * the call is from the legacy SDK/NDK reportActualWorkDuration API.
+ */
+ long cpuDurationNanos;
+
+ /**
+ * GPU work duration in nanoseconds.
+ * The GPU work duration could be zero if the call is from the legacy
+ * SDK/NDK reportActualWorkDuration API.
+ */
+ long gpuDurationNanos;
+}
diff --git a/power/aidl/default/Android.bp b/power/aidl/default/Android.bp
index e3af179..b4ccc7d 100644
--- a/power/aidl/default/Android.bp
+++ b/power/aidl/default/Android.bp
@@ -29,8 +29,12 @@
vintf_fragments: [":android.hardware.power.xml"],
vendor: true,
shared_libs: [
+ "android.hardware.common-V2-ndk",
+ "android.hardware.common.fmq-V1-ndk",
"libbase",
"libbinder_ndk",
+ "libcutils",
+ "libfmq",
],
srcs: [
"main.cpp",
diff --git a/power/aidl/default/Power.cpp b/power/aidl/default/Power.cpp
index 8fe370c..8f15663 100644
--- a/power/aidl/default/Power.cpp
+++ b/power/aidl/default/Power.cpp
@@ -18,6 +18,8 @@
#include "PowerHintSession.h"
#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <fmq/EventFlag.h>
namespace aidl {
namespace android {
@@ -27,6 +29,10 @@
namespace example {
using namespace std::chrono_literals;
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::aidl::android::hardware::power::ChannelMessage;
+using ::android::AidlMessageQueue;
using ndk::ScopedAStatus;
@@ -70,6 +76,27 @@
return ScopedAStatus::ok();
}
+ndk::ScopedAStatus Power::createHintSessionWithConfig(
+ int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds, int64_t durationNanos,
+ SessionTag, SessionConfig* config, std::shared_ptr<IPowerHintSession>* _aidl_return) {
+ auto out = createHintSession(tgid, uid, threadIds, durationNanos, _aidl_return);
+ static_cast<PowerHintSession*>(_aidl_return->get())->getSessionConfig(config);
+ return out;
+}
+
+ndk::ScopedAStatus Power::getSessionChannel(int32_t, int32_t, ChannelConfig* _aidl_return) {
+ static AidlMessageQueue<ChannelMessage, SynchronizedReadWrite> stubQueue{1, true};
+ _aidl_return->channelDescriptor = stubQueue.dupeDesc();
+ _aidl_return->readFlagBitmask = 0;
+ _aidl_return->writeFlagBitmask = 0;
+ _aidl_return->eventFlagDescriptor = std::nullopt;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Power::closeSessionChannel(int32_t, int32_t) {
+ return ndk::ScopedAStatus::ok();
+}
+
ScopedAStatus Power::getHintSessionPreferredRate(int64_t* outNanoseconds) {
*outNanoseconds = std::chrono::nanoseconds(1ms).count();
return ScopedAStatus::ok();
diff --git a/power/aidl/default/Power.h b/power/aidl/default/Power.h
index 7f8405e..baabaa7 100644
--- a/power/aidl/default/Power.h
+++ b/power/aidl/default/Power.h
@@ -17,6 +17,7 @@
#pragma once
#include <aidl/android/hardware/power/BnPower.h>
+#include "aidl/android/hardware/power/SessionTag.h"
namespace aidl {
namespace android {
@@ -35,7 +36,14 @@
const std::vector<int32_t>& threadIds,
int64_t durationNanos,
std::shared_ptr<IPowerHintSession>* _aidl_return) override;
+ ndk::ScopedAStatus createHintSessionWithConfig(
+ int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds, int64_t durationNanos,
+ SessionTag tag, SessionConfig* config,
+ std::shared_ptr<IPowerHintSession>* _aidl_return) override;
ndk::ScopedAStatus getHintSessionPreferredRate(int64_t* outNanoseconds) override;
+ ndk::ScopedAStatus getSessionChannel(int32_t tgid, int32_t uid,
+ ChannelConfig* _aidl_return) override;
+ ndk::ScopedAStatus closeSessionChannel(int32_t tgid, int32_t uid) override;
private:
std::vector<std::shared_ptr<IPowerHintSession>> mPowerHintSessions;
diff --git a/power/aidl/default/PowerHintSession.cpp b/power/aidl/default/PowerHintSession.cpp
index 452e435..847a42e 100644
--- a/power/aidl/default/PowerHintSession.cpp
+++ b/power/aidl/default/PowerHintSession.cpp
@@ -17,6 +17,7 @@
#include "PowerHintSession.h"
#include <android-base/logging.h>
+#include "android/binder_auto_utils.h"
namespace aidl::android::hardware::power::impl::example {
@@ -63,4 +64,9 @@
return ScopedAStatus::ok();
}
+ScopedAStatus PowerHintSession::getSessionConfig(SessionConfig* _aidl_return) {
+ _aidl_return->id = 1;
+ return ScopedAStatus::ok();
+}
+
} // namespace aidl::android::hardware::power::impl::example
diff --git a/power/aidl/default/PowerHintSession.h b/power/aidl/default/PowerHintSession.h
index b488bf1..2ed5588 100644
--- a/power/aidl/default/PowerHintSession.h
+++ b/power/aidl/default/PowerHintSession.h
@@ -35,6 +35,7 @@
ndk::ScopedAStatus sendHint(SessionHint hint) override;
ndk::ScopedAStatus setThreads(const std::vector<int32_t>& threadIds) override;
ndk::ScopedAStatus setMode(SessionMode mode, bool enabled) override;
+ ndk::ScopedAStatus getSessionConfig(SessionConfig* _aidl_return) override;
};
} // namespace aidl::android::hardware::power::impl::example
diff --git a/power/aidl/vts/Android.bp b/power/aidl/vts/Android.bp
index eb98b8b..c9285f4 100644
--- a/power/aidl/vts/Android.bp
+++ b/power/aidl/vts/Android.bp
@@ -31,6 +31,11 @@
srcs: ["VtsHalPowerTargetTest.cpp"],
shared_libs: [
"libbinder_ndk",
+ "libfmq",
+ ],
+ static_libs: [
+ "android.hardware.common.fmq-V1-ndk",
+ "android.hardware.common-V2-ndk",
],
test_suites: [
"general-tests",
diff --git a/power/aidl/vts/VtsHalPowerTargetTest.cpp b/power/aidl/vts/VtsHalPowerTargetTest.cpp
index 96995a0..d8e73bf 100644
--- a/power/aidl/vts/VtsHalPowerTargetTest.cpp
+++ b/power/aidl/vts/VtsHalPowerTargetTest.cpp
@@ -24,12 +24,22 @@
#include <android/binder_process.h>
#include <android/binder_status.h>
+#include <fmq/AidlMessageQueue.h>
+#include <fmq/EventFlag.h>
+
#include <unistd.h>
+#include <cstdint>
+#include "aidl/android/hardware/common/fmq/SynchronizedReadWrite.h"
+#include "fmq/EventFlag.h"
namespace aidl::android::hardware::power {
namespace {
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::android::AidlMessageQueue;
using android::hardware::power::Boost;
+using android::hardware::power::ChannelConfig;
+using android::hardware::power::ChannelMessage;
using android::hardware::power::IPower;
using android::hardware::power::IPowerHintSession;
using android::hardware::power::Mode;
@@ -37,6 +47,8 @@
using android::hardware::power::SessionMode;
using android::hardware::power::WorkDuration;
+using SessionMessageQueue = AidlMessageQueue<ChannelMessage, SynchronizedReadWrite>;
+
const std::vector<Boost> kBoosts{ndk::enum_range<Boost>().begin(), ndk::enum_range<Boost>().end()};
const std::vector<Mode> kModes{ndk::enum_range<Mode>().begin(), ndk::enum_range<Mode>().end()};
@@ -81,8 +93,6 @@
const std::vector<int32_t> kEmptyTids = {};
-const std::vector<WorkDuration> kNoDurations = {};
-
const std::vector<WorkDuration> kDurationsWithZero = {
DurationWrapper(1000L, 1L),
DurationWrapper(0L, 2L),
@@ -190,6 +200,31 @@
ASSERT_GE(rate, 1000000);
}
+TEST_P(PowerAidl, createHintSessionWithConfig) {
+ if (mServiceVersion < 5) {
+ GTEST_SKIP() << "DEVICE not launching with Power V5 and beyond.";
+ }
+ std::shared_ptr<IPowerHintSession> session;
+ SessionConfig config;
+
+ auto status = power->createHintSessionWithConfig(getpid(), getuid(), kSelfTids, 16666666L,
+ SessionTag::OTHER, &config, &session);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_NE(nullptr, session);
+}
+
+TEST_P(PowerAidl, getAndCloseSessionChannel) {
+ if (mServiceVersion < 5) {
+ GTEST_SKIP() << "DEVICE not launching with Power V5 and beyond.";
+ }
+ ChannelConfig config;
+ auto status = power->getSessionChannel(getpid(), getuid(), &config);
+ ASSERT_TRUE(status.isOk());
+ auto messageQueue = std::make_shared<SessionMessageQueue>(config.channelDescriptor, true);
+ ASSERT_TRUE(messageQueue->isValid());
+ ASSERT_TRUE(power->closeSessionChannel(getpid(), getuid()).isOk());
+}
+
TEST_P(HintSessionAidl, createAndCloseHintSession) {
ASSERT_TRUE(mSession->pause().isOk());
ASSERT_TRUE(mSession->resume().isOk());
@@ -252,6 +287,14 @@
}
}
+TEST_P(HintSessionAidl, getSessionConfig) {
+ if (mServiceVersion < 5) {
+ GTEST_SKIP() << "DEVICE not launching with Power V5 and beyond.";
+ }
+ SessionConfig config;
+ ASSERT_TRUE(mSession->getSessionConfig(&config).isOk());
+}
+
// FIXED_PERFORMANCE mode is required for all devices which ship on Android 11
// or later
TEST_P(PowerAidl, hasFixedPerformance) {
diff --git a/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp b/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp
index 4ee14e3..edc25b8 100644
--- a/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp
+++ b/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp
@@ -65,10 +65,10 @@
template <typename T, typename S, typename R>
void testMatching(std::vector<T> const& c1, R T::*f1, std::vector<S> const& c2, R S::*f2);
- bool containsTimedEntity(const std::string& str);
+ bool isEntitySkipped(const std::string& str);
- void excludeTimedEntities(std::vector<PowerEntity>* entities,
- std::vector<StateResidencyResult>* results);
+ void excludeSkippedEntities(std::vector<PowerEntity>* entities,
+ std::vector<StateResidencyResult>* results);
std::shared_ptr<IPowerStats> powerstats;
};
@@ -116,15 +116,20 @@
EXPECT_EQ(c1fields, c2fields);
}
-bool PowerStatsAidl::containsTimedEntity(const std::string& str) {
+bool PowerStatsAidl::isEntitySkipped(const std::string& str) {
+ bool skip = false;
// TODO(b/229698505): Extend PowerEntityInfo to identify timed power entity
- return str.find("AoC") != std::string::npos;
+ skip |= str.find("AoC") != std::string::npos;
+ // Lassen GNSS power stats will be present after running GPS session once.
+ // Otherwise, VTS will fail due to missing GPS power stats.
+ skip |= str.find("GPS") != std::string::npos;
+ return skip;
}
-void PowerStatsAidl::excludeTimedEntities(std::vector<PowerEntity>* entities,
- std::vector<StateResidencyResult>* results) {
+void PowerStatsAidl::excludeSkippedEntities(std::vector<PowerEntity>* entities,
+ std::vector<StateResidencyResult>* results) {
for (auto it = entities->begin(); it != entities->end(); it++) {
- if (containsTimedEntity((*it).name)) {
+ if (isEntitySkipped((*it).name)) {
auto entityId = (*it).id;
entities->erase(it--);
@@ -214,19 +219,19 @@
}
// State residency must return all results except timed power entities
-TEST_P(PowerStatsAidl, TestGetStateResidencyAllResultsExceptTimedEntities) {
+TEST_P(PowerStatsAidl, TestGetStateResidencyAllResultsExceptSkippedEntities) {
std::vector<PowerEntity> entities;
ASSERT_OK(powerstats->getPowerEntityInfo(&entities));
std::vector<StateResidencyResult> results;
ASSERT_OK(powerstats->getStateResidency({}, &results));
- excludeTimedEntities(&entities, &results);
+ excludeSkippedEntities(&entities, &results);
testMatching(entities, &PowerEntity::id, results, &StateResidencyResult::id);
}
// Each result must contain all state residencies except timed power entities
-TEST_P(PowerStatsAidl, TestGetStateResidencyAllStateResidenciesExceptTimedEntities) {
+TEST_P(PowerStatsAidl, TestGetStateResidencyAllStateResidenciesExceptSkippedEntities) {
std::vector<PowerEntity> entities;
ASSERT_OK(powerstats->getPowerEntityInfo(&entities));
@@ -234,7 +239,7 @@
ASSERT_OK(powerstats->getStateResidency({}, &results));
for (auto entity : entities) {
- if (!containsTimedEntity(entity.name)) {
+ if (!isEntitySkipped(entity.name)) {
auto it = std::find_if(results.begin(), results.end(),
[&entity](const auto& x) { return x.id == entity.id; });
ASSERT_NE(it, results.end());
@@ -255,7 +260,7 @@
std::vector<PowerEntity> selectedEntities = getRandomSubset(entities);
std::vector<int32_t> selectedIds;
for (auto it = selectedEntities.begin(); it != selectedEntities.end(); it++) {
- if (!containsTimedEntity((*it).name)) {
+ if (!isEntitySkipped((*it).name)) {
selectedIds.push_back((*it).id);
} else {
selectedEntities.erase(it--);
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_data.cpp b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
index 38cb33b..e89f4ee 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
@@ -16,6 +16,7 @@
#include <android-base/logging.h>
#include <android/hardware/radio/1.2/IRadio.h>
+#include <gtest/gtest.h>
#include <radio_hidl_hal_utils_v1_0.h>
using namespace ::android::hardware::radio::V1_0;
@@ -72,11 +73,16 @@
CellIdentityTdscdma cit = cellIdentities.cellIdentityTdscdma[0];
hidl_mcc = cit.mcc;
hidl_mnc = cit.mnc;
- } else {
+ } else if (cellInfoType == CellInfoType::CDMA) {
// CellIndentityCdma has no mcc and mnc.
EXPECT_EQ(CellInfoType::CDMA, cellInfoType);
EXPECT_EQ(1, cellIdentities.cellIdentityCdma.size());
checkMccMnc = false;
+ } else {
+ // This test can be skipped for newer networks if a new RAT (e.g. 5g) that was not
+ // supported in this version is added to the response from a modem that supports a new
+ // version of this interface.
+ GTEST_SKIP() << "Exempt from 1.0 test: camped on a new network:" << (int)cellInfoType;
}
// Check only one CellIdentity is size 1, and others must be 0.
diff --git a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
index 2bce2f9..51ca967 100644
--- a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
@@ -807,11 +807,16 @@
cellIdentities.cellIdentityTdscdma[0];
hidl_mcc = cit.base.mcc;
hidl_mnc = cit.base.mnc;
- } else {
+ } else if (cellInfoType == CellInfoType::CDMA) {
// CellIndentityCdma has no mcc and mnc.
EXPECT_EQ(CellInfoType::CDMA, cellInfoType);
EXPECT_EQ(1, cellIdentities.cellIdentityCdma.size());
checkMccMnc = false;
+ } else {
+ // This test can be skipped for newer networks if a new RAT (e.g. 5g) that was not
+ // supported in this version is added to the response from a modem that supports a new
+ // version of this interface.
+ GTEST_SKIP() << "Exempt from 1.2 test: camped on a new network:" << (int)cellInfoType;
}
// Check only one CellIdentity is size 1, and others must be 0.
diff --git a/radio/OWNERS b/radio/OWNERS
index 67ac2e2..8107287 100644
--- a/radio/OWNERS
+++ b/radio/OWNERS
@@ -2,3 +2,4 @@
jackyu@google.com
sarahchin@google.com
+jayachandranc@google.com
\ No newline at end of file
diff --git a/radio/aidl/Android.bp b/radio/aidl/Android.bp
index 1971832..7d4eb13 100644
--- a/radio/aidl/Android.bp
+++ b/radio/aidl/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_fwk_telephony",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfig.aidl
index 0f5e7e4..bc1c292 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfig.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfig.aidl
@@ -51,4 +51,5 @@
oneway void setPreferredDataModem(in int serial, in byte modemId);
oneway void setResponseFunctions(in android.hardware.radio.config.IRadioConfigResponse radioConfigResponse, in android.hardware.radio.config.IRadioConfigIndication radioConfigIndication);
oneway void setSimSlotsMapping(in int serial, in android.hardware.radio.config.SlotPortMapping[] slotMap);
+ oneway void getSimultaneousCallingSupport(in int serial);
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigIndication.aidl
index 9189f90..f786373 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigIndication.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigIndication.aidl
@@ -36,4 +36,5 @@
@VintfStability
interface IRadioConfigIndication {
oneway void simSlotsStatusChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.config.SimSlotStatus[] slotStatus);
+ oneway void onSimultaneousCallingSupportChanged(in int[] enabledLogicalSlots);
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigResponse.aidl
index 348aa34..6ff7bd0 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigResponse.aidl
@@ -42,4 +42,5 @@
oneway void setNumOfLiveModemsResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void setPreferredDataModemResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void setSimSlotsMappingResponse(in android.hardware.radio.RadioResponseInfo info);
+ oneway void getSimultaneousCallingSupportResponse(in android.hardware.radio.RadioResponseInfo info, in int[] enabledLogicalSlots);
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/PhoneCapability.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/PhoneCapability.aidl
index 3648866..2c66abd 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/PhoneCapability.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/PhoneCapability.aidl
@@ -39,4 +39,6 @@
byte maxActiveInternetData;
boolean isInternetLingeringSupported;
byte[] logicalModemIds;
+ byte maxActiveVoice = UNKNOWN /* -1 */;
+ const byte UNKNOWN = (-1) /* -1 */;
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpReceptionStats.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpReceptionStats.aidl
index 82b798b..216da4c 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpReceptionStats.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpReceptionStats.aidl
@@ -35,8 +35,8 @@
@VintfStability
parcelable RtpReceptionStats {
int rtpTimestamp;
- int rtpSequenceNumber;
- int timeDurationMs;
+ int rtcpSrTimestamp;
+ long rtcpSrNtpTimestamp;
int jitterBufferMs;
int roundTripTimeMs;
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SuggestedAction.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SuggestedAction.aidl
index 120e7e8..9846006 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SuggestedAction.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SuggestedAction.aidl
@@ -38,4 +38,6 @@
NONE,
TRIGGER_PLMN_BLOCK,
TRIGGER_PLMN_BLOCK_WITH_TIMEOUT,
+ TRIGGER_RAT_BLOCK,
+ TRIGGER_CLEAR_RAT_BLOCKS,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ConnectionEvent.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ConnectionEvent.aidl
index 3161322..1529512 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ConnectionEvent.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ConnectionEvent.aidl
@@ -35,18 +35,20 @@
/* @hide */
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum ConnectionEvent {
- CS_SERVICE_GSM = 0,
- SIGNALLING_GSM = 1,
- PS_SERVICE_GPRS = 2,
- SIGNALLING_GPRS = 3,
- PS_SERVICE_3G = 4,
- SIGNALLING_3G = 5,
- NAS_SIGNALLING_LTE = 6,
- AS_SIGNALLING_LTE = 7,
- VOLTE_SIP = 8,
- VOLTE_RTP = 9,
+ CS_SIGNALLING_GSM = 0,
+ PS_SIGNALLING_GPRS = 1,
+ CS_SIGNALLING_3G = 2,
+ PS_SIGNALLING_3G = 3,
+ NAS_SIGNALLING_LTE = 4,
+ AS_SIGNALLING_LTE = 5,
+ VOLTE_SIP = 6,
+ VOLTE_SIP_SOS = 7,
+ VOLTE_RTP = 8,
+ VOLTE_RTP_SOS = 9,
NAS_SIGNALLING_5G = 10,
AS_SIGNALLING_5G = 11,
VONR_SIP = 12,
- VONR_RTP = 13,
+ VONR_SIP_SOS = 13,
+ VONR_RTP = 14,
+ VONR_RTP_SOS = 15,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NasProtocolMessage.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NasProtocolMessage.aidl
index 9f852cc..4fbc802 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NasProtocolMessage.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NasProtocolMessage.aidl
@@ -44,4 +44,7 @@
AUTHENTICATION_AND_CIPHERING_RESPONSE = 6,
REGISTRATION_REQUEST = 7,
DEREGISTRATION_REQUEST = 8,
+ CM_REESTABLISHMENT_REQUEST = 9,
+ CM_SERVICE_REQUEST = 10,
+ IMSI_DETACH_INDICATION = 11,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegistrationFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegistrationFailCause.aidl
index 56f516d..fcc079e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegistrationFailCause.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegistrationFailCause.aidl
@@ -50,7 +50,11 @@
ROAMING_NOT_ALLOWED = 13,
GPRS_SERVICES_NOT_ALLOWED_IN_PLMN = 14,
NO_SUITABLE_CELLS = 15,
+ /**
+ * @deprecated MSC_TEMPORARILY_NOT_REACHABLE value is wrong and should not be used. Use MSC_TEMP_NOT_REACHABLE instead.
+ */
MSC_TEMPORARILY_NOT_REACHABLE = 15,
+ MSC_TEMP_NOT_REACHABLE = 16,
NETWORK_FAILURE = 17,
MAC_FAILURE = 20,
SYNC_FAILURE = 21,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithm.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithm.aidl
index 97ce004..c3333bf 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithm.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithm.aidl
@@ -53,11 +53,12 @@
EEA1 = 42,
EEA2 = 43,
EEA3 = 44,
- EEA4_ZUC = 45,
NEA0 = 55,
NEA1 = 56,
NEA2 = 57,
NEA3 = 58,
+ SIP_NO_IPSEC_CONFIG = 66,
+ IMS_NULL = 67,
SIP_NULL = 68,
AES_GCM = 69,
AES_GMAC = 70,
@@ -65,9 +66,9 @@
DES_EDE3_CBC = 72,
AES_EDE3_CBC = 73,
HMAC_SHA1_96 = 74,
- HMAC_SHA1_96_null = 75,
- HMAC_MD5_96 = 76,
- HMAC_MD5_96_null = 77,
+ HMAC_MD5_96 = 75,
+ RTP = 85,
+ SRTP_NULL = 86,
SRTP_AES_COUNTER = 87,
SRTP_AES_F8 = 88,
SRTP_HMAC_SHA1 = 89,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierInfo.aidl
new file mode 100644
index 0000000..7d4a54b
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierInfo.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.radio.sim;
+/* @hide */
+@JavaDerive(toString=true) @VintfStability
+parcelable CarrierInfo {
+ String mcc;
+ String mnc;
+ @nullable String spn;
+ @nullable String gid1;
+ @nullable String gid2;
+ @nullable String imsiPrefix;
+ @nullable List<android.hardware.radio.sim.Plmn> ehplmn;
+ @nullable String iccid;
+ @nullable String impi;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl
index 84cdf5d..a5b8dc9 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl
@@ -35,10 +35,18 @@
/* @hide */
@JavaDerive(toString=true) @VintfStability
parcelable CarrierRestrictions {
+ /**
+ * @deprecated use @List<CarrierInfo> allowedCarrierInfoList
+ */
android.hardware.radio.sim.Carrier[] allowedCarriers;
+ /**
+ * @deprecated use @List<CarrierInfo> excludedCarrierInfoList
+ */
android.hardware.radio.sim.Carrier[] excludedCarriers;
boolean allowedCarriersPrioritized;
android.hardware.radio.sim.CarrierRestrictions.CarrierRestrictionStatus status;
+ android.hardware.radio.sim.CarrierInfo[] allowedCarrierInfoList = {};
+ android.hardware.radio.sim.CarrierInfo[] excludedCarrierInfoList = {};
@Backing(type="int") @VintfStability
enum CarrierRestrictionStatus {
UNKNOWN = 0,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/Plmn.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/Plmn.aidl
new file mode 100644
index 0000000..b29a4a7
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/Plmn.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.radio.sim;
+/* @hide */
+@JavaDerive(toString=true) @VintfStability
+parcelable Plmn {
+ String mcc;
+ String mnc;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl
index 5a5e8ac..8cfe417 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl
@@ -37,4 +37,11 @@
enum SimLockMultiSimPolicy {
NO_MULTISIM_POLICY,
ONE_VALID_SIM_MUST_BE_PRESENT,
+ APPLY_TO_ALL_SLOTS,
+ APPLY_TO_ONLY_SLOT_1,
+ VALID_SIM_MUST_PRESENT_ON_SLOT_1,
+ ACTIVE_SERVICE_ON_SLOT_1_TO_UNBLOCK_OTHER_SLOTS,
+ ACTIVE_SERVICE_ON_ANY_SLOT_TO_UNBLOCK_OTHER_SLOTS,
+ ALL_SIMS_MUST_BE_VALID,
+ SLOT_POLICY_OTHER,
}
diff --git a/radio/aidl/android/hardware/radio/config/IRadioConfig.aidl b/radio/aidl/android/hardware/radio/config/IRadioConfig.aidl
index 9058d9d..8f4dff4 100644
--- a/radio/aidl/android/hardware/radio/config/IRadioConfig.aidl
+++ b/radio/aidl/android/hardware/radio/config/IRadioConfig.aidl
@@ -191,4 +191,20 @@
* This is available when android.hardware.telephony.subscription is defined.
*/
void setSimSlotsMapping(in int serial, in SlotPortMapping[] slotMap);
+
+ /**
+ * Get the set of logical slots where simultaneous cellular calling is currently possible. This
+ * does not include simultaneous calling availability over other non-cellular transports, such
+ * as IWLAN.
+ *
+ * Get the set of slots that currently support simultaneous cellular calling. When a new
+ * cellular call is placed/received, if another slot is active and handing a call, both the
+ * active slot and proposed slot must be in this list in order to support simultaneous cellular
+ * calling for both of those slots.
+ *
+ * @param serial Serial number of request
+ *
+ * This is available when android.hardware.telephony is defined.
+ */
+ void getSimultaneousCallingSupport(in int serial);
}
diff --git a/radio/aidl/android/hardware/radio/config/IRadioConfigIndication.aidl b/radio/aidl/android/hardware/radio/config/IRadioConfigIndication.aidl
index ed2366b..9eacb8e 100644
--- a/radio/aidl/android/hardware/radio/config/IRadioConfigIndication.aidl
+++ b/radio/aidl/android/hardware/radio/config/IRadioConfigIndication.aidl
@@ -37,4 +37,15 @@
*/
void simSlotsStatusChanged(
in android.hardware.radio.RadioIndicationType type, in SimSlotStatus[] slotStatus);
+
+ /**
+ * The logical slots supporting simultaneous cellular calling has changed.
+ *
+ * @param enabledLogicalSlots The slots that have simultaneous cellular calling enabled. If
+ * there is a call active on logical slot X, then a simultaneous cellular call is only possible
+ * on logical slot Y if BOTH slot X and slot Y are in enabledLogicalSlots. If simultaneous
+ * cellular calling is not currently supported, the expected value of enabledLogicalSLots is an
+ * empty int array. Sending only one radio slot is not acceptable in any case.
+ */
+ void onSimultaneousCallingSupportChanged(in int[] enabledLogicalSlots);
}
diff --git a/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl b/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl
index df93e3c..33b0ff0 100644
--- a/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl
+++ b/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl
@@ -129,4 +129,27 @@
* RadioError:INVALID_ARGUMENTS
*/
void setSimSlotsMappingResponse(in android.hardware.radio.RadioResponseInfo info);
+
+ /**
+ * Response to the asynchronous
+ * {@link IRadioConfig#getSimultaneousCallingSupport} request.
+ *
+ * @param info Response info struct containing response type, serial no. and error
+ * @param enabledLogicalSlots The slots that have simultaneous cellular calling enabled. If
+ * there is a call active on logical slot X, then a simultaneous cellular call is only possible
+ * on logical slot Y if BOTH slot X and slot Y are in enabledLogicalSlots. If simultaneous
+ * cellular calling is not currently supported, the expected value of enabledLogicalSLots is an
+ * empty int array. Sending only one radio slot is not acceptable in any case.
+ *
+ * Valid errors returned:
+ * RadioError:REQUEST_NOT_SUPPORTED when android.hardware.telephony is not defined
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ * RadioError:MODEM_ERR
+ *
+ * @see IRadioConfig#getSimultaneousCallingSupport for more information.
+ */
+ void getSimultaneousCallingSupportResponse(
+ in android.hardware.radio.RadioResponseInfo info, in int[] enabledLogicalSlots);
}
diff --git a/radio/aidl/android/hardware/radio/config/PhoneCapability.aidl b/radio/aidl/android/hardware/radio/config/PhoneCapability.aidl
index 35d6b5d..7936eb6 100644
--- a/radio/aidl/android/hardware/radio/config/PhoneCapability.aidl
+++ b/radio/aidl/android/hardware/radio/config/PhoneCapability.aidl
@@ -25,6 +25,7 @@
@VintfStability
@JavaDerive(toString=true)
parcelable PhoneCapability {
+ const byte UNKNOWN = -1;
/**
* maxActiveData defines how many logical modems can have
* PS attached simultaneously. For example, for L+L modem it
@@ -47,4 +48,10 @@
* List of logical modem IDs.
*/
byte[] logicalModemIds;
+ /**
+ * maxActiveVoice defines how many logical modems can have
+ * cellular voice calls simultaneously. For example, for cellular DSDA
+ * with simultaneous calling support, it should be 2.
+ */
+ byte maxActiveVoice = UNKNOWN;
}
diff --git a/radio/aidl/android/hardware/radio/ims/SuggestedAction.aidl b/radio/aidl/android/hardware/radio/ims/SuggestedAction.aidl
index 443042d..73c57fa 100644
--- a/radio/aidl/android/hardware/radio/ims/SuggestedAction.aidl
+++ b/radio/aidl/android/hardware/radio/ims/SuggestedAction.aidl
@@ -35,4 +35,19 @@
* management timer value as per the carrier requirements.
*/
TRIGGER_PLMN_BLOCK_WITH_TIMEOUT,
+ /**
+ * Indicates that the IMS registration on current RAT failed multiple times.
+ * The radio shall block the {@link AccessNetwork} included with this and
+ * search for other available RATs in the background.
+ * If no other RAT is available that meets the carrier requirements, the
+ * radio may remain on the blocked RAT for internet service. The radio clears all
+ * RATs marked as unavailable if {@link IRadioIms#updateImsRegistrationInfo()} API
+ * with REGISTERED state is invoked.
+ */
+ TRIGGER_RAT_BLOCK,
+ /**
+ * Indicates that the radio clears all RATs marked as unavailable and tries to find
+ * an available RAT that meets the carrier requirements.
+ */
+ TRIGGER_CLEAR_RAT_BLOCKS,
}
diff --git a/radio/aidl/android/hardware/radio/ims/media/IImsMediaSession.aidl b/radio/aidl/android/hardware/radio/ims/media/IImsMediaSession.aidl
index 0fe6740..69ca780 100644
--- a/radio/aidl/android/hardware/radio/ims/media/IImsMediaSession.aidl
+++ b/radio/aidl/android/hardware/radio/ims/media/IImsMediaSession.aidl
@@ -110,8 +110,7 @@
* Adjust the delay in the jitter buffer to synchronize the audio with the time of video
* frames
*
- * @param delayMs The delay to apply to the jitter buffer. If it is positive, the jitter
- * buffer increases the delay, if it is negative, the jitter buffer decreases the delay.
+ * @param delayMs The additional delay to the jitter buffer in milliseconds.
*
* This is available when android.hardware.telephony.ims is defined.
*/
diff --git a/radio/aidl/android/hardware/radio/ims/media/RtpReceptionStats.aidl b/radio/aidl/android/hardware/radio/ims/media/RtpReceptionStats.aidl
index 1239d13..81c0bb2 100644
--- a/radio/aidl/android/hardware/radio/ims/media/RtpReceptionStats.aidl
+++ b/radio/aidl/android/hardware/radio/ims/media/RtpReceptionStats.aidl
@@ -20,12 +20,19 @@
parcelable RtpReceptionStats {
/** The timestamp of the latest RTP packet received */
int rtpTimestamp;
- /** The sequence number of latest RTP packet received */
- int rtpSequenceNumber;
- /** The system clock time in millisecond of latest RTP packet received */
- int timeDurationMs;
- /** The jitter buffer size in millisecond when latest RTP packet received */
+
+ /** The timestamp of the latest RTCP-SR packet received */
+ int rtcpSrTimestamp;
+
+ /** The NTP timestamp of latest RTCP-SR packet received */
+ long rtcpSrNtpTimestamp;
+
+ /**
+ * The mean jitter buffer delay of a media stream from received to playback, measured in
+ * milliseconds, within the reporting interval
+ */
int jitterBufferMs;
+
/** The round trip time delay in millisecond when latest RTP packet received */
int roundTripTimeMs;
}
diff --git a/radio/aidl/android/hardware/radio/network/ConnectionEvent.aidl b/radio/aidl/android/hardware/radio/network/ConnectionEvent.aidl
index 639ba89..d5f367f 100644
--- a/radio/aidl/android/hardware/radio/network/ConnectionEvent.aidl
+++ b/radio/aidl/android/hardware/radio/network/ConnectionEvent.aidl
@@ -25,31 +25,37 @@
@Backing(type="int")
@JavaDerive(toString=true)
enum ConnectionEvent {
- // 2G GSM
- CS_SERVICE_GSM = 0,
- SIGNALLING_GSM = 1,
+ // 2G GSM circuit switched
+ CS_SIGNALLING_GSM = 0,
// 2G GPRS packet services
- PS_SERVICE_GPRS = 2,
- SIGNALLING_GPRS = 3,
+ PS_SIGNALLING_GPRS = 1,
- // 3G packet services
- PS_SERVICE_3G = 4,
- SIGNALLING_3G = 5,
+ // 3G circuit switched
+ CS_SIGNALLING_3G = 2,
+
+ // 3G packet switched
+ PS_SIGNALLING_3G = 3,
// 4G LTE packet services
- NAS_SIGNALLING_LTE = 6,
- AS_SIGNALLING_LTE = 7,
+ NAS_SIGNALLING_LTE = 4,
+ AS_SIGNALLING_LTE = 5,
// VoLTE
- VOLTE_SIP = 8,
- VOLTE_RTP = 9,
+ // Note: emergency calls could use either normal or SOS (emergency) PDN in practice
+ VOLTE_SIP = 6,
+ VOLTE_SIP_SOS = 7,
+ VOLTE_RTP = 8,
+ VOLTE_RTP_SOS = 9,
// 5G packet services
NAS_SIGNALLING_5G = 10,
AS_SIGNALLING_5G = 11,
// VoNR
+ // Note: emergency calls could use either normal or SOS (emergency) PDN in practice
VONR_SIP = 12,
- VONR_RTP = 13,
+ VONR_SIP_SOS = 13,
+ VONR_RTP = 14,
+ VONR_RTP_SOS = 15
}
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
index 32890ec..5f26195 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
@@ -649,8 +649,8 @@
/**
* Get whether pre-auth cellular identifier in-the-clear transparency is enabled. If
* IRadioNetworkInterface.setCellularIdentifierTransparencyEnabled has been called, this should
- * return the value of the `enabled` parameter of the last successful call. If it hasn't been
- * called this should return the default value of true.
+ * return the value of the `enabled` parameter of the last successful call and false if
+ * IRadioNetworkInterface.setCellularIdentifierTransparencyEnabled has not been called yet.
*
* @param serial Serial number of request
*
@@ -669,7 +669,7 @@
* Note: Cellular identifiers disclosed in uplink messages covered under a NAS Security Context
* as well as identifiers disclosed in downlink messages are out of scope.
*
- * This feature applies to 2g, 3g, 4g, and 5g (SA and NSA) messages sent before a NAS security
+ * This feature applies to 2g, 3g, 4g, and 5g (SA and NSA) messages sent before a security
* context is established. In scope message definitions and their associated spec references can
* be found in NasProtocolMessage.
*
@@ -678,8 +678,6 @@
* re-enables this functionality. The modem may choose to stop tracking cellular identifiers in
* the clear during this time.
*
- * Note: The default value of enabled shall be true.
- *
* @param serial Serial number of request
* @param enabled Whether or not to enable sending indications for cellular identifiers in the
* clear
@@ -694,8 +692,6 @@
* Enables or disables security algorithm update reports via indication API
* {@link IRadioNetworkIndication.securityAlgorithmsUpdated()}.
*
- * Note: The default value shall be enabled.
- *
* @param serial Serial number of request.
* @param enable {@code true} to enable security algorithm update reports, {@code false} to
* disable.
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
index 9c2502d..da82b78 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
@@ -231,16 +231,24 @@
/*
* Indicates that a new ciphering or integrity algorithm was used for a particular voice,
- * signaling, or data connection attempt for a given PLMN and/or access network. Due to
- * power concerns, once a connection type has been reported on, follow-up reports about that
- * connection type are only generated if there is any change to the previously reported
- * encryption or integrity. Thus the AP is only to be notified when there is new information.
- * List is reset upon rebooting thus info about initial connections is always passed to the
- * AP after a reboot. List is also reset if the SIM is changed or if there has been a change
- * in the access network.
+ * signaling, or data connection for a given PLMN and/or access network. Due to power
+ * concerns, once a connection type has been reported on, follow-up reports about that
+ * connection type are only generated if there is any change to the most-recently reported
+ * encryption or integrity, or if the value of SecurityAlgorithmUpdate#isUnprotectedEmergency
+ * changes. A change only in cell ID should not trigger an update, as the design is intended
+ * to be agnostic to dual connectivity ("secondary serving cells").
*
- * Note: a change only in cell ID should not trigger an update, as the design is intended to
- * be agnostic to dual connectivity ("secondary serving cells").
+ * Sample scenario to further clarify "most-recently reported":
+ *
+ * 1. Modem reports user is connected to a null-ciphered 3G network.
+ * 2. User then moves and connects to a well-ciphered 5G network, and modem reports this.
+ * 3. User returns to original location and reconnects to the null-ciphered 3G network. Modem
+ * should report this as it's different than the most-recently reported data from step (2).
+ *
+ * State is reset when (1) RadioState is transitioned to ON from any other state (e.g. radio
+ * is turned on during device boot, or modem boot), and (2) when CardState is transitioned
+ * to PRESENT from any other state (e.g. when SIM is inserted), or (3) if there is a change in
+ * access network (PLMN).
*
* @param type Type of radio indication
* @param securityAlgorithmUpdate SecurityAlgorithmUpdate encapsulates details of security
diff --git a/radio/aidl/android/hardware/radio/network/NasProtocolMessage.aidl b/radio/aidl/android/hardware/radio/network/NasProtocolMessage.aidl
index e8d8047..5a23661 100644
--- a/radio/aidl/android/hardware/radio/network/NasProtocolMessage.aidl
+++ b/radio/aidl/android/hardware/radio/network/NasProtocolMessage.aidl
@@ -17,8 +17,9 @@
package android.hardware.radio.network;
/**
- * Each enum value represents a message type on the NAS. The relevant cellular generation is noted.
- * Sample spec references are provided, but generally only reference one network generation's spec.
+ * Each enum value represents a message type on the Non-Access Stratum (NAS). The relevant cellular
+ * generation is noted for each message type. Sample spec references are provided, but generally
+ * only reference one network generation's spec.
*
* @hide
*/
@@ -54,5 +55,14 @@
REGISTRATION_REQUEST = 7,
// Reference: 3GPP TS 24.501 8.2.12
// Applies to 5g networks
- DEREGISTRATION_REQUEST = 8
+ DEREGISTRATION_REQUEST = 8,
+ // Reference: 3GPP TS 24.008 9.2.4
+ // Applies to 2g and 3g networks
+ CM_REESTABLISHMENT_REQUEST = 9,
+ // Reference: 3GPP TS 24.008 9.2.9
+ // Applies to 2g and 3g networks
+ CM_SERVICE_REQUEST = 10,
+ // Reference: 3GPP TS 24.008 9.2.14
+ // Applies to 2g and 3g networks. Used for circuit-switched detach.
+ IMSI_DETACH_INDICATION = 11
}
diff --git a/radio/aidl/android/hardware/radio/network/RegistrationFailCause.aidl b/radio/aidl/android/hardware/radio/network/RegistrationFailCause.aidl
index 2955f96..11fd8c5 100644
--- a/radio/aidl/android/hardware/radio/network/RegistrationFailCause.aidl
+++ b/radio/aidl/android/hardware/radio/network/RegistrationFailCause.aidl
@@ -86,10 +86,15 @@
*/
NO_SUITABLE_CELLS = 15,
/**
- * 16 - MSC temporarily not reachable
+ * @deprecated MSC_TEMPORARILY_NOT_REACHABLE value is wrong and should not be used.
+ * Use MSC_TEMP_NOT_REACHABLE instead.
*/
MSC_TEMPORARILY_NOT_REACHABLE = 15,
/**
+ * 16 - MSC temporarily not reachable
+ */
+ MSC_TEMP_NOT_REACHABLE = 16,
+ /**
* 17 - Network Failure
*/
NETWORK_FAILURE = 17,
diff --git a/radio/aidl/android/hardware/radio/network/SecurityAlgorithm.aidl b/radio/aidl/android/hardware/radio/network/SecurityAlgorithm.aidl
index 6d2c018..01f7327 100644
--- a/radio/aidl/android/hardware/radio/network/SecurityAlgorithm.aidl
+++ b/radio/aidl/android/hardware/radio/network/SecurityAlgorithm.aidl
@@ -52,7 +52,6 @@
EEA1 = 42,
EEA2 = 43,
EEA3 = 44,
- EEA4_ZUC = 45,
// 5G PS services (3GPP TS 33.401 for 5G NSA and 3GPP TS 33.501 for 5G SA)
NEA0 = 55,
@@ -60,7 +59,12 @@
NEA2 = 57,
NEA3 = 58,
- // SIP layer security (See 3GPP TS 33.203)
+ // IMS and SIP layer security (See 3GPP TS 33.203)
+ // No IPsec config
+ SIP_NO_IPSEC_CONFIG = 66,
+ IMS_NULL = 67,
+
+ // Has IPsec config
SIP_NULL = 68,
AES_GCM = 69,
AES_GMAC = 70,
@@ -68,16 +72,18 @@
DES_EDE3_CBC = 72,
AES_EDE3_CBC = 73,
HMAC_SHA1_96 = 74,
- HMAC_SHA1_96_null = 75,
- HMAC_MD5_96 = 76,
- HMAC_MD5_96_null = 77,
+ HMAC_MD5_96 = 75,
- // RTP (see 3GPP TS 33.328)
+ // RTP and SRTP (see 3GPP TS 33.328)
+ // When SRTP is not being used
+ RTP = 85,
+ // When SRTP is available and used
+ SRTP_NULL = 86,
SRTP_AES_COUNTER = 87,
SRTP_AES_F8 = 88,
SRTP_HMAC_SHA1 = 89,
- // ePDG (3GPP TS 33.402)
+ // ePDG (3GPP TS 33.402) (reserved for future use)
ENCR_AES_GCM_16 = 99,
ENCR_AES_CBC = 100,
AUTH_HMAC_SHA2_256_128 = 101,
diff --git a/radio/aidl/android/hardware/radio/sim/CarrierInfo.aidl b/radio/aidl/android/hardware/radio/sim/CarrierInfo.aidl
new file mode 100644
index 0000000..74fe31b
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/sim/CarrierInfo.aidl
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.sim;
+
+import android.hardware.radio.sim.Plmn;
+
+/** @hide */
+@VintfStability
+@JavaDerive(toString=true)
+parcelable CarrierInfo {
+ /**
+ * MCC (Mobile Country Code) of Carrier. Wild char is either '*' or '?'.
+ */
+ String mcc;
+
+ /**
+ * MNC (Mobile Network Code) of the Carrier. Wild char is either '*' or '?'.
+ */
+ String mnc;
+ /**
+ * Service Provider Name(SPN) of the SIM card of the Carrier.
+ */
+ @nullable
+ String spn;
+ /**
+ * GID1 value of the SIM card of the Carrier.
+ */
+ @nullable
+ String gid1;
+ /**
+ * GID2 value of the SIM card of the Carrier.
+ */
+ @nullable
+ String gid2;
+
+ /**
+ * IMSI (International Mobile Subscriber Identity) prefix. Wild char is '*'.
+ */
+ @nullable
+ String imsiPrefix;
+ /**
+ * Equivalent HPLMN of the SIM card of the Carrier.
+ */
+ @nullable
+ List<Plmn> ehplmn;
+ /**
+ * ICCID (Integrated Circuit Card Identification) of the SIM card.
+ */
+ @nullable
+ String iccid;
+ /**
+ * IMPI (IMS Private Identity) of the SIM card of the Carrier.
+ */
+ @nullable
+ String impi;
+}
\ No newline at end of file
diff --git a/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl b/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
index d5e0c43..0002d5a 100644
--- a/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
+++ b/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
@@ -17,6 +17,7 @@
package android.hardware.radio.sim;
import android.hardware.radio.sim.Carrier;
+import android.hardware.radio.sim.CarrierInfo;
/** @hide */
@VintfStability
@@ -40,12 +41,14 @@
}
/**
* Allowed carriers
+ * @deprecated use @List<CarrierInfo> allowedCarrierInfoList
*/
Carrier[] allowedCarriers;
/**
* Explicitly excluded carriers which match allowed_carriers. Eg. allowedCarriers match mcc/mnc,
* excludedCarriers has same mcc/mnc and gid1 is ABCD. It means except the carrier whose gid1
* is ABCD, all carriers with the same mcc/mnc are allowed.
+ * @deprecated use @List<CarrierInfo> excludedCarrierInfoList
*/
Carrier[] excludedCarriers;
/**
@@ -59,4 +62,14 @@
boolean allowedCarriersPrioritized;
/** Current restriction status as defined in CarrierRestrictionStatus enum */
CarrierRestrictionStatus status;
-}
+
+ /** Allowed carriers. */
+ CarrierInfo[] allowedCarrierInfoList = {};
+
+ /**
+ * Explicitly excluded carriers which match allowed_carriers. Eg. allowedCarriers match mcc/mnc,
+ * excludedCarriers has same mcc/mnc and gid1 is ABCD. It means except the carrier whose gid1
+ * is ABCD, all carriers with the same mcc/mnc are allowed.
+ */
+ CarrierInfo[] excludedCarrierInfoList = {};
+}
\ No newline at end of file
diff --git a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp b/radio/aidl/android/hardware/radio/sim/Plmn.aidl
similarity index 63%
copy from health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
copy to radio/aidl/android/hardware/radio/sim/Plmn.aidl
index aba6cc3..fd82692 100644
--- a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
+++ b/radio/aidl/android/hardware/radio/sim/Plmn.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,12 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "include/StorageHealthDefault.h"
-void get_storage_info(std::vector<struct StorageInfo>&) {
- // Use defaults.
-}
+package android.hardware.radio.sim;
-void get_disk_stats(std::vector<struct DiskStats>&) {
- // Use defaults
-}
+/** @hide */
+@VintfStability
+@JavaDerive(toString=true)
+parcelable Plmn {
+ /**
+ * MCC (Mobile Country Code) of the PLMN
+ */
+ String mcc;
+ /**
+ * MNC (Mobile Network Code) of the PLMN
+ */
+ String mnc;
+}
\ No newline at end of file
diff --git a/radio/aidl/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl b/radio/aidl/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl
index 18f97f7..89d85a9 100644
--- a/radio/aidl/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl
+++ b/radio/aidl/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl
@@ -21,14 +21,56 @@
@Backing(type="int")
@JavaDerive(toString=true)
enum SimLockMultiSimPolicy {
+
/**
* Indicates that configuration applies to each slot independently.
*/
NO_MULTISIM_POLICY,
+
/**
* Indicates that any SIM card can be used as far as one valid card is present in the device.
* For the modem, a SIM card is valid when its content (i.e. MCC, MNC, GID, SPN) matches the
* carrier restriction configuration.
*/
ONE_VALID_SIM_MUST_BE_PRESENT,
+
+ /**
+ * Indicates that the SIM lock policy applies uniformly to all sim slots.
+ */
+ APPLY_TO_ALL_SLOTS,
+
+ /**
+ * The SIM lock configuration applies exclusively to sim slot 1, leaving
+ * all other sim slots unlocked irrespective of the SIM card in slot 1
+ */
+ APPLY_TO_ONLY_SLOT_1,
+
+ /**
+ * Valid sim cards must be present on sim slot1 in order
+ * to use other sim slots.
+ */
+ VALID_SIM_MUST_PRESENT_ON_SLOT_1,
+
+ /**
+ * Valid sim card must be present on slot1 and it must be in full service
+ * in order to use other sim slots.
+ */
+ ACTIVE_SERVICE_ON_SLOT_1_TO_UNBLOCK_OTHER_SLOTS,
+
+ /**
+ * Valid sim card be present on any slot and it must be in full service
+ * in order to use other sim slots.
+ */
+ ACTIVE_SERVICE_ON_ANY_SLOT_TO_UNBLOCK_OTHER_SLOTS,
+
+ /**
+ * Valid sim cards must be present on all slots. If any SIM cards become
+ * invalid then device would set other SIM cards as invalid as well.
+ */
+ ALL_SIMS_MUST_BE_VALID,
+
+ /**
+ * In case there is no match policy listed above.
+ */
+ SLOT_POLICY_OTHER
}
diff --git a/radio/aidl/compat/libradiocompat/Android.bp b/radio/aidl/compat/libradiocompat/Android.bp
index 66970db..d78455e 100644
--- a/radio/aidl/compat/libradiocompat/Android.bp
+++ b/radio/aidl/compat/libradiocompat/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_fwk_telephony",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/radio/aidl/compat/libradiocompat/CallbackManager.cpp b/radio/aidl/compat/libradiocompat/CallbackManager.cpp
index c2eaed1..96aaebc 100644
--- a/radio/aidl/compat/libradiocompat/CallbackManager.cpp
+++ b/radio/aidl/compat/libradiocompat/CallbackManager.cpp
@@ -53,6 +53,10 @@
return *mRadioResponse;
}
+RadioIndication& CallbackManager::indication() const {
+ return *mRadioIndication;
+}
+
void CallbackManager::setResponseFunctionsDelayed() {
std::unique_lock<std::mutex> lock(mDelayedSetterGuard);
mDelayedSetterDeadline = std::chrono::steady_clock::now() + kDelayedSetterDelay;
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp b/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
index b450418..837c626 100644
--- a/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
@@ -62,6 +62,13 @@
return ok();
}
+ScopedAStatus RadioConfig::getSimultaneousCallingSupport(int32_t serial) {
+ LOG_CALL << serial;
+ LOG(ERROR) << " getSimultaneousCallingSupport is unsupported by HIDL HALs";
+ respond()->getSimultaneousCallingSupportResponse(notSupported(serial), {});
+ return ok();
+}
+
ScopedAStatus RadioConfig::getSimSlotsStatus(int32_t serial) {
LOG_CALL << serial;
mHal1_1->getSimSlotsStatus(serial);
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/CallbackManager.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/CallbackManager.h
index f1a7b49..34ab5d7 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/CallbackManager.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/CallbackManager.h
@@ -46,6 +46,7 @@
~CallbackManager();
RadioResponse& response() const;
+ RadioIndication& indication() const;
template <typename ResponseType, typename IndicationType>
void setResponseFunctions(const std::shared_ptr<ResponseType>& response,
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h
index 89ddea0..17d5985 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h
@@ -42,6 +42,7 @@
::ndk::ScopedAStatus getHalDeviceCapabilities(int32_t serial) override;
::ndk::ScopedAStatus getNumOfLiveModems(int32_t serial) override;
::ndk::ScopedAStatus getPhoneCapability(int32_t serial) override;
+ ::ndk::ScopedAStatus getSimultaneousCallingSupport(int32_t serial) override;
::ndk::ScopedAStatus getSimSlotsStatus(int32_t serial) override;
::ndk::ScopedAStatus setNumOfLiveModems(int32_t serial, int8_t numOfLiveModems) override;
::ndk::ScopedAStatus setPreferredDataModem(int32_t serial, int8_t modemId) override;
diff --git a/radio/aidl/compat/service/Android.bp b/radio/aidl/compat/service/Android.bp
index 62c99fe..c8bbd4c 100644
--- a/radio/aidl/compat/service/Android.bp
+++ b/radio/aidl/compat/service/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_fwk_telephony",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/radio/aidl/vts/Android.bp b/radio/aidl/vts/Android.bp
index d985686..e83a7c1 100644
--- a/radio/aidl/vts/Android.bp
+++ b/radio/aidl/vts/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_fwk_telephony",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/radio/aidl/vts/radio_config_indication.cpp b/radio/aidl/vts/radio_config_indication.cpp
index a84c20b..c707663 100644
--- a/radio/aidl/vts/radio_config_indication.cpp
+++ b/radio/aidl/vts/radio_config_indication.cpp
@@ -22,3 +22,8 @@
RadioIndicationType /*type*/, const std::vector<SimSlotStatus>& /*slotStatus*/) {
return ndk::ScopedAStatus::ok();
}
+
+ndk::ScopedAStatus RadioConfigIndication::onSimultaneousCallingSupportChanged(
+ const std::vector<int32_t>& /*enabledLogicalSlots*/) {
+ return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_config_response.cpp b/radio/aidl/vts/radio_config_response.cpp
index 7384f87..c532440 100644
--- a/radio/aidl/vts/radio_config_response.cpp
+++ b/radio/aidl/vts/radio_config_response.cpp
@@ -40,6 +40,14 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus RadioConfigResponse::getSimultaneousCallingSupportResponse(
+ const RadioResponseInfo& info, const std::vector<int32_t>& enabledLogicalSlots) {
+ rspInfo = info;
+ currentEnabledLogicalSlots = enabledLogicalSlots;
+ parent_config.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
+
ndk::ScopedAStatus RadioConfigResponse::setPreferredDataModemResponse(
const RadioResponseInfo& info) {
rspInfo = info;
diff --git a/radio/aidl/vts/radio_config_test.cpp b/radio/aidl/vts/radio_config_test.cpp
index d8c0142..6f18d18 100644
--- a/radio/aidl/vts/radio_config_test.cpp
+++ b/radio/aidl/vts/radio_config_test.cpp
@@ -122,6 +122,48 @@
}
/*
+ * Test IRadioConfig.getSimultaneousCallingSupport() for the response returned.
+ */
+TEST_P(RadioConfigTest, getSimultaneousCallingSupport) {
+ if (telephony_flags::enforce_telephony_feature_mapping()) {
+ if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
+ GTEST_SKIP() << "Skipping getSimultaneousCallingSupport "
+ "due to undefined FEATURE_TELEPHONY";
+ }
+ }
+
+ int32_t aidl_version;
+ ndk::ScopedAStatus aidl_status = radio_config->getInterfaceVersion(&aidl_version);
+ ASSERT_OK(aidl_status);
+ if (aidl_version < 3) {
+ ALOGI("Skipped the test since"
+ " getSimultaneousCallingSupport is not supported on version < 3.");
+ GTEST_SKIP();
+ }
+
+ serial = GetRandomSerialNumber();
+ ndk::ScopedAStatus res = radio_config->getSimultaneousCallingSupport(serial);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_config->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_config->rspInfo.serial);
+ ALOGI("getSimultaneousCallingSupport, rspInfo.error = %s\n",
+ toString(radioRsp_config->rspInfo.error).c_str());
+
+ // REQUEST_NOT_SUPPORTED is omitted here because users of the V3 HAL should implement this
+ // method and return at least an empty array
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_config->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR,
+ RadioError::MODEM_ERR}));
+
+ if (radioRsp_config->rspInfo.error == RadioError ::NONE) {
+ // The size of enabledLogicalSLots should be 0 or a positive number:
+ EXPECT_GE(radioRsp_config->currentEnabledLogicalSlots.size(), 0);
+ }
+}
+
+/*
* Test IRadioConfig.setPreferredDataModem() for the response returned.
*/
TEST_P(RadioConfigTest, setPreferredDataModem) {
diff --git a/radio/aidl/vts/radio_config_utils.h b/radio/aidl/vts/radio_config_utils.h
index f79aedb..84c74fc 100644
--- a/radio/aidl/vts/radio_config_utils.h
+++ b/radio/aidl/vts/radio_config_utils.h
@@ -39,6 +39,7 @@
PhoneCapability phoneCap;
bool modemReducedFeatureSet1;
std::vector<SimSlotStatus> simSlotStatus;
+ std::vector<int32_t> currentEnabledLogicalSlots;
virtual ndk::ScopedAStatus getSimSlotsStatusResponse(
const RadioResponseInfo& info, const std::vector<SimSlotStatus>& slotStatus) override;
@@ -48,6 +49,9 @@
virtual ndk::ScopedAStatus getPhoneCapabilityResponse(
const RadioResponseInfo& info, const PhoneCapability& phoneCapability) override;
+ virtual ndk::ScopedAStatus getSimultaneousCallingSupportResponse(
+ const RadioResponseInfo& info, const std::vector<int32_t>& enabledLogicalSlots) override;
+
virtual ndk::ScopedAStatus setPreferredDataModemResponse(
const RadioResponseInfo& info) override;
@@ -71,6 +75,9 @@
virtual ndk::ScopedAStatus simSlotsStatusChanged(
RadioIndicationType type, const std::vector<SimSlotStatus>& slotStatus) override;
+
+ virtual ndk::ScopedAStatus onSimultaneousCallingSupportChanged(
+ const std::vector<int32_t>& /*enabledLogicalSlots*/) override;
};
// The main test class for Radio AIDL Config.
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index c893553..5cb0158 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -90,6 +90,11 @@
serial = GetRandomSerialNumber();
+ // get aidl version
+ int32_t aidl_version;
+ ndk::ScopedAStatus aidl_status = radio_network->getInterfaceVersion(&aidl_version);
+ ASSERT_OK(aidl_status);
+
// save current value
radio_network->getAllowedNetworkTypesBitmap(serial);
EXPECT_EQ(std::cv_status::no_timeout, wait());
@@ -125,6 +130,11 @@
RadioError::INVALID_ARGUMENTS, RadioError::MODEM_ERR,
RadioError::REQUEST_NOT_SUPPORTED, RadioError::NO_RESOURCES}));
if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+ if (aidl_version < 2) {
+ radioRsp_network->networkTypeBitmapResponse
+ &= ~static_cast<int32_t>(RadioAccessFamily::LTE_CA);
+ }
+
// verify we get the value we set
EXPECT_EQ(radioRsp_network->networkTypeBitmapResponse, allowedNetworkTypesBitmap);
}
@@ -227,8 +237,10 @@
{RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_STATE,
RadioError::SIM_ABSENT, RadioError::INTERNAL_ERR, RadioError::NONE});
- ASSERT_TRUE(radioRsp_network->usageSetting == UsageSetting::VOICE_CENTRIC ||
- radioRsp_network->usageSetting == UsageSetting::DATA_CENTRIC);
+ if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+ ASSERT_TRUE(radioRsp_network->usageSetting == UsageSetting::VOICE_CENTRIC ||
+ radioRsp_network->usageSetting == UsageSetting::DATA_CENTRIC);
+ }
}
void RadioNetworkTest::testSetUsageSetting_InvalidValues(std::vector<RadioError> errors) {
@@ -873,7 +885,7 @@
ALOGI("setLinkCapacityReportingCriteria_invalidHysteresisDlKbps, rspInfo.error = %s\n",
toString(radioRsp_network->rspInfo.error).c_str());
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
}
/*
@@ -899,7 +911,7 @@
ALOGI("setLinkCapacityReportingCriteria_invalidHysteresisUlKbps, rspInfo.error = %s\n",
toString(radioRsp_network->rspInfo.error).c_str());
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
}
/*
@@ -924,7 +936,7 @@
ALOGI("setLinkCapacityReportingCriteria_emptyParams, rspInfo.error = %s\n",
toString(radioRsp_network->rspInfo.error).c_str());
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE}));
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
}
/*
@@ -1412,19 +1424,12 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
- if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
- ASSERT_TRUE(CheckAnyOfErrors(
- radioRsp_network->rspInfo.error,
- {RadioError::NONE, RadioError::ILLEGAL_SIM_OR_ME, RadioError::INVALID_ARGUMENTS,
- RadioError::INVALID_STATE, RadioError::RADIO_NOT_AVAILABLE, RadioError::NO_MEMORY,
- RadioError::INTERNAL_ERR, RadioError::SYSTEM_ERR, RadioError::CANCELLED}));
- } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
- ASSERT_TRUE(CheckAnyOfErrors(
- radioRsp_network->rspInfo.error,
- {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_ARGUMENTS,
- RadioError::INVALID_STATE, RadioError::NO_MEMORY, RadioError::INTERNAL_ERR,
- RadioError::SYSTEM_ERR, RadioError::CANCELLED}));
- }
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::ILLEGAL_SIM_OR_ME, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::NO_MEMORY,
+ RadioError::INTERNAL_ERR, RadioError::SYSTEM_ERR, RadioError::CANCELLED,
+ RadioError::MODEM_ERR, RadioError::OPERATION_NOT_ALLOWED, RadioError::NO_RESOURCES}));
}
/*
@@ -2372,9 +2377,9 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
- ASSERT_TRUE(CheckAnyOfErrors(
- radioRsp_network->rspInfo.error,
- {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR}));
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
}
/**
@@ -2406,9 +2411,9 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
- ASSERT_TRUE(CheckAnyOfErrors(
- radioRsp_network->rspInfo.error,
- {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR}));
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
}
TEST_P(RadioNetworkTest, isCellularIdentifierTransparencyEnabled) {
@@ -2433,10 +2438,6 @@
ASSERT_TRUE(CheckAnyOfErrors(
radioRsp_network->rspInfo.error,
{RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR}));
-
- // the default value should be true if we have not called the setter
- EXPECT_TRUE(radioRsp_network->isCellularIdentifierTransparencyEnabled);
-
}
TEST_P(RadioNetworkTest, setCellularIdentifierTransparencyEnabled) {
@@ -2567,7 +2568,4 @@
ASSERT_TRUE(CheckAnyOfErrors(
radioRsp_network->rspInfo.error,
{RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR}));
-
- // the default value should be true if we have not called the setter
- EXPECT_TRUE(radioRsp_network->isSecurityAlgorithmsUpdatedEnabled);
}
diff --git a/radio/aidl/vts/radio_network_utils.h b/radio/aidl/vts/radio_network_utils.h
index 470ee73..ad530eb 100644
--- a/radio/aidl/vts/radio_network_utils.h
+++ b/radio/aidl/vts/radio_network_utils.h
@@ -38,16 +38,16 @@
RadioResponseInfo rspInfo;
std::vector<RadioBandMode> radioBandModes;
std::vector<OperatorInfo> networkInfos;
- bool isNrDualConnectivityEnabled;
- int networkTypeBitmapResponse;
+ bool isNrDualConnectivityEnabled = false;
+ int networkTypeBitmapResponse = 0;
RegStateResult voiceRegResp;
RegStateResult dataRegResp;
CellIdentity barringCellIdentity;
std::vector<BarringInfo> barringInfoList;
UsageSetting usageSetting;
std::vector<RadioAccessSpecifier> specifiers;
- bool isCellularIdentifierTransparencyEnabled;
- bool isSecurityAlgorithmsUpdatedEnabled;
+ bool isCellularIdentifierTransparencyEnabled = false;
+ bool isSecurityAlgorithmsUpdatedEnabled = false;
virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
diff --git a/radio/config/1.0/Android.bp b/radio/config/1.0/Android.bp
index 9e317b3..98be5a7 100644
--- a/radio/config/1.0/Android.bp
+++ b/radio/config/1.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_fwk_telephony",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/radio/config/1.0/default/Android.bp b/radio/config/1.0/default/Android.bp
index e221ceb..ed12108 100644
--- a/radio/config/1.0/default/Android.bp
+++ b/radio/config/1.0/default/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_fwk_telephony",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/radio/config/1.0/vts/functional/Android.bp b/radio/config/1.0/vts/functional/Android.bp
index 36aecff..e28eb43 100644
--- a/radio/config/1.0/vts/functional/Android.bp
+++ b/radio/config/1.0/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_telephony",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/radio/config/1.1/Android.bp b/radio/config/1.1/Android.bp
index b1705f9..8aa8a4d 100644
--- a/radio/config/1.1/Android.bp
+++ b/radio/config/1.1/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_fwk_telephony",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/radio/config/1.1/vts/functional/Android.bp b/radio/config/1.1/vts/functional/Android.bp
index 9037b79..87bcaa9 100644
--- a/radio/config/1.1/vts/functional/Android.bp
+++ b/radio/config/1.1/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_telephony",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/radio/config/1.2/Android.bp b/radio/config/1.2/Android.bp
index 3327af4..e58ac0b 100644
--- a/radio/config/1.2/Android.bp
+++ b/radio/config/1.2/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_fwk_telephony",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/radio/config/1.2/vts/functional/Android.bp b/radio/config/1.2/vts/functional/Android.bp
index 1a15d3f..5ebb222 100644
--- a/radio/config/1.2/vts/functional/Android.bp
+++ b/radio/config/1.2/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_telephony",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/radio/config/1.3/Android.bp b/radio/config/1.3/Android.bp
index dc0d82c..c39984c 100644
--- a/radio/config/1.3/Android.bp
+++ b/radio/config/1.3/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_fwk_telephony",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/radio/config/1.3/vts/functional/Android.bp b/radio/config/1.3/vts/functional/Android.bp
index 20c480f..738d5d3 100644
--- a/radio/config/1.3/vts/functional/Android.bp
+++ b/radio/config/1.3/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_telephony",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -50,7 +51,7 @@
cc_library_static {
name: "RadioConfigVtsTestResponse",
defaults: ["VtsHalTargetTestDefaults"],
- srcs : [
+ srcs: [
"radio_config_response.cpp",
"radio_config_hidl_hal_test.cpp",
],
diff --git a/radio/deprecated/1.0/Android.bp b/radio/deprecated/1.0/Android.bp
index 53f6da5..a607644 100644
--- a/radio/deprecated/1.0/Android.bp
+++ b/radio/deprecated/1.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_fwk_telephony",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/renderscript/1.0/default/Android.bp b/renderscript/1.0/default/Android.bp
index c68e370..23fa252 100644
--- a/renderscript/1.0/default/Android.bp
+++ b/renderscript/1.0/default/Android.bp
@@ -27,6 +27,12 @@
"android.hardware.renderscript@1.0",
],
+ runtime_libs: [
+ "libRS_internal",
+ //TODO(b/313564579) Install libRSDriver as dependency of libRS_internal
+ "libRSDriver",
+ ],
+
product_variables: {
override_rs_driver: {
cflags: ["-DOVERRIDE_RS_DRIVER=%s"],
diff --git a/secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp b/secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp
index 63c2eca..1623960 100644
--- a/secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp
+++ b/secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp
@@ -75,6 +75,7 @@
se_->init(se_cb_);
auto res = se_cb_->WaitForCallback(kCallbackNameOnStateChange);
EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.args);
EXPECT_TRUE(res.args->state_);
}
diff --git a/secure_element/1.1/vts/functional/VtsHalSecureElementV1_1TargetTest.cpp b/secure_element/1.1/vts/functional/VtsHalSecureElementV1_1TargetTest.cpp
index 234c33c..d7e4546 100644
--- a/secure_element/1.1/vts/functional/VtsHalSecureElementV1_1TargetTest.cpp
+++ b/secure_element/1.1/vts/functional/VtsHalSecureElementV1_1TargetTest.cpp
@@ -72,6 +72,7 @@
se_->init_1_1(se_cb_);
auto res = se_cb_->WaitForCallback(kCallbackNameOnStateChange);
EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.args);
EXPECT_TRUE(res.args->state_);
EXPECT_NE(res.args->reason_, "");
}
diff --git a/secure_element/1.2/vts/functional/VtsHalSecureElementV1_2TargetTest.cpp b/secure_element/1.2/vts/functional/VtsHalSecureElementV1_2TargetTest.cpp
index 66d581e..26b2ded 100644
--- a/secure_element/1.2/vts/functional/VtsHalSecureElementV1_2TargetTest.cpp
+++ b/secure_element/1.2/vts/functional/VtsHalSecureElementV1_2TargetTest.cpp
@@ -73,6 +73,7 @@
se_->init_1_1(se_cb_);
auto res = se_cb_->WaitForCallback(kCallbackNameOnStateChange);
EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.args);
EXPECT_TRUE(res.args->state_);
EXPECT_NE(res.args->reason_, "");
}
@@ -93,10 +94,12 @@
auto res = se_cb_->WaitForCallback(kCallbackNameOnStateChange);
EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.args);
EXPECT_FALSE(res.args->state_);
res = se_cb_->WaitForCallback(kCallbackNameOnStateChange);
EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.args);
EXPECT_TRUE(res.args->state_);
}
diff --git a/audio/aidl/vts/VtsHalAudioCoreTargetTest.xml b/secure_element/aidl/vts/AndroidTest.xml
similarity index 61%
copy from audio/aidl/vts/VtsHalAudioCoreTargetTest.xml
copy to secure_element/aidl/vts/AndroidTest.xml
index 9d3adc1..94dfa82 100644
--- a/audio/aidl/vts/VtsHalAudioCoreTargetTest.xml
+++ b/secure_element/aidl/vts/AndroidTest.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2023 The Android Open Source Project
+<!-- 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.
@@ -13,26 +13,21 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<configuration description="Runs VtsHalAudioCoreTargetTest.">
+<configuration description="Runs VtsHalSecureElementTargetTest.">
<option name="test-suite-tag" value="apct" />
<option name="test-suite-tag" value="apct-native" />
+ <option name="config-descriptor:metadata" key="token" value="SECURE_ELEMENT_SIM_CARD" />
- <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
- <target_preparer class="com.android.tradefed.targetprep.StopServicesSetup"/>
-
- <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
- <option name="run-command" value="setprop vts.native_server.on 1"/>
- <option name="teardown-command" value="setprop vts.native_server.on 0"/>
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
</target_preparer>
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
<option name="cleanup" value="true" />
- <option name="push" value="VtsHalAudioCoreTargetTest->/data/local/tmp/VtsHalAudioCoreTargetTest" />
+ <option name="push" value="VtsHalSecureElementTargetTest->/data/local/tmp/VtsHalSecureElementTargetTest" />
</target_preparer>
<test class="com.android.tradefed.testtype.GTest" >
<option name="native-test-device-path" value="/data/local/tmp" />
- <option name="module-name" value="VtsHalAudioCoreTargetTest" />
- <option name="native-test-timeout" value="10m" />
+ <option name="module-name" value="VtsHalSecureElementTargetTest" />
</test>
</configuration>
diff --git a/security/authgraph/aidl/Android.bp b/security/authgraph/aidl/Android.bp
index d94f640..f3d1281 100644
--- a/security/authgraph/aidl/Android.bp
+++ b/security/authgraph/aidl/Android.bp
@@ -34,7 +34,7 @@
platform_apis: true,
},
ndk: {
- apps_enabled: false,
+ enabled: true,
},
rust: {
enabled: true,
diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/Arc.cddl b/security/authgraph/aidl/android/hardware/security/authgraph/Arc.cddl
index 4c1b965..0bc39d6 100644
--- a/security/authgraph/aidl/android/hardware/security/authgraph/Arc.cddl
+++ b/security/authgraph/aidl/android/hardware/security/authgraph/Arc.cddl
@@ -28,19 +28,19 @@
? -70003 : int, ; Timestamp in milliseconds since some starting point (generally
; the most recent device boot) which all of the applications within
; the secure domain must agree upon
- ? -70004 : bstr .size 16, ; Nonce used in key exchange methods
+ ? -70004 : bstr .size 16, ; Nonce (a cryptographic random number of 16 bytes) used in key
+ ; exchange methods
? -70005 : PayloadType, ; Payload type, if needed to disambiguate, when processing an arc
? -70006 : int, ; Version of the payload structure (if applicable)
? -70007 : int, ; Sequence number (if needed to prevent replay attacks)
? -70008 : Direction ; Direction of the encryption key (i.e. whether it is used to
; encrypt incoming messages or outgoing messages)
? -70009 : bool, ; "authentication_completed" - this is used during authenticated
- ; key exchange indicate whether signature verification is done
- ? -70010 : bstr .size 32 ; "session_id" computed during key exchange protocol
+ ; key exchange to indicate whether signature verification is done
+ ? -70010 : bstr .size 32 ; "session_id" computed during the key exchange protocol
}
-; Permissions indicate what an arc can be used with. Permissions are added to an arc during the
-; `create()` primitive operation and are propagated during `mint` and `snap` primitive operations.
+; Permissions indicate what an arc can be used with.
Permission = &(
-4770552 : IdentityEncoded, ; "source_id" - in the operations performed by a source, the
; source adds its own identity to the permissions of an arc.
@@ -54,12 +54,10 @@
; biometrics.
)
-; Limitations indicate what restrictions are applied on the usage of an arc. Permissions are added
-; to an arc during the `create` primitive operation and are propagated during `snap` primitive
-; operation.
+; Limitations indicate what restrictions are applied on the usage of an arc.
Limitation = &(
- -4770554 : bstr, ; "challenge" - is added to an arc that transfers an auth key to a channel
- ; key, in order to ensure the freshness of the authentication.
+ -4770554 : bstr, ; "challenge" - is added to an arc that encrypts an auth key from a
+ ; channel key, in order to ensure the freshness of the authentication.
; A challenge is issued by a sink (e.g. Keymint TA, Biometric TAs).
)
@@ -83,7 +81,7 @@
; Any other payload formats should also be defined here
)
-SecretKey = &( ; One of the payload types of an Arc is a secret key
+SecretKey = &(
SymmetricKey,
ECPrivateKey, ; Private key of a key pair generated for key exchange
)
diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/ExplicitKeyDiceCertChain.cddl b/security/authgraph/aidl/android/hardware/security/authgraph/ExplicitKeyDiceCertChain.cddl
index 3de5617..2d6c696 100644
--- a/security/authgraph/aidl/android/hardware/security/authgraph/ExplicitKeyDiceCertChain.cddl
+++ b/security/authgraph/aidl/android/hardware/security/authgraph/ExplicitKeyDiceCertChain.cddl
@@ -19,11 +19,10 @@
* DiceChainEntry
]
-DiceCertChainInitialPayload = {
- -4670552 : bstr .cbor PubKeyEd25519 /
- bstr .cbor PubKeyECDSA256 /
- bstr .cbor PubKeyECDSA384 ; subjectPublicKey
-}
+; Encoded in accordance with Core Deterministic Encoding Requirements [RFC 8949 s4.2.1]
+DiceCertChainInitialPayload = bstr .cbor PubKeyEd25519
+ / bstr .cbor PubKeyECDSA256
+ / bstr .cbor PubKeyECDSA384 ; subjectPublicKey
; INCLUDE generateCertificateRequestV2.cddl for: PubKeyEd25519, PubKeyECDSA256, PubKeyECDSA384,
; DiceChainEntry
diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/IAuthGraphKeyExchange.aidl b/security/authgraph/aidl/android/hardware/security/authgraph/IAuthGraphKeyExchange.aidl
index 6ceb09c..a3fb959 100644
--- a/security/authgraph/aidl/android/hardware/security/authgraph/IAuthGraphKeyExchange.aidl
+++ b/security/authgraph/aidl/android/hardware/security/authgraph/IAuthGraphKeyExchange.aidl
@@ -41,8 +41,8 @@
interface IAuthGraphKeyExchange {
/**
* This method is invoked on P1 (source).
- * Create an ephermeral EC key pair on NIST curve P-256 and a nonce (of 16 bytes) for
- * key exchange.
+ * Create an ephermeral EC key pair on NIST curve P-256 and a nonce (a cryptographic random
+ * number of 16 bytes) for key exchange.
*
* @return SessionInitiationInfo including the `Key` containing the public key of the created
* key pair and an arc from the per-boot key to the private key, the nonce, the persistent
@@ -52,8 +52,8 @@
* `SessionInitiationInfo` serves two purposes:
* i. A mapping to correlate `create` and `finish` calls to P1 in a particular instance of the
* key exchange protocol.
- * ii.A way to minimize the in-memory storage (P1 can include the nonce in the protected headers
- * of the arc).
+ * ii.A way to minimize the in-memory storage of P1 allocated for key exchange (P1 can include
+ * the nonce in the protected headers of the arc).
* However, P1 should maintain some form of in-memory record to be able to verify that the input
* `Key` sent to `finish` is from an unfinished instance of a key exchange protocol, to prevent
* any replay attacks in `finish`.
@@ -66,9 +66,9 @@
* 0. If either `peerPubKey`, `peerId`, `peerNonce` is not in the expected format, return
* errors: INVALID_PEER_KE_KEY, INVALID_IDENTITY, INVALID_PEER_NONCE respectively.
* 1. Create an ephemeral EC key pair on NIST curve P-256.
- * 2. Create a nonce (of 16 bytes).
- * 3. Compute the diffie-hellman shared secret: Z.
- * 4. Compute a salt = bstr .cbor [
+ * 2. Create a nonce (a cryptographic random number of 16 bytes).
+ * 3. Compute the Diffie-Hellman shared secret: Z.
+ * 4. Compute a salt_input = bstr .cbor [
* source_version: int, ; from input `peerVersion`
* sink_pub_key: bstr .cbor PlainPubKey, ; from step #1
* source_pub_key: bstr .cbor PlainPubKey, ; from input `peerPubKey`
@@ -77,7 +77,8 @@
* sink_cert_chain: bstr .cbor ExplicitKeyDiceCertChain, ; from own identity
* source_cert_chain: bstr .cbor ExplicitKeyDiceCertChain, ; from input `peerId`
* ]
- * 5. Extract a cryptographic secret S from Z, using the salt from #4 above.
+ * 5. Extract a cryptographic secret S from Z, using the SHA256 digest of the salt_input
+ * as the salt.
* 6. Derive two symmetric encryption keys of 256 bits with:
* i. b"KE_ENCRYPTION_KEY_SOURCE_TO_SINK" as context for the key used to encrypt incoming
* messages
@@ -96,28 +97,29 @@
* part of the party's identity.
*
* @param peerPubKey - the public key of the key pair created by the peer (P1) for key exchange
+ * in `create`
*
* @param peerId - the persistent identity of the peer
*
- * @param peerNonce - nonce created by the peer
+ * @param peerNonce - nonce created by the peer in `create`
*
* @param peerVersion - an integer representing the latest protocol version (i.e. AIDL version)
* supported by the peer
*
- * @return KeInitResult including the `Key` containing the public key of the created key pair,
- * the nonce, the persistent identity, two shared key arcs from step #7, session id, signature
- * over the session id and the negotiated protocol version. The negotiated protocol version
- * should be less than or equal to the peer's version.
+ * @return KeInitResult including the `Key` containing the public key of the key pair created in
+ * step #1, the nonce from step #2, the persistent identity of P2, two shared key arcs
+ * from step #7, session id from step #10, signature over the session id from step #11 and the
+ * negotiated protocol version. The negotiated protocol version should be less than or equal to
+ * the `peerVersion`.
*
- * Note: The two shared key arcs in the return type: `KeInitResult` serves two purposes:
+ * Note: The two shared key arcs in the return type: `KeInitResult` serve two purposes:
* i. A mapping to correlate `init` and `authenticationComplete` calls to P2 in a particular
* instance of the key exchange protocol.
* ii.A way to minimize the in-memory storage of P2 allocated for key exchange.
* However, P2 should maintain some in-memory record to be able to verify that the input
- * `sharedkeys` sent to `authenticationComplete` and to any subsequent AuthGraph protocol
- * methods are valid shared keys agreed with the party identified by `peerId`, to prevent
- * any replay attacks in `authenticationComplete` and in any subsequent AuthGraph protocol
- * methods which use the shared keys to encrypt the secret messages.
+ * `sharedkeys` sent to `authenticationComplete` are from an unfinished instance of a key
+ * exchange protocol carried out with the party identified by `peerId`, to prevent any replay
+ * attacks in `authenticationComplete`.
*/
KeInitResult init(
in PubKey peerPubKey, in Identity peerId, in byte[] peerNonce, in int peerVersion);
@@ -133,8 +135,8 @@
* exchange protocol, return error: INVALID_KE_KEY. Similarly, if the public key or the
* arc containing the private key in `ownKey` is invalid, return INVALID_PUB_KEY_IN_KEY
* and INVALID_PRIV_KEY_ARC_IN_KEY respectively.
- * 1. Compute the diffie-hellman shared secret: Z.
- * 2. Compute a salt = bstr .cbor [
+ * 1. Compute the Diffie-Hellman shared secret: Z.
+ * 2. Compute a salt_input = bstr .cbor [
* source_version: int, ; the protocol version used in `create`
* sink_pub_key: bstr .cbor PlainPubKey, ; from input `peerPubKey`
* source_pub_key: bstr .cbor PlainPubKey, ; from the output of `create`
@@ -143,7 +145,8 @@
* sink_cert_chain: bstr .cbor ExplicitKeyDiceCertChain, ; from input `peerId`
* source_cert_chain: bstr .cbor ExplicitKeyDiceCertChain, ; from own identity
* ]
- * 3. Extract a cryptographic secret S from Z, using the salt from #2 above.
+ * 3. Extract a cryptographic secret S from Z, using the SHA256 digest of the salt_input
+ * as the salt.
* 4. Derive two symmetric encryption keys of 256 bits with:
* i. b"KE_ENCRYPTION_KEY_SOURCE_TO_SINK" as context for the key used to encrypt outgoing
* messages
@@ -164,25 +167,26 @@
* part of the party's identity.
*
* @param peerPubKey - the public key of the key pair created by the peer (P2) for key exchange
+ * in `init`
*
* @param peerId - the persistent identity of the peer
*
* @param peerSignature - the signature created by the peer over the session id computed by the
- * peer
+ * peer in `init`
*
- * @param peerNonce - nonce created by the peer
+ * @param peerNonce - nonce created by the peer in `init`
*
* @param peerVersion - an integer representing the protocol version (i.e. AIDL version)
* negotiated with the peer
*
- * @param ownKey - the key created by P1 (source) in `create()` for key exchange
+ * @param ownKey - the key created by P1 (source) in `create` for key exchange
*
- * @return SessionInfo including the two shared key arcs from step #9, session id and the
- * signature over the session id.
+ * @return SessionInfo including the two shared key arcs from step #9, session id from step #7
+ * and the signature over the session id from step #10.
*
- * Note: The two shared key arcs in the return type: `SessionInfo` serves two purposes:
+ * Note: The two shared key arcs in the return type: `SessionInfo` serve two purposes:
* i. A mapping to correlate the key exchange protocol taken place with a particular peer and
- * subsequent AuthGraph protocols execued with the same peer.
+ * subsequent AuthGraph protocols executed with the same peer.
* ii.A way to minimize the in-memory storage for shared keys.
* However, P1 should maintain some in-memory record to be able to verify that the shared key
* arcs sent to any subsequent AuthGraph protocol methods are valid shared keys agreed with the
@@ -196,21 +200,33 @@
* This method is invoked on P2 (sink).
* Perform the following steps:
* 0. If input `sharedKeys` is invalid (i.e. they cannot be decrypted with P2's per-boot key
- * or they are not in P2's in-memory records as valid shared keys agreed with the party
- * identified by `peerId`), return error: INVALID_SHARED_KEY_ARCS.
+ * or they are not in P2's in-memory records for unfinished instances of a key exchange
+ * protocol carried out with the party identified by the identity included in the
+ * `source_id` protected header of the shared key arcs),
+ * return error: INVALID_SHARED_KEY_ARCS.
* 1. Verify that both shared key arcs have the same session id and peer identity.
- * 2. Verify the peer's signature over the session id attached to the shared key arcs'
- * headers. If successful, proceed, otherwise, return error: INVALID_SIGNATURE.
- * 3. Mark authentication_complete = true in the shared key arcs' headers
+ * 2. Verify the `peerSignature` over the session id included in the `session_id` protected
+ * header of the shared key arcs.
+ * If successful, proceed, otherwise, return error: INVALID_SIGNATURE.
+ * 3. Mark authentication_complete = true in the shared key arcs' headers.
*
* @param peerSignature - the signature created by the peer over the session id computed by the
- * peer
+ * peer in `finish`
*
* @param sharedKeys - two shared key arcs created by P2 in `init`. P2 obtains from the arcs'
* protected headers, the session id and the peer's identity to verify the
* peer's signature over the session id.
*
* @return Arc[] - an array of two updated shared key arcs
+ *
+ * Note: The two returned shared key arcs serve two purposes:
+ * i. A mapping to correlate the key exchange protocol taken place with a particular peer and
+ * subsequent AuthGraph protocols executed with the same peer.
+ * ii.A way to minimize the in-memory storage for shared keys.
+ * However, P2 should maintain some in-memory record to be able to verify that the shared key
+ * arcs sent to any subsequent AuthGraph protocol methods are valid shared keys agreed with the
+ * party identified by the identity included in the `source_id` protected header of the shared
+ * key arcs, to prevent any replay attacks.
*/
Arc[2] authenticationComplete(in SessionIdSignature peerSignature, in Arc[2] sharedKeys);
}
diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/SessionInfo.aidl b/security/authgraph/aidl/android/hardware/security/authgraph/SessionInfo.aidl
index ef49a1a..82b8c17 100644
--- a/security/authgraph/aidl/android/hardware/security/authgraph/SessionInfo.aidl
+++ b/security/authgraph/aidl/android/hardware/security/authgraph/SessionInfo.aidl
@@ -26,8 +26,8 @@
@RustDerive(Clone=true, Eq=true, PartialEq=true)
parcelable SessionInfo {
/**
- * The arcs that encrypt the two derived symmetric encryption keys (for two-way communication)
- * from the party's per-boot key.
+ * The arcs that encrypt the two derived symmetric encryption keys (for two-way communication).
+ * The encryption key is the party's per-boot key.
*/
Arc[2] sharedKeys;
diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/SessionInitiationInfo.aidl b/security/authgraph/aidl/android/hardware/security/authgraph/SessionInitiationInfo.aidl
index c630d91..8179ac2 100644
--- a/security/authgraph/aidl/android/hardware/security/authgraph/SessionInitiationInfo.aidl
+++ b/security/authgraph/aidl/android/hardware/security/authgraph/SessionInitiationInfo.aidl
@@ -27,20 +27,22 @@
@RustDerive(Clone=true, Eq=true, PartialEq=true)
parcelable SessionInitiationInfo {
/**
- * An ephemeral EC key created for the ECDH process.
+ * An ephemeral EC key created for the Elliptic-curve Diffie-Hellman (ECDH) process.
*/
Key key;
/**
- * The identity of the party who created the Diffie-Hellman key exchange key.
+ * The identity of the party who creates this `SessionInitiationInfo`.
*/
Identity identity;
/**
- * Nonce value specific to this session. The nonce serves three purposes:
+ * Nonce (a cryptographic random number of 16 bytes) specific to this session.
+ * The nonce serves three purposes:
* 1. freshness of key exchange
* 2. creating a session id (a publicly known value related to the exchanged keys)
- * 3. usage as salt into the HKDF-EXTRACT function during key derivation from the shared DH key
+ * 3. usage as salt into the HKDF-EXTRACT function during key derivation from the Diffie-Hellman
+ * shared secret
*/
byte[] nonce;
diff --git a/security/authgraph/aidl/vts/functional/Android.bp b/security/authgraph/aidl/vts/functional/Android.bp
index 0e3480f..28a70e2 100644
--- a/security/authgraph/aidl/vts/functional/Android.bp
+++ b/security/authgraph/aidl/vts/functional/Android.bp
@@ -50,6 +50,7 @@
rust_test {
name: "VtsAidlAuthGraphRoleTest",
srcs: ["role_test.rs"],
+ require_root: true,
test_suites: [
"general-tests",
"vts",
diff --git a/security/authgraph/aidl/vts/functional/lib.rs b/security/authgraph/aidl/vts/functional/lib.rs
index da3fa1c..f4c1da9 100644
--- a/security/authgraph/aidl/vts/functional/lib.rs
+++ b/security/authgraph/aidl/vts/functional/lib.rs
@@ -26,6 +26,7 @@
use authgraph_boringssl as boring;
use authgraph_core::{error::Error as AgError, keyexchange as ke};
use coset::CborSerializable;
+use std::{cell::RefCell, rc::Rc};
pub mod sink;
pub mod source;
@@ -34,7 +35,7 @@
pub fn test_ag_participant() -> Result<ke::AuthGraphParticipant, AgError> {
Ok(ke::AuthGraphParticipant::new(
boring::crypto_trait_impls(),
- Box::<boring::test_device::AgDevice>::default(),
+ Rc::new(RefCell::new(boring::test_device::AgDevice::default())),
ke::MAX_OPENED_SESSIONS,
)?)
}
diff --git a/security/authgraph/aidl/vts/functional/role_test.rs b/security/authgraph/aidl/vts/functional/role_test.rs
index 71a2fae..3075d8a 100644
--- a/security/authgraph/aidl/vts/functional/role_test.rs
+++ b/security/authgraph/aidl/vts/functional/role_test.rs
@@ -22,13 +22,18 @@
use android_hardware_security_authgraph::aidl::android::hardware::security::authgraph::{
IAuthGraphKeyExchange::IAuthGraphKeyExchange,
};
+use binder::StatusCode;
const AUTH_GRAPH_NONSECURE: &str =
"android.hardware.security.authgraph.IAuthGraphKeyExchange/nonsecure";
/// Retrieve the /nonsecure instance of AuthGraph, which supports both sink and source roles.
fn get_nonsecure() -> Option<binder::Strong<dyn IAuthGraphKeyExchange>> {
- binder::get_interface(AUTH_GRAPH_NONSECURE).ok()
+ match binder::get_interface(AUTH_GRAPH_NONSECURE) {
+ Ok(ag) => Some(ag),
+ Err(StatusCode::NAME_NOT_FOUND) => None,
+ Err(e) => panic!("failed to get AuthGraph/nonsecure: {e:?}"),
+ }
}
/// Macro to require availability of a /nonsecure instance of AuthGraph.
diff --git a/security/authgraph/aidl/vts/functional/sink.rs b/security/authgraph/aidl/vts/functional/sink.rs
index bb357b8..a331eef 100644
--- a/security/authgraph/aidl/vts/functional/sink.rs
+++ b/security/authgraph/aidl/vts/functional/sink.rs
@@ -29,11 +29,11 @@
}
/// Perform mainline AuthGraph key exchange with the provided sink and local implementation.
-/// Return the agreed AES keys in plaintext.
+/// Return the agreed AES keys in plaintext, together with the session ID.
pub fn test_mainline(
local_source: &mut ke::AuthGraphParticipant,
sink: binder::Strong<dyn IAuthGraphKeyExchange>,
-) -> [key::AesKey; 2] {
+) -> ([key::AesKey; 2], Vec<u8>) {
// Step 1: create an ephemeral ECDH key at the (local) source.
let source_init_info = local_source
.create()
@@ -113,7 +113,7 @@
Ok(array) => array,
Err(_) => panic!("wrong number of decrypted shared key arcs"),
};
- decrypted_shared_keys_array
+ (decrypted_shared_keys_array, sink_info.sessionId)
}
/// Perform mainline AuthGraph key exchange with the provided sink, but provide an invalid
diff --git a/security/authgraph/aidl/vts/functional/source.rs b/security/authgraph/aidl/vts/functional/source.rs
index 4178a99..019e1e8 100644
--- a/security/authgraph/aidl/vts/functional/source.rs
+++ b/security/authgraph/aidl/vts/functional/source.rs
@@ -29,11 +29,11 @@
}
/// Perform mainline AuthGraph key exchange with the provided source.
-/// Return the agreed AES keys in plaintext.
+/// Return the agreed AES keys in plaintext, together with the session ID.
pub fn test_mainline(
local_sink: &mut ke::AuthGraphParticipant,
source: binder::Strong<dyn IAuthGraphKeyExchange>,
-) -> [key::AesKey; 2] {
+) -> ([key::AesKey; 2], Vec<u8>) {
// Step 1: create an ephemeral ECDH key at the (remote) source.
let source_init_info = source
.create()
@@ -120,7 +120,7 @@
Ok(array) => array,
Err(_) => panic!("wrong number of decrypted shared key arcs"),
};
- decrypted_shared_keys_array
+ (decrypted_shared_keys_array, source_info.sessionId)
}
/// Perform mainline AuthGraph key exchange with the provided source, but provide an invalid session
@@ -250,9 +250,13 @@
&corrupt_key,
);
- let err = result.expect_err("expect failure with corrupt signature");
- assert_eq!(
- err,
- binder::Status::new_service_specific_error(Error::INVALID_PRIV_KEY_ARC_IN_KEY.0, None)
+ let err = result.expect_err("expect failure with corrupt key");
+ assert!(
+ err == binder::Status::new_service_specific_error(Error::INVALID_KE_KEY.0, None)
+ || err
+ == binder::Status::new_service_specific_error(
+ Error::INVALID_PRIV_KEY_ARC_IN_KEY.0,
+ None
+ )
);
}
diff --git a/security/authgraph/default/Android.bp b/security/authgraph/default/Android.bp
index c481075..7894477 100644
--- a/security/authgraph/default/Android.bp
+++ b/security/authgraph/default/Android.bp
@@ -46,11 +46,11 @@
name: "android.hardware.security.authgraph-service.nonsecure",
relative_install_path: "hw",
vendor: true,
- init_rc: ["authgraph.rc"],
- vintf_fragments: ["authgraph.xml"],
+ installable: false, // install com.android.hardware.security.authgraph
defaults: [
"authgraph_use_latest_hal_aidl_rust",
],
+ prefer_rlib: true,
rustlibs: [
"libandroid_logger",
"libauthgraph_hal",
@@ -80,3 +80,34 @@
],
},
}
+
+prebuilt_etc {
+ name: "authgraph.xml",
+ src: "authgraph.xml",
+ sub_dir: "vintf",
+ installable: false,
+}
+
+prebuilt_etc {
+ name: "authgraph.rc",
+ src: "authgraph.rc",
+ installable: false,
+}
+
+apex {
+ name: "com.android.hardware.security.authgraph",
+ manifest: "apex_manifest.json",
+ file_contexts: "apex_file_contexts",
+ key: "com.android.hardware.key",
+ certificate: ":com.android.hardware.certificate",
+ vendor: true,
+ updatable: false,
+
+ binaries: [
+ "android.hardware.security.authgraph-service.nonsecure",
+ ],
+ prebuilts: [
+ "authgraph.rc",
+ "authgraph.xml",
+ ],
+}
diff --git a/security/authgraph/default/apex_file_contexts b/security/authgraph/default/apex_file_contexts
new file mode 100644
index 0000000..9a54613
--- /dev/null
+++ b/security/authgraph/default/apex_file_contexts
@@ -0,0 +1,3 @@
+(/.*)? u:object_r:vendor_file:s0
+/etc(/.*)? u:object_r:vendor_configs_file:s0
+/bin/hw/android\.hardware\.security\.authgraph-service\.nonsecure u:object_r:hal_authgraph_default_exec:s0
diff --git a/security/authgraph/default/apex_manifest.json b/security/authgraph/default/apex_manifest.json
new file mode 100644
index 0000000..0723846
--- /dev/null
+++ b/security/authgraph/default/apex_manifest.json
@@ -0,0 +1,4 @@
+{
+ "name": "com.android.hardware.security.authgraph",
+ "version": 1
+}
\ No newline at end of file
diff --git a/security/authgraph/default/authgraph.rc b/security/authgraph/default/authgraph.rc
index 0222994..2d07542 100644
--- a/security/authgraph/default/authgraph.rc
+++ b/security/authgraph/default/authgraph.rc
@@ -1,4 +1,4 @@
-service vendor.authgraph /vendor/bin/hw/android.hardware.security.authgraph-service.nonsecure
+service vendor.authgraph /apex/com.android.hardware.security.authgraph/bin/hw/android.hardware.security.authgraph-service.nonsecure
interface aidl android.hardware.security.authgraph.IAuthGraph/nonsecure
class hal
user nobody
diff --git a/security/authgraph/default/src/fuzzer.rs b/security/authgraph/default/src/fuzzer.rs
index d401777..387d72f 100644
--- a/security/authgraph/default/src/fuzzer.rs
+++ b/security/authgraph/default/src/fuzzer.rs
@@ -22,10 +22,9 @@
use authgraph_nonsecure::LocalTa;
use binder_random_parcel_rs::fuzz_service;
use libfuzzer_sys::fuzz_target;
-use std::sync::{Arc, Mutex};
fuzz_target!(|data: &[u8]| {
let local_ta = LocalTa::new().expect("Failed to create an AuthGraph local TA.");
- let service = AuthGraphService::new_as_binder(Arc::new(Mutex::new(local_ta)));
+ let service = AuthGraphService::new_as_binder(local_ta);
fuzz_service(&mut service.as_binder(), data);
});
diff --git a/security/authgraph/default/src/lib.rs b/security/authgraph/default/src/lib.rs
index 43d037c..1d6ffb3 100644
--- a/security/authgraph/default/src/lib.rs
+++ b/security/authgraph/default/src/lib.rs
@@ -18,67 +18,80 @@
use authgraph_boringssl as boring;
use authgraph_core::{
- error,
- key::MillisecondsSinceEpoch,
- keyexchange,
+ error, keyexchange,
ta::{AuthGraphTa, Role},
- traits,
};
use authgraph_hal::channel::SerializedChannel;
-use std::sync::{Arc, Mutex};
-use std::time::Instant;
-
-/// Monotonic clock with an epoch that starts at the point of construction.
-/// (This makes it unsuitable for use outside of testing, because the epoch
-/// will not match that of any other component.)
-pub struct StdClock(Instant);
-
-impl Default for StdClock {
- fn default() -> Self {
- Self(Instant::now())
- }
-}
-
-impl traits::MonotonicClock for StdClock {
- fn now(&self) -> MillisecondsSinceEpoch {
- let millis: i64 = self
- .0
- .elapsed()
- .as_millis()
- .try_into()
- .expect("failed to fit timestamp in i64");
- MillisecondsSinceEpoch(millis)
- }
-}
+use log::error;
+use std::cell::RefCell;
+use std::rc::Rc;
+use std::sync::{mpsc, Mutex};
/// Implementation of the AuthGraph TA that runs locally in-process (and which is therefore
/// insecure).
pub struct LocalTa {
- ta: Arc<Mutex<AuthGraphTa>>,
+ channels: Mutex<Channels>,
+}
+
+struct Channels {
+ in_tx: mpsc::Sender<Vec<u8>>,
+ out_rx: mpsc::Receiver<Vec<u8>>,
}
impl LocalTa {
/// Create a new instance.
pub fn new() -> Result<Self, error::Error> {
- Ok(Self {
- ta: Arc::new(Mutex::new(AuthGraphTa::new(
+ // Create a pair of channels to communicate with the TA thread.
+ let (in_tx, in_rx) = mpsc::channel();
+ let (out_tx, out_rx) = mpsc::channel();
+
+ // The TA code expects to run single threaded, so spawn a thread to run it in.
+ std::thread::spawn(move || {
+ let mut ta = AuthGraphTa::new(
keyexchange::AuthGraphParticipant::new(
boring::crypto_trait_impls(),
- Box::<boring::test_device::AgDevice>::default(),
+ Rc::new(RefCell::new(boring::test_device::AgDevice::default())),
keyexchange::MAX_OPENED_SESSIONS,
- )?,
+ )
+ .expect("failed to create AG participant"),
Role::Both,
- ))),
+ );
+ // Loop forever processing request messages.
+ loop {
+ let req_data: Vec<u8> = match in_rx.recv() {
+ Ok(data) => data,
+ Err(_) => {
+ error!("local TA failed to receive request!");
+ break;
+ }
+ };
+ let rsp_data = ta.process(&req_data);
+ match out_tx.send(rsp_data) {
+ Ok(_) => {}
+ Err(_) => {
+ error!("local TA failed to send out response");
+ break;
+ }
+ }
+ }
+ error!("local TA terminating!");
+ });
+ Ok(Self {
+ channels: Mutex::new(Channels { in_tx, out_rx }),
})
}
}
-/// Pretend to be a serialized channel to the TA, but actually just directly invoke the TA with
-/// incoming requests.
impl SerializedChannel for LocalTa {
const MAX_SIZE: usize = usize::MAX;
- fn execute(&mut self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
- Ok(self.ta.lock().unwrap().process(req_data))
+ fn execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
+ // Serialize across both request and response.
+ let channels = self.channels.lock().unwrap();
+ channels
+ .in_tx
+ .send(req_data.to_vec())
+ .expect("failed to send in request");
+ Ok(channels.out_rx.recv().expect("failed to receive response"))
}
}
diff --git a/security/authgraph/default/src/main.rs b/security/authgraph/default/src/main.rs
index 81f2dd6..65ced75 100644
--- a/security/authgraph/default/src/main.rs
+++ b/security/authgraph/default/src/main.rs
@@ -25,7 +25,6 @@
use authgraph_hal::service;
use authgraph_nonsecure::LocalTa;
use log::{error, info};
-use std::sync::{Arc, Mutex};
static SERVICE_NAME: &str = "android.hardware.security.authgraph.IAuthGraphKeyExchange";
static SERVICE_INSTANCE: &str = "nonsecure";
@@ -51,8 +50,8 @@
android_logger::init_once(
android_logger::Config::default()
.with_tag("authgraph-hal-nonsecure")
- .with_min_level(log::Level::Info)
- .with_log_id(android_logger::LogId::System),
+ .with_max_level(log::LevelFilter::Info)
+ .with_log_buffer(android_logger::LogId::System),
);
// Redirect panic messages to logcat.
std::panic::set_hook(Box::new(|panic_info| {
@@ -65,9 +64,8 @@
binder::ProcessState::start_thread_pool();
// Register the service
- let local_ta =
- LocalTa::new().map_err(|e| format!("Failed to create the TA because: {e:?}"))?;
- let service = service::AuthGraphService::new_as_binder(Arc::new(Mutex::new(local_ta)));
+ let local_ta = LocalTa::new().map_err(|e| format!("Failed to create the TA because: {e:?}"))?;
+ let service = service::AuthGraphService::new_as_binder(local_ta);
let service_name = format!("{}/{}", SERVICE_NAME, SERVICE_INSTANCE);
binder::add_service(&service_name, service.as_binder()).map_err(|e| {
format!(
diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
index aa7bf28..be29f59 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
@@ -974,8 +974,8 @@
* time in milliseconds. This value is used when generating attestation or self signed
* certificates. ErrorCode::MISSING_NOT_BEFORE must be returned if this tag is not provided if
* this tag is not provided to generateKey or importKey. For importWrappedKey, there is no way
- * to specify the value of this tag for the wrapped key, so a value of 0 must be used for
- * certificate generation.
+ * to specify the value of this tag for a wrapped asymmetric key, so a value of 0 is suggested
+ * for certificate generation.
*/
CERTIFICATE_NOT_BEFORE = TagType.DATE | 1008,
@@ -983,8 +983,9 @@
* Tag::CERTIFICATE_NOT_AFTER the end of the validity of the certificate in UNIX epoch time in
* milliseconds. This value is used when generating attestation or self signed certificates.
* ErrorCode::MISSING_NOT_AFTER must be returned if this tag is not provided to generateKey or
- * importKey. For importWrappedKey, there is no way to specify the value of this tag for the
- * wrapped key, so a value of 253402300799000 is used for certificate generation.
+ * importKey. For importWrappedKey, there is no way to specify the value of this tag for a
+ * wrapped asymmetric key, so a value of 253402300799000 is suggested for certificate
+ * generation.
*/
CERTIFICATE_NOT_AFTER = TagType.DATE | 1009,
diff --git a/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp b/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp
index 54f187c..808ed18 100644
--- a/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp
+++ b/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp
@@ -149,7 +149,9 @@
digest512.data());
ASSERT_TRUE((attestedVbmetaDigest_ == digest256) || (attestedVbmetaDigest_ == digest512))
- << "Attested digest does not match computed digest.";
+ << "Attested vbmeta digest (" << bin2hex(attestedVbmetaDigest_)
+ << ") does not match computed digest (sha256: " << bin2hex(digest256)
+ << ", sha512: " << bin2hex(digest512) << ").";
}
INSTANTIATE_KEYMINT_AIDL_TEST(BootloaderStateTest);
diff --git a/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp b/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp
index 7ccd246..c2509b8 100644
--- a/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp
@@ -258,7 +258,8 @@
if (upgraded_keyblob.empty()) {
std::cerr << "Keyblob '" << name << "' did not require upgrade\n";
- EXPECT_TRUE(!expectUpgrade) << "Keyblob '" << name << "' unexpectedly upgraded";
+ EXPECT_FALSE(expectUpgrade)
+ << "Keyblob '" << name << "' unexpectedly left as-is";
} else {
// Ensure the old format keyblob is deleted (so any secure deletion data is
// cleaned up).
@@ -275,8 +276,7 @@
save_keyblob(subdir, name, upgraded_keyblob, key_characteristics);
// Cert file is left unchanged.
std::cerr << "Keyblob '" << name << "' upgraded\n";
- EXPECT_TRUE(expectUpgrade)
- << "Keyblob '" << name << "' unexpectedly left as-is";
+ EXPECT_TRUE(expectUpgrade) << "Keyblob '" << name << "' unexpectedly upgraded";
}
}
}
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 822770d..087f763 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -64,6 +64,13 @@
namespace {
+// Possible values for the feature version. Assumes that future KeyMint versions
+// will continue with the 100 * AIDL_version numbering scheme.
+//
+// Must be kept in numerically increasing order.
+const int32_t kFeatureVersions[] = {10, 11, 20, 30, 40, 41, 100, 200,
+ 300, 400, 500, 600, 700, 800, 900};
+
// Invalid value for a patchlevel (which is of form YYYYMMDD).
const uint32_t kInvalidPatchlevel = 99998877;
@@ -1792,6 +1799,12 @@
std::string empty_boot_key(32, '\0');
std::string verified_boot_key_str((const char*)verified_boot_key.data(),
verified_boot_key.size());
+ if (get_vsr_api_level() >= __ANDROID_API_V__) {
+ // The attestation should contain the SHA-256 hash of the verified boot
+ // key. However, this was not checked for earlier versions of the KeyMint
+ // HAL so only be strict for VSR-V and above.
+ EXPECT_LE(verified_boot_key.size(), 32);
+ }
EXPECT_NE(property_get("ro.boot.verifiedbootstate", property_value, ""), 0);
if (!strcmp(property_value, "green")) {
EXPECT_EQ(verified_boot_state, VerifiedBoot::VERIFIED);
@@ -2272,6 +2285,43 @@
return hasFeature;
}
+// Return the numeric value associated with a feature.
+std::optional<int32_t> keymint_feature_value(bool strongbox) {
+ std::string name = strongbox ? FEATURE_STRONGBOX_KEYSTORE : FEATURE_HARDWARE_KEYSTORE;
+ ::android::String16 name16(name.c_str());
+ ::android::sp<::android::IServiceManager> sm(::android::defaultServiceManager());
+ ::android::sp<::android::IBinder> binder(
+ sm->waitForService(::android::String16("package_native")));
+ if (binder == nullptr) {
+ GTEST_LOG_(ERROR) << "waitForService package_native failed";
+ return std::nullopt;
+ }
+ ::android::sp<::android::content::pm::IPackageManagerNative> packageMgr =
+ ::android::interface_cast<::android::content::pm::IPackageManagerNative>(binder);
+ if (packageMgr == nullptr) {
+ GTEST_LOG_(ERROR) << "Cannot find package manager";
+ return std::nullopt;
+ }
+
+ // Package manager has no mechanism to retrieve the version of a feature,
+ // only to indicate whether a certain version or above is present.
+ std::optional<int32_t> result = std::nullopt;
+ for (auto version : kFeatureVersions) {
+ bool hasFeature = false;
+ auto status = packageMgr->hasSystemFeature(name16, version, &hasFeature);
+ if (!status.isOk()) {
+ GTEST_LOG_(ERROR) << "hasSystemFeature('" << name << "', " << version
+ << ") failed: " << status;
+ return result;
+ } else if (hasFeature) {
+ result = version;
+ } else {
+ break;
+ }
+ }
+ return result;
+}
+
} // namespace test
} // namespace aidl::android::hardware::security::keymint
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index 4fb711c..4ed7698 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -56,6 +56,7 @@
const string FEATURE_KEYSTORE_APP_ATTEST_KEY = "android.hardware.keystore.app_attest_key";
const string FEATURE_STRONGBOX_KEYSTORE = "android.hardware.strongbox_keystore";
+const string FEATURE_HARDWARE_KEYSTORE = "android.hardware.hardware_keystore";
// RAII class to ensure that a keyblob is deleted regardless of how a test exits.
class KeyBlobDeleter {
@@ -444,6 +445,7 @@
void p256_pub_key(const vector<uint8_t>& coseKeyData, EVP_PKEY_Ptr* signingKey);
void device_id_attestation_check_acceptable_error(Tag tag, const ErrorCode& result);
bool check_feature(const std::string& name);
+std::optional<int32_t> keymint_feature_value(bool strongbox);
AuthorizationSet HwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
AuthorizationSet SwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index a8f17dd..0b7627c 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -21,6 +21,7 @@
#include <algorithm>
#include <iostream>
+#include <map>
#include <openssl/curve25519.h>
#include <openssl/ec.h>
@@ -1027,9 +1028,9 @@
* The KeyMint V1 spec required that CERTIFICATE_NOT_{BEFORE,AFTER} be
* specified for asymmetric key generation. However, this was not
* checked at the time so we can only be strict about checking this for
- * implementations of KeyMint version 2 and above.
+ * implementations of KeyMint version 3 and above.
*/
- GTEST_SKIP() << "Validity strict since KeyMint v2";
+ GTEST_SKIP() << "Validity strict since KeyMint v3";
}
// Per RFC 5280 4.1.2.5, an undefined expiration (not-after) field should be set to
// GeneralizedTime 999912312359559, which is 253402300799000 ms from Jan 1, 1970.
@@ -1063,32 +1064,53 @@
TEST_P(NewKeyGenerationTest, RsaWithSpecifiedValidity) {
vector<uint8_t> key_blob;
vector<KeyCharacteristics> key_characteristics;
- ASSERT_EQ(ErrorCode::OK,
- GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(2048, 65537)
- .Digest(Digest::NONE)
- .Padding(PaddingMode::NONE)
- .Authorization(TAG_CERTIFICATE_NOT_BEFORE,
- 1183806000000 /* 2007-07-07T11:00:00Z */)
- .Authorization(TAG_CERTIFICATE_NOT_AFTER,
- 1916049600000 /* 2030-09-19T12:00:00Z */),
- &key_blob, &key_characteristics));
- ASSERT_GT(cert_chain_.size(), 0);
+ vector<uint64_t> test_vector_not_before_millis = {
+ 458046000000, /* 1984-07-07T11:00:00Z */
+ 1183806000000, /* 2007-07-07T11:00:00Z */
+ 1924991999000, /* 2030-12-31T23:59:59Z */
+ 3723753599000, /* 2087-12-31T23:59:59Z */
+ 26223868799000, /* 2800-12-31T23:59:59Z */
+ 45157996799000, /* 3400-12-31T23:59:59Z */
+ 60719587199000, /* 3894-02-15T23:59:59Z */
+ 95302051199000, /* 4989-12-31T23:59:59Z */
+ 86182012799000, /* 4700-12-31T23:59:59Z */
+ 111427574399000, /* 5500-12-31T23:59:59Z */
+ 136988668799000, /* 6310-12-31T23:59:59Z */
+ 139828895999000, /* 6400-12-31T23:59:59Z */
+ 169839503999000, /* 7351-12-31T23:59:59Z */
+ 171385804799000, /* 7400-12-31T23:59:59Z */
+ 190320019199000, /* 8000-12-31T23:59:59Z */
+ 193475692799000, /* 8100-12-31T23:59:59Z */
+ 242515209599000, /* 9654-12-31T23:59:59Z */
+ 250219065599000, /* 9899-02-15T23:59:59Z */
+ };
+ for (auto notBefore : test_vector_not_before_millis) {
+ uint64_t notAfter = notBefore + 378691200000 /* 12 years milliseconds*/;
+ ASSERT_EQ(ErrorCode::OK,
+ GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(2048, 65537)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE)
+ .Authorization(TAG_CERTIFICATE_NOT_BEFORE, notBefore)
+ .Authorization(TAG_CERTIFICATE_NOT_AFTER, notAfter),
+ &key_blob, &key_characteristics));
+ ASSERT_GT(cert_chain_.size(), 0);
- X509_Ptr cert(parse_cert_blob(cert_chain_[0].encodedCertificate));
- ASSERT_TRUE(!!cert.get());
+ X509_Ptr cert(parse_cert_blob(cert_chain_[0].encodedCertificate));
+ ASSERT_TRUE(!!cert.get());
- const ASN1_TIME* not_before = X509_get0_notBefore(cert.get());
- ASSERT_NE(not_before, nullptr);
- time_t not_before_time;
- ASSERT_EQ(ASN1_TIME_to_time_t(not_before, ¬_before_time), 1);
- EXPECT_EQ(not_before_time, 1183806000);
+ const ASN1_TIME* not_before = X509_get0_notBefore(cert.get());
+ ASSERT_NE(not_before, nullptr);
+ time_t not_before_time;
+ ASSERT_EQ(ASN1_TIME_to_time_t(not_before, ¬_before_time), 1);
+ EXPECT_EQ(not_before_time, (notBefore / 1000));
- const ASN1_TIME* not_after = X509_get0_notAfter(cert.get());
- ASSERT_NE(not_after, nullptr);
- time_t not_after_time;
- ASSERT_EQ(ASN1_TIME_to_time_t(not_after, ¬_after_time), 1);
- EXPECT_EQ(not_after_time, 1916049600);
+ const ASN1_TIME* not_after = X509_get0_notAfter(cert.get());
+ ASSERT_NE(not_after, nullptr);
+ time_t not_after_time;
+ ASSERT_EQ(ASN1_TIME_to_time_t(not_after, ¬_after_time), 1);
+ EXPECT_EQ(not_after_time, (notAfter / 1000));
+ }
}
/*
@@ -4123,13 +4145,13 @@
* when the EC_CURVE is not explicitly specified.
*/
TEST_P(ImportKeyTest, EcdsaSuccessCurveNotSpecified) {
- if (AidlVersion() < 4) {
+ if (get_vsr_api_level() < __ANDROID_API_V__) {
/*
- * The KeyMint spec before V4 was not clear as to whether EC_CURVE was optional on import of
- * EC keys. However, this was not checked at the time so we can only be strict about
- * checking this for implementations of KeyMint version 4 and above.
+ * The KeyMint spec was previously not clear as to whether EC_CURVE was optional on import
+ * of EC keys. However, this was not checked at the time so we can only be strict about
+ * checking this for implementations at VSR-V or later.
*/
- GTEST_SKIP() << "Skipping EC_CURVE on import only strict since KeyMint v4";
+ GTEST_SKIP() << "Skipping EC_CURVE on import only strict >= VSR-V";
}
ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder()
@@ -8794,12 +8816,97 @@
INSTANTIATE_KEYMINT_AIDL_TEST(VsrRequirementTest);
+class InstanceTest : public testing::Test {
+ protected:
+ static void SetUpTestSuite() {
+ auto params = ::android::getAidlHalInstanceNames(IKeyMintDevice::descriptor);
+ for (auto& param : params) {
+ ASSERT_TRUE(AServiceManager_isDeclared(param.c_str()))
+ << "IKeyMintDevice instance " << param << " found but not declared.";
+ ::ndk::SpAIBinder binder(AServiceManager_waitForService(param.c_str()));
+ auto keymint = IKeyMintDevice::fromBinder(binder);
+ ASSERT_NE(keymint, nullptr) << "Failed to get IKeyMintDevice instance " << param;
+
+ KeyMintHardwareInfo info;
+ ASSERT_TRUE(keymint->getHardwareInfo(&info).isOk());
+ ASSERT_EQ(keymints_.count(info.securityLevel), 0)
+ << "There must be exactly one IKeyMintDevice with security level "
+ << info.securityLevel;
+
+ keymints_[info.securityLevel] = std::move(keymint);
+ }
+ }
+
+ int32_t AidlVersion(shared_ptr<IKeyMintDevice> keymint) {
+ int32_t version = 0;
+ auto status = keymint->getInterfaceVersion(&version);
+ if (!status.isOk()) {
+ ADD_FAILURE() << "Failed to determine interface version";
+ }
+ return version;
+ }
+
+ static std::map<SecurityLevel, shared_ptr<IKeyMintDevice>> keymints_;
+};
+
+std::map<SecurityLevel, shared_ptr<IKeyMintDevice>> InstanceTest::keymints_;
+
+// @VsrTest = VSR-3.10-017
+// Check that the AIDL version advertised by the HAL service matches
+// the value in the package manager feature version.
+TEST_F(InstanceTest, AidlVersionInFeature) {
+ if (is_gsi_image()) {
+ GTEST_SKIP() << "Versions not required to match under GSI";
+ }
+ if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 1) {
+ auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
+ int32_t tee_aidl_version = AidlVersion(tee) * 100;
+ std::optional<int32_t> tee_feature_version = keymint_feature_value(/* strongbox */ false);
+ ASSERT_TRUE(tee_feature_version.has_value());
+ EXPECT_EQ(tee_aidl_version, tee_feature_version.value());
+ }
+ if (keymints_.count(SecurityLevel::STRONGBOX) == 1) {
+ auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
+ int32_t sb_aidl_version = AidlVersion(sb) * 100;
+ std::optional<int32_t> sb_feature_version = keymint_feature_value(/* strongbox */ true);
+ ASSERT_TRUE(sb_feature_version.has_value());
+ EXPECT_EQ(sb_aidl_version, sb_feature_version.value());
+ }
+}
+
+// @VsrTest = VSR-3.10-017
+// Check that if package manager advertises support for KeyMint of a particular version, that
+// version is present as a HAL service.
+TEST_F(InstanceTest, FeatureVersionInAidl) {
+ if (is_gsi_image()) {
+ GTEST_SKIP() << "Versions not required to match under GSI";
+ }
+ std::optional<int32_t> tee_feature_version = keymint_feature_value(/* strongbox */ false);
+ if (tee_feature_version.has_value() && tee_feature_version.value() >= 100) {
+ // Feature flag advertises the existence of KeyMint; check it is present.
+ ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
+ auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
+ int32_t tee_aidl_version = AidlVersion(tee) * 100;
+ EXPECT_EQ(tee_aidl_version, tee_feature_version.value());
+ }
+
+ std::optional<int32_t> sb_feature_version = keymint_feature_value(/* strongbox */ true);
+ if (sb_feature_version.has_value() && sb_feature_version.value() >= 100) {
+ // Feature flag advertises the existence of KeyMint; check it is present.
+ ASSERT_EQ(keymints_.count(SecurityLevel::STRONGBOX), 1);
+ auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
+ int32_t sb_aidl_version = AidlVersion(sb) * 100;
+ EXPECT_EQ(sb_aidl_version, sb_feature_version.value());
+ }
+}
+
} // namespace aidl::android::hardware::security::keymint::test
+using aidl::android::hardware::security::keymint::test::KeyMintAidlTestBase;
+
int main(int argc, char** argv) {
std::cout << "Testing ";
- auto halInstances =
- aidl::android::hardware::security::keymint::test::KeyMintAidlTestBase::build_params();
+ auto halInstances = KeyMintAidlTestBase::build_params();
std::cout << "HAL instances:\n";
for (auto& entry : halInstances) {
std::cout << " " << entry << '\n';
@@ -8809,12 +8916,10 @@
for (int i = 1; i < argc; ++i) {
if (argv[i][0] == '-') {
if (std::string(argv[i]) == "--arm_deleteAllKeys") {
- aidl::android::hardware::security::keymint::test::KeyMintAidlTestBase::
- arm_deleteAllKeys = true;
+ KeyMintAidlTestBase::arm_deleteAllKeys = true;
}
if (std::string(argv[i]) == "--dump_attestations") {
- aidl::android::hardware::security::keymint::test::KeyMintAidlTestBase::
- dump_Attestations = true;
+ KeyMintAidlTestBase::dump_Attestations = true;
} else {
std::cout << "NOT dumping attestations" << std::endl;
}
@@ -8829,8 +8934,7 @@
std::cerr << "Missing argument for --keyblob_dir\n";
return 1;
}
- aidl::android::hardware::security::keymint::test::KeyMintAidlTestBase::keyblob_dir =
- std::string(argv[i + 1]);
+ KeyMintAidlTestBase::keyblob_dir = std::string(argv[i + 1]);
++i;
}
if (std::string(argv[i]) == "--expect_upgrade") {
@@ -8839,11 +8943,17 @@
return 1;
}
std::string arg = argv[i + 1];
- aidl::android::hardware::security::keymint::test::KeyMintAidlTestBase::
- expect_upgrade =
- arg == "yes"
- ? true
- : (arg == "no" ? false : std::optional<bool>(std::nullopt));
+ KeyMintAidlTestBase::expect_upgrade =
+ arg == "yes" ? true
+ : (arg == "no" ? false : std::optional<bool>(std::nullopt));
+ if (KeyMintAidlTestBase::expect_upgrade.has_value()) {
+ std::cout << "expect_upgrade = "
+ << (KeyMintAidlTestBase::expect_upgrade.value() ? "true" : "false")
+ << std::endl;
+ } else {
+ std::cerr << "Error! Option --expect_upgrade " << arg << " unrecognized"
+ << std::endl;
+ }
++i;
}
}
diff --git a/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp b/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp
index c9a156d..9f7322a 100644
--- a/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp
+++ b/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp
@@ -114,6 +114,12 @@
const auto& vbKey = rot->asArray()->get(pos++);
ASSERT_TRUE(vbKey);
ASSERT_TRUE(vbKey->asBstr());
+ if (get_vsr_api_level() >= __ANDROID_API_V__) {
+ // The attestation should contain the SHA-256 hash of the verified boot
+ // key. However, this not was checked for earlier versions of the KeyMint
+ // HAL so only be strict for VSR-V and above.
+ ASSERT_LE(vbKey->asBstr()->value().size(), 32);
+ }
const auto& deviceLocked = rot->asArray()->get(pos++);
ASSERT_TRUE(deviceLocked);
diff --git a/security/keymint/support/include/remote_prov/remote_prov_utils.h b/security/keymint/support/include/remote_prov/remote_prov_utils.h
index 79189a1..b8c69eb 100644
--- a/security/keymint/support/include/remote_prov/remote_prov_utils.h
+++ b/security/keymint/support/include/remote_prov/remote_prov_utils.h
@@ -17,6 +17,7 @@
#pragma once
#include <memory>
+#include <string>
#include <vector>
#include "aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h"
@@ -129,8 +130,8 @@
* "name": <string>
* }
*/
-JsonOutput jsonEncodeCsrWithBuild(const std::string instance_name,
- const cppbor::Array& csr);
+JsonOutput jsonEncodeCsrWithBuild(const std::string& instance_name, const cppbor::Array& csr,
+ const std::string& serialno_prop);
/**
* Parses a DeviceInfo structure from the given CBOR data. The parsed data is then validated to
diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp
index 34f7ce4..a830041 100644
--- a/security/keymint/support/remote_prov_utils.cpp
+++ b/security/keymint/support/remote_prov_utils.cpp
@@ -337,9 +337,9 @@
return result;
}
-JsonOutput jsonEncodeCsrWithBuild(const std::string instance_name, const cppbor::Array& csr) {
+JsonOutput jsonEncodeCsrWithBuild(const std::string& instance_name, const cppbor::Array& csr,
+ const std::string& serialno_prop) {
const std::string kFingerprintProp = "ro.build.fingerprint";
- const std::string kSerialNoProp = "ro.serialno";
if (!::android::base::WaitForPropertyCreation(kFingerprintProp)) {
return JsonOutput::Error("Unable to read build fingerprint");
@@ -364,7 +364,7 @@
Json::Value json(Json::objectValue);
json["name"] = instance_name;
json["build_fingerprint"] = ::android::base::GetProperty(kFingerprintProp, /*default=*/"");
- json["serialno"] = ::android::base::GetProperty(kSerialNoProp, /*default=*/"");
+ json["serialno"] = ::android::base::GetProperty(serialno_prop, /*default=*/"");
json["csr"] = base64.data(); // Boring writes a NUL-terminated c-string
Json::StreamWriterBuilder factory;
@@ -520,6 +520,15 @@
std::to_string(info.versionNumber) + ").";
}
}
+ // Bypasses the device info validation since the device info in AVF is currently
+ // empty. Check b/299256925 for more information.
+ //
+ // TODO(b/300911665): This check is temporary and will be replaced once the markers
+ // on the DICE chain become available. We need to determine if the CSR is from the
+ // RKP VM using the markers on the DICE chain.
+ if (info.uniqueId == "AVF Remote Provisioning 1") {
+ return std::move(parsed);
+ }
std::string error;
std::string tmp;
@@ -969,7 +978,7 @@
return hwtrust::DiceChain::Kind::kVsr13;
case __ANDROID_API_U__:
return hwtrust::DiceChain::Kind::kVsr14;
- case __ANDROID_API_V__:
+ case 202404: /* TODO(b/315056516) Use a version macro for vendor API 24Q2 */
return hwtrust::DiceChain::Kind::kVsr15;
default:
return "Unsupported vendor API level: " + std::to_string(vendor_api_level);
diff --git a/security/keymint/support/remote_prov_utils_test.cpp b/security/keymint/support/remote_prov_utils_test.cpp
index eaaba45..89469f1 100644
--- a/security/keymint/support/remote_prov_utils_test.cpp
+++ b/security/keymint/support/remote_prov_utils_test.cpp
@@ -14,20 +14,23 @@
* limitations under the License.
*/
-#include "cppbor.h"
-#include "keymaster/cppcose/cppcose.h"
#include <aidl/android/hardware/security/keymint/RpcHardwareInfo.h>
#include <android-base/properties.h>
+#include <cppbor.h>
#include <cppbor_parse.h>
-#include <cstdint>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/cppcose/cppcose.h>
#include <keymaster/logger.h>
#include <keymaster/remote_provisioning_utils.h>
#include <openssl/curve25519.h>
#include <remote_prov/remote_prov_utils.h>
+#include <algorithm>
+#include <cstdint>
+#include <span>
+
namespace aidl::android::hardware::security::keymint::remote_prov {
namespace {
@@ -36,7 +39,11 @@
using ::keymaster::kStatusInvalidEek;
using ::keymaster::StatusOr;
using ::testing::ElementsAreArray;
-using byte_view = std::basic_string_view<uint8_t>;
+using byte_view = std::span<const uint8_t>;
+
+inline bool equal_byte_views(const byte_view& view1, const byte_view& view2) {
+ return std::equal(view1.begin(), view1.end(), view2.begin(), view2.end());
+}
struct KeyInfoEcdsa {
CoseKeyCurve curve;
@@ -44,7 +51,8 @@
byte_view pubKeyY;
bool operator==(const KeyInfoEcdsa& other) const {
- return curve == other.curve && pubKeyX == other.pubKeyX && pubKeyY == other.pubKeyY;
+ return curve == other.curve && equal_byte_views(pubKeyX, other.pubKeyX) &&
+ equal_byte_views(pubKeyY, other.pubKeyY);
}
};
@@ -182,10 +190,11 @@
}
TEST(RemoteProvUtilsTest, JsonEncodeCsr) {
+ const std::string kSerialNoProp = "ro.serialno";
cppbor::Array array;
array.add(1);
- auto [json, error] = jsonEncodeCsrWithBuild(std::string("test"), array);
+ auto [json, error] = jsonEncodeCsrWithBuild(std::string("test"), array, kSerialNoProp);
ASSERT_TRUE(error.empty()) << error;
diff --git a/security/rkp/README.md b/security/rkp/README.md
index 15ea817..2d00b83 100644
--- a/security/rkp/README.md
+++ b/security/rkp/README.md
@@ -190,3 +190,30 @@
* [RpcHardwareInfo](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl)
* [DeviceInfo](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/DeviceInfo.aidl)
+### Support for Android Virtualization Framework
+
+The Android Virtualization Framwork (AVF) relies on RKP to provision keys for VMs. A
+privileged vm, the RKP VM, is reponsible for generating and managing the keys for client
+VMs that run virtualized workloads. See the following for more background information on the
+RKP VM:
+* [rkp-vm](https://android.googlesource.com/platform/packages/modules/Virtualization/+/main/service_vm/README.md#rkp-vm-remote-key-provisioning-virtual-machine)
+* [rkp-service](https://source.android.com/docs/core/ota/modular-system/remote-key-provisioning#stack-architecture)
+
+It is important to distinquish the RKP VM from other components, such as KeyMint. An
+[RKP VM marker](https://pigweed.googlesource.com/open-dice/+/HEAD/docs/android.md#configuration-descriptor)
+(key `-70006) is used for this purpose. The existence or absence of this marker is used to
+identify the type of component decribed by a given DICE chain.
+
+The following describes which certificate types may be request based on the RKP VM marker:
+1. "rkp-vm": If a DICE chain has zero or more certificates without the RKP VM
+ marker followed by one or more certificates with the marker, then that chain
+ describes an RKP VM. If there are further certificates without the RKP VM
+ marker, then the chain does not describe an RKP VM.
+
+ Implementations must include the first RKP VM marker as early as possible
+ after the point of divergence between TEE and non-TEE components in the DICE
+ chain, prior to loading the Android Bootloader (ABL).
+2. "widevine" or "keymint": If there are no certificates with the RKP VM
+ marker then it describes a TEE component.
+3. None: Any component described by a DICE chain that does not match the above
+ two categories.
diff --git a/security/rkp/aidl/Android.bp b/security/rkp/aidl/Android.bp
index e9e2021..adc63f6 100644
--- a/security/rkp/aidl/Android.bp
+++ b/security/rkp/aidl/Android.bp
@@ -25,6 +25,9 @@
"//apex_available:platform",
"com.android.rkpd",
],
+ lint: {
+ baseline_filename: "lint-baseline.xml",
+ },
},
rust: {
enabled: true,
diff --git a/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl b/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl
index 61404d4..3c43238 100644
--- a/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl
+++ b/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl
@@ -14,8 +14,9 @@
; be extended without requiring a version bump of the HAL. Custom certificate types may
; be used, but the provisioning server may reject the request for an unknown certificate
; type. The currently defined certificate types are:
-; - "widevine"
-; - "keymint"
+; * "widevine" -- Widevine content protection system
+; * "keymint" -- KeyMint HAL
+; * "rkp-vm" -- See "Support for Android Virtualization Framework" in the README.md file.
CertificateType = tstr
KeysToSign = [ * PublicKey ] ; Please see PublicKey.cddl for the PublicKey definition.
@@ -112,6 +113,7 @@
? -70003 : int / tstr, ; Component version
? -70004 : null, ; Resettable
? -70005 : uint, ; Security version
+ ? -70006 : null, ; RKP VM marker
}
; Each entry in the DICE chain is a DiceChainEntryPayload signed by the key from the previous
diff --git a/security/rkp/aidl/lint-baseline.xml b/security/rkp/aidl/lint-baseline.xml
index d25d383..8e98094 100644
--- a/security/rkp/aidl/lint-baseline.xml
+++ b/security/rkp/aidl/lint-baseline.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-dev" type="baseline" dependencies="true" variant="all" version="8.0.0-dev">
+<issues format="6" by="lint 8.4.0-alpha01" type="baseline" client="" dependencies="true" name="" variant="all" version="8.4.0-alpha01">
<issue
id="NewApi"
@@ -7,8 +7,8 @@
errorLine1=" this.markVintfStability();"
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
- file="out/.intermediates/hardware/interfaces/security/rkp/aidl/android.hardware.security.rkp-V1-java-source/gen/android/hardware/security/keymint/IRemotelyProvisionedComponent.java"
- line="50"
+ file="out/soong/.intermediates/hardware/interfaces/security/rkp/aidl/android.hardware.security.rkp-V1-java-source/gen/android/hardware/security/keymint/IRemotelyProvisionedComponent.java"
+ line="52"
column="12"/>
</issue>
@@ -18,8 +18,8 @@
errorLine1=" this.markVintfStability();"
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
- file="out/.intermediates/hardware/interfaces/security/rkp/aidl/android.hardware.security.rkp-V2-java-source/gen/android/hardware/security/keymint/IRemotelyProvisionedComponent.java"
- line="50"
+ file="out/soong/.intermediates/hardware/interfaces/security/rkp/aidl/android.hardware.security.rkp-V2-java-source/gen/android/hardware/security/keymint/IRemotelyProvisionedComponent.java"
+ line="52"
column="12"/>
</issue>
@@ -29,8 +29,19 @@
errorLine1=" this.markVintfStability();"
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
- file="out/.intermediates/hardware/interfaces/security/rkp/aidl/android.hardware.security.rkp-V3-java-source/gen/android/hardware/security/keymint/IRemotelyProvisionedComponent.java"
- line="495"
+ file="out/soong/.intermediates/hardware/interfaces/security/rkp/aidl/android.hardware.security.rkp-V3-java-source/gen/android/hardware/security/keymint/IRemotelyProvisionedComponent.java"
+ line="56"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 34 (current min is 33): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/soong/.intermediates/hardware/interfaces/security/rkp/aidl/android.hardware.security.rkp-V4-java-source/gen/android/hardware/security/keymint/IRemotelyProvisionedComponent.java"
+ line="257"
column="12"/>
</issue>
diff --git a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 62463eb..68b966c 100644
--- a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -55,6 +55,8 @@
constexpr uint8_t MIN_CHALLENGE_SIZE = 0;
constexpr uint8_t MAX_CHALLENGE_SIZE = 64;
+const string RKP_VM_INSTANCE_NAME =
+ "android.hardware.security.keymint.IRemotelyProvisionedComponent/avf";
#define INSTANTIATE_REM_PROV_AIDL_TEST(name) \
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(name); \
@@ -181,7 +183,12 @@
provisionable_ = IRemotelyProvisionedComponent::fromBinder(binder);
}
ASSERT_NE(provisionable_, nullptr);
- ASSERT_TRUE(provisionable_->getHardwareInfo(&rpcHardwareInfo).isOk());
+ auto status = provisionable_->getHardwareInfo(&rpcHardwareInfo);
+ if (GetParam() == RKP_VM_INSTANCE_NAME &&
+ status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+ GTEST_SKIP() << "The RKP VM is not supported on this system.";
+ }
+ ASSERT_TRUE(status.isOk());
}
static vector<string> build_params() {
@@ -207,7 +214,11 @@
ASSERT_NE(rpc, nullptr);
RpcHardwareInfo hwInfo;
- ASSERT_TRUE(rpc->getHardwareInfo(&hwInfo).isOk());
+ auto status = rpc->getHardwareInfo(&hwInfo);
+ if (hal == RKP_VM_INSTANCE_NAME && status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+ GTEST_SKIP() << "The RKP VM is not supported on this system.";
+ }
+ ASSERT_TRUE(status.isOk());
if (hwInfo.versionNumber >= VERSION_WITH_UNIQUE_ID_SUPPORT) {
ASSERT_TRUE(hwInfo.uniqueId);
@@ -391,7 +402,7 @@
for (auto& key : keysToSign_) {
bytevec privateKeyBlob;
auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &key, &privateKeyBlob);
- ASSERT_TRUE(status.isOk()) << status.getMessage();
+ ASSERT_TRUE(status.isOk()) << status.getDescription();
vector<uint8_t> payload_value;
check_maced_pubkey(key, testMode, &payload_value);
@@ -436,7 +447,7 @@
auto status = provisionable_->generateCertificateRequest(
testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
&protectedData, &keysToSignMac);
- ASSERT_TRUE(status.isOk()) << status.getMessage();
+ ASSERT_TRUE(status.isOk()) << status.getDescription();
auto result = verifyProductionProtectedData(
deviceInfo, cppbor::Array(), keysToSignMac, protectedData, testEekChain_, eekId_,
@@ -461,7 +472,7 @@
auto status = provisionable_->generateCertificateRequest(
testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
&protectedData, &keysToSignMac);
- ASSERT_TRUE(status.isOk()) << status.getMessage();
+ ASSERT_TRUE(status.isOk()) << status.getDescription();
auto firstBcc = verifyProductionProtectedData(
deviceInfo, /*keysToSign=*/cppbor::Array(), keysToSignMac, protectedData, testEekChain_,
@@ -471,7 +482,7 @@
status = provisionable_->generateCertificateRequest(
testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
&protectedData, &keysToSignMac);
- ASSERT_TRUE(status.isOk()) << status.getMessage();
+ ASSERT_TRUE(status.isOk()) << status.getDescription();
auto secondBcc = verifyProductionProtectedData(
deviceInfo, /*keysToSign=*/cppbor::Array(), keysToSignMac, protectedData, testEekChain_,
@@ -521,7 +532,7 @@
auto status = provisionable_->generateCertificateRequest(
testMode, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo, &protectedData,
&keysToSignMac);
- ASSERT_TRUE(status.isOk()) << status.getMessage();
+ ASSERT_TRUE(status.isOk()) << status.getDescription();
auto result = verifyProductionProtectedData(
deviceInfo, cborKeysToSign_, keysToSignMac, protectedData, testEekChain_, eekId_,
@@ -565,7 +576,7 @@
auto status = provisionable_->generateCertificateRequest(
testMode, {keyWithCorruptMac}, testEekChain_.chain, challenge_, &deviceInfo,
&protectedData, &keysToSignMac);
- ASSERT_FALSE(status.isOk()) << status.getMessage();
+ ASSERT_FALSE(status.isOk()) << status.getDescription();
EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
}
@@ -585,7 +596,7 @@
auto status = provisionable_->generateCertificateRequest(
testMode, {keyWithCorruptMac}, getProdEekChain(rpcHardwareInfo.supportedEekCurve),
challenge_, &deviceInfo, &protectedData, &keysToSignMac);
- ASSERT_FALSE(status.isOk()) << status.getMessage();
+ ASSERT_FALSE(status.isOk()) << status.getDescription();
EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
}
@@ -711,7 +722,7 @@
auto challenge = randomBytes(size);
auto status =
provisionable_->generateCertificateRequestV2({} /* keysToSign */, challenge, &csr);
- ASSERT_TRUE(status.isOk()) << status.getMessage();
+ ASSERT_TRUE(status.isOk()) << status.getDescription();
auto result = verifyProductionCsr(cppbor::Array(), csr, provisionable_.get(), challenge);
ASSERT_TRUE(result) << result.message();
@@ -732,7 +743,7 @@
SCOPED_TRACE(testing::Message() << "challenge[" << size << "]");
auto challenge = randomBytes(size);
auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge, &csr);
- ASSERT_TRUE(status.isOk()) << status.getMessage();
+ ASSERT_TRUE(status.isOk()) << status.getDescription();
auto result = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge);
ASSERT_TRUE(result) << result.message();
@@ -747,7 +758,7 @@
auto status = provisionable_->generateCertificateRequestV2(
/* keysToSign */ {}, randomBytes(MAX_CHALLENGE_SIZE + 1), &csr);
- EXPECT_FALSE(status.isOk()) << status.getMessage();
+ EXPECT_FALSE(status.isOk()) << status.getDescription();
EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_FAILED);
}
@@ -762,13 +773,13 @@
bytevec csr;
auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
- ASSERT_TRUE(status.isOk()) << status.getMessage();
+ ASSERT_TRUE(status.isOk()) << status.getDescription();
auto firstCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_);
ASSERT_TRUE(firstCsr) << firstCsr.message();
status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
- ASSERT_TRUE(status.isOk()) << status.getMessage();
+ ASSERT_TRUE(status.isOk()) << status.getDescription();
auto secondCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_);
ASSERT_TRUE(secondCsr) << secondCsr.message();
@@ -786,7 +797,7 @@
bytevec csr;
auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
- ASSERT_TRUE(status.isOk()) << status.getMessage();
+ ASSERT_TRUE(status.isOk()) << status.getDescription();
auto result = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_);
ASSERT_TRUE(result) << result.message();
@@ -804,7 +815,7 @@
bytevec csr;
auto status =
provisionable_->generateCertificateRequestV2({keyWithCorruptMac}, challenge_, &csr);
- ASSERT_FALSE(status.isOk()) << status.getMessage();
+ ASSERT_FALSE(status.isOk()) << status.getDescription();
EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
}
@@ -818,7 +829,7 @@
auto status = provisionable_->generateCertificateRequest(
false /* testMode */, {} /* keysToSign */, {} /* EEK chain */, challenge_, &deviceInfo,
&protectedData, &keysToSignMac);
- ASSERT_FALSE(status.isOk()) << status.getMessage();
+ ASSERT_FALSE(status.isOk()) << status.getDescription();
EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED);
}
@@ -832,7 +843,7 @@
auto status = provisionable_->generateCertificateRequest(
true /* testMode */, {} /* keysToSign */, {} /* EEK chain */, challenge_, &deviceInfo,
&protectedData, &keysToSignMac);
- ASSERT_FALSE(status.isOk()) << status.getMessage();
+ ASSERT_FALSE(status.isOk()) << status.getDescription();
EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED);
}
@@ -916,7 +927,7 @@
bytevec csr;
irpcStatus =
provisionable_->generateCertificateRequestV2({} /* keysToSign */, challenge_, &csr);
- ASSERT_TRUE(irpcStatus.isOk()) << irpcStatus.getMessage();
+ ASSERT_TRUE(irpcStatus.isOk()) << irpcStatus.getDescription();
auto result = verifyProductionCsr(cppbor::Array(), csr, provisionable_.get(), challenge_);
ASSERT_TRUE(result) << result.message();
diff --git a/security/secretkeeper/OWNERS b/security/secretkeeper/OWNERS
new file mode 100644
index 0000000..acf4c6c
--- /dev/null
+++ b/security/secretkeeper/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 867125
+
+alanstokes@google.com
+drysdale@google.com
+hasinitg@google.com
+shikhapanwar@google.com
diff --git a/security/secretkeeper/aidl/Android.bp b/security/secretkeeper/aidl/Android.bp
new file mode 100644
index 0000000..5307bf9
--- /dev/null
+++ b/security/secretkeeper/aidl/Android.bp
@@ -0,0 +1,85 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ default_team: "trendy_team_virtualization",
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+aidl_interface {
+ name: "android.hardware.security.secretkeeper",
+ vendor_available: true,
+ srcs: ["android/hardware/security/secretkeeper/*.aidl"],
+ imports: [
+ "android.hardware.security.authgraph-V1",
+ ],
+ stability: "vintf",
+ frozen: false,
+ backend: {
+ java: {
+ enabled: false,
+ },
+ ndk: {
+ enabled: true,
+ },
+ rust: {
+ enabled: true,
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.virt",
+ ],
+ },
+ },
+}
+
+// cc_defaults that includes the latest Secretkeeper AIDL library.
+// Modules that depend on Secretkeeper directly can include this cc_defaults to avoid
+// managing dependency versions explicitly.
+cc_defaults {
+ name: "secretkeeper_use_latest_hal_aidl_ndk_static",
+ static_libs: [
+ "android.hardware.security.secretkeeper-V1-ndk",
+ ],
+}
+
+cc_defaults {
+ name: "secretkeeper_use_latest_hal_aidl_ndk_shared",
+ shared_libs: [
+ "android.hardware.security.secretkeeper-V1-ndk",
+ ],
+}
+
+cc_defaults {
+ name: "secretkeeper_use_latest_hal_aidl_cpp_static",
+ static_libs: [
+ "android.hardware.security.secretkeeper-V1-cpp",
+ ],
+}
+
+cc_defaults {
+ name: "secretkeeper_use_latest_hal_aidl_cpp_shared",
+ shared_libs: [
+ "android.hardware.security.secretkeeper-V1-cpp",
+ ],
+}
+
+// A rust_defaults that includes the latest Secretkeeper AIDL library.
+// Modules that depend on Secretkeeper directly can include this rust_defaults to avoid
+// managing dependency versions explicitly.
+rust_defaults {
+ name: "secretkeeper_use_latest_hal_aidl_rust",
+ rustlibs: [
+ "android.hardware.security.secretkeeper-V1-rust",
+ ],
+}
diff --git a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ISecretkeeper.aidl b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ISecretkeeper.aidl
new file mode 100644
index 0000000..8ce37cd
--- /dev/null
+++ b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ISecretkeeper.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.security.secretkeeper;
+@VintfStability
+interface ISecretkeeper {
+ android.hardware.security.authgraph.IAuthGraphKeyExchange getAuthGraphKe();
+ byte[] processSecretManagementRequest(in byte[] request);
+ void deleteIds(in android.hardware.security.secretkeeper.SecretId[] ids);
+ void deleteAll();
+ const int ERROR_UNKNOWN_KEY_ID = 1;
+ const int ERROR_INTERNAL_ERROR = 2;
+ const int ERROR_REQUEST_MALFORMED = 3;
+}
diff --git a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/SecretId.aidl b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/SecretId.aidl
new file mode 100644
index 0000000..9887066
--- /dev/null
+++ b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/SecretId.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.security.secretkeeper;
+/* @hide */
+@VintfStability
+parcelable SecretId {
+ byte[64] id;
+}
diff --git a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl
new file mode 100644
index 0000000..b07dba8
--- /dev/null
+++ b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.security.secretkeeper;
+
+import android.hardware.security.authgraph.IAuthGraphKeyExchange;
+import android.hardware.security.secretkeeper.SecretId;
+
+@VintfStability
+/**
+ * Secretkeeper service definition.
+ *
+ * An ISecretkeeper instance provides secure storage of secrets on behalf of other components in
+ * Android, in particular for protected virtual machine instances. From the perspective of security
+ * privilege, Secretkeeper must be implemented in an environment with privilege higher than any of
+ * its clients. Since AVF based protected Virtual Machines are one set of its clients, the
+ * implementation of ISecretkeeper should live in a secure environment, such as:
+ * - A trusted execution environment such as ARM TrustZone.
+ * - A completely separate, purpose-built and certified secure CPU.
+ *
+ */
+interface ISecretkeeper {
+ const int ERROR_UNKNOWN_KEY_ID = 1;
+ const int ERROR_INTERNAL_ERROR = 2;
+ const int ERROR_REQUEST_MALFORMED = 3;
+
+ /**
+ * Retrieve the instance of the `IAuthGraphKeyExchange` HAL that should be used for shared
+ * session key establishment. These keys are used to perform encryption of messages as
+ * described in SecretManagement.cddl, allowing the client and Secretkeeper to have a
+ * cryptographically secure channel. In the key exchange protocol the client acts as P1
+ * (source) and Secretkeeper as P2 (sink). The interface returned here can be used to invoke
+ * methods on the sink.
+ *
+ * The client's identity is its DICE chain; Secretkeeper's identity is a
+ * per-boot key pair.
+ */
+ IAuthGraphKeyExchange getAuthGraphKe();
+
+ /**
+ * processSecretManagementRequest method is used for interacting with the Secret Management API
+ *
+ * Secret Management API: The clients can use this API to store (& get) 32 bytes of data.
+ * The API is a CBOR based protocol, which follows request/response model.
+ * See SecretManagement.cddl for the API spec.
+ *
+ * Further, the requests (from client) & responses (from service) must be encrypted into
+ * ProtectedRequestPacket & ProtectedResponsePacket using symmetric keys agreed between
+ * the client & service. This cryptographic protection is required because the messages are
+ * ferried via Android, which is allowed to be outside the TCB of clients (for example protected
+ * Virtual Machines). For this, service (& client) must implement the AuthGraph key exchange
+ * protocol to establish a secure channel between them.
+ *
+ * If an encrypted response cannot be generated, then a service-specific Binder error using one
+ * of the ERROR_ codes above will be returned.
+ *
+ * Secretkeeper database should guarantee the following properties:
+ *
+ * 1. Confidentiality: No entity (of security privilege lower than Secretkeeper) should
+ * be able to get a client's data in clear.
+ *
+ * 2. Integrity: The data is protected against malicious Android OS tampering with database.
+ * ie, if Android (userspace & kernel) tampers with the client's secret, the Secretkeeper
+ * service must be able to detect it & return error when clients requests for their secrets.
+ * Note: the integrity requirements also include Antirollback protection ie, reverting the
+ * database into an old state should be detected.
+ *
+ * 3. The data is persistent across device boot.
+ * Note: Denial of service is not in scope. A malicious Android may be able to delete data,
+ * but for ideal Android, the data should be persistent.
+ *
+ * @param CBOR-encoded ProtectedRequestPacket. See SecretManagement.cddl for its definition.
+ * @return CBOR-encoded ProtectedResponsePacket. See SecretManagement.cddl for its definition
+ */
+ byte[] processSecretManagementRequest(in byte[] request);
+
+ /**
+ * Delete the data corresponding to a collection of IDs.
+ *
+ * Note that unlike `processSecretManagementRequest`, the contents of this method are in
+ * plaintext, and no client authentication is required.
+ *
+ * @param Secret identifiers to delete.
+ */
+ void deleteIds(in SecretId[] ids);
+
+ /**
+ * Delete data of all clients.
+ */
+ void deleteAll();
+}
diff --git a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretId.aidl
similarity index 64%
copy from health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
copy to security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretId.aidl
index aba6cc3..b17917f 100644
--- a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
+++ b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretId.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,12 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "include/StorageHealthDefault.h"
-void get_storage_info(std::vector<struct StorageInfo>&) {
- // Use defaults.
-}
+package android.hardware.security.secretkeeper;
-void get_disk_stats(std::vector<struct DiskStats>&) {
- // Use defaults
+/**
+ * SecretId contains an identifier for a secret held by Secretkeeper.
+ * @hide
+ */
+@VintfStability
+parcelable SecretId {
+ /**
+ * 64-byte identifier for a secret.
+ */
+ byte[64] id;
}
diff --git a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretManagement.cddl b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretManagement.cddl
new file mode 100644
index 0000000..6a824c9
--- /dev/null
+++ b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretManagement.cddl
@@ -0,0 +1,116 @@
+; CDDL for the Secret Management API.
+
+; The input parameter to the `processSecretManagementRequest` operation in
+; `ISecretkeeper.aidl` is always an encrypted request message, CBOR-encoded as a
+; COSE_Encrypt0 object. The encryption uses the first of the keys agreed using
+; the associated AuthGraph instance, referred to as `KeySourceToSink`. Additionally,
+; an external aad is used - RequestSeqNum.
+ProtectedRequestPacket = CryptoPayload<RequestPacket, KeySourceToSink, RequestSeqNum>
+
+CryptoPayload<Payload, Key, SeqNum> = [ ; COSE_Encrypt0 (untagged), [RFC 9052 s5.2]
+ protected: bstr .cbor {
+ 1 : 3, ; Algorithm: AES-GCM mode w/ 256-bit key, 128-bit tag
+ 4 : bstr ; key identifier set to session ID produced
+ ; by AuthGraph key exchange.
+ },
+ unprotected: {
+ 5 : bstr .size 12 ; IV
+ },
+ ciphertext : bstr ; AES-GCM-256(Key, bstr .cbor Payload)
+ ; AAD for the encryption is CBOR-serialized
+ ; Enc_structure (RFC 9052 s5.3) with SeqNum as the external_aad.
+]
+
+; Once decrypted, the request packet is an encoded CBOR array holding:
+; - An initial integer indicating which request is present.
+; - Subsequent objects holding the parameters for that specific request.
+RequestPacket =
+ [GetVersionOpcode, GetVersionParams] /
+ [StoreSecretOpcode, StoreSecretParams] /
+ [GetSecretOpcode, GetSecretParams]
+
+GetVersionOpcode = 1 ; Get version of the SecretManagement API
+StoreSecretOpcode = 2 ; Store a secret
+GetSecretOpcode = 3 ; Get the secret
+
+; Retrieve Secretkeeper version.
+GetVersionParams = ()
+
+; Store a secret identified by the given ID, with access to the secret policed
+; by the associated sealing policy.
+StoreSecretParams = (
+ id : SecretId,
+ secret : Secret,
+ sealing_policy : bstr .cbor DicePolicy,
+)
+
+; INCLUDE DicePolicy.cddl for: DicePolicy
+
+; Retrieve a secret identified by the given ID, policed according to the sealing
+; policy that was associated with the secret. If successful, optionally also
+; update the sealing policy for the secret.
+GetSecretParams = (
+ id : SecretId,
+ ; Retrieving the value of a secret may optionally also update the sealing
+ ; policy associated with a secret.
+ updated_sealing_policy : bstr .cbor DicePolicy / nil,
+)
+
+SecretId = bstr .size 64 ; Unique identifier of the secret.
+Secret = bstr .size 32 ; The secret value.
+
+; A monotonically incrementing number is associated with each RequestPacket to prevent replay
+; of messages within a session. This starts with 0 and is incremented (by 1) for each request
+; in a session. Secretkeeper implementation must maintain an expected RequestSeqNum for each
+; session (increasing it by 1 for each SecretManagement request received). This will be used in
+; in decryption (external_aad).
+RequestSeqNum = bstr .cbor uint ; Encoded in accordance with Core Deterministic Encoding
+ ; Requirements [RFC 8949 s4.2.1]
+
+; The return value from a successful `processSecretManagementRequest` operation is a
+; response message encrypted with the second of the keys agreed using the associated
+; AuthGraph instance, referred to as `KeySinkToSource`.
+ProtectedResponsePacket = CryptoPayload<ResponsePacket, KeySinkToSource, ResponseSeqNum>
+
+; Once decrypted, the inner response message is encoded as a CBOR array holding:
+; - An initial integer return code value.
+; - Subsequently:
+; - If the return code is zero: result value(s).
+; - If the return code is non-zero: an error message.
+ResponsePacket =
+ [0, Result] /
+ [error_code: ErrorCode, error_message: tstr]
+
+; An error code in the inner response message indicates a failure in
+; secret management processing.
+ErrorCode = &(
+ ; Use this as if no other error code can be used.
+ ErrorCode_UnexpectedServerError: 1,
+ ; Indicate the Request was malformed & hence couldnt be served.
+ ErrorCode_RequestMalformed: 2,
+ ; Requested Entry not found.
+ ErrorCode_EntryNotFound: 3,
+ ; Error happened while serialization or deserialization.
+ ErrorCode_SerializationError: 4,
+ ; Indicates that Dice Policy matching did not succeed & hence access not granted.
+ ErrorCode_DicePolicyError: 5,
+)
+
+; The particular result variant present is determined by which request
+; message was originally sent.
+Result = &(
+ GetVersionResult,
+ StoreSecretResult,
+ GetSecretResult,
+)
+
+GetVersionResult = (1)
+
+StoreSecretResult = ()
+
+GetSecretResult = (secret : Secret)
+
+; Analogous to RequestSeqNum, Secretkeeper must maintain ResponseSeqNum for each session.
+; This will be input to the encryption (ProtectedResponsePacket) as external_aad.
+ResponseSeqNum = bstr .cbor uint ; Encoded in accordance with Core Deterministic Encoding
+ ; Requirements [RFC 8949 s4.2.1]
diff --git a/security/secretkeeper/aidl/vts/Android.bp b/security/secretkeeper/aidl/vts/Android.bp
new file mode 100644
index 0000000..e6521ae
--- /dev/null
+++ b/security/secretkeeper/aidl/vts/Android.bp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+ default_team: "trendy_team_virtualization",
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+rust_library {
+ name: "libsecretkeeper_test",
+ crate_name: "secretkeeper_test",
+ srcs: ["lib.rs"],
+ rustlibs: [
+ "libciborium",
+ "libcoset",
+ "libdiced_open_dice",
+ "liblog_rust",
+ "libsecretkeeper_client",
+ ],
+}
+
+rust_test {
+ name: "VtsSecretkeeperTargetTest",
+ srcs: ["secretkeeper_test_client.rs"],
+ defaults: [
+ "rdroidtest.defaults",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+ test_config: "AndroidTest.xml",
+ rustlibs: [
+ "android.hardware.security.secretkeeper-V1-rust",
+ "libauthgraph_boringssl",
+ "libauthgraph_core",
+ "libauthgraph_vts_test",
+ "libbinder_rs",
+ "libciborium",
+ "libcoset",
+ "libdice_policy_builder",
+ "liblog_rust",
+ "libsecretkeeper_client",
+ "libsecretkeeper_comm_nostd",
+ "libsecretkeeper_core_nostd",
+ "libsecretkeeper_test",
+ ],
+ require_root: true,
+}
+
+rust_binary {
+ name: "secretkeeper_cli",
+ srcs: ["secretkeeper_cli.rs"],
+ lints: "android",
+ rlibs: [
+ "android.hardware.security.secretkeeper-V1-rust",
+ "libanyhow",
+ "libauthgraph_boringssl",
+ "libauthgraph_core",
+ "libbinder_rs",
+ "libclap",
+ "libcoset",
+ "libdice_policy_builder",
+ "libhex",
+ "liblog_rust",
+ "libsecretkeeper_client",
+ "libsecretkeeper_comm_nostd",
+ "libsecretkeeper_test",
+ ],
+}
diff --git a/security/secretkeeper/aidl/vts/AndroidTest.xml b/security/secretkeeper/aidl/vts/AndroidTest.xml
new file mode 100644
index 0000000..4fee78f
--- /dev/null
+++ b/security/secretkeeper/aidl/vts/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Config for Secretkeeper VTS tests.">
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="push-file" key="VtsSecretkeeperTargetTest" value="/data/local/tmp/VtsSecretkeeperTargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.rust.RustBinaryTest" >
+ <option name="test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsSecretkeeperTargetTest" />
+ <!-- Rust tests are run in parallel by default. Run these ones
+ single-threaded, so that one test's secrets don't affect
+ the behaviour of a different test. -->
+ <option name="native-test-flag" value="--test-threads=1" />
+ </test>
+</configuration>
diff --git a/security/secretkeeper/aidl/vts/dice_sample.rs b/security/secretkeeper/aidl/vts/dice_sample.rs
new file mode 100644
index 0000000..97b4789
--- /dev/null
+++ b/security/secretkeeper/aidl/vts/dice_sample.rs
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//! This module provides a set of sample DICE chains for testing purpose only. Note that this
+//! module duplicates a large chunk of code in libdiced_sample_inputs. We avoid modifying the
+//! latter for testing purposes because it is installed on device.
+
+use crate::{
+ COMPONENT_NAME, COMPONENT_RESETTABLE, COMPONENT_VERSION, SUBCOMPONENT_AUTHORITY_HASH,
+ SUBCOMPONENT_CODE_HASH, SUBCOMPONENT_DESCRIPTORS, SUBCOMPONENT_NAME,
+ SUBCOMPONENT_SECURITY_VERSION,
+};
+use ciborium::{cbor, de, ser, value::Value};
+use core::ffi::CStr;
+use coset::{
+ iana, Algorithm, AsCborValue, CborSerializable, CoseKey, KeyOperation, KeyType, Label,
+};
+use diced_open_dice::{
+ derive_cdi_private_key_seed, keypair_from_seed, retry_bcc_format_config_descriptor,
+ retry_bcc_main_flow, retry_dice_main_flow, Config, DiceArtifacts, DiceConfigValues, DiceError,
+ DiceMode, InputValues, OwnedDiceArtifacts, CDI_SIZE, HASH_SIZE, HIDDEN_SIZE,
+};
+use log::error;
+use secretkeeper_client::dice::OwnedDiceArtifactsWithExplicitKey;
+
+/// Sample UDS used to perform the root DICE flow by `make_sample_bcc_and_cdis`.
+const UDS: &[u8; CDI_SIZE] = &[
+ 0x65, 0x4f, 0xab, 0xa9, 0xa5, 0xad, 0x0f, 0x5e, 0x15, 0xc3, 0x12, 0xf7, 0x77, 0x45, 0xfa, 0x55,
+ 0x18, 0x6a, 0xa6, 0x34, 0xb6, 0x7c, 0x82, 0x7b, 0x89, 0x4c, 0xc5, 0x52, 0xd3, 0x27, 0x35, 0x8e,
+];
+
+const CODE_HASH_ABL: [u8; HASH_SIZE] = [
+ 0x16, 0x48, 0xf2, 0x55, 0x53, 0x23, 0xdd, 0x15, 0x2e, 0x83, 0x38, 0xc3, 0x64, 0x38, 0x63, 0x26,
+ 0x0f, 0xcf, 0x5b, 0xd1, 0x3a, 0xd3, 0x40, 0x3e, 0x23, 0xf8, 0x34, 0x4c, 0x6d, 0xa2, 0xbe, 0x25,
+ 0x1c, 0xb0, 0x29, 0xe8, 0xc3, 0xfb, 0xb8, 0x80, 0xdc, 0xb1, 0xd2, 0xb3, 0x91, 0x4d, 0xd3, 0xfb,
+ 0x01, 0x0f, 0xe4, 0xe9, 0x46, 0xa2, 0xc0, 0x26, 0x57, 0x5a, 0xba, 0x30, 0xf7, 0x15, 0x98, 0x14,
+];
+const AUTHORITY_HASH_ABL: [u8; HASH_SIZE] = [
+ 0xf9, 0x00, 0x9d, 0xc2, 0x59, 0x09, 0xe0, 0xb6, 0x98, 0xbd, 0xe3, 0x97, 0x4a, 0xcb, 0x3c, 0xe7,
+ 0x6b, 0x24, 0xc3, 0xe4, 0x98, 0xdd, 0xa9, 0x6a, 0x41, 0x59, 0x15, 0xb1, 0x23, 0xe6, 0xc8, 0xdf,
+ 0xfb, 0x52, 0xb4, 0x52, 0xc1, 0xb9, 0x61, 0xdd, 0xbc, 0x5b, 0x37, 0x0e, 0x12, 0x12, 0xb2, 0xfd,
+ 0xc1, 0x09, 0xb0, 0xcf, 0x33, 0x81, 0x4c, 0xc6, 0x29, 0x1b, 0x99, 0xea, 0xae, 0xfd, 0xaa, 0x0d,
+];
+const HIDDEN_ABL: [u8; HIDDEN_SIZE] = [
+ 0xa2, 0x01, 0xd0, 0xc0, 0xaa, 0x75, 0x3c, 0x06, 0x43, 0x98, 0x6c, 0xc3, 0x5a, 0xb5, 0x5f, 0x1f,
+ 0x0f, 0x92, 0x44, 0x3b, 0x0e, 0xd4, 0x29, 0x75, 0xe3, 0xdb, 0x36, 0xda, 0xc8, 0x07, 0x97, 0x4d,
+ 0xff, 0xbc, 0x6a, 0xa4, 0x8a, 0xef, 0xc4, 0x7f, 0xf8, 0x61, 0x7d, 0x51, 0x4d, 0x2f, 0xdf, 0x7e,
+ 0x8c, 0x3d, 0xa3, 0xfc, 0x63, 0xd4, 0xd4, 0x74, 0x8a, 0xc4, 0x14, 0x45, 0x83, 0x6b, 0x12, 0x7e,
+];
+const CODE_HASH_AVB: [u8; HASH_SIZE] = [
+ 0xa4, 0x0c, 0xcb, 0xc1, 0xbf, 0xfa, 0xcc, 0xfd, 0xeb, 0xf4, 0xfc, 0x43, 0x83, 0x7f, 0x46, 0x8d,
+ 0xd8, 0xd8, 0x14, 0xc1, 0x96, 0x14, 0x1f, 0x6e, 0xb3, 0xa0, 0xd9, 0x56, 0xb3, 0xbf, 0x2f, 0xfa,
+ 0x88, 0x70, 0x11, 0x07, 0x39, 0xa4, 0xd2, 0xa9, 0x6b, 0x18, 0x28, 0xe8, 0x29, 0x20, 0x49, 0x0f,
+ 0xbb, 0x8d, 0x08, 0x8c, 0xc6, 0x54, 0xe9, 0x71, 0xd2, 0x7e, 0xa4, 0xfe, 0x58, 0x7f, 0xd3, 0xc7,
+];
+const AUTHORITY_HASH_AVB: [u8; HASH_SIZE] = [
+ 0xb2, 0x69, 0x05, 0x48, 0x56, 0xb5, 0xfa, 0x55, 0x6f, 0xac, 0x56, 0xd9, 0x02, 0x35, 0x2b, 0xaa,
+ 0x4c, 0xba, 0x28, 0xdd, 0x82, 0x3a, 0x86, 0xf5, 0xd4, 0xc2, 0xf1, 0xf9, 0x35, 0x7d, 0xe4, 0x43,
+ 0x13, 0xbf, 0xfe, 0xd3, 0x36, 0xd8, 0x1c, 0x12, 0x78, 0x5c, 0x9c, 0x3e, 0xf6, 0x66, 0xef, 0xab,
+ 0x3d, 0x0f, 0x89, 0xa4, 0x6f, 0xc9, 0x72, 0xee, 0x73, 0x43, 0x02, 0x8a, 0xef, 0xbc, 0x05, 0x98,
+];
+const HIDDEN_AVB: [u8; HIDDEN_SIZE] = [
+ 0x5b, 0x3f, 0xc9, 0x6b, 0xe3, 0x95, 0x59, 0x40, 0x5e, 0x64, 0xe5, 0x64, 0x3f, 0xfd, 0x21, 0x09,
+ 0x9d, 0xf3, 0xcd, 0xc7, 0xa4, 0x2a, 0xe2, 0x97, 0xdd, 0xe2, 0x4f, 0xb0, 0x7d, 0x7e, 0xf5, 0x8e,
+ 0xd6, 0x4d, 0x84, 0x25, 0x54, 0x41, 0x3f, 0x8f, 0x78, 0x64, 0x1a, 0x51, 0x27, 0x9d, 0x55, 0x8a,
+ 0xe9, 0x90, 0x35, 0xab, 0x39, 0x80, 0x4b, 0x94, 0x40, 0x84, 0xa2, 0xfd, 0x73, 0xeb, 0x35, 0x7a,
+];
+const AUTHORITY_HASH_ANDROID: [u8; HASH_SIZE] = [
+ 0x04, 0x25, 0x5d, 0x60, 0x5f, 0x5c, 0x45, 0x0d, 0xf2, 0x9a, 0x6e, 0x99, 0x30, 0x03, 0xb8, 0xd6,
+ 0xe1, 0x99, 0x71, 0x1b, 0xf8, 0x44, 0xfa, 0xb5, 0x31, 0x79, 0x1c, 0x37, 0x68, 0x4e, 0x1d, 0xc0,
+ 0x24, 0x74, 0x68, 0xf8, 0x80, 0x20, 0x3e, 0x44, 0xb1, 0x43, 0xd2, 0x9c, 0xfc, 0x12, 0x9e, 0x77,
+ 0x0a, 0xde, 0x29, 0x24, 0xff, 0x2e, 0xfa, 0xc7, 0x10, 0xd5, 0x73, 0xd4, 0xc6, 0xdf, 0x62, 0x9f,
+];
+
+/// Encode the public key to CBOR Value. The input (raw 32 bytes) is wrapped into CoseKey.
+fn ed25519_public_key_to_cbor_value(public_key: &[u8]) -> Value {
+ let key = CoseKey {
+ kty: KeyType::Assigned(iana::KeyType::OKP),
+ alg: Some(Algorithm::Assigned(iana::Algorithm::EdDSA)),
+ key_ops: vec![KeyOperation::Assigned(iana::KeyOperation::Verify)].into_iter().collect(),
+ params: vec![
+ (
+ Label::Int(iana::Ec2KeyParameter::Crv as i64),
+ Value::from(iana::EllipticCurve::Ed25519 as u64),
+ ),
+ (Label::Int(iana::Ec2KeyParameter::X as i64), Value::Bytes(public_key.to_vec())),
+ ],
+ ..Default::default()
+ };
+ key.to_cbor_value().unwrap()
+}
+
+/// Makes a DICE chain (BCC) from the sample input.
+///
+/// The DICE chain is of the following format:
+/// public key derived from UDS -> ABL certificate -> AVB certificate -> Android certificate
+/// The `security_version` is included in the Android certificate as well as each subcomponent
+/// of AVB certificate.
+pub fn make_explicit_owned_dice(security_version: u64) -> OwnedDiceArtifactsWithExplicitKey {
+ let dice = make_sample_bcc_and_cdis(security_version);
+ OwnedDiceArtifactsWithExplicitKey::from_owned_artifacts(dice).unwrap()
+}
+
+fn make_sample_bcc_and_cdis(security_version: u64) -> OwnedDiceArtifacts {
+ let private_key_seed = derive_cdi_private_key_seed(UDS).unwrap();
+
+ // Gets the root public key in DICE chain (BCC).
+ let (public_key, _) = keypair_from_seed(private_key_seed.as_array()).unwrap();
+ let ed25519_public_key_value = ed25519_public_key_to_cbor_value(&public_key);
+
+ // Gets the ABL certificate to as the root certificate of DICE chain.
+ let config_values = DiceConfigValues {
+ component_name: Some(CStr::from_bytes_with_nul(b"ABL\0").unwrap()),
+ component_version: Some(1),
+ resettable: true,
+ ..Default::default()
+ };
+ let config_descriptor = retry_bcc_format_config_descriptor(&config_values).unwrap();
+ let input_values = InputValues::new(
+ CODE_HASH_ABL,
+ Config::Descriptor(config_descriptor.as_slice()),
+ AUTHORITY_HASH_ABL,
+ DiceMode::kDiceModeNormal,
+ HIDDEN_ABL,
+ );
+ let (cdi_values, cert) = retry_dice_main_flow(UDS, UDS, &input_values).unwrap();
+ let bcc_value =
+ Value::Array(vec![ed25519_public_key_value, de::from_reader(&cert[..]).unwrap()]);
+ let mut bcc: Vec<u8> = vec![];
+ ser::into_writer(&bcc_value, &mut bcc).unwrap();
+
+ // Appends AVB certificate to DICE chain.
+ let config_desc = cbor!({
+ COMPONENT_NAME => "AVB",
+ COMPONENT_VERSION => 1,
+ COMPONENT_RESETTABLE => null,
+ SUBCOMPONENT_DESCRIPTORS => [
+ {
+ SUBCOMPONENT_NAME => "sub_1",
+ SUBCOMPONENT_SECURITY_VERSION => security_version,
+ SUBCOMPONENT_CODE_HASH=> b"xoxo",
+ SUBCOMPONENT_AUTHORITY_HASH => b"oxox"
+ },
+ {
+ SUBCOMPONENT_NAME => "sub_2",
+ SUBCOMPONENT_SECURITY_VERSION => security_version,
+ SUBCOMPONENT_CODE_HASH => b"xoxo",
+ SUBCOMPONENT_AUTHORITY_HASH => b"oxox",
+ }
+ ]
+ })
+ .unwrap()
+ .to_vec()
+ .unwrap();
+ let input_values = InputValues::new(
+ CODE_HASH_AVB,
+ Config::Descriptor(&config_desc),
+ AUTHORITY_HASH_AVB,
+ DiceMode::kDiceModeNormal,
+ HIDDEN_AVB,
+ );
+ let dice_artifacts =
+ retry_bcc_main_flow(&cdi_values.cdi_attest, &cdi_values.cdi_seal, &bcc, &input_values)
+ .unwrap();
+
+ // Appends Android certificate to DICE chain.
+ let config_values = DiceConfigValues {
+ component_name: Some(CStr::from_bytes_with_nul(b"Android\0").unwrap()),
+ component_version: Some(12),
+ security_version: Some(security_version),
+ resettable: true,
+ ..Default::default()
+ };
+ let config_descriptor = retry_bcc_format_config_descriptor(&config_values).unwrap();
+ let input_values = InputValues::new(
+ [0u8; HASH_SIZE], // code_hash
+ Config::Descriptor(config_descriptor.as_slice()),
+ AUTHORITY_HASH_ANDROID,
+ DiceMode::kDiceModeNormal,
+ [0u8; HIDDEN_SIZE], // hidden
+ );
+ retry_bcc_main_flow(
+ dice_artifacts.cdi_attest(),
+ dice_artifacts.cdi_seal(),
+ dice_artifacts
+ .bcc()
+ .ok_or_else(|| {
+ error!("bcc is none");
+ DiceError::InvalidInput
+ })
+ .unwrap(),
+ &input_values,
+ )
+ .unwrap()
+}
diff --git a/security/secretkeeper/aidl/vts/lib.rs b/security/secretkeeper/aidl/vts/lib.rs
new file mode 100644
index 0000000..3afe938
--- /dev/null
+++ b/security/secretkeeper/aidl/vts/lib.rs
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//! Test helper functions.
+
+pub mod dice_sample;
+
+// Constants for DICE map keys.
+
+/// Map key for authority hash.
+pub const AUTHORITY_HASH: i64 = -4670549;
+/// Map key for config descriptor.
+pub const CONFIG_DESC: i64 = -4670548;
+/// Map key for component name.
+pub const COMPONENT_NAME: i64 = -70002;
+/// Map key for component version.
+pub const COMPONENT_VERSION: i64 = -70003;
+/// Map key for Resettable.
+pub const COMPONENT_RESETTABLE: i64 = -70004;
+/// Map key for security version.
+pub const SECURITY_VERSION: i64 = -70005;
+/// Map key for mode.
+pub const MODE: i64 = -4670551;
+/// Map key for SubcomponentDescriptor.
+pub const SUBCOMPONENT_DESCRIPTORS: i64 = -71002;
+/// Map key for name of subcomponent.
+pub const SUBCOMPONENT_NAME: i64 = 1;
+/// Map key for Security Version of subcomponent.
+pub const SUBCOMPONENT_SECURITY_VERSION: i64 = 2;
+/// Map key for Code hash of subcomponent.
+pub const SUBCOMPONENT_CODE_HASH: i64 = 3;
+/// Map key for Authority Hash of subcomponent.
+pub const SUBCOMPONENT_AUTHORITY_HASH: i64 = 4;
diff --git a/security/secretkeeper/aidl/vts/rustfmt.toml b/security/secretkeeper/aidl/vts/rustfmt.toml
new file mode 120000
index 0000000..ed2086b
--- /dev/null
+++ b/security/secretkeeper/aidl/vts/rustfmt.toml
@@ -0,0 +1 @@
+../../../../../../build/soong/scripts/rustfmt.toml
\ No newline at end of file
diff --git a/security/secretkeeper/aidl/vts/secretkeeper_cli.rs b/security/secretkeeper/aidl/vts/secretkeeper_cli.rs
new file mode 100644
index 0000000..d02bfe6
--- /dev/null
+++ b/security/secretkeeper/aidl/vts/secretkeeper_cli.rs
@@ -0,0 +1,382 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//! Command line test tool for interacting with Secretkeeper.
+
+use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::{
+ ISecretkeeper::ISecretkeeper, SecretId::SecretId,
+};
+use anyhow::{anyhow, bail, Context, Result};
+use authgraph_boringssl::BoringSha256;
+use authgraph_core::traits::Sha256;
+use clap::{Args, Parser, Subcommand};
+use coset::CborSerializable;
+use dice_policy_builder::{
+ policy_for_dice_chain, CertIndex, ConstraintSpec, ConstraintType, MissingAction,
+ WILDCARD_FULL_ARRAY,
+};
+
+use secretkeeper_client::{dice::OwnedDiceArtifactsWithExplicitKey, SkSession};
+use secretkeeper_comm::data_types::{
+ error::SecretkeeperError,
+ packet::{ResponsePacket, ResponseType},
+ request::Request,
+ request_response_impl::{GetSecretRequest, GetSecretResponse, StoreSecretRequest},
+ response::Response,
+ {Id, Secret},
+};
+use secretkeeper_test::{
+ dice_sample::make_explicit_owned_dice, AUTHORITY_HASH, CONFIG_DESC, MODE, SECURITY_VERSION,
+ SUBCOMPONENT_AUTHORITY_HASH, SUBCOMPONENT_DESCRIPTORS, SUBCOMPONENT_SECURITY_VERSION,
+};
+use std::io::Write;
+
+#[derive(Parser, Debug)]
+#[command(about = "Interact with Secretkeeper HAL")]
+#[command(version = "0.1")]
+#[command(propagate_version = true)]
+struct Cli {
+ #[command(subcommand)]
+ command: Command,
+
+ /// Secretkeeper instance to connect to.
+ #[arg(long, short)]
+ instance: Option<String>,
+
+ /// Security version in leaf DICE node.
+ #[clap(default_value_t = 100)]
+ #[arg(long, short = 'v')]
+ dice_version: u64,
+
+ /// Show hex versions of secrets and their IDs.
+ #[clap(default_value_t = false)]
+ #[arg(long, short = 'v')]
+ hex: bool,
+}
+
+#[derive(Subcommand, Debug)]
+enum Command {
+ /// Store a secret value.
+ Store(StoreArgs),
+ /// Get a secret value.
+ Get(GetArgs),
+ /// Delete a secret value.
+ Delete(DeleteArgs),
+ /// Delete all secret values.
+ DeleteAll(DeleteAllArgs),
+}
+
+#[derive(Args, Debug)]
+struct StoreArgs {
+ /// Identifier for the secret, as either a short (< 32 byte) string, or as 32 bytes of hex.
+ id: String,
+ /// Value to use as the secret value. If specified as 32 bytes of hex, the decoded value
+ /// will be used as-is; otherwise, a string (less than 31 bytes in length) will be encoded
+ /// as the secret.
+ value: String,
+}
+
+#[derive(Args, Debug)]
+struct GetArgs {
+ /// Identifier for the secret, as either a short (< 32 byte) string, or as 32 bytes of hex.
+ id: String,
+}
+
+#[derive(Args, Debug)]
+struct DeleteArgs {
+ /// Identifier for the secret, as either a short (< 32 byte) string, or as 32 bytes of hex.
+ id: String,
+}
+
+#[derive(Args, Debug)]
+struct DeleteAllArgs {
+ /// Confirm deletion of all secrets.
+ yes: bool,
+}
+
+const SECRETKEEPER_SERVICE: &str = "android.hardware.security.secretkeeper.ISecretkeeper";
+
+/// Secretkeeper client information.
+struct SkClient {
+ sk: binder::Strong<dyn ISecretkeeper>,
+ session: SkSession,
+ dice_artifacts: OwnedDiceArtifactsWithExplicitKey,
+}
+
+impl SkClient {
+ fn new(instance: &str, dice_artifacts: OwnedDiceArtifactsWithExplicitKey) -> Self {
+ let sk: binder::Strong<dyn ISecretkeeper> =
+ binder::get_interface(&format!("{SECRETKEEPER_SERVICE}/{instance}")).unwrap();
+ let session = SkSession::new(sk.clone(), &dice_artifacts).unwrap();
+ Self { sk, session, dice_artifacts }
+ }
+
+ fn secret_management_request(&mut self, req_data: &[u8]) -> Result<Vec<u8>> {
+ self.session
+ .secret_management_request(req_data)
+ .map_err(|e| anyhow!("secret management: {e:?}"))
+ }
+
+ /// Construct a sealing policy on the DICE chain with constraints:
+ /// 1. `ExactMatch` on `AUTHORITY_HASH` (non-optional).
+ /// 2. `ExactMatch` on `MODE` (non-optional).
+ /// 3. `GreaterOrEqual` on `SECURITY_VERSION` (optional).
+ fn sealing_policy(&self) -> Result<Vec<u8>> {
+ let dice =
+ self.dice_artifacts.explicit_key_dice_chain().context("extract explicit DICE chain")?;
+
+ let constraint_spec = [
+ ConstraintSpec::new(
+ ConstraintType::ExactMatch,
+ vec![AUTHORITY_HASH],
+ MissingAction::Fail,
+ CertIndex::All,
+ ),
+ ConstraintSpec::new(
+ ConstraintType::ExactMatch,
+ vec![MODE],
+ MissingAction::Fail,
+ CertIndex::All,
+ ),
+ ConstraintSpec::new(
+ ConstraintType::GreaterOrEqual,
+ vec![CONFIG_DESC, SECURITY_VERSION],
+ MissingAction::Ignore,
+ CertIndex::All,
+ ),
+ // Constraints on sub components in the second last DiceChainEntry
+ ConstraintSpec::new(
+ ConstraintType::GreaterOrEqual,
+ vec![
+ CONFIG_DESC,
+ SUBCOMPONENT_DESCRIPTORS,
+ WILDCARD_FULL_ARRAY,
+ SUBCOMPONENT_SECURITY_VERSION,
+ ],
+ MissingAction::Fail,
+ CertIndex::FromEnd(1),
+ ),
+ ConstraintSpec::new(
+ ConstraintType::ExactMatch,
+ vec![
+ CONFIG_DESC,
+ SUBCOMPONENT_DESCRIPTORS,
+ WILDCARD_FULL_ARRAY,
+ SUBCOMPONENT_AUTHORITY_HASH,
+ ],
+ MissingAction::Fail,
+ CertIndex::FromEnd(1),
+ ),
+ ];
+ policy_for_dice_chain(dice, &constraint_spec)
+ .unwrap()
+ .to_vec()
+ .context("serialize DICE policy")
+ }
+
+ fn store(&mut self, id: &Id, secret: &Secret) -> Result<()> {
+ let store_request = StoreSecretRequest {
+ id: id.clone(),
+ secret: secret.clone(),
+ sealing_policy: self.sealing_policy().context("build sealing policy")?,
+ };
+ let store_request =
+ store_request.serialize_to_packet().to_vec().context("serialize StoreSecretRequest")?;
+
+ let store_response = self.secret_management_request(&store_request)?;
+ let store_response =
+ ResponsePacket::from_slice(&store_response).context("deserialize ResponsePacket")?;
+ let response_type = store_response.response_type().unwrap();
+ if response_type == ResponseType::Success {
+ Ok(())
+ } else {
+ let err = *SecretkeeperError::deserialize_from_packet(store_response).unwrap();
+ Err(anyhow!("STORE failed: {err:?}"))
+ }
+ }
+
+ fn get(&mut self, id: &Id) -> Result<Option<Secret>> {
+ let get_request = GetSecretRequest { id: id.clone(), updated_sealing_policy: None }
+ .serialize_to_packet()
+ .to_vec()
+ .context("serialize GetSecretRequest")?;
+
+ let get_response = self.secret_management_request(&get_request).context("secret mgmt")?;
+ let get_response =
+ ResponsePacket::from_slice(&get_response).context("deserialize ResponsePacket")?;
+
+ if get_response.response_type().unwrap() == ResponseType::Success {
+ let get_response = *GetSecretResponse::deserialize_from_packet(get_response).unwrap();
+ Ok(Some(Secret(get_response.secret.0)))
+ } else {
+ // Only expect a not-found failure.
+ let err = *SecretkeeperError::deserialize_from_packet(get_response).unwrap();
+ if err == SecretkeeperError::EntryNotFound {
+ Ok(None)
+ } else {
+ Err(anyhow!("GET failed: {err:?}"))
+ }
+ }
+ }
+
+ /// Helper method to delete secrets.
+ fn delete(&self, ids: &[&Id]) -> Result<()> {
+ let ids: Vec<SecretId> = ids.iter().map(|id| SecretId { id: id.0 }).collect();
+ self.sk.deleteIds(&ids).context("deleteIds")
+ }
+
+ /// Helper method to delete everything.
+ fn delete_all(&self) -> Result<()> {
+ self.sk.deleteAll().context("deleteAll")
+ }
+}
+
+/// Convert a string input into an `Id`. Input can be 64 bytes of hex, or a string
+/// that will be hashed to give the `Id` value. Returns the `Id` and a display string.
+fn string_to_id(s: &str, show_hex: bool) -> (Id, String) {
+ if let Ok(data) = hex::decode(s) {
+ if data.len() == 64 {
+ // Assume something that parses as 64 bytes of hex is it.
+ return (Id(data.try_into().unwrap()), s.to_string().to_lowercase());
+ }
+ }
+ // Create a secret ID by repeating the SHA-256 hash of the string twice.
+ let hash = BoringSha256.compute_sha256(s.as_bytes()).unwrap();
+ let mut id = Id([0; 64]);
+ id.0[..32].copy_from_slice(&hash);
+ id.0[32..].copy_from_slice(&hash);
+ if show_hex {
+ let hex_id = hex::encode(&id.0);
+ (id, format!("'{s}' (as {hex_id})"))
+ } else {
+ (id, format!("'{s}'"))
+ }
+}
+
+/// Convert a string input into a `Secret`. Input can be 32 bytes of hex, or a short string
+/// that will be encoded as the `Secret` value. Returns the `Secret` and a display string.
+fn value_to_secret(s: &str, show_hex: bool) -> Result<(Secret, String)> {
+ if let Ok(data) = hex::decode(s) {
+ if data.len() == 32 {
+ // Assume something that parses as 32 bytes of hex is it.
+ return Ok((Secret(data.try_into().unwrap()), s.to_string().to_lowercase()));
+ }
+ }
+ let data = s.as_bytes();
+ if data.len() > 31 {
+ return Err(anyhow!("secret too long"));
+ }
+ let mut secret = Secret([0; 32]);
+ secret.0[0] = data.len() as u8;
+ secret.0[1..1 + data.len()].copy_from_slice(data);
+ Ok(if show_hex {
+ let hex_secret = hex::encode(&secret.0);
+ (secret, format!("'{s}' (as {hex_secret})"))
+ } else {
+ (secret, format!("'{s}'"))
+ })
+}
+
+/// Convert a `Secret` into a displayable string. If the secret looks like an encoded
+/// string, show that, otherwise show the value in hex.
+fn secret_to_value_display(secret: &Secret, show_hex: bool) -> String {
+ let hex = hex::encode(&secret.0);
+ secret_to_value(secret)
+ .map(|s| if show_hex { format!("'{s}' (from {hex})") } else { format!("'{s}'") })
+ .unwrap_or_else(|_e| format!("{hex}"))
+}
+
+/// Attempt to convert a `Secret` back to a string.
+fn secret_to_value(secret: &Secret) -> Result<String> {
+ let len = secret.0[0] as usize;
+ if len > 31 {
+ return Err(anyhow!("too long"));
+ }
+ std::str::from_utf8(&secret.0[1..1 + len]).map(|s| s.to_string()).context("not UTF-8 string")
+}
+
+fn main() -> Result<()> {
+ let cli = Cli::parse();
+
+ // Figure out which Secretkeeper instance is desired, and connect to it.
+ let instance = if let Some(instance) = &cli.instance {
+ // Explicitly specified.
+ instance.clone()
+ } else {
+ // If there's only one instance, use that.
+ let instances: Vec<String> = binder::get_declared_instances(SECRETKEEPER_SERVICE)
+ .unwrap_or_default()
+ .into_iter()
+ .collect();
+ match instances.len() {
+ 0 => bail!("No Secretkeeper instances available on device!"),
+ 1 => instances[0].clone(),
+ _ => {
+ bail!(
+ concat!(
+ "Multiple Secretkeeper instances available on device: {}\n",
+ "Use --instance <instance> to specify one."
+ ),
+ instances.join(", ")
+ );
+ }
+ }
+ };
+ let dice = make_explicit_owned_dice(cli.dice_version);
+ let mut sk_client = SkClient::new(&instance, dice);
+
+ match cli.command {
+ Command::Get(args) => {
+ let (id, display_id) = string_to_id(&args.id, cli.hex);
+ print!("GET key {display_id}: ");
+ match sk_client.get(&id).context("GET") {
+ Ok(None) => println!("not found"),
+ Ok(Some(s)) => println!("{}", secret_to_value_display(&s, cli.hex)),
+ Err(e) => {
+ println!("failed!");
+ return Err(e);
+ }
+ }
+ }
+ Command::Store(args) => {
+ let (id, display_id) = string_to_id(&args.id, cli.hex);
+ let (secret, display_secret) = value_to_secret(&args.value, cli.hex)?;
+ println!("STORE key {display_id}: {display_secret}");
+ sk_client.store(&id, &secret).context("STORE")?;
+ }
+ Command::Delete(args) => {
+ let (id, display_id) = string_to_id(&args.id, cli.hex);
+ println!("DELETE key {display_id}");
+ sk_client.delete(&[&id]).context("DELETE")?;
+ }
+ Command::DeleteAll(args) => {
+ if !args.yes {
+ // Request confirmation.
+ println!("Confirm delete all secrets: [y/N]");
+ let _ = std::io::stdout().flush();
+ let mut input = String::new();
+ std::io::stdin().read_line(&mut input)?;
+ let c = input.chars().next();
+ if c != Some('y') && c != Some('Y') {
+ bail!("DELETE_ALL not confirmed");
+ }
+ }
+ println!("DELETE_ALL");
+ sk_client.delete_all().context("DELETE_ALL")?;
+ }
+ }
+ Ok(())
+}
diff --git a/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs b/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
new file mode 100644
index 0000000..72d3e57
--- /dev/null
+++ b/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
@@ -0,0 +1,626 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::ISecretkeeper::ISecretkeeper;
+use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::SecretId::SecretId;
+use authgraph_vts_test as ag_vts;
+use authgraph_boringssl as boring;
+use authgraph_core::key;
+use coset::{CborSerializable, CoseEncrypt0};
+use dice_policy_builder::{CertIndex, ConstraintSpec, ConstraintType, MissingAction, WILDCARD_FULL_ARRAY, policy_for_dice_chain};
+use rdroidtest::{ignore_if, rdroidtest};
+use secretkeeper_client::dice::OwnedDiceArtifactsWithExplicitKey;
+use secretkeeper_client::SkSession;
+use secretkeeper_core::cipher;
+use secretkeeper_comm::data_types::error::SecretkeeperError;
+use secretkeeper_comm::data_types::request::Request;
+use secretkeeper_comm::data_types::request_response_impl::{
+ GetVersionRequest, GetVersionResponse, GetSecretRequest, GetSecretResponse, StoreSecretRequest,
+ StoreSecretResponse };
+use secretkeeper_comm::data_types::{Id, Secret, SeqNum};
+use secretkeeper_comm::data_types::response::Response;
+use secretkeeper_comm::data_types::packet::{ResponsePacket, ResponseType};
+use secretkeeper_test::{
+ AUTHORITY_HASH, MODE, CONFIG_DESC, SECURITY_VERSION, SUBCOMPONENT_AUTHORITY_HASH,
+ SUBCOMPONENT_DESCRIPTORS, SUBCOMPONENT_SECURITY_VERSION,
+ dice_sample::make_explicit_owned_dice
+};
+
+const SECRETKEEPER_SERVICE: &str = "android.hardware.security.secretkeeper.ISecretkeeper";
+const CURRENT_VERSION: u64 = 1;
+// Random bytes (of ID_SIZE/SECRET_SIZE) generated for tests.
+const ID_EXAMPLE: Id = Id([
+ 0xF1, 0xB2, 0xED, 0x3B, 0xD1, 0xBD, 0xF0, 0x7D, 0xE1, 0xF0, 0x01, 0xFC, 0x61, 0x71, 0xD3, 0x42,
+ 0xE5, 0x8A, 0xAF, 0x33, 0x6C, 0x11, 0xDC, 0xC8, 0x6F, 0xAE, 0x12, 0x5C, 0x26, 0x44, 0x6B, 0x86,
+ 0xCC, 0x24, 0xFD, 0xBF, 0x91, 0x4A, 0x54, 0x84, 0xF9, 0x01, 0x59, 0x25, 0x70, 0x89, 0x38, 0x8D,
+ 0x5E, 0xE6, 0x91, 0xDF, 0x68, 0x60, 0x69, 0x26, 0xBE, 0xFE, 0x79, 0x58, 0xF7, 0xEA, 0x81, 0x7D,
+]);
+const ID_EXAMPLE_2: Id = Id([
+ 0x6A, 0xCC, 0xB1, 0xEB, 0xBB, 0xAB, 0xE3, 0xEA, 0x44, 0xBD, 0xDC, 0x75, 0x75, 0x7D, 0xC0, 0xE5,
+ 0xC7, 0x86, 0x41, 0x56, 0x39, 0x66, 0x96, 0x10, 0xCB, 0x43, 0x10, 0x79, 0x03, 0xDC, 0xE6, 0x9F,
+ 0x12, 0x2B, 0xEF, 0x28, 0x9C, 0x1E, 0x32, 0x46, 0x5F, 0xA3, 0xE7, 0x8D, 0x53, 0x63, 0xE8, 0x30,
+ 0x5A, 0x17, 0x6F, 0xEF, 0x42, 0xD6, 0x58, 0x7A, 0xF0, 0xCB, 0xD4, 0x40, 0x58, 0x96, 0x32, 0xF4,
+]);
+const ID_NOT_STORED: Id = Id([
+ 0x56, 0xD0, 0x4E, 0xAA, 0xC1, 0x7B, 0x55, 0x6B, 0xA0, 0x2C, 0x65, 0x43, 0x39, 0x0A, 0x6C, 0xE9,
+ 0x1F, 0xD0, 0x0E, 0x20, 0x3E, 0xFB, 0xF5, 0xF9, 0x3F, 0x5B, 0x11, 0x1B, 0x18, 0x73, 0xF6, 0xBB,
+ 0xAB, 0x9F, 0xF2, 0xD6, 0xBD, 0xBA, 0x25, 0x68, 0x22, 0x30, 0xF2, 0x1F, 0x90, 0x05, 0xF3, 0x64,
+ 0xE7, 0xEF, 0xC6, 0xB6, 0xA0, 0x85, 0xC9, 0x40, 0x40, 0xF0, 0xB4, 0xB9, 0xD8, 0x28, 0xEE, 0x9C,
+]);
+const SECRET_EXAMPLE: Secret = Secret([
+ 0xA9, 0x89, 0x97, 0xFE, 0xAE, 0x97, 0x55, 0x4B, 0x32, 0x35, 0xF0, 0xE8, 0x93, 0xDA, 0xEA, 0x24,
+ 0x06, 0xAC, 0x36, 0x8B, 0x3C, 0x95, 0x50, 0x16, 0x67, 0x71, 0x65, 0x26, 0xEB, 0xD0, 0xC3, 0x98,
+]);
+
+fn get_instances() -> Vec<(String, String)> {
+ // Determine which instances are available.
+ binder::get_declared_instances(SECRETKEEPER_SERVICE)
+ .unwrap_or_default()
+ .into_iter()
+ .map(|v| (v.clone(), v))
+ .collect()
+}
+
+fn get_connection(instance: &str) -> binder::Strong<dyn ISecretkeeper> {
+ let name = format!("{SECRETKEEPER_SERVICE}/{instance}");
+ binder::get_interface(&name).unwrap()
+}
+
+/// Secretkeeper client information.
+struct SkClient {
+ sk: binder::Strong<dyn ISecretkeeper>,
+ session: SkSession,
+ dice_artifacts: OwnedDiceArtifactsWithExplicitKey,
+}
+
+impl Drop for SkClient {
+ fn drop(&mut self) {
+ // Delete any IDs that may be left over.
+ self.delete(&[&ID_EXAMPLE, &ID_EXAMPLE_2]);
+ }
+}
+
+impl SkClient {
+ /// Create an `SkClient` using the default `OwnedDiceArtifactsWithExplicitKey` for identity.
+ fn new(instance: &str) -> Self {
+ let default_dice = make_explicit_owned_dice(/*Security version in a node */ 5);
+ Self::with_identity(instance, default_dice)
+ }
+
+ /// Create an `SkClient` using the given `OwnedDiceArtifactsWithExplicitKey` for identity.
+ fn with_identity(instance: &str, dice_artifacts: OwnedDiceArtifactsWithExplicitKey) -> Self {
+ let sk = get_connection(instance);
+ Self {
+ sk: sk.clone(),
+ session: SkSession::new(sk, &dice_artifacts).unwrap(),
+ dice_artifacts,
+ }
+ }
+
+ /// This method is wrapper that use `SkSession::secret_management_request` which handles
+ /// encryption and decryption.
+ fn secret_management_request(&mut self, req_data: &[u8]) -> Result<Vec<u8>, Error> {
+ Ok(self.session.secret_management_request(req_data)?)
+ }
+
+ /// Unlike the method [`secret_management_request`], this method directly uses
+ /// `cipher::encrypt_message` & `cipher::decrypt_message`, allowing finer control of request
+ /// & response aad.
+ fn secret_management_request_custom_aad(
+ &self,
+ req_data: &[u8],
+ req_aad: &[u8],
+ expected_res_aad: &[u8],
+ ) -> Result<Vec<u8>, Error> {
+ let aes_gcm = boring::BoringAes;
+ let rng = boring::BoringRng;
+ let request_bytes = cipher::encrypt_message(
+ &aes_gcm,
+ &rng,
+ self.session.encryption_key(),
+ self.session.session_id(),
+ &req_data,
+ req_aad,
+ )
+ .map_err(|e| secretkeeper_client::Error::CipherError(e))?;
+
+ // Binder call!
+ let response_bytes = self.sk.processSecretManagementRequest(&request_bytes)?;
+
+ let response_encrypt0 = CoseEncrypt0::from_slice(&response_bytes)?;
+ Ok(cipher::decrypt_message(
+ &aes_gcm,
+ self.session.decryption_key(),
+ &response_encrypt0,
+ expected_res_aad,
+ )
+ .map_err(|e| secretkeeper_client::Error::CipherError(e))?)
+ }
+
+ /// Helper method to store a secret. This uses the default compatible sealing_policy on
+ /// dice_chain.
+ fn store(&mut self, id: &Id, secret: &Secret) -> Result<(), Error> {
+ let sealing_policy = sealing_policy(
+ self.dice_artifacts.explicit_key_dice_chain().ok_or(Error::UnexpectedError)?,
+ );
+ let store_request =
+ StoreSecretRequest { id: id.clone(), secret: secret.clone(), sealing_policy };
+ let store_request = store_request.serialize_to_packet().to_vec()?;
+
+ let store_response = self.secret_management_request(&store_request)?;
+ let store_response = ResponsePacket::from_slice(&store_response)?;
+
+ assert_eq!(store_response.response_type()?, ResponseType::Success);
+ // Really just checking that the response is indeed StoreSecretResponse
+ let _ = StoreSecretResponse::deserialize_from_packet(store_response)?;
+ Ok(())
+ }
+
+ /// Helper method to get a secret.
+ fn get(&mut self, id: &Id) -> Result<Secret, Error> {
+ self.get_update_policy(id, None)
+ }
+
+ /// Helper method to get a secret, updating the sealing policy along the way.
+ fn get_update_policy(
+ &mut self,
+ id: &Id,
+ updated_sealing_policy: Option<Vec<u8>>,
+ ) -> Result<Secret, Error> {
+ let get_request = GetSecretRequest { id: id.clone(), updated_sealing_policy };
+ let get_request = get_request.serialize_to_packet().to_vec()?;
+
+ let get_response = self.secret_management_request(&get_request)?;
+ let get_response = ResponsePacket::from_slice(&get_response)?;
+
+ if get_response.response_type()? == ResponseType::Success {
+ let get_response = *GetSecretResponse::deserialize_from_packet(get_response)?;
+ Ok(Secret(get_response.secret.0))
+ } else {
+ let err = *SecretkeeperError::deserialize_from_packet(get_response)?;
+ Err(Error::SecretkeeperError(err))
+ }
+ }
+
+ /// Helper method to delete secrets.
+ fn delete(&self, ids: &[&Id]) {
+ let ids: Vec<SecretId> = ids.iter().map(|id| SecretId { id: id.0 }).collect();
+ self.sk.deleteIds(&ids).unwrap();
+ }
+
+ /// Helper method to delete everything.
+ fn delete_all(&self) {
+ self.sk.deleteAll().unwrap();
+ }
+}
+
+#[derive(Debug)]
+enum Error {
+ // Errors from Secretkeeper API errors. These are thrown by core SecretManagement and
+ // not visible without decryption.
+ SecretkeeperError(SecretkeeperError),
+ InfraError(secretkeeper_client::Error),
+ UnexpectedError,
+}
+
+impl From<secretkeeper_client::Error> for Error {
+ fn from(e: secretkeeper_client::Error) -> Self {
+ Self::InfraError(e)
+ }
+}
+
+impl From<SecretkeeperError> for Error {
+ fn from(e: SecretkeeperError) -> Self {
+ Self::SecretkeeperError(e)
+ }
+}
+
+impl From<coset::CoseError> for Error {
+ fn from(e: coset::CoseError) -> Self {
+ Self::InfraError(secretkeeper_client::Error::from(e))
+ }
+}
+
+impl From<binder::Status> for Error {
+ fn from(s: binder::Status) -> Self {
+ Self::InfraError(secretkeeper_client::Error::from(s))
+ }
+}
+
+impl From<secretkeeper_comm::data_types::error::Error> for Error {
+ fn from(e: secretkeeper_comm::data_types::error::Error) -> Self {
+ Self::InfraError(secretkeeper_client::Error::from(e))
+ }
+}
+
+// Assert that the error is EntryNotFound
+fn assert_entry_not_found(res: Result<Secret, Error>) {
+ assert!(matches!(res.unwrap_err(), Error::SecretkeeperError(SecretkeeperError::EntryNotFound)))
+}
+
+/// Construct a sealing policy on the dice chain. This method uses the following set of
+/// constraints which are compatible with sample DICE chains used in VTS.
+/// 1. ExactMatch on AUTHORITY_HASH (non-optional).
+/// 2. ExactMatch on MODE (non-optional).
+/// 3. GreaterOrEqual on SECURITY_VERSION (optional).
+/// 4. The second last DiceChainEntry contain SubcomponentDescriptor, for each of those:
+/// a) GreaterOrEqual on SECURITY_VERSION (Required)
+// b) ExactMatch on AUTHORITY_HASH (Required).
+fn sealing_policy(dice: &[u8]) -> Vec<u8> {
+ let constraint_spec = [
+ ConstraintSpec::new(
+ ConstraintType::ExactMatch,
+ vec![AUTHORITY_HASH],
+ MissingAction::Fail,
+ CertIndex::All,
+ ),
+ ConstraintSpec::new(
+ ConstraintType::ExactMatch,
+ vec![MODE],
+ MissingAction::Fail,
+ CertIndex::All,
+ ),
+ ConstraintSpec::new(
+ ConstraintType::GreaterOrEqual,
+ vec![CONFIG_DESC, SECURITY_VERSION],
+ MissingAction::Ignore,
+ CertIndex::All,
+ ),
+ // Constraints on sub components in the second last DiceChainEntry
+ ConstraintSpec::new(
+ ConstraintType::GreaterOrEqual,
+ vec![
+ CONFIG_DESC,
+ SUBCOMPONENT_DESCRIPTORS,
+ WILDCARD_FULL_ARRAY,
+ SUBCOMPONENT_SECURITY_VERSION,
+ ],
+ MissingAction::Fail,
+ CertIndex::FromEnd(1),
+ ),
+ ConstraintSpec::new(
+ ConstraintType::ExactMatch,
+ vec![
+ CONFIG_DESC,
+ SUBCOMPONENT_DESCRIPTORS,
+ WILDCARD_FULL_ARRAY,
+ SUBCOMPONENT_AUTHORITY_HASH,
+ ],
+ MissingAction::Fail,
+ CertIndex::FromEnd(1),
+ ),
+ ];
+
+ policy_for_dice_chain(dice, &constraint_spec).unwrap().to_vec().unwrap()
+}
+
+/// Perform AuthGraph key exchange, returning the session keys and session ID.
+fn authgraph_key_exchange(sk: binder::Strong<dyn ISecretkeeper>) -> ([key::AesKey; 2], Vec<u8>) {
+ let sink = sk.getAuthGraphKe().expect("failed to get AuthGraph");
+ let mut source = ag_vts::test_ag_participant().expect("failed to create a local source");
+ ag_vts::sink::test_mainline(&mut source, sink)
+}
+
+// Test that the AuthGraph instance returned by SecretKeeper correctly performs
+// mainline key exchange against a local source implementation.
+#[rdroidtest(get_instances())]
+fn authgraph_mainline(instance: String) {
+ let sk = get_connection(&instance);
+ let (_aes_keys, _session_id) = authgraph_key_exchange(sk);
+}
+
+// Test that the AuthGraph instance returned by SecretKeeper correctly rejects
+// a corrupted session ID signature.
+#[rdroidtest(get_instances())]
+fn authgraph_corrupt_sig(instance: String) {
+ let sk = get_connection(&instance);
+ let sink = sk.getAuthGraphKe().expect("failed to get AuthGraph");
+ let mut source = ag_vts::test_ag_participant().expect("failed to create a local source");
+ ag_vts::sink::test_corrupt_sig(&mut source, sink);
+}
+
+// Test that the AuthGraph instance returned by SecretKeeper correctly detects
+// when corrupted keys are returned to it.
+#[rdroidtest(get_instances())]
+fn authgraph_corrupt_keys(instance: String) {
+ let sk = get_connection(&instance);
+ let sink = sk.getAuthGraphKe().expect("failed to get AuthGraph");
+ let mut source = ag_vts::test_ag_participant().expect("failed to create a local source");
+ ag_vts::sink::test_corrupt_keys(&mut source, sink);
+}
+
+// TODO(b/2797757): Add tests that match different HAL defined objects (like request/response)
+// with expected bytes.
+
+#[rdroidtest(get_instances())]
+fn secret_management_get_version(instance: String) {
+ let mut sk_client = SkClient::new(&instance);
+
+ let request = GetVersionRequest {};
+ let request_packet = request.serialize_to_packet();
+ let request_bytes = request_packet.to_vec().unwrap();
+
+ let response_bytes = sk_client.secret_management_request(&request_bytes).unwrap();
+
+ let response_packet = ResponsePacket::from_slice(&response_bytes).unwrap();
+ assert_eq!(response_packet.response_type().unwrap(), ResponseType::Success);
+ let get_version_response =
+ *GetVersionResponse::deserialize_from_packet(response_packet).unwrap();
+ assert_eq!(get_version_response.version, CURRENT_VERSION);
+}
+
+#[rdroidtest(get_instances())]
+fn secret_management_malformed_request(instance: String) {
+ let mut sk_client = SkClient::new(&instance);
+
+ let request = GetVersionRequest {};
+ let request_packet = request.serialize_to_packet();
+ let mut request_bytes = request_packet.to_vec().unwrap();
+
+ // Deform the request
+ request_bytes[0] = !request_bytes[0];
+
+ let response_bytes = sk_client.secret_management_request(&request_bytes).unwrap();
+
+ let response_packet = ResponsePacket::from_slice(&response_bytes).unwrap();
+ assert_eq!(response_packet.response_type().unwrap(), ResponseType::Error);
+ let err = *SecretkeeperError::deserialize_from_packet(response_packet).unwrap();
+ assert_eq!(err, SecretkeeperError::RequestMalformed);
+}
+
+#[rdroidtest(get_instances())]
+fn secret_management_store_get_secret_found(instance: String) {
+ let mut sk_client = SkClient::new(&instance);
+
+ sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
+
+ // Get the secret that was just stored
+ assert_eq!(sk_client.get(&ID_EXAMPLE).unwrap(), SECRET_EXAMPLE);
+}
+
+#[rdroidtest(get_instances())]
+fn secret_management_store_get_secret_not_found(instance: String) {
+ let mut sk_client = SkClient::new(&instance);
+
+ // Store a secret (corresponding to an id).
+ sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
+
+ // Get the secret that was never stored
+ assert_entry_not_found(sk_client.get(&ID_NOT_STORED));
+}
+
+#[rdroidtest(get_instances())]
+fn secretkeeper_store_delete_ids(instance: String) {
+ let mut sk_client = SkClient::new(&instance);
+
+ sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
+ sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE).unwrap();
+ sk_client.delete(&[&ID_EXAMPLE]);
+ assert_entry_not_found(sk_client.get(&ID_EXAMPLE));
+ assert_eq!(sk_client.get(&ID_EXAMPLE_2).unwrap(), SECRET_EXAMPLE);
+
+ sk_client.delete(&[&ID_EXAMPLE_2]);
+
+ assert_entry_not_found(sk_client.get(&ID_EXAMPLE));
+ assert_entry_not_found(sk_client.get(&ID_EXAMPLE_2));
+}
+
+#[rdroidtest(get_instances())]
+fn secretkeeper_store_delete_multiple_ids(instance: String) {
+ let mut sk_client = SkClient::new(&instance);
+
+ sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
+ sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE).unwrap();
+ sk_client.delete(&[&ID_EXAMPLE, &ID_EXAMPLE_2]);
+
+ assert_entry_not_found(sk_client.get(&ID_EXAMPLE));
+ assert_entry_not_found(sk_client.get(&ID_EXAMPLE_2));
+}
+#[rdroidtest(get_instances())]
+fn secretkeeper_store_delete_duplicate_ids(instance: String) {
+ let mut sk_client = SkClient::new(&instance);
+
+ sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
+ sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE).unwrap();
+ // Delete the same secret twice.
+ sk_client.delete(&[&ID_EXAMPLE, &ID_EXAMPLE]);
+
+ assert_entry_not_found(sk_client.get(&ID_EXAMPLE));
+ assert_eq!(sk_client.get(&ID_EXAMPLE_2).unwrap(), SECRET_EXAMPLE);
+}
+
+#[rdroidtest(get_instances())]
+fn secretkeeper_store_delete_nonexistent(instance: String) {
+ let mut sk_client = SkClient::new(&instance);
+
+ sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
+ sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE).unwrap();
+ sk_client.delete(&[&ID_NOT_STORED]);
+
+ assert_eq!(sk_client.get(&ID_EXAMPLE).unwrap(), SECRET_EXAMPLE);
+ assert_eq!(sk_client.get(&ID_EXAMPLE_2).unwrap(), SECRET_EXAMPLE);
+ assert_entry_not_found(sk_client.get(&ID_NOT_STORED));
+}
+
+// Don't run deleteAll() on a secure device, as it might affect real secrets.
+#[rdroidtest(get_instances())]
+#[ignore_if(|p| p != "nonsecure")]
+fn secretkeeper_store_delete_all(instance: String) {
+ let mut sk_client = SkClient::new(&instance);
+
+ sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
+ sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE).unwrap();
+
+ sk_client.delete_all();
+
+ assert_entry_not_found(sk_client.get(&ID_EXAMPLE));
+ assert_entry_not_found(sk_client.get(&ID_EXAMPLE_2));
+
+ // Store a new secret (corresponding to an id).
+ sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
+
+ // Get the restored secret.
+ assert_eq!(sk_client.get(&ID_EXAMPLE).unwrap(), SECRET_EXAMPLE);
+
+ // (Try to) Get the secret that was never stored
+ assert_entry_not_found(sk_client.get(&ID_NOT_STORED));
+}
+
+// This test checks that Secretkeeper uses the expected [`RequestSeqNum`] as aad while
+// decrypting requests and the responses are encrypted with correct [`ResponseSeqNum`] for the
+// first few messages.
+#[rdroidtest(get_instances())]
+fn secret_management_replay_protection_seq_num(instance: String) {
+ let dice_chain = make_explicit_owned_dice(/*Security version in a node */ 5);
+ let sealing_policy = sealing_policy(dice_chain.explicit_key_dice_chain().unwrap());
+ let sk_client = SkClient::with_identity(&instance, dice_chain);
+ // Construct encoded request packets for the test
+ let (req_1, req_2, req_3) = construct_secret_management_requests(sealing_policy);
+
+ // Lets now construct the seq_numbers(in request & expected in response)
+ let mut seq_a = SeqNum::new();
+ let [seq_0, seq_1, seq_2] = std::array::from_fn(|_| seq_a.get_then_increment().unwrap());
+
+ // Check first request/response is successful
+ let res = ResponsePacket::from_slice(
+ &sk_client.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0).unwrap(),
+ )
+ .unwrap();
+ assert_eq!(res.response_type().unwrap(), ResponseType::Success);
+
+ // Check 2nd request/response is successful
+ let res = ResponsePacket::from_slice(
+ &sk_client.secret_management_request_custom_aad(&req_2, &seq_1, &seq_1).unwrap(),
+ )
+ .unwrap();
+ assert_eq!(res.response_type().unwrap(), ResponseType::Success);
+
+ // Check 3rd request/response is successful
+ let res = ResponsePacket::from_slice(
+ &sk_client.secret_management_request_custom_aad(&req_3, &seq_2, &seq_2).unwrap(),
+ )
+ .unwrap();
+ assert_eq!(res.response_type().unwrap(), ResponseType::Success);
+}
+
+// This test checks that Secretkeeper uses fresh [`RequestSeqNum`] & [`ResponseSeqNum`]
+// for new sessions.
+#[rdroidtest(get_instances())]
+fn secret_management_replay_protection_seq_num_per_session(instance: String) {
+ let dice_chain = make_explicit_owned_dice(/*Security version in a node */ 5);
+ let sealing_policy = sealing_policy(dice_chain.explicit_key_dice_chain().unwrap());
+ let sk_client = SkClient::with_identity(&instance, dice_chain);
+
+ // Construct encoded request packets for the test
+ let (req_1, _, _) = construct_secret_management_requests(sealing_policy);
+
+ // Lets now construct the seq_number (in request & expected in response)
+ let mut seq_a = SeqNum::new();
+ let seq_0 = seq_a.get_then_increment().unwrap();
+ // Check first request/response is successful
+ let res = ResponsePacket::from_slice(
+ &sk_client.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0).unwrap(),
+ )
+ .unwrap();
+ assert_eq!(res.response_type().unwrap(), ResponseType::Success);
+
+ // Start another session
+ let sk_client_diff = SkClient::new(&instance);
+ // Check first request/response is with seq_0 is successful
+ let res = ResponsePacket::from_slice(
+ &sk_client_diff.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0).unwrap(),
+ )
+ .unwrap();
+ assert_eq!(res.response_type().unwrap(), ResponseType::Success);
+}
+
+// This test checks that Secretkeeper rejects requests with out of order [`RequestSeqNum`]
+// TODO(b/317416663): This test fails, when HAL is not present in the device. Refactor to fix this.
+#[rdroidtest(get_instances())]
+fn secret_management_replay_protection_out_of_seq_req_not_accepted(instance: String) {
+ let dice_chain = make_explicit_owned_dice(/*Security version in a node */ 5);
+ let sealing_policy = sealing_policy(dice_chain.explicit_key_dice_chain().unwrap());
+ let sk_client = SkClient::with_identity(&instance, dice_chain);
+
+ // Construct encoded request packets for the test
+ let (req_1, req_2, _) = construct_secret_management_requests(sealing_policy);
+
+ // Lets now construct the seq_numbers(in request & expected in response)
+ let mut seq_a = SeqNum::new();
+ let [seq_0, seq_1, seq_2] = std::array::from_fn(|_| seq_a.get_then_increment().unwrap());
+
+ // Assume First request/response is successful
+ sk_client.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0).unwrap();
+
+ // Check 2nd request/response with skipped seq_num in request is a binder error
+ let res = sk_client
+ .secret_management_request_custom_aad(&req_2, /*Skipping seq_1*/ &seq_2, &seq_1);
+ let err = res.expect_err("Out of Seq messages accepted!");
+ // Incorrect sequence numbers lead to failed decryption. The resultant error should be
+ // thrown in clear text & wrapped in Binder errors.
+ assert!(matches!(err, Error::InfraError(secretkeeper_client::Error::BinderStatus(_e))));
+}
+
+// This test checks DICE policy based access control of Secretkeeper.
+#[rdroidtest(get_instances())]
+fn secret_management_policy_gate(instance: String) {
+ let dice_chain = make_explicit_owned_dice(/*Security version in a node */ 100);
+ let mut sk_client_original = SkClient::with_identity(&instance, dice_chain);
+ sk_client_original.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
+ assert_eq!(sk_client_original.get(&ID_EXAMPLE).unwrap(), SECRET_EXAMPLE);
+
+ // Start a session with higher security_version & get the stored secret.
+ let dice_chain_upgraded = make_explicit_owned_dice(/*Security version in a node */ 101);
+ let mut sk_client_upgraded = SkClient::with_identity(&instance, dice_chain_upgraded);
+ assert_eq!(sk_client_upgraded.get(&ID_EXAMPLE).unwrap(), SECRET_EXAMPLE);
+
+ // Start a session with lower security_version (This should be denied access to the secret).
+ let dice_chain_downgraded = make_explicit_owned_dice(/*Security version in a node */ 99);
+ let mut sk_client_downgraded = SkClient::with_identity(&instance, dice_chain_downgraded);
+ assert!(matches!(
+ sk_client_downgraded.get(&ID_EXAMPLE).unwrap_err(),
+ Error::SecretkeeperError(SecretkeeperError::DicePolicyError)
+ ));
+
+ // Now get the secret with the later version, and upgrade the sealing policy along the way.
+ let sealing_policy =
+ sealing_policy(sk_client_upgraded.dice_artifacts.explicit_key_dice_chain().unwrap());
+ assert_eq!(
+ sk_client_upgraded.get_update_policy(&ID_EXAMPLE, Some(sealing_policy)).unwrap(),
+ SECRET_EXAMPLE
+ );
+
+ // The original version of the client should no longer be able to retrieve the secret.
+ assert!(matches!(
+ sk_client_original.get(&ID_EXAMPLE).unwrap_err(),
+ Error::SecretkeeperError(SecretkeeperError::DicePolicyError)
+ ));
+}
+
+// Helper method that constructs 3 SecretManagement requests. Callers would usually not care about
+// what each of the request concretely is.
+fn construct_secret_management_requests(sealing_policy: Vec<u8>) -> (Vec<u8>, Vec<u8>, Vec<u8>) {
+ let version_request = GetVersionRequest {};
+ let version_request = version_request.serialize_to_packet().to_vec().unwrap();
+ let store_request =
+ StoreSecretRequest { id: ID_EXAMPLE, secret: SECRET_EXAMPLE, sealing_policy };
+ let store_request = store_request.serialize_to_packet().to_vec().unwrap();
+ let get_request = GetSecretRequest { id: ID_EXAMPLE, updated_sealing_policy: None };
+ let get_request = get_request.serialize_to_packet().to_vec().unwrap();
+ (version_request, store_request, get_request)
+}
+
+rdroidtest::test_main!();
diff --git a/security/secretkeeper/default/Android.bp b/security/secretkeeper/default/Android.bp
new file mode 100644
index 0000000..799188f
--- /dev/null
+++ b/security/secretkeeper/default/Android.bp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+ default_team: "trendy_team_virtualization",
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+rust_library {
+ name: "libsecretkeeper_nonsecure",
+ crate_name: "secretkeeper_nonsecure",
+ srcs: [
+ "src/lib.rs",
+ ],
+ vendor_available: true,
+ defaults: [
+ "authgraph_use_latest_hal_aidl_rust",
+ ],
+ rustlibs: [
+ "android.hardware.security.secretkeeper-V1-rust",
+ "libauthgraph_boringssl",
+ "libauthgraph_core",
+ "libauthgraph_hal",
+ "libbinder_rs",
+ "libcoset",
+ "liblog_rust",
+ "libsecretkeeper_core_nostd",
+ "libsecretkeeper_comm_nostd",
+ ],
+}
+
+rust_binary {
+ name: "android.hardware.security.secretkeeper-service.nonsecure",
+ relative_install_path: "hw",
+ vendor: true,
+ installable: false, // install APEX
+ prefer_rlib: true,
+ defaults: [
+ "authgraph_use_latest_hal_aidl_rust",
+ ],
+ rustlibs: [
+ "android.hardware.security.secretkeeper-V1-rust",
+ "libandroid_logger",
+ "libbinder_rs",
+ "liblog_rust",
+ "libsecretkeeper_hal",
+ "libsecretkeeper_nonsecure",
+ ],
+ srcs: [
+ "src/main.rs",
+ ],
+}
+
+rust_fuzz {
+ name: "android.hardware.security.secretkeeper-service.nonsecure_fuzzer",
+ rustlibs: [
+ "libsecretkeeper_hal",
+ "libsecretkeeper_nonsecure",
+ "libbinder_random_parcel_rs",
+ "libbinder_rs",
+ ],
+ srcs: ["src/fuzzer.rs"],
+ fuzz_config: {
+ cc: [
+ "alanstokes@google.com",
+ "drysdale@google.com",
+ "shikhapanwar@google.com",
+ ],
+ },
+}
+
+prebuilt_etc {
+ name: "secretkeeper.rc",
+ src: "secretkeeper.rc",
+ installable: false,
+}
+
+prebuilt_etc {
+ name: "secretkeeper.xml",
+ src: "secretkeeper.xml",
+ sub_dir: "vintf",
+ installable: false,
+}
+
+apex {
+ name: "com.android.hardware.security.secretkeeper",
+ manifest: "apex_manifest.json",
+ file_contexts: "apex_file_contexts",
+ key: "com.android.hardware.key",
+ certificate: ":com.android.hardware.certificate",
+ vendor: true,
+ updatable: false,
+
+ binaries: [
+ "android.hardware.security.secretkeeper-service.nonsecure",
+ ],
+ prebuilts: [
+ "secretkeeper.rc",
+ "secretkeeper.xml",
+ ],
+}
diff --git a/security/secretkeeper/default/apex_file_contexts b/security/secretkeeper/default/apex_file_contexts
new file mode 100644
index 0000000..71369a8
--- /dev/null
+++ b/security/secretkeeper/default/apex_file_contexts
@@ -0,0 +1,3 @@
+(/.*)? u:object_r:vendor_file:s0
+/etc(/.*)? u:object_r:vendor_configs_file:s0
+/bin/hw/android\.hardware\.security\.secretkeeper-service\.nonsecure u:object_r:hal_secretkeeper_default_exec:s0
diff --git a/security/secretkeeper/default/apex_manifest.json b/security/secretkeeper/default/apex_manifest.json
new file mode 100644
index 0000000..7287095
--- /dev/null
+++ b/security/secretkeeper/default/apex_manifest.json
@@ -0,0 +1,4 @@
+{
+ "name": "com.android.hardware.security.secretkeeper",
+ "version": 1
+}
\ No newline at end of file
diff --git a/security/secretkeeper/default/secretkeeper.rc b/security/secretkeeper/default/secretkeeper.rc
new file mode 100644
index 0000000..38ee50d
--- /dev/null
+++ b/security/secretkeeper/default/secretkeeper.rc
@@ -0,0 +1,5 @@
+service vendor.secretkeeper /apex/com.android.hardware.security.secretkeeper/bin/hw/android.hardware.security.secretkeeper-service.nonsecure
+ interface aidl android.hardware.security.secretkeeper.ISecretkeeper/nonsecure
+ class hal
+ user nobody
+ group nobody
diff --git a/security/secretkeeper/default/secretkeeper.xml b/security/secretkeeper/default/secretkeeper.xml
new file mode 100644
index 0000000..40aebe0
--- /dev/null
+++ b/security/secretkeeper/default/secretkeeper.xml
@@ -0,0 +1,28 @@
+<manifest version="1.0" type="device">
+<!--
+/*
+** Copyright 2022, 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.
+*/
+-->
+
+ <hal format="aidl">
+ <name>android.hardware.security.secretkeeper</name>
+ <version>1</version>
+ <interface>
+ <name>ISecretkeeper</name>
+ <instance>nonsecure</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/security/secretkeeper/default/src/fuzzer.rs b/security/secretkeeper/default/src/fuzzer.rs
new file mode 100644
index 0000000..914ebe6
--- /dev/null
+++ b/security/secretkeeper/default/src/fuzzer.rs
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#![allow(missing_docs)]
+#![no_main]
+extern crate libfuzzer_sys;
+
+use binder_random_parcel_rs::fuzz_service;
+use libfuzzer_sys::fuzz_target;
+use secretkeeper_hal::SecretkeeperService;
+use secretkeeper_nonsecure::{AuthGraphChannel, LocalTa, SecretkeeperChannel};
+use std::sync::{Arc, Mutex};
+
+fuzz_target!(|data: &[u8]| {
+ let ta = Arc::new(Mutex::new(LocalTa::new()));
+ let ag_channel = AuthGraphChannel(ta.clone());
+ let sk_channel = SecretkeeperChannel(ta.clone());
+
+ let service = SecretkeeperService::new_as_binder(sk_channel, ag_channel);
+ fuzz_service(&mut service.as_binder(), data);
+});
diff --git a/security/secretkeeper/default/src/lib.rs b/security/secretkeeper/default/src/lib.rs
new file mode 100644
index 0000000..eb7817c
--- /dev/null
+++ b/security/secretkeeper/default/src/lib.rs
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//! Non-secure implementation of a local Secretkeeper TA.
+
+use authgraph_boringssl as boring;
+use authgraph_core::keyexchange::{AuthGraphParticipant, MAX_OPENED_SESSIONS};
+use authgraph_core::ta::{AuthGraphTa, Role};
+use authgraph_hal::channel::SerializedChannel;
+use log::error;
+use secretkeeper_core::ta::SecretkeeperTa;
+use std::cell::RefCell;
+use std::rc::Rc;
+use std::sync::mpsc;
+use std::sync::{Arc, Mutex};
+
+mod store;
+
+/// Implementation of the Secrekeeper TA that runs locally in-process (and which is therefore
+/// insecure).
+pub struct LocalTa {
+ in_tx: mpsc::Sender<Vec<u8>>,
+ out_rx: mpsc::Receiver<Vec<u8>>,
+}
+
+/// Prefix byte for messages intended for the AuthGraph TA.
+const AG_MESSAGE_PREFIX: u8 = 0x00;
+/// Prefix byte for messages intended for the Secretkeeper TA.
+const SK_MESSAGE_PREFIX: u8 = 0x01;
+
+impl LocalTa {
+ /// Create a new instance.
+ pub fn new() -> Self {
+ // Create a pair of channels to communicate with the TA thread.
+ let (in_tx, in_rx) = mpsc::channel();
+ let (out_tx, out_rx) = mpsc::channel();
+
+ // The TA code expects to run single threaded, so spawn a thread to run it in.
+ std::thread::spawn(move || {
+ let mut crypto_impls = boring::crypto_trait_impls();
+ let storage_impl = Box::new(store::InMemoryStore::default());
+ let sk_ta = Rc::new(RefCell::new(
+ SecretkeeperTa::new(
+ &mut crypto_impls,
+ storage_impl,
+ coset::iana::EllipticCurve::Ed25519,
+ )
+ .expect("Failed to create local Secretkeeper TA"),
+ ));
+ let mut ag_ta = AuthGraphTa::new(
+ AuthGraphParticipant::new(crypto_impls, sk_ta.clone(), MAX_OPENED_SESSIONS)
+ .expect("Failed to create local AuthGraph TA"),
+ Role::Sink,
+ );
+
+ // Loop forever processing request messages.
+ loop {
+ let req_data: Vec<u8> = match in_rx.recv() {
+ Ok(data) => data,
+ Err(_) => {
+ error!("local TA failed to receive request!");
+ break;
+ }
+ };
+ let rsp_data = match req_data[0] {
+ AG_MESSAGE_PREFIX => ag_ta.process(&req_data[1..]),
+ SK_MESSAGE_PREFIX => {
+ // It's safe to `borrow_mut()` because this code is not a callback
+ // from AuthGraph (the only other holder of an `Rc`), and so there
+ // can be no live `borrow()`s in this (single) thread.
+ sk_ta.borrow_mut().process(&req_data[1..])
+ }
+ prefix => panic!("unexpected messageprefix {prefix}!"),
+ };
+ match out_tx.send(rsp_data) {
+ Ok(_) => {}
+ Err(_) => {
+ error!("local TA failed to send out response");
+ break;
+ }
+ }
+ }
+ error!("local TA terminating!");
+ });
+ Self { in_tx, out_rx }
+ }
+
+ fn execute_for(&mut self, prefix: u8, req_data: &[u8]) -> Vec<u8> {
+ let mut prefixed_req = Vec::with_capacity(req_data.len() + 1);
+ prefixed_req.push(prefix);
+ prefixed_req.extend_from_slice(req_data);
+ self.in_tx
+ .send(prefixed_req)
+ .expect("failed to send in request");
+ self.out_rx.recv().expect("failed to receive response")
+ }
+}
+
+pub struct AuthGraphChannel(pub Arc<Mutex<LocalTa>>);
+
+impl SerializedChannel for AuthGraphChannel {
+ const MAX_SIZE: usize = usize::MAX;
+ fn execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
+ Ok(self
+ .0
+ .lock()
+ .unwrap()
+ .execute_for(AG_MESSAGE_PREFIX, req_data))
+ }
+}
+
+pub struct SecretkeeperChannel(pub Arc<Mutex<LocalTa>>);
+
+impl SerializedChannel for SecretkeeperChannel {
+ const MAX_SIZE: usize = usize::MAX;
+ fn execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
+ Ok(self
+ .0
+ .lock()
+ .unwrap()
+ .execute_for(SK_MESSAGE_PREFIX, req_data))
+ }
+}
diff --git a/security/secretkeeper/default/src/main.rs b/security/secretkeeper/default/src/main.rs
new file mode 100644
index 0000000..081b97d
--- /dev/null
+++ b/security/secretkeeper/default/src/main.rs
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//! Non-secure implementation of the Secretkeeper HAL.
+
+use log::{error, info, LevelFilter};
+use secretkeeper_hal::SecretkeeperService;
+use secretkeeper_nonsecure::{AuthGraphChannel, SecretkeeperChannel, LocalTa};
+use std::sync::{Arc, Mutex};
+use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::ISecretkeeper::{
+ BpSecretkeeper, ISecretkeeper,
+};
+
+fn main() {
+ // Initialize Android logging.
+ android_logger::init_once(
+ android_logger::Config::default()
+ .with_tag("NonSecureSecretkeeper")
+ .with_max_level(LevelFilter::Info)
+ .with_log_buffer(android_logger::LogId::System),
+ );
+ // Redirect panic messages to logcat.
+ std::panic::set_hook(Box::new(|panic_info| {
+ error!("{}", panic_info);
+ }));
+
+ let ta = Arc::new(Mutex::new(LocalTa::new()));
+ let ag_channel = AuthGraphChannel(ta.clone());
+ let sk_channel = SecretkeeperChannel(ta.clone());
+
+ let service = SecretkeeperService::new_as_binder(sk_channel, ag_channel);
+ let service_name = format!(
+ "{}/nonsecure",
+ <BpSecretkeeper as ISecretkeeper>::get_descriptor()
+ );
+ binder::add_service(&service_name, service.as_binder()).unwrap_or_else(|e| {
+ panic!("Failed to register service {service_name} because of {e:?}.",);
+ });
+ info!("Registered Binder service, joining threadpool.");
+ binder::ProcessState::join_thread_pool();
+}
diff --git a/security/secretkeeper/default/src/store.rs b/security/secretkeeper/default/src/store.rs
new file mode 100644
index 0000000..6c7dba1
--- /dev/null
+++ b/security/secretkeeper/default/src/store.rs
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//! In-memory store for nonsecure Secretkeeper.
+
+use secretkeeper_comm::data_types::error::Error;
+use secretkeeper_core::store::KeyValueStore;
+use std::collections::HashMap;
+
+/// An in-memory implementation of [`KeyValueStore`]. Please note that this is entirely for testing
+/// purposes. Refer to the documentation of `PolicyGatedStorage` and Secretkeeper HAL for
+/// persistence requirements.
+#[derive(Default)]
+pub struct InMemoryStore(HashMap<Vec<u8>, Vec<u8>>);
+impl KeyValueStore for InMemoryStore {
+ fn store(&mut self, key: &[u8], val: &[u8]) -> Result<(), Error> {
+ // This will overwrite the value if key is already present.
+ let _ = self.0.insert(key.to_vec(), val.to_vec());
+ Ok(())
+ }
+
+ fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
+ let optional_val = self.0.get(key);
+ Ok(optional_val.cloned())
+ }
+
+ fn delete(&mut self, key: &[u8]) -> Result<(), Error> {
+ self.0.remove(key);
+ Ok(())
+ }
+
+ fn delete_all(&mut self) -> Result<(), Error> {
+ self.0.clear();
+ Ok(())
+ }
+}
diff --git a/sensors/aidl/Android.bp b/sensors/aidl/Android.bp
index 3914ec1..8877e6e 100644
--- a/sensors/aidl/Android.bp
+++ b/sensors/aidl/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_sensors",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/sensors/aidl/convert/Android.bp b/sensors/aidl/convert/Android.bp
index 53060b9..7217b2f 100644
--- a/sensors/aidl/convert/Android.bp
+++ b/sensors/aidl/convert/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_sensors",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/sensors/aidl/default/Android.bp b/sensors/aidl/default/Android.bp
index 384ee97..6f011ee 100644
--- a/sensors/aidl/default/Android.bp
+++ b/sensors/aidl/default/Android.bp
@@ -15,6 +15,7 @@
*/
package {
+ default_team: "trendy_team_android_sensors",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -23,18 +24,6 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
-filegroup {
- name: "sensors-default.rc",
- srcs: ["sensors-default.rc"],
-}
-
-prebuilt_etc {
- name: "sensors-default.xml",
- src: "sensors-default.xml",
- sub_dir: "vintf",
- installable: false,
-}
-
cc_library_static {
name: "libsensorsexampleimpl",
vendor: true,
@@ -59,21 +48,55 @@
cc_binary {
name: "android.hardware.sensors-service.example",
relative_install_path: "hw",
- init_rc: [":sensors-default.rc"],
- vintf_fragments: [":sensors-default.xml"],
+ installable: false, // install APEX below
+
vendor: true,
shared_libs: [
- "libbase",
"libbinder_ndk",
- "libfmq",
- "libpower",
- "libcutils",
"liblog",
- "libutils",
- "android.hardware.sensors-V2-ndk",
],
static_libs: [
+ "android.hardware.common-V2-ndk",
+ "android.hardware.common.fmq-V1-ndk",
+ "android.hardware.sensors-V2-ndk",
+ "android.system.suspend-V1-ndk",
+ "libbase",
+ "libcutils",
+ "libfmq",
+ "libpower",
"libsensorsexampleimpl",
+ "libutils",
],
srcs: ["main.cpp"],
}
+
+prebuilt_etc {
+ name: "sensors-default.rc",
+ src: "sensors-default.rc",
+ installable: false,
+}
+
+prebuilt_etc {
+ name: "sensors-default.xml",
+ src: "sensors-default.xml",
+ sub_dir: "vintf",
+ installable: false,
+}
+
+// Default vendor APEX for android.hardware.sensors.
+// Custom implementations may use override_apex based on this APEX.
+apex {
+ name: "com.android.hardware.sensors",
+ manifest: "apex_manifest.json",
+ key: "com.android.hardware.key",
+ certificate: ":com.android.hardware.certificate",
+ file_contexts: "file_contexts",
+ updatable: false,
+ vendor: true,
+
+ binaries: ["android.hardware.sensors-service.example"],
+ prebuilts: [
+ "sensors-default.rc", // init rc
+ "sensors-default.xml", // vintf fragment
+ ],
+}
diff --git a/sensors/aidl/default/apex/Android.bp b/sensors/aidl/default/apex/Android.bp
deleted file mode 100644
index 5482086..0000000
--- a/sensors/aidl/default/apex/Android.bp
+++ /dev/null
@@ -1,41 +0,0 @@
-package {
- default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-genrule {
- name: "com.android.hardware.sensors.rc-gen",
- srcs: [":sensors-default.rc"],
- out: ["com.android.hardware.sensors.rc"],
- cmd: "sed -E 's/\\/vendor/\\/apex\\/com.android.hardware.sensors/' $(in) > $(out)",
-}
-
-prebuilt_etc {
- name: "com.android.hardware.sensors.rc",
- src: ":com.android.hardware.sensors.rc-gen",
- installable: false,
-}
-
-// Default vendor APEX for android.hardware.sensors.
-// Custom implementations may use override_apex based on this APEX.
-apex {
- name: "com.android.hardware.sensors",
- manifest: "apex_manifest.json",
- key: "com.android.hardware.key",
- certificate: ":com.android.hardware.certificate",
- file_contexts: "file_contexts",
- updatable: false,
- vendor: true,
-
- binaries: ["android.hardware.sensors-service.example"],
- prebuilts: [
- "com.android.hardware.sensors.rc", // init rc
- "sensors-default.xml", // vintf fragment
- "android.hardware.sensor.ambient_temperature.prebuilt.xml",
- "android.hardware.sensor.barometer.prebuilt.xml",
- "android.hardware.sensor.gyroscope.prebuilt.xml",
- "android.hardware.sensor.hinge_angle.prebuilt.xml",
- "android.hardware.sensor.light.prebuilt.xml",
- "android.hardware.sensor.proximity.prebuilt.xml",
- "android.hardware.sensor.relative_humidity.prebuilt.xml",
- ],
-}
diff --git a/sensors/aidl/default/apex/com.android.hardware.sensors.avbpubkey b/sensors/aidl/default/apex/com.android.hardware.sensors.avbpubkey
deleted file mode 100644
index 98dfb71..0000000
--- a/sensors/aidl/default/apex/com.android.hardware.sensors.avbpubkey
+++ /dev/null
Binary files differ
diff --git a/sensors/aidl/default/apex/com.android.hardware.sensors.pem b/sensors/aidl/default/apex/com.android.hardware.sensors.pem
deleted file mode 100644
index a2f1833..0000000
--- a/sensors/aidl/default/apex/com.android.hardware.sensors.pem
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJKAIBAAKCAgEArUwl9rjXtNrSqJ2rfEryTnVEte7uhZlsn42rXRHFZtuV8N03
-AKAFDDkhJIT+FqmVJLW1Whrno+goaKzA23BodZcSo/xOJuTopgQ/TVqIO2QZ2WUS
-1NiYT3+kydZgtBHhfS+ek9h6aTLgJUn/XBX2xgEA6kp/NkcLpGkqj9Xs7XUpG+n/
-KnyYg+/YFqooEKHTTi4dT9YgRblgzv5zhCKxjB9gqy8dmhwDTpbPGavNiMIZvnSs
-aQzXh7+UMwte+V4QdaEqonoVWm85vEh6rsPpvvmxvlkVnUstRWRwsvbA183gvwZg
-f7OmAgpVu0kEkSHpoJJWpDUhzxmTdxmwvmL92eCJqQUjvxLqak4uBt+epUgbgxcA
-nS7rNg6PsNlHhYl5wRArPP17iW/QK3qnoz8rKgJCtdxPPD13byA13eY9q+Fdwb2H
-uHxGu1iYlRxUAzptvb6pIED/v9MMw/g3yMJkR89WG+pBLbUXHko6H0qOVchYrd8C
-OtcGo7GBBPbJmj9ZGZDX7p5YBSdTZs8f9wWqJmXkfVR60zZE0dOnOchzL44c8oUh
-uwEZMee7Ae/2LfWnfIe5KBNTvvH1CzU8KbQUJJVbATbb3j/eYExgsbnk0WgFi6i4
-osuJZZmfC44tAg18gXozcji+xYuW3MIMV2+drdc3xXn7LXKn5JZCLVJ6n+cCAwEA
-AQKCAgATT6P/XVO0NJo67e75F8Tul0TD3U85FgKzuO66nUtZDekkgRIrAKnvVcJq
-tmM2FUmoYJNH6i2b5zfxiianjVwmlmIeYfQ3g1Slg12megsqSxpSTmAN1eELItcz
-Iq9+AWwWLiNGqF3jsSanIRrSoSPxppT6hrisTLhwZsO2aYlQYLjnAmlLy7yXHzf+
-NpHmYJISaTMc/Wh1PJYcGuC2fcM5MRntmX9799kqfcWwP6PUtIR347p+rk6qMuAJ
-3B+GPEQrR31fw6jzfed6Ir2BEhXPETYMVxMAhysRS4L/fl247pk30Dcao+NA4PPy
-vc1Devr0yLnc7IrK8DetkvBOFuvgl53gHPZ4f7ge2PQMPghwjBaFuXklcfY96PVw
-Yo/CyAN+VEANThFFcKUzovtHI6m3sNTlxE6F+AYvx5dE/WZKmE5/cYCSJ8bhLPJl
-G68VkdeNv0LMZ/7rf1OEWP/YWw/5/tQ7MJ0IO5GShjE2EAGG0SZgK8/fwHZZJFES
-oYVWlriGtGDfiYjPLqVIjdZI6iOo6BMQh6pl0TPIJpn3ODqtRy8gN3TMvG6VcTJy
-QE3Z+br7UsK4gXSw0+MNLC3VKhX2bjT5q9lVpVnLv4L7q1ad4kwHblFAo686ZbWt
-eKTUv7QTI3fFqYeZEgCqRBQZ3UoKyWOBg0MAbf26hZFTFFpbEQKCAQEA2JdW6wDM
-iO1haR168l497nUC382/f/fJA8vzFdJ7cHVM95Tx/5JNYNJSL30XDyux9RJNqnFu
-tByec4c5CVuX/Gv/B4Q++xaaI7OVT9hTl/aoTShObGRJGbVh8xZagb7on7dAfD6G
-1SzTaahxQT5neoiki13GvJ6teL+0ZbCxRDMfPyy79lRzH5d0mw+EQvtc0Vvkweyj
-zf/Mn0yMZHO19oCKjJo8QkciseOqaS2mpgtOiRDc01uuaFAcw6taiERrR86xK2Yl
-OowIx6Yu8n7jRyTGUfr2Oz97a/zDVMVRi3BuyePOyCD9PfUmoj9JyCFbQSS1Lq3N
-AWacnNwQpkDDiQKCAQEAzNQ3/hKhjrLyEm2ktQk1Tzyk4eGu/NElxSKM7uJTeU0k
-xxKuMNMQCJbZmklJKojVYZ0fsh6AyLEpBMV6mWTmVo0qA/A09jKD2tsKu52KGCMt
-vgrN4Gi5JJJACNbtpG7uSJstAYuUGYQSTuS/xCE+urgMVbWBTocsf0bEeEe0FRWX
-txhS/zdj6wspTd6lJ0SSahWG/BsV7990zaRDGYv0N1+SwF8/C0Ml99WbyRof6oP9
-jx0esKA+giWc5lSk+Ag2gpsTIH36aF53lQnDBZL3hqSgqP0ollKa9Uyjfmp65D1m
-TwoENrKnVNO5ZKteTM3SGQ+zsHxBPpinK7T2BPe77wKCAQBdS+Nu2ys/mDErnD1H
-hXzb6J9SVEg3ET8PWZzeO4pciMqcoxYS5qxaFn68Yf+60zGWxUmbL71l7CX80bSp
-6UBwxPxX+ok+kx/WXRbmC+MGRIN+qOwPGKu8XTtSAMD/voJpugAXBMADt4lhq+MN
-HZppV865Ea33tco3hyxn2VKic/rztYtJslrcstrRqD9qsufqbtD9D7gHljZIMCsR
-Yh5xjjEgG5f1XLr/MXhIUhfE0n4D4LWefZGE8W1Sg889f2tOxSPf8+H5dDSb+2Oh
-pTK1hIvA6H+ESfYaMAjbzRsxGz89y9lYr40mUSFRJj3b7TJnvy4ka00xW0f+8XRi
-iOcxAoIBAB0o8Te4i0t3akL5XQNw5if7qDWIHZNcaxYfjxTLH7sbIms825OT2KqA
-X0Y5vLLTfB1Dcym2cfsgTYiiXIvN84TK3/pjjgamtmLH4EVJbkl1aKOvghO6lPEB
-6R/ZCUfpiv7HKKcZqeHgDYMxyaMwYG/Ql+Dz0A7P66PK/VlqS9bclha43cf7qLvj
-gOPXGIf4mSeFHQxzBrJ5i3VjNzJB3GitsIS2ipEd5B/eRylgEL8gP07KhH38silx
-FV8tGbc95BS/4v8zMBz/peKP2zXF8Hs4oK6uK8MKy4i0emoa2pf3rcL+2A65bF0F
-L1WHmAszGf/7Xkd3yQoSTWpJfuTCJ/0CggEBAJjkBaEoiRYp0RBq1Ty0wa+xbPHp
-gAcpco+VC3T8uqniKBDrf5QsMDm7+P9IZRYrfgyy0KFeG4mHrTt61JgOLnhSTOyz
-EEChc8SOn6+vqMB36FmSSqVb6CdLEZhv5dtTzzHgyd3xS3cwga9Mf2SCoG/l34HJ
-XzfoQyLKvqF0kWOq/76k+kBM5QwWIGc2fVXcpJpWaAuPWKDQJnkvTcPp8XPyEADv
-z2YbSDDqqcwczX2DWepf2t2RU1fdyjS5wS6pNDvsuyd6gwUTQT1P5ODHbIdAwcdi
-5Gxui8voJmzvrfabIsN6H73ZS4Lw20ZB+ejYyiwxZcb0os45C1coicMJ9wQ=
------END RSA PRIVATE KEY-----
diff --git a/sensors/aidl/default/apex/com.android.hardware.sensors.pk8 b/sensors/aidl/default/apex/com.android.hardware.sensors.pk8
deleted file mode 100644
index 7a1cca0..0000000
--- a/sensors/aidl/default/apex/com.android.hardware.sensors.pk8
+++ /dev/null
Binary files differ
diff --git a/sensors/aidl/default/apex/com.android.hardware.sensors.x509.pem b/sensors/aidl/default/apex/com.android.hardware.sensors.x509.pem
deleted file mode 100644
index 20a06f9..0000000
--- a/sensors/aidl/default/apex/com.android.hardware.sensors.x509.pem
+++ /dev/null
@@ -1,34 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIF3TCCA8UCFAbIl4RS714WSLo4k64MHsINz4VEMA0GCSqGSIb3DQEBCwUAMIGp
-MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
-bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEi
-MCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTElMCMGA1UEAwwcY29t
-LmFuZHJvaWQuaGFyZHdhcmUuc2Vuc29yczAgFw0yMTA5MDMxNjEyNDNaGA80NzU5
-MDczMTE2MTI0M1owgakxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh
-MRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYD
-VQQLDAdBbmRyb2lkMSIwIAYJKoZIhvcNAQkBFhNhbmRyb2lkQGFuZHJvaWQuY29t
-MSUwIwYDVQQDDBxjb20uYW5kcm9pZC5oYXJkd2FyZS5zZW5zb3JzMIICIjANBgkq
-hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnluNTPcq4pDEeb5gEYszRYQCawq8czUY
-J+x2b0i7qO2wLidX45CX6BLZ9N7c5veoV3FvC1wMTRR6lGAyg7UbD80vVmPdmr6R
-vw2AdIqrghXinvAEv6gxQQPVQa8UHkCL4lULLXo2gdmoCBM8VJHihjO/2F8ZLsP/
-nKhYx9Nr6w9LEyalmHTkXOgNyrNprpbJwugdk3hDXbAK+j5nF9fsz/iWFoXnPuNe
-oqdWj21YhXKDAbewBXaM6l3qmTdGsVVJL4HmVURGUY2f2UZwMWTEjpy9UDzyfqqg
-CSdH1RLmGVAINyfNI3Zswo0CjnOCf0jW6mq9/6mfGYu8hBCrky/rOH8reDwYZTGe
-H6JbNj0dhEN5HzQcxGEQQ43L1nmH7XlnuPO0xPSsw5binPVuUvURivR3PSsFgpPl
-0Uche62XgLAXCXhNV2uUQtZLVFGug7JcGgS4O3GoKr6w35Q+W9SEXanXFMW6X+wN
-hkbhB4MDSuKTZrjEnZEyxMOLG8ILN9i7osa+yjWONTn9bZc6q3Y9jyu3u84o8kC8
-KDcvr8YZEL63nQsQXO44GiQmqBptuB+ehcAC6uRCKkY9tQ95EQ7laGQ3C85d3gPj
-NcGjT7SSuUir7n+LI9pZsotedd9+rGhiiyT8CM4sVWiYJFnA2UX/bsnkZyAOq9Po
-jz1aMdHc4wUCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEATEPN2SZk8pJc4DaWmhyR
-MUklzVeuN0J0Mij1mHuVmID7Q5IhBBXxtVmwRIo208rHSvFLAo7Z4FnuZCV3A/c9
-TlXT3S2t+iYG5eOyXSsoSc/uerJ7kIBcOe27qIrO9GwcK5CQlTaXP+CG1gbLp1nl
-IaqKAT+eb/ji5wmFxMI77wo3uKLPTCfpaptFNaYlRqvxiXdJsCZwCPgmCtXJUeeZ
-R/HKOA4PcS2QB+HwhYePY5kUJPwt6MwJEyno72oenfl49FrGHj0BzVmQ7KMfiYjZ
-eRSB2Wbo50xfiICkPlUcvWD8rRNg7N9CM/Q5O0MW3ivAe42aGap/8qfXUa+L5vu4
-9vaxgQvBVcPXE/pyeCYM8beB84Us+FOYPC7gIUhcctBqGYAQmHzp3sXvIg0DVxz7
-0aqolFGpjRFqbgheS9WRkDHFpYrhR1XMVOQjussHqWEyRcvliqeFlZr8+JNkJNi+
-lmGMdnEAWZs8PL0/AEf+8y0Nr/w0k3Y6IZCDcwpxbpJQOU5pAbkfUzEJHkxMfuvW
-ZshvqIMOaLWCGxZaxlbLRxWGuarWYzfmDY3n9TwJmAIUdMLiswv3UsCmLBJO1XGX
-SUWfgi4fyG1/phfzhdU3efMvmN+XT16/ykMrY8P5S+ghwK12IZ3DgTl0ooLFABUj
-zYeQ8LLz3SP9LNgeLnPP/po=
------END CERTIFICATE-----
diff --git a/sensors/aidl/default/apex/apex_manifest.json b/sensors/aidl/default/apex_manifest.json
similarity index 100%
rename from sensors/aidl/default/apex/apex_manifest.json
rename to sensors/aidl/default/apex_manifest.json
diff --git a/sensors/aidl/default/apex/file_contexts b/sensors/aidl/default/file_contexts
similarity index 100%
rename from sensors/aidl/default/apex/file_contexts
rename to sensors/aidl/default/file_contexts
diff --git a/sensors/aidl/default/multihal/Android.bp b/sensors/aidl/default/multihal/Android.bp
index a20d6d7..7482ffe 100644
--- a/sensors/aidl/default/multihal/Android.bp
+++ b/sensors/aidl/default/multihal/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_sensors",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -45,11 +46,6 @@
"HalProxyAidl.cpp",
"ConvertUtils.cpp",
],
- visibility: [
- ":__subpackages__",
- "//hardware/interfaces/sensors/aidl/multihal:__subpackages__",
- "//hardware/interfaces/tests/extension/sensors:__subpackages__",
- ],
static_libs: [
"android.hardware.sensors@1.0-convert",
"android.hardware.sensors@2.X-multihal",
diff --git a/sensors/aidl/default/sensors-default.rc b/sensors/aidl/default/sensors-default.rc
index 96da85d..e0b0ef0 100644
--- a/sensors/aidl/default/sensors-default.rc
+++ b/sensors/aidl/default/sensors-default.rc
@@ -1,4 +1,4 @@
-service vendor.sensors-default /vendor/bin/hw/android.hardware.sensors-service.example
+service vendor.sensors-default /apex/com.android.hardware.sensors/bin/hw/android.hardware.sensors-service.example
class hal
user system
group system
diff --git a/sensors/aidl/multihal/Android.bp b/sensors/aidl/multihal/Android.bp
index 522d305..cac5fc2 100644
--- a/sensors/aidl/multihal/Android.bp
+++ b/sensors/aidl/multihal/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_sensors",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/sensors/aidl/vts/Android.bp b/sensors/aidl/vts/Android.bp
index c17a558..1f96bb4 100644
--- a/sensors/aidl/vts/Android.bp
+++ b/sensors/aidl/vts/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_android_sensors",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/sensors/common/convert/Android.bp b/sensors/common/convert/Android.bp
index 230665e..5c6aba3 100644
--- a/sensors/common/convert/Android.bp
+++ b/sensors/common/convert/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_android_sensors",
default_applicable_licenses: ["Android-Apache-2.0"],
}
diff --git a/sensors/common/default/2.X/Android.bp b/sensors/common/default/2.X/Android.bp
index 82c942f..300598f 100644
--- a/sensors/common/default/2.X/Android.bp
+++ b/sensors/common/default/2.X/Android.bp
@@ -14,6 +14,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_android_sensors",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/sensors/common/default/2.X/multihal/Android.bp b/sensors/common/default/2.X/multihal/Android.bp
index b0ad934..c25b17a 100644
--- a/sensors/common/default/2.X/multihal/Android.bp
+++ b/sensors/common/default/2.X/multihal/Android.bp
@@ -14,6 +14,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_android_sensors",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/sensors/common/default/2.X/multihal/tests/Android.bp b/sensors/common/default/2.X/multihal/tests/Android.bp
index 21d1d77..d743d1e 100644
--- a/sensors/common/default/2.X/multihal/tests/Android.bp
+++ b/sensors/common/default/2.X/multihal/tests/Android.bp
@@ -14,6 +14,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_android_sensors",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/sensors/common/utils/Android.bp b/sensors/common/utils/Android.bp
index 97e857c..2aeeb14 100644
--- a/sensors/common/utils/Android.bp
+++ b/sensors/common/utils/Android.bp
@@ -14,6 +14,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_android_sensors",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/sensors/common/vts/2_X/Android.bp b/sensors/common/vts/2_X/Android.bp
index 4cf6a08..e7cab6d 100644
--- a/sensors/common/vts/2_X/Android.bp
+++ b/sensors/common/vts/2_X/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_sensors",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/sensors/common/vts/utils/Android.bp b/sensors/common/vts/utils/Android.bp
index ab3984c..69b1224 100644
--- a/sensors/common/vts/utils/Android.bp
+++ b/sensors/common/vts/utils/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_sensors",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/soundtrigger/aidl/Android.bp b/soundtrigger/aidl/Android.bp
index aa400c1..fcbaf6b 100644
--- a/soundtrigger/aidl/Android.bp
+++ b/soundtrigger/aidl/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/soundtrigger/aidl/cli/Android.bp b/soundtrigger/aidl/cli/Android.bp
index 935e438..2d01b0b 100644
--- a/soundtrigger/aidl/cli/Android.bp
+++ b/soundtrigger/aidl/cli/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_media_audio_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/tetheroffload/aidl/Android.bp b/tetheroffload/aidl/Android.bp
index 6de27c3..e091c5b 100644
--- a/tetheroffload/aidl/Android.bp
+++ b/tetheroffload/aidl/Android.bp
@@ -18,6 +18,9 @@
],
min_sdk_version: "30",
enabled: true,
+ lint: {
+ baseline_filename: "lint-baseline.xml",
+ },
},
ndk: {
apps_enabled: false,
diff --git a/tetheroffload/aidl/lint-baseline.xml b/tetheroffload/aidl/lint-baseline.xml
new file mode 100644
index 0000000..62924b1
--- /dev/null
+++ b/tetheroffload/aidl/lint-baseline.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.4.0-alpha01" type="baseline" client="" dependencies="true" name="" variant="all" version="8.4.0-alpha01">
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/soong/.intermediates/hardware/interfaces/tetheroffload/aidl/android.hardware.tetheroffload-V1-java-source/gen/android/hardware/tetheroffload/IOffload.java"
+ line="64"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/soong/.intermediates/hardware/interfaces/tetheroffload/aidl/android.hardware.tetheroffload-V1-java-source/gen/android/hardware/tetheroffload/ITetheringOffloadCallback.java"
+ line="45"
+ column="12"/>
+ </issue>
+
+</issues>
\ No newline at end of file
diff --git a/tetheroffload/config/1.0/Android.bp b/tetheroffload/config/1.0/Android.bp
index 116c9b6..b5c4185 100644
--- a/tetheroffload/config/1.0/Android.bp
+++ b/tetheroffload/config/1.0/Android.bp
@@ -19,4 +19,8 @@
"android.hidl.base@1.0",
],
gen_java: true,
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.tethering",
+ ],
}
diff --git a/tetheroffload/control/1.0/Android.bp b/tetheroffload/control/1.0/Android.bp
index acb5ee8..6589ee2 100644
--- a/tetheroffload/control/1.0/Android.bp
+++ b/tetheroffload/control/1.0/Android.bp
@@ -21,4 +21,8 @@
"android.hidl.base@1.0",
],
gen_java: true,
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.tethering",
+ ],
}
diff --git a/thermal/aidl/Android.bp b/thermal/aidl/Android.bp
index 9382b94..734aab7 100644
--- a/thermal/aidl/Android.bp
+++ b/thermal/aidl/Android.bp
@@ -45,6 +45,6 @@
imports: [],
},
],
- frozen: true,
+ frozen: false,
}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingDevice.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingDevice.aidl
index dff3c4c..7e1aed7 100644
--- a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingDevice.aidl
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingDevice.aidl
@@ -38,4 +38,7 @@
android.hardware.thermal.CoolingType type;
String name;
long value;
+ long powerLimitMw;
+ long powerMw;
+ long timeWindowMs;
}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingType.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingType.aidl
index 1f87cf2..5e88aa0 100644
--- a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingType.aidl
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingType.aidl
@@ -46,4 +46,8 @@
POWER_AMPLIFIER,
DISPLAY,
SPEAKER,
+ WIFI,
+ CAMERA,
+ FLASHLIGHT,
+ USB_PORT,
}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/ICoolingDeviceChangedCallback.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/ICoolingDeviceChangedCallback.aidl
new file mode 100644
index 0000000..ea75b1c
--- /dev/null
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/ICoolingDeviceChangedCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.thermal;
+/* @hide */
+@VintfStability
+interface ICoolingDeviceChangedCallback {
+ oneway void notifyCoolingDeviceChanged(in android.hardware.thermal.CoolingDevice coolingDevice);
+}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/IThermal.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/IThermal.aidl
index c9b6cab..904496c 100644
--- a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/IThermal.aidl
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/IThermal.aidl
@@ -44,4 +44,6 @@
void registerThermalChangedCallback(in android.hardware.thermal.IThermalChangedCallback callback);
void registerThermalChangedCallbackWithType(in android.hardware.thermal.IThermalChangedCallback callback, in android.hardware.thermal.TemperatureType type);
void unregisterThermalChangedCallback(in android.hardware.thermal.IThermalChangedCallback callback);
+ void registerCoolingDeviceChangedCallbackWithType(in android.hardware.thermal.ICoolingDeviceChangedCallback callback, in android.hardware.thermal.CoolingType type);
+ void unregisterCoolingDeviceChangedCallback(in android.hardware.thermal.ICoolingDeviceChangedCallback callback);
}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureType.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureType.aidl
index e9710a7..665a36e 100644
--- a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureType.aidl
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureType.aidl
@@ -35,7 +35,7 @@
/* @hide */
@Backing(type="int") @VintfStability
enum TemperatureType {
- UNKNOWN = (-1),
+ UNKNOWN = (-1) /* -1 */,
CPU = 0,
GPU = 1,
BATTERY = 2,
@@ -50,4 +50,10 @@
DISPLAY = 11,
MODEM = 12,
SOC = 13,
+ WIFI = 14,
+ CAMERA = 15,
+ FLASHLIGHT = 16,
+ SPEAKER = 17,
+ AMBIENT = 18,
+ POGO = 19,
}
diff --git a/thermal/aidl/android/hardware/thermal/CoolingDevice.aidl b/thermal/aidl/android/hardware/thermal/CoolingDevice.aidl
index 0c5c17d..406733b 100644
--- a/thermal/aidl/android/hardware/thermal/CoolingDevice.aidl
+++ b/thermal/aidl/android/hardware/thermal/CoolingDevice.aidl
@@ -40,4 +40,16 @@
* means deeper throttling.
*/
long value;
+ /**
+ * Power budget (mW) of the cooling device.
+ */
+ long powerLimitMw;
+ /**
+ * Target cooling device's AVG power for the last time_window_ms.
+ */
+ long powerMw;
+ /**
+ * The time window (millisecond) to calculate the power consumption
+ */
+ long timeWindowMs;
}
diff --git a/thermal/aidl/android/hardware/thermal/CoolingType.aidl b/thermal/aidl/android/hardware/thermal/CoolingType.aidl
index 08beb55..c00028d 100644
--- a/thermal/aidl/android/hardware/thermal/CoolingType.aidl
+++ b/thermal/aidl/android/hardware/thermal/CoolingType.aidl
@@ -34,4 +34,8 @@
POWER_AMPLIFIER,
DISPLAY,
SPEAKER,
+ WIFI,
+ CAMERA,
+ FLASHLIGHT,
+ USB_PORT,
}
diff --git a/thermal/aidl/android/hardware/thermal/ICoolingDeviceChangedCallback.aidl b/thermal/aidl/android/hardware/thermal/ICoolingDeviceChangedCallback.aidl
new file mode 100644
index 0000000..e6bb9fe
--- /dev/null
+++ b/thermal/aidl/android/hardware/thermal/ICoolingDeviceChangedCallback.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.thermal;
+
+import android.hardware.thermal.CoolingDevice;
+import android.hardware.thermal.Temperature;
+
+/**
+ * ICoolingDeviceChangedCallback send cooling device change notification to clients.
+ * @hide
+ */
+@VintfStability
+interface ICoolingDeviceChangedCallback {
+ /**
+ * Send a cooling device change event to all ThermalHAL
+ * cooling device event listeners.
+ *
+ * @param cooling_device The cooling device information associated with the
+ * change event.
+ */
+ oneway void notifyCoolingDeviceChanged(in CoolingDevice coolingDevice);
+}
diff --git a/thermal/aidl/android/hardware/thermal/IThermal.aidl b/thermal/aidl/android/hardware/thermal/IThermal.aidl
index c94edcd..4aa4090 100644
--- a/thermal/aidl/android/hardware/thermal/IThermal.aidl
+++ b/thermal/aidl/android/hardware/thermal/IThermal.aidl
@@ -18,6 +18,7 @@
import android.hardware.thermal.CoolingDevice;
import android.hardware.thermal.CoolingType;
+import android.hardware.thermal.ICoolingDeviceChangedCallback;
import android.hardware.thermal.IThermalChangedCallback;
import android.hardware.thermal.Temperature;
import android.hardware.thermal.TemperatureThreshold;
@@ -188,4 +189,40 @@
* getMessage() must be populated with human-readable error message.
*/
void unregisterThermalChangedCallback(in IThermalChangedCallback callback);
+
+ /**
+ * Register an ICoolingDeviceChangedCallback for a given CoolingType, used by
+ * the Thermal HAL to receive CDEV events when cooling device status
+ * changed.
+ * Multiple registrations with different ICoolingDeviceChangedCallback must be allowed.
+ * Multiple registrations with same ICoolingDeviceChangedCallback is not allowed, client
+ * should unregister the given ICoolingDeviceChangedCallback first.
+ *
+ * @param callback the ICoolingChangedCallback to use for receiving
+ * cooling device events. If nullptr callback is given, the status code will be
+ * STATUS_BAD_VALUE and the operation will fail.
+ * @param type the type to be filtered.
+ *
+ * @throws EX_ILLEGAL_ARGUMENT If the callback is given nullptr or already registered. And the
+ * getMessage() must be populated with human-readable error message.
+ * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+ * getMessage() must be populated with human-readable error message.
+ */
+ void registerCoolingDeviceChangedCallbackWithType(
+ in ICoolingDeviceChangedCallback callback, in CoolingType type);
+
+ /**
+ * Unregister an ICoolingDeviceChangedCallback, used by the Thermal HAL
+ * to receive CDEV events when cooling device status changed.
+ *
+ * @param callback the ICoolingDeviceChangedCallback to use for receiving
+ * cooling device events. if nullptr callback is given, the status code will be
+ * STATUS_BAD_VALUE and the operation will fail.
+ *
+ * @throws EX_ILLEGAL_ARGUMENT If the callback is given nullptr or not previously registered.
+ * And the getMessage() must be populated with human-readable error message.
+ * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+ * getMessage() must be populated with human-readable error message.
+ */
+ void unregisterCoolingDeviceChangedCallback(in ICoolingDeviceChangedCallback callback);
}
diff --git a/thermal/aidl/android/hardware/thermal/TemperatureType.aidl b/thermal/aidl/android/hardware/thermal/TemperatureType.aidl
index 467d096..ce2a9fc 100644
--- a/thermal/aidl/android/hardware/thermal/TemperatureType.aidl
+++ b/thermal/aidl/android/hardware/thermal/TemperatureType.aidl
@@ -44,4 +44,10 @@
DISPLAY = 11,
MODEM = 12,
SOC = 13,
+ WIFI = 14,
+ CAMERA = 15,
+ FLASHLIGHT = 16,
+ SPEAKER = 17,
+ AMBIENT = 18,
+ POGO = 19,
}
diff --git a/thermal/aidl/default/Android.bp b/thermal/aidl/default/Android.bp
index 451e1e2..9fe62ce 100644
--- a/thermal/aidl/default/Android.bp
+++ b/thermal/aidl/default/Android.bp
@@ -27,7 +27,7 @@
vendor: true,
stl: "c++_static",
static_libs: [
- "android.hardware.thermal-V1-ndk",
+ "android.hardware.thermal-V2-ndk",
"libbase",
],
shared_libs: [
diff --git a/thermal/aidl/default/Thermal.cpp b/thermal/aidl/default/Thermal.cpp
index f643d22..41d0be8 100644
--- a/thermal/aidl/default/Thermal.cpp
+++ b/thermal/aidl/default/Thermal.cpp
@@ -142,4 +142,53 @@
return ScopedAStatus::ok();
}
+ScopedAStatus Thermal::registerCoolingDeviceChangedCallbackWithType(
+ const std::shared_ptr<ICoolingDeviceChangedCallback>& in_callback, CoolingType in_type) {
+ LOG(VERBOSE) << __func__ << " ICoolingDeviceChangedCallback: " << in_callback
+ << ", CoolingType: " << static_cast<int32_t>(in_type);
+ if (in_callback == nullptr) {
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "Invalid nullptr callback");
+ }
+ {
+ std::lock_guard<std::mutex> _lock(cdev_callback_mutex_);
+ if (std::any_of(cdev_callbacks_.begin(), cdev_callbacks_.end(),
+ [&](const std::shared_ptr<ICoolingDeviceChangedCallback>& c) {
+ return interfacesEqual(c, in_callback);
+ })) {
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "Callback already registered");
+ }
+ cdev_callbacks_.push_back(in_callback);
+ }
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus Thermal::unregisterCoolingDeviceChangedCallback(
+ const std::shared_ptr<ICoolingDeviceChangedCallback>& in_callback) {
+ LOG(VERBOSE) << __func__ << " ICoolingDeviceChangedCallback: " << in_callback;
+ if (in_callback == nullptr) {
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "Invalid nullptr callback");
+ }
+ {
+ std::lock_guard<std::mutex> _lock(cdev_callback_mutex_);
+ bool removed = false;
+ cdev_callbacks_.erase(
+ std::remove_if(cdev_callbacks_.begin(), cdev_callbacks_.end(),
+ [&](const std::shared_ptr<ICoolingDeviceChangedCallback>& c) {
+ if (interfacesEqual(c, in_callback)) {
+ removed = true;
+ return true;
+ }
+ return false;
+ }),
+ cdev_callbacks_.end());
+ if (!removed) {
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "Callback wasn't registered");
+ }
+ }
+ return ScopedAStatus::ok();
+}
} // namespace aidl::android::hardware::thermal::impl::example
diff --git a/thermal/aidl/default/Thermal.h b/thermal/aidl/default/Thermal.h
index 8885e63..d3d8874 100644
--- a/thermal/aidl/default/Thermal.h
+++ b/thermal/aidl/default/Thermal.h
@@ -46,6 +46,7 @@
ndk::ScopedAStatus registerThermalChangedCallback(
const std::shared_ptr<IThermalChangedCallback>& in_callback) override;
+
ndk::ScopedAStatus registerThermalChangedCallbackWithType(
const std::shared_ptr<IThermalChangedCallback>& in_callback,
TemperatureType in_type) override;
@@ -53,9 +54,18 @@
ndk::ScopedAStatus unregisterThermalChangedCallback(
const std::shared_ptr<IThermalChangedCallback>& in_callback) override;
+ ndk::ScopedAStatus registerCoolingDeviceChangedCallbackWithType(
+ const std::shared_ptr<ICoolingDeviceChangedCallback>& in_callback,
+ CoolingType in_type) override;
+
+ ndk::ScopedAStatus unregisterCoolingDeviceChangedCallback(
+ const std::shared_ptr<ICoolingDeviceChangedCallback>& in_callback) override;
+
private:
std::mutex thermal_callback_mutex_;
std::vector<std::shared_ptr<IThermalChangedCallback>> thermal_callbacks_;
+ std::mutex cdev_callback_mutex_;
+ std::vector<std::shared_ptr<ICoolingDeviceChangedCallback>> cdev_callbacks_;
};
} // namespace example
diff --git a/thermal/aidl/default/thermal-example.xml b/thermal/aidl/default/thermal-example.xml
index bdee744..08dc68c 100644
--- a/thermal/aidl/default/thermal-example.xml
+++ b/thermal/aidl/default/thermal-example.xml
@@ -1,7 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.thermal</name>
- <version>1</version>
+ <version>2</version>
<fqname>IThermal/default</fqname>
</hal>
</manifest>
diff --git a/thermal/aidl/vts/Android.bp b/thermal/aidl/vts/Android.bp
index b00eb33..0812811 100644
--- a/thermal/aidl/vts/Android.bp
+++ b/thermal/aidl/vts/Android.bp
@@ -32,7 +32,7 @@
"libbinder_ndk",
],
static_libs: [
- "android.hardware.thermal-V1-ndk",
+ "android.hardware.thermal-V2-ndk",
],
test_suites: [
"vts",
diff --git a/thermal/aidl/vts/VtsHalThermalTargetTest.cpp b/thermal/aidl/vts/VtsHalThermalTargetTest.cpp
index ecb64a7..4208d09 100644
--- a/thermal/aidl/vts/VtsHalThermalTargetTest.cpp
+++ b/thermal/aidl/vts/VtsHalThermalTargetTest.cpp
@@ -27,6 +27,7 @@
#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
+#include <aidl/android/hardware/thermal/BnCoolingDeviceChangedCallback.h>
#include <aidl/android/hardware/thermal/BnThermal.h>
#include <aidl/android/hardware/thermal/BnThermalChangedCallback.h>
#include <android-base/logging.h>
@@ -60,6 +61,15 @@
.throttlingStatus = ThrottlingSeverity::CRITICAL,
};
+static const CoolingDevice kCoolingDevice = {
+ .type = CoolingType::CPU,
+ .name = "test cooling device",
+ .value = 1,
+ .powerLimitMw = 300,
+ .powerMw = 500,
+ .timeWindowMs = 7000,
+};
+
// Callback class for receiving thermal event notifications from main class
class ThermalCallback : public BnThermalChangedCallback {
public:
@@ -86,6 +96,33 @@
bool mInvoke = false;
};
+// Callback class for receiving cooling device event notifications from main class
+class CoolingDeviceCallback : public BnCoolingDeviceChangedCallback {
+ public:
+ ndk::ScopedAStatus notifyCoolingDeviceChanged(const CoolingDevice&) override {
+ {
+ std::lock_guard<std::mutex> lock(mMutex);
+ mInvoke = true;
+ }
+ mNotifyCoolingDeviceChanged.notify_all();
+ return ndk::ScopedAStatus::ok();
+ }
+
+ template <typename R, typename P>
+ [[nodiscard]] bool waitForCallback(std::chrono::duration<R, P> duration) {
+ std::unique_lock<std::mutex> lock(mMutex);
+ bool r = mNotifyCoolingDeviceChanged.wait_for(lock, duration,
+ [this] { return this->mInvoke; });
+ mInvoke = false;
+ return r;
+ }
+
+ private:
+ std::mutex mMutex;
+ std::condition_variable mNotifyCoolingDeviceChanged;
+ bool mInvoke = false;
+};
+
// The main test class for THERMAL HIDL HAL.
class ThermalAidlTest : public testing::TestWithParam<std::string> {
public:
@@ -98,19 +135,42 @@
ASSERT_NE(mThermalCallback, nullptr);
::ndk::ScopedAStatus status = mThermal->registerThermalChangedCallback(mThermalCallback);
ASSERT_TRUE(status.isOk()) << status.getMessage();
+
+ auto ret = mThermal->getInterfaceVersion(&thermal_version);
+ ASSERT_TRUE(ret.isOk()) << ret;
+ if (thermal_version > 1) {
+ mCoolingDeviceCallback = ndk::SharedRefBase::make<CoolingDeviceCallback>();
+ ASSERT_NE(mCoolingDeviceCallback, nullptr);
+ status = mThermal->registerCoolingDeviceChangedCallbackWithType(mCoolingDeviceCallback,
+ kCoolingDevice.type);
+ ASSERT_TRUE(status.isOk()) << status.getMessage();
+ }
}
void TearDown() override {
::ndk::ScopedAStatus status = mThermal->unregisterThermalChangedCallback(mThermalCallback);
ASSERT_TRUE(status.isOk()) << status.getMessage();
+
// Expect to fail if unregister again
status = mThermal->unregisterThermalChangedCallback(mThermalCallback);
ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
+
+ auto ret = mThermal->getInterfaceVersion(&thermal_version);
+ ASSERT_TRUE(ret.isOk()) << ret;
+ if (thermal_version > 1) {
+ status = mThermal->unregisterCoolingDeviceChangedCallback(mCoolingDeviceCallback);
+ ASSERT_TRUE(status.isOk()) << status.getMessage();
+ status = mThermal->unregisterCoolingDeviceChangedCallback(mCoolingDeviceCallback);
+ ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
+ }
}
+ // Stores thermal version
+ int32_t thermal_version;
protected:
std::shared_ptr<IThermal> mThermal;
std::shared_ptr<ThermalCallback> mThermalCallback;
+ std::shared_ptr<CoolingDeviceCallback> mCoolingDeviceCallback;
};
// Test ThermalChangedCallback::notifyThrottling().
@@ -122,6 +182,21 @@
ASSERT_TRUE(thermalCallback->waitForCallback(200ms));
}
+// Test CoolingDeviceChangedCallback::notifyCoolingDeviceChanged().
+// This just calls into and back from our local CoolingDeviceChangedCallback impl.
+TEST_P(ThermalAidlTest, NotifyCoolingDeviceChangedTest) {
+ auto ret = mThermal->getInterfaceVersion(&thermal_version);
+ ASSERT_TRUE(ret.isOk()) << ret;
+ if (thermal_version < 2) {
+ return;
+ }
+ std::shared_ptr<CoolingDeviceCallback> cdevCallback =
+ ndk::SharedRefBase::make<CoolingDeviceCallback>();
+ ::ndk::ScopedAStatus status = cdevCallback->notifyCoolingDeviceChanged(kCoolingDevice);
+ ASSERT_TRUE(status.isOk()) << status.getMessage();
+ ASSERT_TRUE(cdevCallback->waitForCallback(200ms));
+}
+
// Test Thermal->registerThermalChangedCallback.
TEST_P(ThermalAidlTest, RegisterThermalChangedCallbackTest) {
// Expect to fail with same callback
@@ -170,6 +245,37 @@
|| status.getExceptionCode() == EX_NULL_POINTER);
}
+// Test Thermal->registerCoolingDeviceChangedCallbackWithType.
+TEST_P(ThermalAidlTest, RegisterCoolingDeviceChangedCallbackWithTypeTest) {
+ auto ret = mThermal->getInterfaceVersion(&thermal_version);
+ ASSERT_TRUE(ret.isOk()) << ret;
+ if (thermal_version < 2) {
+ return;
+ }
+
+ // Expect to fail with same callback
+ ::ndk::ScopedAStatus status = mThermal->registerCoolingDeviceChangedCallbackWithType(
+ mCoolingDeviceCallback, CoolingType::CPU);
+ ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
+ // Expect to fail with null callback
+ status = mThermal->registerCoolingDeviceChangedCallbackWithType(nullptr, CoolingType::CPU);
+ ASSERT_TRUE(status.getExceptionCode() == EX_ILLEGAL_ARGUMENT ||
+ status.getExceptionCode() == EX_NULL_POINTER);
+ std::shared_ptr<CoolingDeviceCallback> localCoolingDeviceCallback =
+ ndk::SharedRefBase::make<CoolingDeviceCallback>();
+ // Expect to succeed with different callback
+ status = mThermal->registerCoolingDeviceChangedCallbackWithType(localCoolingDeviceCallback,
+ CoolingType::CPU);
+ ASSERT_TRUE(status.isOk()) << status.getMessage();
+ // Remove the local callback
+ status = mThermal->unregisterCoolingDeviceChangedCallback(localCoolingDeviceCallback);
+ ASSERT_TRUE(status.isOk()) << status.getMessage();
+ // Expect to fail with null callback
+ status = mThermal->unregisterCoolingDeviceChangedCallback(nullptr);
+ ASSERT_TRUE(status.getExceptionCode() == EX_ILLEGAL_ARGUMENT ||
+ status.getExceptionCode() == EX_NULL_POINTER);
+}
+
// Test Thermal->getCurrentTemperatures().
TEST_P(ThermalAidlTest, TemperatureTest) {
std::vector<Temperature> ret;
diff --git a/threadnetwork/aidl/Android.bp b/threadnetwork/aidl/Android.bp
index c621b81..7e674e0 100644
--- a/threadnetwork/aidl/Android.bp
+++ b/threadnetwork/aidl/Android.bp
@@ -15,9 +15,6 @@
apex_available: [
"//apex_available:platform",
"com.android.tethering",
- // Keep the threadnetwork apex to make it buildable on udc-mainline-prod.
- // TODO: remove it after moving ot-daemon into tethering.
- "com.android.threadnetwork",
],
min_sdk_version: "30",
},
diff --git a/threadnetwork/aidl/default/Android.bp b/threadnetwork/aidl/default/Android.bp
index 816f892..82a76e0 100644
--- a/threadnetwork/aidl/default/Android.bp
+++ b/threadnetwork/aidl/default/Android.bp
@@ -37,6 +37,7 @@
srcs: [
"main.cpp",
"service.cpp",
+ "socket_interface.cpp",
"thread_chip.cpp",
"utils.cpp",
],
@@ -63,6 +64,7 @@
],
srcs: [
+ "socket_interface.cpp",
"thread_chip.cpp",
"utils.cpp",
"fuzzer.cpp",
diff --git a/threadnetwork/aidl/default/socket_interface.cpp b/threadnetwork/aidl/default/socket_interface.cpp
new file mode 100644
index 0000000..f874209
--- /dev/null
+++ b/threadnetwork/aidl/default/socket_interface.cpp
@@ -0,0 +1,301 @@
+/*
+ * 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.
+ */
+
+/**
+ * @file
+ * This file includes the implementation for the Socket interface to radio
+ * (RCP).
+ */
+
+#include "socket_interface.hpp"
+
+#include <errno.h>
+#include <openthread/logging.h>
+#include <sys/inotify.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/un.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <string>
+
+#include "common/code_utils.hpp"
+#include "openthread/openthread-system.h"
+#include "platform-posix.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace threadnetwork {
+
+SocketInterface::SocketInterface(const ot::Url::Url& aRadioUrl)
+ : mReceiveFrameCallback(nullptr),
+ mReceiveFrameContext(nullptr),
+ mReceiveFrameBuffer(nullptr),
+ mSockFd(-1),
+ mRadioUrl(aRadioUrl) {
+ memset(&mInterfaceMetrics, 0, sizeof(mInterfaceMetrics));
+ mInterfaceMetrics.mRcpInterfaceType = kSpinelInterfaceTypeVendor;
+}
+
+otError SocketInterface::Init(ReceiveFrameCallback aCallback, void* aCallbackContext,
+ RxFrameBuffer& aFrameBuffer) {
+ otError error = OT_ERROR_NONE;
+
+ VerifyOrExit(mSockFd == -1, error = OT_ERROR_ALREADY);
+
+ WaitForSocketFileCreated(mRadioUrl.GetPath());
+
+ mSockFd = OpenFile(mRadioUrl);
+ VerifyOrExit(mSockFd != -1, error = OT_ERROR_FAILED);
+
+ mReceiveFrameCallback = aCallback;
+ mReceiveFrameContext = aCallbackContext;
+ mReceiveFrameBuffer = &aFrameBuffer;
+
+exit:
+ return error;
+}
+
+SocketInterface::~SocketInterface(void) {
+ Deinit();
+}
+
+void SocketInterface::Deinit(void) {
+ CloseFile();
+
+ mReceiveFrameCallback = nullptr;
+ mReceiveFrameContext = nullptr;
+ mReceiveFrameBuffer = nullptr;
+}
+
+otError SocketInterface::SendFrame(const uint8_t* aFrame, uint16_t aLength) {
+ Write(aFrame, aLength);
+
+ return OT_ERROR_NONE;
+}
+
+otError SocketInterface::WaitForFrame(uint64_t aTimeoutUs) {
+ otError error = OT_ERROR_NONE;
+ struct timeval timeout;
+ timeout.tv_sec = static_cast<time_t>(aTimeoutUs / US_PER_S);
+ timeout.tv_usec = static_cast<suseconds_t>(aTimeoutUs % US_PER_S);
+
+ fd_set readFds;
+ fd_set errorFds;
+ int rval;
+
+ FD_ZERO(&readFds);
+ FD_ZERO(&errorFds);
+ FD_SET(mSockFd, &readFds);
+ FD_SET(mSockFd, &errorFds);
+
+ rval = TEMP_FAILURE_RETRY(select(mSockFd + 1, &readFds, nullptr, &errorFds, &timeout));
+
+ if (rval > 0) {
+ if (FD_ISSET(mSockFd, &readFds)) {
+ Read();
+ } else if (FD_ISSET(mSockFd, &errorFds)) {
+ DieNowWithMessage("RCP error", OT_EXIT_FAILURE);
+ } else {
+ DieNow(OT_EXIT_FAILURE);
+ }
+ } else if (rval == 0) {
+ ExitNow(error = OT_ERROR_RESPONSE_TIMEOUT);
+ } else {
+ DieNowWithMessage("wait response", OT_EXIT_FAILURE);
+ }
+
+exit:
+ return error;
+}
+
+void SocketInterface::UpdateFdSet(void* aMainloopContext) {
+ otSysMainloopContext* context = reinterpret_cast<otSysMainloopContext*>(aMainloopContext);
+
+ assert(context != nullptr);
+
+ FD_SET(mSockFd, &context->mReadFdSet);
+
+ if (context->mMaxFd < mSockFd) {
+ context->mMaxFd = mSockFd;
+ }
+}
+
+void SocketInterface::Process(const void* aMainloopContext) {
+ const otSysMainloopContext* context =
+ reinterpret_cast<const otSysMainloopContext*>(aMainloopContext);
+
+ assert(context != nullptr);
+
+ if (FD_ISSET(mSockFd, &context->mReadFdSet)) {
+ Read();
+ }
+}
+
+void SocketInterface::Read(void) {
+ uint8_t buffer[kMaxFrameSize];
+
+ ssize_t rval = TEMP_FAILURE_RETRY(read(mSockFd, buffer, sizeof(buffer)));
+
+ if (rval > 0) {
+ ProcessReceivedData(buffer, static_cast<uint16_t>(rval));
+ } else if (rval < 0) {
+ DieNow(OT_EXIT_ERROR_ERRNO);
+ } else {
+ otLogCritPlat("Socket connection is closed by remote.");
+ exit(OT_EXIT_FAILURE);
+ }
+}
+
+void SocketInterface::Write(const uint8_t* aFrame, uint16_t aLength) {
+ ssize_t rval = TEMP_FAILURE_RETRY(write(mSockFd, aFrame, aLength));
+ VerifyOrDie(rval >= 0, OT_EXIT_ERROR_ERRNO);
+ VerifyOrDie(rval > 0, OT_EXIT_FAILURE);
+}
+
+void SocketInterface::ProcessReceivedData(const uint8_t* aBuffer, uint16_t aLength) {
+ while (aLength--) {
+ uint8_t byte = *aBuffer++;
+ if (mReceiveFrameBuffer->CanWrite(sizeof(uint8_t))) {
+ IgnoreError(mReceiveFrameBuffer->WriteByte(byte));
+ } else {
+ HandleSocketFrame(this, OT_ERROR_NO_BUFS);
+ return;
+ }
+ }
+ HandleSocketFrame(this, OT_ERROR_NONE);
+}
+
+void SocketInterface::HandleSocketFrame(void* aContext, otError aError) {
+ static_cast<SocketInterface*>(aContext)->HandleSocketFrame(aError);
+}
+
+void SocketInterface::HandleSocketFrame(otError aError) {
+ VerifyOrExit((mReceiveFrameCallback != nullptr) && (mReceiveFrameBuffer != nullptr));
+
+ if (aError == OT_ERROR_NONE) {
+ mReceiveFrameCallback(mReceiveFrameContext);
+ } else {
+ mReceiveFrameBuffer->DiscardFrame();
+ otLogWarnPlat("Process socket frame failed: %s", otThreadErrorToString(aError));
+ }
+
+exit:
+ return;
+}
+
+int SocketInterface::OpenFile(const ot::Url::Url& aRadioUrl) {
+ int fd = -1;
+ sockaddr_un serverAddress;
+
+ VerifyOrExit(sizeof(serverAddress.sun_path) > strlen(aRadioUrl.GetPath()),
+ otLogCritPlat("Invalid file path length"));
+ strncpy(serverAddress.sun_path, aRadioUrl.GetPath(), sizeof(serverAddress.sun_path));
+ serverAddress.sun_family = AF_UNIX;
+
+ fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+ VerifyOrExit(fd != -1, otLogCritPlat("open(): errno=%s", strerror(errno)));
+
+ if (connect(fd, reinterpret_cast<struct sockaddr*>(&serverAddress), sizeof(serverAddress)) ==
+ -1) {
+ otLogCritPlat("connect(): errno=%s", strerror(errno));
+ close(fd);
+ fd = -1;
+ }
+
+exit:
+ return fd;
+}
+
+void SocketInterface::CloseFile(void) {
+ VerifyOrExit(mSockFd != -1);
+
+ VerifyOrExit(0 == close(mSockFd), otLogCritPlat("close(): errno=%s", strerror(errno)));
+ VerifyOrExit(wait(nullptr) != -1 || errno == ECHILD,
+ otLogCritPlat("wait(): errno=%s", strerror(errno)));
+
+ mSockFd = -1;
+
+exit:
+ return;
+}
+
+void SocketInterface::WaitForSocketFileCreated(const char* aPath) {
+ int inotifyFd;
+ int wd;
+ int lastSlashIdx;
+ std::string folderPath;
+ std::string socketPath(aPath);
+
+ VerifyOrExit(!IsSocketFileExisted(aPath));
+
+ inotifyFd = inotify_init();
+ VerifyOrDie(inotifyFd != -1, OT_EXIT_ERROR_ERRNO);
+
+ lastSlashIdx = socketPath.find_last_of('/');
+ VerifyOrDie(lastSlashIdx != std::string::npos, OT_EXIT_ERROR_ERRNO);
+
+ folderPath = socketPath.substr(0, lastSlashIdx);
+ wd = inotify_add_watch(inotifyFd, folderPath.c_str(), IN_CREATE);
+ VerifyOrDie(wd != -1, OT_EXIT_ERROR_ERRNO);
+
+ otLogInfoPlat("Waiting for socket file %s be created...", aPath);
+
+ while (true) {
+ fd_set fds;
+ FD_ZERO(&fds);
+ FD_SET(inotifyFd, &fds);
+ struct timeval timeout = {kMaxSelectTimeMs / MS_PER_S,
+ (kMaxSelectTimeMs % MS_PER_S) * MS_PER_S};
+
+ int rval = select(inotifyFd + 1, &fds, nullptr, nullptr, &timeout);
+ VerifyOrDie(rval >= 0, OT_EXIT_ERROR_ERRNO);
+
+ if (rval == 0 && IsSocketFileExisted(aPath)) {
+ break;
+ }
+
+ if (FD_ISSET(inotifyFd, &fds)) {
+ char buffer[sizeof(struct inotify_event)];
+ ssize_t bytesRead = read(inotifyFd, buffer, sizeof(buffer));
+
+ VerifyOrDie(bytesRead >= 0, OT_EXIT_ERROR_ERRNO);
+
+ struct inotify_event* event = reinterpret_cast<struct inotify_event*>(buffer);
+ if ((event->mask & IN_CREATE) && IsSocketFileExisted(aPath)) {
+ break;
+ }
+ }
+ }
+
+ close(inotifyFd);
+
+exit:
+ otLogInfoPlat("Socket file: %s is created", aPath);
+ return;
+}
+
+bool SocketInterface::IsSocketFileExisted(const char* aPath) {
+ struct stat st;
+ return stat(aPath, &st) == 0 && S_ISSOCK(st.st_mode);
+}
+
+} // namespace threadnetwork
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/threadnetwork/aidl/default/socket_interface.hpp b/threadnetwork/aidl/default/socket_interface.hpp
new file mode 100644
index 0000000..f88e926
--- /dev/null
+++ b/threadnetwork/aidl/default/socket_interface.hpp
@@ -0,0 +1,258 @@
+/*
+ * 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.
+ */
+
+/**
+ * @file
+ * This file includes definitions for the Socket interface interface to radio
+ * (RCP).
+ */
+
+#include "lib/spinel/spinel_interface.hpp"
+#include "lib/url/url.hpp"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace threadnetwork {
+
+/**
+ * Defines a Socket interface to the Radio Co-processor (RCP)
+ *
+ */
+class SocketInterface : public ot::Spinel::SpinelInterface {
+ public:
+ /**
+ * Initializes the object.
+ *
+ * @param[in] aRadioUrl RadioUrl parsed from radio url.
+ *
+ */
+ explicit SocketInterface(const ot::Url::Url& aRadioUrl);
+
+ /**
+ * This destructor deinitializes the object.
+ *
+ */
+ ~SocketInterface();
+
+ /**
+ * Initializes the interface to the Radio Co-processor (RCP)
+ *
+ * @note This method should be called before reading and sending Spinel
+ * frames to the interface.
+ *
+ * @param[in] aCallback Callback on frame received
+ * @param[in] aCallbackContext Callback context
+ * @param[in] aFrameBuffer A reference to a `RxFrameBuffer` object.
+ *
+ * @retval OT_ERROR_NONE The interface is initialized successfully
+ * @retval OT_ERROR_ALREADY The interface is already initialized.
+ * @retval OT_ERROR_FAILED Failed to initialize the interface.
+ *
+ */
+ otError Init(ReceiveFrameCallback aCallback, void* aCallbackContext,
+ RxFrameBuffer& aFrameBuffer);
+
+ /**
+ * Deinitializes the interface to the RCP.
+ *
+ */
+ void Deinit(void);
+
+ /**
+ * Sends a Spinel frame to Radio Co-processor (RCP) over the
+ * socket.
+ *
+ * @param[in] aFrame A pointer to buffer containing the Spinel frame to
+ * send.
+ * @param[in] aLength The length (number of bytes) in the frame.
+ *
+ * @retval OT_ERROR_NONE Successfully sent the Spinel frame.
+ * @retval OT_ERROR_FAILED Failed to send a frame.
+ *
+ */
+ otError SendFrame(const uint8_t* aFrame, uint16_t aLength);
+
+ /**
+ * Waits for receiving part or all of Spinel frame within specified
+ * interval.
+ *
+ * @param[in] aTimeout The timeout value in microseconds.
+ *
+ * @retval OT_ERROR_NONE Part or all of Spinel frame is
+ * received.
+ * @retval OT_ERROR_RESPONSE_TIMEOUT No Spinel frame is received within @p
+ * aTimeout.
+ * @retval OT_EXIT_FAILURE RCP error
+ *
+ */
+ otError WaitForFrame(uint64_t aTimeoutUs);
+
+ /**
+ * Updates the file descriptor sets with file descriptors used by the radio
+ * driver.
+ *
+ * @param[in,out] aMainloopContext A pointer to the mainloop context
+ * containing fd_sets.
+ *
+ */
+ void UpdateFdSet(void* aMainloopContext);
+
+ /**
+ * Performs radio driver processing.
+ *
+ * @param[in] aMainloopContext A pointer to the mainloop context
+ * containing fd_sets.
+ *
+ */
+ void Process(const void* aMainloopContext);
+
+ /**
+ * Returns the bus speed between the host and the radio.
+ *
+ * @return Bus speed in bits/second.
+ *
+ */
+ uint32_t GetBusSpeed(void) const { return 1000000; }
+
+ /**
+ * Hardware resets the RCP.
+ *
+ * @retval OT_ERROR_NONE Successfully reset the RCP.
+ * @retval OT_ERROR_NOT_IMPLEMENT The hardware reset is not implemented.
+ *
+ */
+ otError HardwareReset(void) { return OT_ERROR_NOT_IMPLEMENTED; }
+
+ /**
+ * Returns the RCP interface metrics.
+ *
+ * @return The RCP interface metrics.
+ *
+ */
+ const otRcpInterfaceMetrics* GetRcpInterfaceMetrics(void) const { return &mInterfaceMetrics; }
+
+ /**
+ * Indicates whether or not the given interface matches this interface name.
+ *
+ * @param[in] aInterfaceName A pointer to the interface name.
+ *
+ * @retval TRUE The given interface name matches this interface name.
+ * @retval FALSE The given interface name doesn't match this interface
+ * name.
+ */
+ static bool IsInterfaceNameMatch(const char* aInterfaceName) {
+ static const char kInterfaceName[] = "spinel+socket";
+ return (strncmp(aInterfaceName, kInterfaceName, strlen(kInterfaceName)) == 0);
+ }
+
+ private:
+ /**
+ * Instructs `SocketInterface` to read data from radio over the
+ * socket.
+ *
+ * If a full Spinel frame is received, this method invokes the
+ * `HandleSocketFrame()` (on the `aCallback` object from constructor) to
+ * pass the received frame to be processed.
+ *
+ */
+ void Read(void);
+
+ /**
+ * Writes a given frame to the socket.
+ *
+ * @param[in] aFrame A pointer to buffer containing the frame to write.
+ * @param[in] aLength The length (number of bytes) in the frame.
+ *
+ */
+ void Write(const uint8_t* aFrame, uint16_t aLength);
+
+ /**
+ * Process received data.
+ *
+ * If a full frame is finished processing and we obtain the raw Spinel
+ * frame, this method invokes the `HandleSocketFrame()` (on the `aCallback`
+ * object from constructor) to pass the received frame to be processed.
+ *
+ * @param[in] aBuffer A pointer to buffer containing data.
+ * @param[in] aLength The length (number of bytes) in the buffer.
+ *
+ */
+ void ProcessReceivedData(const uint8_t* aBuffer, uint16_t aLength);
+
+ static void HandleSocketFrame(void* aContext, otError aError);
+ void HandleSocketFrame(otError aError);
+
+ /**
+ * Opens file specified by aRadioUrl.
+ *
+ * @param[in] aRadioUrl A reference to object containing path to file and
+ * data for configuring the connection with tty type file.
+ *
+ * @retval The file descriptor of newly opened file.
+ * @retval -1 Fail to open file.
+ *
+ */
+ int OpenFile(const ot::Url::Url& aRadioUrl);
+
+ /**
+ * Closes file associated with the file descriptor.
+ *
+ */
+ void CloseFile(void);
+
+ /**
+ * Check if socket file is created.
+ *
+ * @param[in] aPath Socket file path name.
+ *
+ * @retval TRUE The required socket file is created.
+ * @retval FALSE The required socket file is not created.
+ *
+ */
+ bool IsSocketFileExisted(const char* aPath);
+
+ /**
+ * Wait until the socket file is created.
+ *
+ * @param[in] aPath Socket file path name.
+ *
+ */
+ void WaitForSocketFileCreated(const char* aPath);
+
+ enum {
+ kMaxSelectTimeMs = 2000, ///< Maximum wait time in Milliseconds for file
+ ///< descriptor to become available.
+ };
+
+ ReceiveFrameCallback mReceiveFrameCallback;
+ void* mReceiveFrameContext;
+ RxFrameBuffer* mReceiveFrameBuffer;
+
+ int mSockFd;
+ const ot::Url::Url& mRadioUrl;
+
+ otRcpInterfaceMetrics mInterfaceMetrics;
+
+ // Non-copyable, intentionally not implemented.
+ SocketInterface(const SocketInterface&);
+ SocketInterface& operator=(const SocketInterface&);
+};
+
+} // namespace threadnetwork
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/threadnetwork/aidl/default/thread_chip.cpp b/threadnetwork/aidl/default/thread_chip.cpp
index ed34e63..d1e1d4c 100644
--- a/threadnetwork/aidl/default/thread_chip.cpp
+++ b/threadnetwork/aidl/default/thread_chip.cpp
@@ -24,6 +24,7 @@
#include <utils/Log.h>
#include "hdlc_interface.hpp"
+#include "socket_interface.hpp"
#include "spi_interface.hpp"
namespace aidl {
@@ -43,6 +44,8 @@
mSpinelInterface = std::make_shared<ot::Posix::SpiInterface>(mUrl);
} else if (ot::Posix::HdlcInterface::IsInterfaceNameMatch(interfaceName)) {
mSpinelInterface = std::make_shared<ot::Posix::HdlcInterface>(mUrl);
+ } else if (SocketInterface::IsInterfaceNameMatch(interfaceName)) {
+ mSpinelInterface = std::make_shared<SocketInterface>(mUrl);
} else {
ALOGE("The interface \"%s\" is not supported", interfaceName);
exit(EXIT_FAILURE);
diff --git a/threadnetwork/aidl/vts/VtsHalThreadNetworkTargetTest.cpp b/threadnetwork/aidl/vts/VtsHalThreadNetworkTargetTest.cpp
index 5925b54..2f71b2f 100644
--- a/threadnetwork/aidl/vts/VtsHalThreadNetworkTargetTest.cpp
+++ b/threadnetwork/aidl/vts/VtsHalThreadNetworkTargetTest.cpp
@@ -87,11 +87,16 @@
}
TEST_P(ThreadNetworkAidl, Reset) {
+ ndk::ScopedAStatus status;
std::shared_ptr<ThreadChipCallback> callback =
ndk::SharedRefBase::make<ThreadChipCallback>([](auto /* data */) {});
EXPECT_TRUE(thread_chip->open(callback).isOk());
- EXPECT_TRUE(thread_chip->hardwareReset().isOk());
+ status = thread_chip->hardwareReset();
+ EXPECT_TRUE(status.isOk() || (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION));
+ if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+ GTEST_SKIP() << "Hardware reset is not supported";
+ }
}
TEST_P(ThreadNetworkAidl, SendSpinelFrame) {
diff --git a/tv/cec/1.0/Android.bp b/tv/cec/1.0/Android.bp
index 889399a..836f265 100644
--- a/tv/cec/1.0/Android.bp
+++ b/tv/cec/1.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_tv_os",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/tv/cec/1.0/default/Android.bp b/tv/cec/1.0/default/Android.bp
index e4c226d..abde1f2 100644
--- a/tv/cec/1.0/default/Android.bp
+++ b/tv/cec/1.0/default/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_tv_os",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/tv/cec/1.0/vts/functional/Android.bp b/tv/cec/1.0/vts/functional/Android.bp
index 9a2c714..4022043 100644
--- a/tv/cec/1.0/vts/functional/Android.bp
+++ b/tv/cec/1.0/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_tv_os",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/tv/cec/1.1/Android.bp b/tv/cec/1.1/Android.bp
index 27b4f03..bdfb64c 100644
--- a/tv/cec/1.1/Android.bp
+++ b/tv/cec/1.1/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_tv_os",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/tv/cec/1.1/default/Android.bp b/tv/cec/1.1/default/Android.bp
index b536d23..0b93cf3 100644
--- a/tv/cec/1.1/default/Android.bp
+++ b/tv/cec/1.1/default/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_tv_os",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/tv/cec/1.1/vts/functional/Android.bp b/tv/cec/1.1/vts/functional/Android.bp
index 5a6548d..f8ca804 100644
--- a/tv/cec/1.1/vts/functional/Android.bp
+++ b/tv/cec/1.1/vts/functional/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_tv_os",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/tv/hdmi/cec/aidl/Android.bp b/tv/hdmi/cec/aidl/Android.bp
index 53cb5a9..11d3af2 100644
--- a/tv/hdmi/cec/aidl/Android.bp
+++ b/tv/hdmi/cec/aidl/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_tv_os",
default_applicable_licenses: ["hardware_interfaces_license"],
}
diff --git a/tv/hdmi/cec/aidl/default/Android.bp b/tv/hdmi/cec/aidl/default/Android.bp
index ea4bb94..71efb09 100644
--- a/tv/hdmi/cec/aidl/default/Android.bp
+++ b/tv/hdmi/cec/aidl/default/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_tv_os",
default_applicable_licenses: ["hardware_interfaces_license"],
}
diff --git a/tv/hdmi/cec/aidl/default/HdmiCecMock.cpp b/tv/hdmi/cec/aidl/default/HdmiCecMock.cpp
index 0212e7e..8a3c6f0 100644
--- a/tv/hdmi/cec/aidl/default/HdmiCecMock.cpp
+++ b/tv/hdmi/cec/aidl/default/HdmiCecMock.cpp
@@ -36,6 +36,7 @@
ALOGE("HdmiCecMock died");
auto hdmiCecMock = static_cast<HdmiCecMock*>(cookie);
hdmiCecMock->mCecThreadRun = false;
+ pthread_join(hdmiCecMock->mThreadId, NULL);
}
ScopedAStatus HdmiCecMock::addLogicalAddress(CecLogicalAddress addr, Result* _aidl_return) {
@@ -89,7 +90,9 @@
mCallback = callback;
if (callback != nullptr) {
- AIBinder_linkToDeath(this->asBinder().get(), mDeathRecipient.get(), 0 /* cookie */);
+ mDeathRecipient =
+ ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(serviceDied));
+ AIBinder_linkToDeath(callback->asBinder().get(), mDeathRecipient.get(), this /* cookie */);
mInputFile = open(CEC_MSG_IN_FIFO, O_RDWR | O_CLOEXEC);
mOutputFile = open(CEC_MSG_OUT_FIFO, O_RDWR | O_CLOEXEC);
@@ -220,7 +223,7 @@
int r = -1;
// Open the input pipe
- while (mInputFile < 0) {
+ while (mCecThreadRun && mInputFile < 0) {
usleep(1000 * 1000);
mInputFile = open(CEC_MSG_IN_FIFO, O_RDONLY | O_CLOEXEC);
}
@@ -257,7 +260,15 @@
HdmiCecMock::HdmiCecMock() {
ALOGE("[halimp_aidl] Opening a virtual CEC HAL for testing and virtual machine.");
mCallback = nullptr;
- mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(serviceDied));
+ mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(nullptr);
+}
+
+HdmiCecMock::~HdmiCecMock() {
+ ALOGE("[halimp_aidl] HdmiCecMock shutting down.");
+ mCallback = nullptr;
+ mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(nullptr);
+ mCecThreadRun = false;
+ pthread_join(mThreadId, NULL);
}
} // namespace implementation
diff --git a/tv/hdmi/cec/aidl/default/HdmiCecMock.h b/tv/hdmi/cec/aidl/default/HdmiCecMock.h
index aca0581..e78b1cf 100644
--- a/tv/hdmi/cec/aidl/default/HdmiCecMock.h
+++ b/tv/hdmi/cec/aidl/default/HdmiCecMock.h
@@ -40,6 +40,7 @@
struct HdmiCecMock : public BnHdmiCec {
HdmiCecMock();
+ ~HdmiCecMock();
::ndk::ScopedAStatus addLogicalAddress(CecLogicalAddress addr, Result* _aidl_return) override;
::ndk::ScopedAStatus clearLogicalAddress() override;
::ndk::ScopedAStatus enableAudioReturnChannel(int32_t portId, bool enable) override;
diff --git a/tv/hdmi/cec/aidl/vts/functional/Android.bp b/tv/hdmi/cec/aidl/vts/functional/Android.bp
index 5c86d3f..32ad7c6 100644
--- a/tv/hdmi/cec/aidl/vts/functional/Android.bp
+++ b/tv/hdmi/cec/aidl/vts/functional/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_tv_os",
default_applicable_licenses: ["hardware_interfaces_license"],
}
diff --git a/tv/hdmi/connection/aidl/Android.bp b/tv/hdmi/connection/aidl/Android.bp
index ff7e166..552b52c 100644
--- a/tv/hdmi/connection/aidl/Android.bp
+++ b/tv/hdmi/connection/aidl/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_tv_os",
default_applicable_licenses: ["hardware_interfaces_license"],
}
diff --git a/tv/hdmi/connection/aidl/default/Android.bp b/tv/hdmi/connection/aidl/default/Android.bp
index 5e7e330..926ff42 100644
--- a/tv/hdmi/connection/aidl/default/Android.bp
+++ b/tv/hdmi/connection/aidl/default/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_tv_os",
default_applicable_licenses: ["hardware_interfaces_license"],
}
diff --git a/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp
index 8f4411b..954982e 100644
--- a/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp
+++ b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp
@@ -15,12 +15,11 @@
*/
#define LOG_TAG "android.hardware.tv.hdmi.connection"
+#include "HdmiConnectionMock.h"
#include <android-base/logging.h>
#include <fcntl.h>
#include <utils/Log.h>
-#include "HdmiConnectionMock.h"
-
using ndk::ScopedAStatus;
namespace android {
@@ -34,6 +33,7 @@
ALOGE("HdmiConnectionMock died");
auto hdmi = static_cast<HdmiConnectionMock*>(cookie);
hdmi->mHdmiThreadRun = false;
+ pthread_join(hdmi->mThreadId, NULL);
}
ScopedAStatus HdmiConnectionMock::getPortInfo(std::vector<HdmiPortInfo>* _aidl_return) {
@@ -55,12 +55,15 @@
ScopedAStatus HdmiConnectionMock::setCallback(
const std::shared_ptr<IHdmiConnectionCallback>& callback) {
if (mCallback != nullptr) {
+ stopThread();
mCallback = nullptr;
}
-
if (callback != nullptr) {
mCallback = callback;
- AIBinder_linkToDeath(this->asBinder().get(), mDeathRecipient.get(), 0 /* cookie */);
+ mDeathRecipient =
+ ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(serviceDied));
+
+ AIBinder_linkToDeath(callback->asBinder().get(), mDeathRecipient.get(), this /* cookie */);
mInputFile = open(HDMI_MSG_IN_FIFO, O_RDWR | O_CLOEXEC);
pthread_create(&mThreadId, NULL, __threadLoop, this);
@@ -153,7 +156,7 @@
int r = -1;
// Open the input pipe
- while (mInputFile < 0) {
+ while (mHdmiThreadRun && mInputFile < 0) {
usleep(1000 * 1000);
mInputFile = open(HDMI_MSG_IN_FIFO, O_RDONLY | O_CLOEXEC);
}
@@ -193,7 +196,21 @@
.physicalAddress = mPhysicalAddress};
mPortConnectionStatus[0] = false;
mHpdSignal[0] = HpdSignal::HDMI_HPD_PHYSICAL;
- mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(serviceDied));
+ mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(nullptr);
+}
+
+void HdmiConnectionMock::stopThread() {
+ if (mCallback != nullptr) {
+ ALOGE("[halimp_aidl] HdmiConnectionMock shutting down.");
+ mCallback = nullptr;
+ mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(nullptr);
+ mHdmiThreadRun = false;
+ pthread_join(mThreadId, NULL);
+ }
+}
+
+HdmiConnectionMock::~HdmiConnectionMock() {
+ stopThread();
}
} // namespace implementation
diff --git a/tv/hdmi/connection/aidl/default/HdmiConnectionMock.h b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.h
index c013fdd..8c66f08 100644
--- a/tv/hdmi/connection/aidl/default/HdmiConnectionMock.h
+++ b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.h
@@ -41,7 +41,7 @@
struct HdmiConnectionMock : public BnHdmiConnection {
HdmiConnectionMock();
-
+ ~HdmiConnectionMock();
::ndk::ScopedAStatus getPortInfo(std::vector<HdmiPortInfo>* _aidl_return) override;
::ndk::ScopedAStatus isConnected(int32_t portId, bool* _aidl_return) override;
::ndk::ScopedAStatus setCallback(
@@ -56,6 +56,7 @@
void threadLoop();
int readMessageFromFifo(unsigned char* buf, int msgCount);
void handleHotplugMessage(unsigned char* msgBuf);
+ void stopThread();
private:
static void serviceDied(void* cookie);
diff --git a/tv/hdmi/connection/aidl/vts/functional/Android.bp b/tv/hdmi/connection/aidl/vts/functional/Android.bp
index fc8e2f7..3b74e06 100644
--- a/tv/hdmi/connection/aidl/vts/functional/Android.bp
+++ b/tv/hdmi/connection/aidl/vts/functional/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_tv_os",
default_applicable_licenses: ["hardware_interfaces_license"],
}
diff --git a/tv/hdmi/earc/aidl/Android.bp b/tv/hdmi/earc/aidl/Android.bp
index d08e46d..7e88b27 100644
--- a/tv/hdmi/earc/aidl/Android.bp
+++ b/tv/hdmi/earc/aidl/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_tv_os",
default_applicable_licenses: ["hardware_interfaces_license"],
}
diff --git a/tv/hdmi/earc/aidl/default/Android.bp b/tv/hdmi/earc/aidl/default/Android.bp
index 5d56c2a..55337d7 100644
--- a/tv/hdmi/earc/aidl/default/Android.bp
+++ b/tv/hdmi/earc/aidl/default/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_tv_os",
default_applicable_licenses: ["hardware_interfaces_license"],
}
diff --git a/tv/hdmi/earc/aidl/vts/functional/Android.bp b/tv/hdmi/earc/aidl/vts/functional/Android.bp
index 36fbf56..b33ad8e 100644
--- a/tv/hdmi/earc/aidl/vts/functional/Android.bp
+++ b/tv/hdmi/earc/aidl/vts/functional/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_tv_os",
default_applicable_licenses: ["hardware_interfaces_license"],
}
diff --git a/tv/input/aidl/Android.bp b/tv/input/aidl/Android.bp
index cd69130..2326549 100644
--- a/tv/input/aidl/Android.bp
+++ b/tv/input/aidl/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_tv_os",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/tv/input/aidl/default/Android.bp b/tv/input/aidl/default/Android.bp
index 05af6a9..67015fb 100644
--- a/tv/input/aidl/default/Android.bp
+++ b/tv/input/aidl/default/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_tv_os",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/tv/input/aidl/vts/functional/Android.bp b/tv/input/aidl/vts/functional/Android.bp
index 930c5a8..c472e24 100644
--- a/tv/input/aidl/vts/functional/Android.bp
+++ b/tv/input/aidl/vts/functional/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_tv_os",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.cpp b/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.cpp
index 746ae1e..7e095f1 100644
--- a/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.cpp
+++ b/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#define LOG_TAG "tv_input_aidl_hal_test"
+
#include "VtsHalTvInputTargetTest.h"
#include <android-base/properties.h>
@@ -181,7 +183,9 @@
ALOGD("OpenAndCloseStreamTest: open stream, device_id=%d, stream_id=%d", device_id,
stream_id);
ASSERT_TRUE(tv_input_->openStream(device_id, stream_id, &handle).isOk());
- ASSERT_TRUE(isValidHandle(handle));
+ if (VERIFY_SIDEBAND_STREAM_HANDLE) {
+ ASSERT_TRUE(isValidHandle(handle));
+ }
ALOGD("OpenAndCloseStreamTest: close stream, device_id=%d, stream_id=%d", device_id,
stream_id);
@@ -283,7 +287,9 @@
ALOGD("OpenAnOpenedStreamsTest: open stream, device_id=%d, stream_id=%d", device_id, stream_id);
ASSERT_TRUE(tv_input_->openStream(device_id, stream_id, &handle).isOk());
- ASSERT_TRUE(isValidHandle(handle));
+ if (VERIFY_SIDEBAND_STREAM_HANDLE) {
+ ASSERT_TRUE(isValidHandle(handle));
+ }
ALOGD("OpenAnOpenedStreamsTest: open stream, device_id=%d, stream_id=%d", device_id, stream_id);
ASSERT_TRUE(tv_input_->openStream(device_id, stream_id, &handle).getServiceSpecificError() ==
diff --git a/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.h b/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.h
index 7e66a88..fd98a18 100644
--- a/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.h
+++ b/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.h
@@ -43,6 +43,7 @@
#define WAIT_FOR_EVENT_TIMEOUT 5
#define DEFAULT_ID INT32_MIN
+#define VERIFY_SIDEBAND_STREAM_HANDLE 1
namespace VtsHalTvInputTargetTest {
diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
index fccd2ed..3d60e89 100644
--- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
+++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
@@ -35,6 +35,7 @@
ASSERT_TRUE(mFrontendTests.setFrontendCallback());
ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+ mFrontendTests.setDemux(demux);
mFilterTests.setDemux(demux);
ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.config1_0.type,
filterConf.config1_0.bufferSize));
diff --git a/tv/tuner/aidl/default/Demux.cpp b/tv/tuner/aidl/default/Demux.cpp
index 34e3442..5eeb36a 100644
--- a/tv/tuner/aidl/default/Demux.cpp
+++ b/tv/tuner/aidl/default/Demux.cpp
@@ -114,22 +114,49 @@
}
}
-void Demux::readIptvThreadLoop(dtv_plugin* interface, dtv_streamer* streamer, void* buf,
- size_t buf_size, int timeout_ms, int buffer_timeout) {
+void Demux::setIptvThreadRunning(bool isIptvThreadRunning) {
+ std::unique_lock<std::mutex> lock(mIsIptvThreadRunningMutex);
+ mIsIptvReadThreadRunning = isIptvThreadRunning;
+ mIsIptvThreadRunningCv.notify_all();
+}
+
+void Demux::frontendIptvInputThreadLoop(dtv_plugin* interface, dtv_streamer* streamer, void* buf) {
Timer *timer, *fullBufferTimer;
- while (mDemuxIptvReadThreadRunning) {
- if (mIsIptvDvrFMQFull && fullBufferTimer->get_elapsed_time_ms() > buffer_timeout) {
- ALOGE("DVR FMQ has not been flushed within timeout of %d ms", buffer_timeout);
+ bool isTuneBytePushedToDvr = false;
+ while (true) {
+ std::unique_lock<std::mutex> lock(mIsIptvThreadRunningMutex);
+ mIsIptvThreadRunningCv.wait(
+ lock, [this] { return mIsIptvReadThreadRunning || mIsIptvReadThreadTerminated; });
+ if (mIsIptvReadThreadTerminated) {
+ ALOGI("[Demux] IPTV reading thread for playback terminated");
+ break;
+ }
+ if (mIsIptvDvrFMQFull &&
+ fullBufferTimer->get_elapsed_time_ms() > IPTV_PLAYBACK_BUFFER_TIMEOUT) {
+ ALOGE("DVR FMQ has not been flushed within timeout of %d ms",
+ IPTV_PLAYBACK_BUFFER_TIMEOUT);
delete fullBufferTimer;
break;
}
timer = new Timer();
- ssize_t bytes_read = interface->read_stream(streamer, buf, buf_size, timeout_ms);
- if (bytes_read == 0) {
+ ssize_t bytes_read;
+ void* tuneByteBuffer = mFrontend->getTuneByteBuffer();
+ if (!isTuneBytePushedToDvr && tuneByteBuffer != nullptr) {
+ memcpy(buf, tuneByteBuffer, 1);
+ char* offsetBuf = (char*)buf + 1;
+ bytes_read = interface->read_stream(streamer, (void*)offsetBuf, IPTV_BUFFER_SIZE - 1,
+ IPTV_PLAYBACK_TIMEOUT);
+ isTuneBytePushedToDvr = true;
+ } else {
+ bytes_read =
+ interface->read_stream(streamer, buf, IPTV_BUFFER_SIZE, IPTV_PLAYBACK_TIMEOUT);
+ }
+
+ if (bytes_read <= 0) {
double elapsed_time = timer->get_elapsed_time_ms();
- if (elapsed_time > timeout_ms) {
+ if (elapsed_time > IPTV_PLAYBACK_TIMEOUT) {
ALOGE("[Demux] timeout reached - elapsed_time: %f, timeout: %d", elapsed_time,
- timeout_ms);
+ IPTV_PLAYBACK_TIMEOUT);
}
ALOGE("[Demux] Cannot read data from the socket");
delete timer;
@@ -158,7 +185,6 @@
ALOGI("Invalid DVR Status");
}
}
- mDemuxIptvReadThreadRunning = false;
}
::ndk::ScopedAStatus Demux::setFrontendDataSource(int32_t in_frontendId) {
@@ -192,41 +218,44 @@
// get plugin interface from frontend
dtv_plugin* interface = mFrontend->getIptvPluginInterface();
+ // if plugin interface is not on frontend, create a new plugin interface
if (interface == nullptr) {
- ALOGE("[Demux] getIptvPluginInterface(): plugin interface is null");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::INVALID_STATE));
+ interface = mFrontend->createIptvPluginInterface();
+ if (interface == nullptr) {
+ ALOGE("[ INFO ] Failed to load plugin.");
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_STATE));
+ }
}
- ALOGI("[Demux] getIptvPluginInterface(): plugin interface is not null");
+
+ // get transport description from frontend
+ string transport_desc = mFrontend->getIptvTransportDescription();
+ if (transport_desc.empty()) {
+ string content_url = "rtp://127.0.0.1:12345";
+ transport_desc = "{ \"uri\": \"" + content_url + "\"}";
+ }
+ ALOGI("[Demux] transport_desc: %s", transport_desc.c_str());
// get streamer object from Frontend instance
dtv_streamer* streamer = mFrontend->getIptvPluginStreamer();
if (streamer == nullptr) {
- ALOGE("[Demux] getIptvPluginStreamer(): streamer is null");
+ streamer = mFrontend->createIptvPluginStreamer(interface, transport_desc.c_str());
+ if (streamer == nullptr) {
+ ALOGE("[ INFO ] Failed to open stream");
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_STATE));
+ }
+ }
+ stopIptvFrontendInput();
+ mIsIptvReadThreadTerminated = false;
+ void* buf = malloc(sizeof(char) * IPTV_BUFFER_SIZE);
+ if (buf == nullptr) {
+ ALOGE("[Demux] Buffer allocation failed");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_STATE));
}
- ALOGI("[Demux] getIptvPluginStreamer(): streamer is not null");
-
- // get transport description from frontend
- string transport_desc = mFrontend->getIptvTransportDescription();
- ALOGI("[Demux] getIptvTransportDescription(): transport_desc: %s", transport_desc.c_str());
-
- // call read_stream on the socket to populate the buffer with TS data
- // while thread is alive, keep reading data
- int timeout_ms = 20;
- int buffer_timeout = 10000; // 10s
- void* buf = malloc(sizeof(char) * IPTV_BUFFER_SIZE);
- if (buf == nullptr) ALOGI("malloc buf failed");
- ALOGI("[ INFO ] Allocated buffer of size %d", IPTV_BUFFER_SIZE);
- ALOGI("Getting FMQ from DVR instance to write socket data");
- mDemuxIptvReadThreadRunning = true;
- mDemuxIptvReadThread = std::thread(&Demux::readIptvThreadLoop, this, interface, streamer,
- buf, IPTV_BUFFER_SIZE, timeout_ms, buffer_timeout);
- if (mDemuxIptvReadThread.joinable()) {
- mDemuxIptvReadThread.join();
- }
- free(buf);
+ mDemuxIptvReadThread =
+ std::thread(&Demux::frontendIptvInputThreadLoop, this, interface, streamer, buf);
}
return ::ndk::ScopedAStatus::ok();
}
@@ -343,6 +372,7 @@
ALOGV("%s", __FUNCTION__);
stopFrontendInput();
+ stopIptvFrontendInput();
set<int64_t>::iterator it;
for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) {
@@ -538,6 +568,15 @@
}
}
+void Demux::stopIptvFrontendInput() {
+ ALOGD("[Demux] stop iptv frontend on demux");
+ if (mDemuxIptvReadThread.joinable()) {
+ mIsIptvReadThreadTerminated = true;
+ mIsIptvThreadRunningCv.notify_all();
+ mDemuxIptvReadThread.join();
+ }
+}
+
void Demux::setIsRecording(bool isRecording) {
mIsRecording = isRecording;
}
diff --git a/tv/tuner/aidl/default/Demux.h b/tv/tuner/aidl/default/Demux.h
index a23063f..af040d4 100644
--- a/tv/tuner/aidl/default/Demux.h
+++ b/tv/tuner/aidl/default/Demux.h
@@ -56,6 +56,9 @@
class TimeFilter;
class Tuner;
+const int IPTV_PLAYBACK_TIMEOUT = 20; // ms
+const int IPTV_PLAYBACK_BUFFER_TIMEOUT = 20000; // ms
+
class DvrPlaybackCallback : public BnDvrCallback {
public:
virtual ::ndk::ScopedAStatus onPlaybackStatus(PlaybackStatus status) override {
@@ -103,8 +106,7 @@
void setIsRecording(bool isRecording);
bool isRecording();
void startFrontendInputLoop();
- void readIptvThreadLoop(dtv_plugin* interface, dtv_streamer* streamer, void* buf, size_t size,
- int timeout_ms, int buffer_timeout);
+ void frontendIptvInputThreadLoop(dtv_plugin* interface, dtv_streamer* streamer, void* buf);
/**
* A dispatcher to read and dispatch input data to all the started filters.
@@ -124,6 +126,15 @@
void setInUse(bool inUse);
void setTunerService(std::shared_ptr<Tuner> tuner);
+ /**
+ * Setter for IPTV Reading thread
+ */
+ void setIptvThreadRunning(bool isIptvThreadRunning);
+ /**
+ * Stops IPTV playback reading thread.
+ */
+ void stopIptvFrontendInput();
+
private:
// Tuner service
std::shared_ptr<Tuner> mTuner;
@@ -196,10 +207,17 @@
* If a specific filter's writing loop is still running
*/
std::atomic<bool> mFrontendInputThreadRunning;
- std::atomic<bool> mDemuxIptvReadThreadRunning;
std::atomic<bool> mKeepFetchingDataFromFrontend;
/**
+ * Controls IPTV reading thread status
+ */
+ bool mIsIptvReadThreadRunning = false;
+ std::atomic<bool> mIsIptvReadThreadTerminated = false;
+ std::mutex mIsIptvThreadRunningMutex;
+ std::condition_variable mIsIptvThreadRunningCv;
+
+ /**
* If the dvr recording is running.
*/
bool mIsRecording = false;
diff --git a/tv/tuner/aidl/default/Filter.cpp b/tv/tuner/aidl/default/Filter.cpp
index d8f5dd5..5f7a4cd 100644
--- a/tv/tuner/aidl/default/Filter.cpp
+++ b/tv/tuner/aidl/default/Filter.cpp
@@ -328,6 +328,8 @@
std::vector<DemuxFilterEvent> events;
mFilterCount += 1;
+ mDemux->setIptvThreadRunning(true);
+
// All the filter event callbacks in start are for testing purpose.
switch (mType.mainType) {
case DemuxFilterMainType::TS:
@@ -364,7 +366,12 @@
::ndk::ScopedAStatus Filter::stop() {
ALOGV("%s", __FUNCTION__);
- mFilterCount -= 1;
+ if (mFilterCount > 0) {
+ mFilterCount -= 1;
+ if (mFilterCount.load() == 0) {
+ mDemux->setIptvThreadRunning(false);
+ }
+ }
mFilterThreadRunning = false;
if (mFilterThread.joinable()) {
diff --git a/tv/tuner/aidl/default/Frontend.cpp b/tv/tuner/aidl/default/Frontend.cpp
index 6bdbac5..1031604 100644
--- a/tv/tuner/aidl/default/Frontend.cpp
+++ b/tv/tuner/aidl/default/Frontend.cpp
@@ -34,6 +34,8 @@
mTuner = nullptr;
// Init callback to nullptr
mCallback = nullptr;
+ mIptvPluginInterface = nullptr;
+ mIptvPluginStreamer = nullptr;
switch (mType) {
case FrontendType::ISDBS: {
@@ -186,6 +188,9 @@
mCallback = nullptr;
mIsLocked = false;
mTuner = nullptr;
+ if (mTuneByteBuffer != nullptr) {
+ free(mTuneByteBuffer);
+ }
}
::ndk::ScopedAStatus Frontend::close() {
@@ -213,19 +218,43 @@
return ::ndk::ScopedAStatus::ok();
}
-void Frontend::readTuneByte(dtv_streamer* streamer, void* buf, size_t buf_size, int timeout_ms) {
- ssize_t bytes_read = mIptvPluginInterface->read_stream(streamer, buf, buf_size, timeout_ms);
- if (bytes_read == 0) {
+dtv_plugin* Frontend::createIptvPluginInterface() {
+ const char* path = "/vendor/lib/iptv_udp_plugin.so";
+ DtvPlugin* plugin = new DtvPlugin(path);
+ bool plugin_loaded = plugin->load();
+ if (!plugin_loaded) {
+ ALOGE("Failed to load plugin");
+ return nullptr;
+ }
+ return plugin->interface();
+}
+
+dtv_streamer* Frontend::createIptvPluginStreamer(dtv_plugin* interface,
+ const char* transport_desc) {
+ dtv_streamer* streamer = interface->create_streamer();
+ int open_fd = interface->open_stream(streamer, transport_desc);
+ if (open_fd < 0) {
+ return nullptr;
+ }
+ ALOGI("[ INFO ] open_stream successful, open_fd=%d", open_fd);
+ return streamer;
+}
+
+void Frontend::readTuneByte(void* buf) {
+ ssize_t bytes_read = mIptvPluginInterface->read_stream(mIptvPluginStreamer, buf,
+ TUNE_BUFFER_SIZE, TUNE_BUFFER_TIMEOUT);
+ if (bytes_read <= 0) {
ALOGI("[ ERROR ] Tune byte couldn't be read.");
return;
}
mCallback->onEvent(FrontendEventType::LOCKED);
mIsLocked = true;
+ mTuneByteBuffer = buf;
}
::ndk::ScopedAStatus Frontend::tune(const FrontendSettings& in_settings) {
if (mCallback == nullptr) {
- ALOGW("[ WARN ] Frontend callback is not set for tunin0g");
+ ALOGW("[ WARN ] Frontend callback is not set for tuning");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_STATE));
}
@@ -240,54 +269,39 @@
ALOGI("[ INFO ] Frontend type is set to IPTV, tag = %d id=%d", in_settings.getTag(),
mId);
- // load udp plugin for reading TS data
- const char* path = "/vendor/lib/iptv_udp_plugin.so";
- DtvPlugin* plugin = new DtvPlugin(path);
- if (!plugin) {
- ALOGE("Failed to create DtvPlugin, plugin_path is invalid");
+ mIptvPluginInterface = createIptvPluginInterface();
+ if (mIptvPluginInterface == nullptr) {
+ ALOGE("[ INFO ] Failed to load plugin.");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_ARGUMENT));
}
- bool plugin_loaded = plugin->load();
- if (!plugin_loaded) {
- ALOGE("Failed to load plugin");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::INVALID_ARGUMENT));
- }
- mIptvPluginInterface = plugin->interface();
// validate content_url format
std::string content_url = in_settings.get<FrontendSettings::Tag::iptv>()->contentUrl;
- std::string transport_desc = "{ \"uri\": \"" + content_url + "\"}";
- ALOGI("[ INFO ] transport_desc: %s", transport_desc.c_str());
- bool is_transport_desc_valid = plugin->validate(transport_desc.c_str());
+ mIptvTransportDescription = "{ \"uri\": \"" + content_url + "\"}";
+ ALOGI("[ INFO ] transport_desc: %s", mIptvTransportDescription.c_str());
+ bool is_transport_desc_valid =
+ mIptvPluginInterface->validate(mIptvTransportDescription.c_str());
if (!is_transport_desc_valid) { // not of format protocol://ip:port
ALOGE("[ INFO ] transport_desc is not valid");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_ARGUMENT));
}
- mIptvTransportDescription = transport_desc;
// create a streamer and open it for reading data
- dtv_streamer* streamer = mIptvPluginInterface->create_streamer();
- mIptvPluginStreamer = streamer;
- int open_fd = mIptvPluginInterface->open_stream(streamer, transport_desc.c_str());
- if (open_fd < 0) {
- ALOGE("[ INFO ] could not open stream");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::INVALID_ARGUMENT));
- }
- ALOGI("[ INFO ] open_stream successful, open_fd=%d", open_fd);
+ mIptvPluginStreamer =
+ createIptvPluginStreamer(mIptvPluginInterface, mIptvTransportDescription.c_str());
- size_t buf_size = 1;
- int timeout_ms = 2000;
- void* buf = malloc(sizeof(char) * buf_size);
- if (buf == nullptr) ALOGI("malloc buf failed [TUNE]");
- ALOGI("[ INFO ] [Tune] Allocated buffer of size %zu", buf_size);
- mIptvFrontendTuneThread =
- std::thread(&Frontend::readTuneByte, this, streamer, buf, buf_size, timeout_ms);
- if (mIptvFrontendTuneThread.joinable()) mIptvFrontendTuneThread.join();
- free(buf);
+ void* buf = malloc(sizeof(char) * TUNE_BUFFER_SIZE);
+ if (buf == nullptr) {
+ ALOGE("Failed to allocate 1 byte buffer for tuning.");
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_STATE));
+ }
+ mIptvFrontendTuneThread = std::thread(&Frontend::readTuneByte, this, buf);
+ if (mIptvFrontendTuneThread.joinable()) {
+ mIptvFrontendTuneThread.join();
+ }
}
return ::ndk::ScopedAStatus::ok();
diff --git a/tv/tuner/aidl/default/Frontend.h b/tv/tuner/aidl/default/Frontend.h
index 17a1aee..f3f8a87 100644
--- a/tv/tuner/aidl/default/Frontend.h
+++ b/tv/tuner/aidl/default/Frontend.h
@@ -33,6 +33,9 @@
class Tuner;
+const int TUNE_BUFFER_SIZE = 1; // byte
+const int TUNE_BUFFER_TIMEOUT = 2000; // ms
+
class Frontend : public BnFrontend {
public:
Frontend(FrontendType type, int32_t id);
@@ -64,7 +67,10 @@
dtv_plugin* getIptvPluginInterface();
string getIptvTransportDescription();
dtv_streamer* getIptvPluginStreamer();
- void readTuneByte(dtv_streamer* streamer, void* buf, size_t size, int timeout_ms);
+ void readTuneByte(void* buf);
+ void* getTuneByteBuffer() { return mTuneByteBuffer; };
+ dtv_streamer* createIptvPluginStreamer(dtv_plugin* interface, const char* transport_desc);
+ dtv_plugin* createIptvPluginInterface();
bool isLocked();
void getFrontendInfo(FrontendInfo* _aidl_return);
void setTunerService(std::shared_ptr<Tuner> tuner);
@@ -90,6 +96,7 @@
string mIptvTransportDescription;
dtv_streamer* mIptvPluginStreamer;
std::thread mIptvFrontendTuneThread;
+ void* mTuneByteBuffer = nullptr;
};
} // namespace tuner
diff --git a/tv/tuner/aidl/vts/functional/Android.bp b/tv/tuner/aidl/vts/functional/Android.bp
index 513007b..09e63fc 100644
--- a/tv/tuner/aidl/vts/functional/Android.bp
+++ b/tv/tuner/aidl/vts/functional/Android.bp
@@ -37,6 +37,7 @@
"FrontendTests.cpp",
"LnbTests.cpp",
"VtsHalTvTunerTargetTest.cpp",
+ "utils/IpStreamer.cpp",
],
generated_headers: [
"tuner_testing_dynamic_configuration_V1_0_enums",
diff --git a/tv/tuner/aidl/vts/functional/FrontendTests.cpp b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
index b0f614e..b7b0185 100644
--- a/tv/tuner/aidl/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
@@ -475,6 +475,10 @@
<< "FrontendConfig does not match the frontend info of the given id.";
mIsSoftwareFe = config.isSoftwareFe;
+ std::unique_ptr<IpStreamer> ipThread = std::make_unique<IpStreamer>();
+ if (config.type == FrontendType::IPTV) {
+ ipThread->startIpStream();
+ }
if (mIsSoftwareFe && testWithDemux) {
if (getDvrTests()->openDvrInDemux(mDvrConfig.type, mDvrConfig.bufferSize) != success()) {
ALOGW("[vts] Software frontend dvr configure openDvr failed.");
@@ -494,6 +498,9 @@
getDvrTests()->startDvrPlayback();
}
mFrontendCallback->tuneTestOnLock(mFrontend, config.settings);
+ if (config.type == FrontendType::IPTV) {
+ ipThread->stopIpStream();
+ }
return AssertionResult(true);
}
diff --git a/tv/tuner/aidl/vts/functional/FrontendTests.h b/tv/tuner/aidl/vts/functional/FrontendTests.h
index 1746c8e..9c2ffc0 100644
--- a/tv/tuner/aidl/vts/functional/FrontendTests.h
+++ b/tv/tuner/aidl/vts/functional/FrontendTests.h
@@ -27,6 +27,7 @@
#include "DvrTests.h"
#include "VtsHalTvTunerTestConfigurations.h"
+#include "utils/IpStreamer.h"
#define WAIT_TIMEOUT 3000000000
#define INVALID_ID -1
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
index 3664b6c..2b39bc6 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
@@ -48,6 +48,7 @@
ASSERT_TRUE(mFrontendTests.setFrontendCallback());
ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+ mFrontendTests.setDemux(demux);
mFilterTests.setDemux(demux);
ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId));
@@ -1111,6 +1112,10 @@
if (!record.support) {
return;
}
+ // Recording is not currently supported for IPTV frontend
+ if (frontendMap[live.frontendId].type == FrontendType::IPTV) {
+ return;
+ }
auto record_configs = generateRecordConfigurations();
for (auto& configuration : record_configs) {
record = configuration;
@@ -1125,6 +1130,10 @@
if (!record.support) {
return;
}
+ // Recording is not currently supported for IPTV frontend
+ if (frontendMap[live.frontendId].type == FrontendType::IPTV) {
+ return;
+ }
auto record_configs = generateRecordConfigurations();
for (auto& configuration : record_configs) {
record = configuration;
@@ -1157,6 +1166,10 @@
if (!record.support) {
return;
}
+ // Recording is not currently supported for IPTV frontend
+ if (frontendMap[live.frontendId].type == FrontendType::IPTV) {
+ return;
+ }
auto record_configs = generateRecordConfigurations();
for (auto& configuration : record_configs) {
record = configuration;
@@ -1194,9 +1207,17 @@
if (!scan.hasFrontendConnection) {
return;
}
+ // Blind scan is not applicable for IPTV frontend
+ if (frontendMap[live.frontendId].type == FrontendType::IPTV) {
+ return;
+ }
vector<ScanHardwareConnections> scan_configs = generateScanConfigurations();
for (auto& configuration : scan_configs) {
scan = configuration;
+ // Skip test if the frontend implementation doesn't support blind scan
+ if (!frontendMap[scan.frontendId].supportBlindScan) {
+ continue;
+ }
mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND);
}
}
@@ -1218,9 +1239,17 @@
if (!scan.hasFrontendConnection) {
return;
}
+ // Blind scan is not application for IPTV frontend
+ if (frontendMap[live.frontendId].type == FrontendType::IPTV) {
+ return;
+ }
vector<ScanHardwareConnections> scan_configs = generateScanConfigurations();
for (auto& configuration : scan_configs) {
scan = configuration;
+ // Skip test if the frontend implementation doesn't support blind scan
+ if (!frontendMap[scan.frontendId].supportBlindScan) {
+ continue;
+ }
mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND);
}
}
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
index 516cb62..ff94639 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
@@ -612,6 +612,7 @@
frontendMap[defaultFeId].isSoftwareFe = true;
frontendMap[defaultFeId].canConnectToCiCam = true;
frontendMap[defaultFeId].ciCamId = 0;
+ frontendMap[defaultFeId].supportBlindScan = true;
FrontendDvbtSettings dvbt;
dvbt.transmissionMode = FrontendDvbtTransmissionMode::MODE_8K_E;
frontendMap[defaultFeId].settings.set<FrontendSettings::Tag::dvbt>(dvbt);
@@ -730,9 +731,20 @@
if (videoFilterIds.empty() || audioFilterIds.empty() || frontendMap.empty()) {
return;
}
- if (hasSwFe && !hasHwFe && dvrMap.empty()) {
- ALOGD("Cannot configure Live. Only software frontends and no dvr connections");
- return;
+ if (!hasHwFe) {
+ if (hasSwFe) {
+ if (dvrMap.empty()) {
+ ALOGD("Cannot configure Live. Only software frontends and no dvr connections.");
+ return;
+ }
+ // Live is available if there is SW FE and some DVR is attached.
+ } else {
+ // We will arrive here because frontendMap won't be empty since
+ // there will be at least a default frontend declared. But the
+ // default frontend doesn't count as "hasSwFe".
+ ALOGD("Cannot configure Live. No frontend declared at all.");
+ return;
+ }
}
ALOGD("Can support live");
live.hasFrontendConnection = true;
diff --git a/tv/tuner/aidl/vts/functional/utils/IpStreamer.cpp b/tv/tuner/aidl/vts/functional/utils/IpStreamer.cpp
new file mode 100644
index 0000000..02b2633
--- /dev/null
+++ b/tv/tuner/aidl/vts/functional/utils/IpStreamer.cpp
@@ -0,0 +1,57 @@
+#include "IpStreamer.h"
+
+IpStreamer::IpStreamer() {}
+
+IpStreamer::~IpStreamer() {}
+
+void IpStreamer::startIpStream() {
+ ALOGI("Starting IP Stream thread");
+ mFp = fopen(mFilePath.c_str(), "rb");
+ if (mFp == nullptr) {
+ ALOGE("Failed to open file at path: %s", mFilePath.c_str());
+ return;
+ }
+ mIpStreamerThread = std::thread(&IpStreamer::ipStreamThreadLoop, this, mFp);
+}
+
+void IpStreamer::stopIpStream() {
+ ALOGI("Stopping IP Stream thread");
+ close(mSockfd);
+ if (mFp != nullptr) fclose(mFp);
+ if (mIpStreamerThread.joinable()) {
+ mIpStreamerThread.join();
+ }
+}
+
+void IpStreamer::ipStreamThreadLoop(FILE* fp) {
+ mSockfd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (mSockfd < 0) {
+ ALOGE("IpStreamer::ipStreamThreadLoop: Socket creation failed (%s)", strerror(errno));
+ exit(1);
+ }
+
+ if (mFp == NULL) {
+ ALOGE("IpStreamer::ipStreamThreadLoop: Cannot open file %s: (%s)", mFilePath.c_str(),
+ strerror(errno));
+ exit(1);
+ }
+
+ struct sockaddr_in destaddr;
+ memset(&destaddr, 0, sizeof(destaddr));
+ destaddr.sin_family = mIsIpV4 ? AF_INET : AF_INET6;
+ destaddr.sin_port = htons(mPort);
+ destaddr.sin_addr.s_addr = inet_addr(mIpAddress.c_str());
+
+ char buf[mBufferSize];
+ int n;
+ while (1) {
+ if (fp == nullptr) break;
+ n = fread(buf, 1, mBufferSize, fp);
+ ALOGI("IpStreamer::ipStreamThreadLoop: Bytes read from fread(): %d\n", n);
+ if (n <= 0) {
+ break;
+ }
+ sendto(mSockfd, buf, n, 0, (struct sockaddr*)&destaddr, sizeof(destaddr));
+ sleep(mSleepTime);
+ }
+}
diff --git a/tv/tuner/aidl/vts/functional/utils/IpStreamer.h b/tv/tuner/aidl/vts/functional/utils/IpStreamer.h
new file mode 100644
index 0000000..8ac2ddb
--- /dev/null
+++ b/tv/tuner/aidl/vts/functional/utils/IpStreamer.h
@@ -0,0 +1,48 @@
+#pragma once
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <log/log.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <string>
+#include <thread>
+
+/**
+ * IP Streamer class to send TS data to a specified socket for testing IPTV frontend functions
+ * e.g. tuning and playback.
+ */
+
+class IpStreamer {
+ public:
+ // Constructor for IP Streamer object
+ IpStreamer();
+
+ // Destructor for IP Streamer object
+ ~IpStreamer();
+
+ // Starts a thread to read data from a socket
+ void startIpStream();
+
+ // Stops the reading thread started by startIpStream
+ void stopIpStream();
+
+ // Thread function that consumes data from a socket
+ void ipStreamThreadLoop(FILE* fp);
+
+ std::string getFilePath() { return mFilePath; };
+
+ private:
+ int mSockfd = -1;
+ FILE* mFp = nullptr;
+ bool mIsIpV4 = true; // By default, set to IPV4
+ int mPort = 12345; // default port
+ int mBufferSize = 188; // bytes
+ int mSleepTime = 1; // second
+ std::string mIpAddress = "127.0.0.1"; // default IP address
+ std::string mFilePath = "/data/local/tmp/segment000000.ts"; // default path for TS file
+ std::thread mIpStreamerThread;
+};
\ No newline at end of file
diff --git a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
index 9517520..5ffb38f 100644
--- a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
+++ b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
@@ -114,6 +114,7 @@
FrontendSettings settings;
vector<FrontendStatusType> tuneStatusTypes;
vector<FrontendStatus> expectTuneStatuses;
+ bool supportBlindScan;
};
struct FilterConfig {
@@ -354,6 +355,11 @@
} else {
hasHwFe = true;
}
+ if (feConfig.hasSupportBlindScan()) {
+ frontendMap[id].supportBlindScan = feConfig.getSupportBlindScan();
+ } else {
+ frontendMap[id].supportBlindScan = true;
+ }
// TODO: b/182519645 complete the tune status config
frontendMap[id].tuneStatusTypes = types;
frontendMap[id].expectTuneStatuses = statuses;
diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt
index dbd3486..ff2df90 100644
--- a/tv/tuner/config/api/current.txt
+++ b/tv/tuner/config/api/current.txt
@@ -369,6 +369,7 @@
method @Nullable public android.media.tuner.testing.configuration.V1_0.IsdbsFrontendSettings getIsdbsFrontendSettings_optional();
method @Nullable public android.media.tuner.testing.configuration.V1_0.IsdbtFrontendSettings getIsdbtFrontendSettings_optional();
method @Nullable public java.math.BigInteger getRemoveOutputPid();
+ method @Nullable public boolean getSupportBlindScan();
method @Nullable public android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum getType();
method public void setAtscFrontendSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.AtscFrontendSettings);
method public void setConnectToCicamId(@Nullable java.math.BigInteger);
@@ -381,6 +382,7 @@
method public void setIsdbsFrontendSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.IsdbsFrontendSettings);
method public void setIsdbtFrontendSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.IsdbtFrontendSettings);
method public void setRemoveOutputPid(@Nullable java.math.BigInteger);
+ method public void setSupportBlindScan(@Nullable boolean);
method public void setType(@Nullable android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum);
}
diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
index c51ac51..eafaca9 100644
--- a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
+++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
@@ -162,6 +162,7 @@
<xs:attribute name="connectToCicamId" type="xs:nonNegativeInteger" use="optional"/>
<xs:attribute name="removeOutputPid" type="xs:nonNegativeInteger" use="optional"/>
<xs:attribute name="endFrequency" type="xs:nonNegativeInteger" use="optional"/>
+ <xs:attribute name="supportBlindScan" type="xs:boolean" use="optional"/>
</xs:complexType>
<!-- FILTER SESSION -->
diff --git a/uwb/aidl/Android.bp b/uwb/aidl/Android.bp
index 3e71913..abd6a23 100755
--- a/uwb/aidl/Android.bp
+++ b/uwb/aidl/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_fwk_uwb",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
index 21951b6..58919d1 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
@@ -46,6 +46,7 @@
CCC_SUPPORTED_MAX_RANGING_SESSION_NUMBER = 0xA8,
CCC_SUPPORTED_MIN_UWB_INITIATION_TIME_MS = 0xA9,
CCC_PRIORITIZED_CHANNEL_LIST = 0xAA,
+ CCC_SUPPORTED_UWBS_MAX_PPM = 0xAB,
RADAR_SUPPORT = 0xB0,
SUPPORTED_AOA_RESULT_REQ_ANTENNA_INTERLEAVING = 0xE3,
SUPPORTED_MIN_RANGING_INTERVAL_MS = 0xE4,
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
index 2141b5a..4df45b6 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
@@ -154,6 +154,11 @@
*/
CCC_PRIORITIZED_CHANNEL_LIST = 0xAA,
+ /**
+ * Short (2-octet) value to indicate the UWBS Max Clock Skew PPM value.
+ */
+ CCC_SUPPORTED_UWBS_MAX_PPM = 0xAB,
+
/*********************************************
* RADAR specific
********************************************/
diff --git a/uwb/aidl/default/Android.bp b/uwb/aidl/default/Android.bp
index f9b79de..eba18cf 100644
--- a/uwb/aidl/default/Android.bp
+++ b/uwb/aidl/default/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_fwk_uwb",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -24,6 +25,8 @@
"libtokio_util",
"libnix",
"libanyhow",
+ "libpdl_runtime",
+ "libuwb_uci_packets",
],
proc_macros: [
"libasync_trait",
diff --git a/uwb/aidl/default/src/service.rs b/uwb/aidl/default/src/service.rs
index 7d5c073..e97b291 100644
--- a/uwb/aidl/default/src/service.rs
+++ b/uwb/aidl/default/src/service.rs
@@ -6,7 +6,7 @@
use std::env;
use std::panic;
-use log::Level;
+use log::LevelFilter;
mod uwb;
mod uwb_chip;
@@ -14,7 +14,7 @@
fn main() -> anyhow::Result<()> {
logger::init(
logger::Config::default()
- .with_min_level(Level::Debug)
+ .with_max_level(LevelFilter::Debug)
.with_tag_on_device("android.hardware.uwb"),
);
diff --git a/uwb/aidl/default/src/uwb_chip.rs b/uwb/aidl/default/src/uwb_chip.rs
index 2b8e481..d1c3c67 100644
--- a/uwb/aidl/default/src/uwb_chip.rs
+++ b/uwb/aidl/default/src/uwb_chip.rs
@@ -14,9 +14,11 @@
use std::fs::{File, OpenOptions};
use std::io::{self, Read, Write};
-use std::os::fd::AsRawFd;
use std::os::unix::fs::OpenOptionsExt;
+use pdl_runtime::Packet;
+use uwb_uci_packets::{DeviceResetCmdBuilder, ResetConfig, UciControlPacket, UciControlPacketHal};
+
enum State {
Closed,
Opened {
@@ -47,11 +49,37 @@
impl State {
/// Terminate the reader task.
async fn close(&mut self) -> Result<()> {
- if let State::Opened { ref mut token, ref callbacks, ref mut death_recipient, ref mut handle, .. } = *self {
+ if let State::Opened {
+ ref mut token,
+ ref callbacks,
+ ref mut death_recipient,
+ ref mut handle,
+ ref mut serial,
+ } = *self
+ {
log::info!("waiting for task cancellation");
callbacks.as_binder().unlink_to_death(death_recipient)?;
token.cancel();
handle.await.unwrap();
+ let packet: UciControlPacket = DeviceResetCmdBuilder {
+ reset_config: ResetConfig::UwbsReset,
+ }
+ .build()
+ .into();
+ // DeviceResetCmd need to be send to reset the device to stop all running
+ // activities on UWBS.
+ let packet_vec: Vec<UciControlPacketHal> = packet.into();
+ for hal_packet in packet_vec.into_iter() {
+ serial
+ .write(&hal_packet.to_vec())
+ .map(|written| written as i32)
+ .map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?;
+ }
+ consume_device_reset_rsp_and_ntf(
+ &mut serial
+ .try_clone()
+ .map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?,
+ );
log::info!("task successfully cancelled");
callbacks.onHalEvent(UwbEvent::CLOSE_CPLT, UwbStatus::OK)?;
*self = State::Closed;
@@ -60,14 +88,26 @@
}
}
-pub fn makeraw(file: File) -> io::Result<File> {
- let fd = file.as_raw_fd();
+fn consume_device_reset_rsp_and_ntf(reader: &mut File) {
+ // Poll the DeviceResetRsp and DeviceStatusNtf before hal is closed to prevent
+ // the host from getting response and notifications from a 'powered down' UWBS.
+ // Do nothing when these packets are received.
+ const DEVICE_RESET_RSP: [u8; 5] = [64, 0, 0, 1, 0];
+ const DEVICE_STATUS_NTF: [u8; 5] = [96, 1, 0, 1, 1];
+ let mut buffer = vec![0; DEVICE_RESET_RSP.len() + DEVICE_STATUS_NTF.len()];
+ read_exact(reader, &mut buffer).unwrap();
- // Configure the file descritpro as raw fd.
+ // Make sure received packets are the expected ones.
+ assert_eq!(&buffer[0..DEVICE_RESET_RSP.len()], &DEVICE_RESET_RSP);
+ assert_eq!(&buffer[DEVICE_RESET_RSP.len()..], &DEVICE_STATUS_NTF);
+}
+
+pub fn makeraw(file: File) -> io::Result<File> {
+ // Configure the file descriptor as raw fd.
use nix::sys::termios::*;
- let mut attrs = tcgetattr(fd)?;
+ let mut attrs = tcgetattr(&file)?;
cfmakeraw(&mut attrs);
- tcsetattr(fd, SetArg::TCSANOW, &attrs)?;
+ tcsetattr(&file, SetArg::TCSANOW, &attrs)?;
Ok(file)
}
@@ -212,7 +252,7 @@
let mut state = self.state.lock().await;
- if matches!(*state, State::Opened { .. }) {
+ if let State::Opened { .. } = *state {
state.close().await
} else {
Err(binder::ExceptionCode::ILLEGAL_STATE.into())
diff --git a/uwb/aidl/vts/Android.bp b/uwb/aidl/vts/Android.bp
index 4d9f653..1beaa6e 100644
--- a/uwb/aidl/vts/Android.bp
+++ b/uwb/aidl/vts/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_fwk_uwb",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/vibrator/aidl/Android.bp b/vibrator/aidl/Android.bp
index c5936e3..b5199e2 100644
--- a/vibrator/aidl/Android.bp
+++ b/vibrator/aidl/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_haptics_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/vibrator/aidl/default/Android.bp b/vibrator/aidl/default/Android.bp
index fb71a82..0f342db 100644
--- a/vibrator/aidl/default/Android.bp
+++ b/vibrator/aidl/default/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_haptics_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/vibrator/aidl/default/apex/Android.bp b/vibrator/aidl/default/apex/Android.bp
index 39626bf..b694e1f 100644
--- a/vibrator/aidl/default/apex/Android.bp
+++ b/vibrator/aidl/default/apex/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_haptics_framework",
default_applicable_licenses: ["hardware_interfaces_license"],
}
diff --git a/vibrator/aidl/default/example_java_client/Android.bp b/vibrator/aidl/default/example_java_client/Android.bp
index 17a649c..5f1e27a 100644
--- a/vibrator/aidl/default/example_java_client/Android.bp
+++ b/vibrator/aidl/default/example_java_client/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_haptics_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/vibrator/aidl/vts/Android.bp b/vibrator/aidl/vts/Android.bp
index 1261870..b6d2fb2 100644
--- a/vibrator/aidl/vts/Android.bp
+++ b/vibrator/aidl/vts/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_haptics_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index c88cb59..6c6846f 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -109,6 +109,11 @@
ASSERT_TRUE(vibrator->getCapabilities(&capabilities).isOk());
}
+ virtual void TearDown() override {
+ // Reset vibrator state between tests.
+ EXPECT_TRUE(vibrator->off().isOk());
+ }
+
sp<IVibrator> vibrator;
int32_t capabilities;
};
@@ -429,189 +434,202 @@
}
TEST_P(VibratorAidl, ComposeValidPrimitives) {
- if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
- std::vector<CompositePrimitive> supported;
- int32_t maxDelay, maxSize;
+ if (!(capabilities & IVibrator::CAP_COMPOSE_EFFECTS)) {
+ GTEST_SKIP() << "CAP_COMPOSE_EFFECTS not supported";
+ }
- ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
- EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
- EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
+ std::vector<CompositePrimitive> supported;
+ int32_t maxDelay, maxSize;
- std::vector<CompositeEffect> composite;
+ ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
+ EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
+ EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
- for (auto primitive : supported) {
- CompositeEffect effect;
+ std::vector<CompositeEffect> composite;
- effect.delayMs = std::rand() % (maxDelay + 1);
- effect.primitive = primitive;
- effect.scale = static_cast<float>(std::rand()) / static_cast<float>(RAND_MAX);
- composite.emplace_back(effect);
+ for (int i = 0; i < supported.size(); i++) {
+ auto primitive = supported[i];
+ float t = static_cast<float>(i + 1) / supported.size();
+ CompositeEffect effect;
- if (composite.size() == maxSize) {
- EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
- composite.clear();
- vibrator->off();
- }
+ effect.delayMs = maxDelay * t;
+ effect.primitive = primitive;
+ effect.scale = t;
+
+ if (composite.size() == maxSize) {
+ break;
}
+ }
- if (composite.size() != 0) {
- EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
- vibrator->off();
- }
+ if (composite.size() != 0) {
+ EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
+ EXPECT_TRUE(vibrator->off().isOk());
}
}
TEST_P(VibratorAidl, ComposeUnsupportedPrimitives) {
- if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
- auto unsupported = kInvalidPrimitives;
- std::vector<CompositePrimitive> supported;
+ if (!(capabilities & IVibrator::CAP_COMPOSE_EFFECTS)) {
+ GTEST_SKIP() << "CAP_COMPOSE_EFFECTS not supported";
+ }
- ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
+ auto unsupported = kInvalidPrimitives;
+ std::vector<CompositePrimitive> supported;
- for (auto primitive : kCompositePrimitives) {
- bool isPrimitiveSupported =
+ ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
+
+ for (auto primitive : kCompositePrimitives) {
+ bool isPrimitiveSupported =
std::find(supported.begin(), supported.end(), primitive) != supported.end();
- if (!isPrimitiveSupported) {
- unsupported.push_back(primitive);
- }
+ if (!isPrimitiveSupported) {
+ unsupported.push_back(primitive);
}
+ }
- for (auto primitive : unsupported) {
- std::vector<CompositeEffect> composite(1);
+ for (auto primitive : unsupported) {
+ std::vector<CompositeEffect> composite(1);
- for (auto &effect : composite) {
- effect.delayMs = 0;
- effect.primitive = primitive;
- effect.scale = 1.0f;
- }
- Status status = vibrator->compose(composite, nullptr);
- EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
- vibrator->off();
+ for (auto& effect : composite) {
+ effect.delayMs = 0;
+ effect.primitive = primitive;
+ effect.scale = 1.0f;
}
+ Status status = vibrator->compose(composite, nullptr);
+ EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
}
}
TEST_P(VibratorAidl, ComposeScaleBoundary) {
- if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
- std::vector<CompositeEffect> composite(1);
- CompositeEffect &effect = composite[0];
-
- effect.delayMs = 0;
- effect.primitive = CompositePrimitive::CLICK;
-
- effect.scale = std::nextafter(0.0f, -1.0f);
- EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
- vibrator->compose(composite, nullptr).exceptionCode());
-
- effect.scale = 0.0f;
- EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
-
- effect.scale = 1.0f;
- EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
-
- effect.scale = std::nextafter(1.0f, 2.0f);
- EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
- vibrator->compose(composite, nullptr).exceptionCode());
-
- vibrator->off();
+ if (!(capabilities & IVibrator::CAP_COMPOSE_EFFECTS)) {
+ GTEST_SKIP() << "CAP_COMPOSE_EFFECTS not supported";
}
+
+ std::vector<CompositeEffect> composite(1);
+ CompositeEffect& effect = composite[0];
+
+ effect.delayMs = 0;
+ effect.primitive = CompositePrimitive::CLICK;
+
+ effect.scale = std::nextafter(0.0f, -1.0f);
+ EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->compose(composite, nullptr).exceptionCode());
+
+ effect.scale = 0.0f;
+ EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
+ EXPECT_TRUE(vibrator->off().isOk());
+
+ effect.scale = 1.0f;
+ EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
+ EXPECT_TRUE(vibrator->off().isOk());
+
+ effect.scale = std::nextafter(1.0f, 2.0f);
+ EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->compose(composite, nullptr).exceptionCode());
}
TEST_P(VibratorAidl, ComposeDelayBoundary) {
- if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
- int32_t maxDelay;
-
- EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
-
- std::vector<CompositeEffect> composite(1);
- CompositeEffect effect;
-
- effect.delayMs = 1;
- effect.primitive = CompositePrimitive::CLICK;
- effect.scale = 1.0f;
-
- std::fill(composite.begin(), composite.end(), effect);
- EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
-
- effect.delayMs = maxDelay + 1;
-
- std::fill(composite.begin(), composite.end(), effect);
- EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
- vibrator->compose(composite, nullptr).exceptionCode());
- vibrator->off();
+ if (!(capabilities & IVibrator::CAP_COMPOSE_EFFECTS)) {
+ GTEST_SKIP() << "CAP_COMPOSE_EFFECTS not supported";
}
+
+ int32_t maxDelay;
+
+ EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
+
+ std::vector<CompositeEffect> composite(1);
+ CompositeEffect& effect = composite[0];
+
+ effect.primitive = CompositePrimitive::CLICK;
+ effect.scale = 1.0f;
+
+ effect.delayMs = 0;
+ EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
+ EXPECT_TRUE(vibrator->off().isOk());
+
+ effect.delayMs = 1;
+ EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
+ EXPECT_TRUE(vibrator->off().isOk());
+
+ effect.delayMs = maxDelay;
+ EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
+ EXPECT_TRUE(vibrator->off().isOk());
+
+ effect.delayMs = maxDelay + 1;
+ EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->compose(composite, nullptr).exceptionCode());
}
TEST_P(VibratorAidl, ComposeSizeBoundary) {
- if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
- int32_t maxSize;
-
- EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
-
- std::vector<CompositeEffect> composite(maxSize);
- CompositeEffect effect;
-
- effect.delayMs = 1;
- effect.primitive = CompositePrimitive::CLICK;
- effect.scale = 1.0f;
-
- std::fill(composite.begin(), composite.end(), effect);
- EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
-
- composite.emplace_back(effect);
- EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
- vibrator->compose(composite, nullptr).exceptionCode());
- vibrator->off();
+ if (!(capabilities & IVibrator::CAP_COMPOSE_EFFECTS)) {
+ GTEST_SKIP() << "CAP_COMPOSE_EFFECTS not supported";
}
+
+ int32_t maxSize;
+
+ EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
+
+ std::vector<CompositeEffect> composite(maxSize);
+ CompositeEffect effect;
+
+ effect.delayMs = 1;
+ effect.primitive = CompositePrimitive::CLICK;
+ effect.scale = 1.0f;
+
+ std::fill(composite.begin(), composite.end(), effect);
+ EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
+ EXPECT_TRUE(vibrator->off().isOk());
+
+ composite.emplace_back(effect);
+ EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->compose(composite, nullptr).exceptionCode());
}
TEST_P(VibratorAidl, ComposeCallback) {
- if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
- std::vector<CompositePrimitive> supported;
+ if (!(capabilities & IVibrator::CAP_COMPOSE_EFFECTS)) {
+ GTEST_SKIP() << "CAP_COMPOSE_EFFECTS not supported";
+ }
- ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
+ std::vector<CompositePrimitive> supported;
- for (auto primitive : supported) {
- if (primitive == CompositePrimitive::NOOP) {
- continue;
- }
+ ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
- std::promise<void> completionPromise;
- std::future<void> completionFuture{completionPromise.get_future()};
- sp<CompletionCallback> callback =
- new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
- CompositeEffect effect;
- std::vector<CompositeEffect> composite;
- int32_t durationMs;
- std::chrono::milliseconds duration;
- std::chrono::time_point<high_resolution_clock> start, end;
- std::chrono::milliseconds elapsed;
-
- effect.delayMs = 0;
- effect.primitive = primitive;
- effect.scale = 1.0f;
- composite.emplace_back(effect);
-
- EXPECT_EQ(Status::EX_NONE,
- vibrator->getPrimitiveDuration(primitive, &durationMs).exceptionCode())
- << toString(primitive);
- duration = std::chrono::milliseconds(durationMs);
-
- start = high_resolution_clock::now();
- EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, callback).exceptionCode())
- << toString(primitive);
-
- // TODO(b/261130361): Investigate why latency from driver and hardware will cause test
- // to fail when wait duration is ~40ms or less.
- EXPECT_EQ(completionFuture.wait_for(duration + std::chrono::milliseconds(50)),
- std::future_status::ready)
- << toString(primitive);
- end = high_resolution_clock::now();
-
- elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
- EXPECT_GE(elapsed.count(), duration.count()) << toString(primitive);
+ for (auto primitive : supported) {
+ if (primitive == CompositePrimitive::NOOP) {
+ continue;
}
+
+ std::promise<void> completionPromise;
+ std::future<void> completionFuture{completionPromise.get_future()};
+ sp<CompletionCallback> callback =
+ new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
+ CompositeEffect effect;
+ std::vector<CompositeEffect> composite;
+ int32_t durationMs;
+ std::chrono::milliseconds duration;
+ std::chrono::time_point<high_resolution_clock> start, end;
+ std::chrono::milliseconds elapsed;
+
+ effect.delayMs = 0;
+ effect.primitive = primitive;
+ effect.scale = 1.0f;
+ composite.emplace_back(effect);
+
+ EXPECT_EQ(Status::EX_NONE,
+ vibrator->getPrimitiveDuration(primitive, &durationMs).exceptionCode())
+ << toString(primitive);
+ duration = std::chrono::milliseconds(durationMs);
+
+ start = high_resolution_clock::now();
+ EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, callback).exceptionCode())
+ << toString(primitive);
+
+ // TODO(b/261130361): Investigate why latency from driver and hardware will cause test
+ // to fail when wait duration is ~40ms or less.
+ EXPECT_EQ(completionFuture.wait_for(duration + std::chrono::milliseconds(50)),
+ std::future_status::ready)
+ << toString(primitive);
+ end = high_resolution_clock::now();
+
+ elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
+ EXPECT_GE(elapsed.count(), duration.count()) << toString(primitive);
+
+ EXPECT_TRUE(vibrator->off().isOk());
}
}
diff --git a/vibrator/bench/Android.bp b/vibrator/bench/Android.bp
index 73e274f..87bdab4 100644
--- a/vibrator/bench/Android.bp
+++ b/vibrator/bench/Android.bp
@@ -14,6 +14,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_haptics_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/vibrator/bench/benchmark.cpp b/vibrator/bench/benchmark.cpp
index e19dc6f..b96e06d 100644
--- a/vibrator/bench/benchmark.cpp
+++ b/vibrator/bench/benchmark.cpp
@@ -118,6 +118,7 @@
});
if (!supported) {
+ state->SkipWithMessage("performApi returned UNSUPPORTED_OPERATION");
return;
}
@@ -140,16 +141,17 @@
}
};
-#define BENCHMARK_WRAPPER(fixt, test, code) \
- BENCHMARK_DEFINE_F(fixt, test) \
- /* NOLINTNEXTLINE */ \
- (State & state) { \
- if (!mVibrator) { \
- return; \
- } \
- \
- code \
- } \
+#define BENCHMARK_WRAPPER(fixt, test, code) \
+ BENCHMARK_DEFINE_F(fixt, test) \
+ /* NOLINTNEXTLINE */ \
+ (State & state) { \
+ if (!mVibrator) { \
+ state.SkipWithMessage("HAL unavailable"); \
+ return; \
+ } \
+ \
+ code \
+ } \
BENCHMARK_REGISTER_F(fixt, test)->Apply(fixt::DefaultConfig)->Apply(fixt::DefaultArgs)
using VibratorBench_V1_0 = VibratorBench<V1_0::IVibrator>;
@@ -186,6 +188,7 @@
uint8_t amplitude = UINT8_MAX;
if (!mVibrator->supportsAmplitudeControl()) {
+ state.SkipWithMessage("Amplitude control unavailable");
return;
}
@@ -227,6 +230,7 @@
bool enable = true;
if (!mVibrator->supportsExternalControl()) {
+ state.SkipWithMessage("external control unavailable");
return;
}
@@ -240,6 +244,7 @@
BENCHMARK_WRAPPER(VibratorBench_V1_3, supportsExternalAmplitudeControl, {
if (!mVibrator->supportsExternalControl()) {
+ state.SkipWithMessage("external control unavailable");
return;
}
@@ -256,12 +261,14 @@
uint8_t amplitude = UINT8_MAX;
if (!mVibrator->supportsExternalControl()) {
+ state.SkipWithMessage("external control unavailable");
return;
}
mVibrator->setExternalControl(true);
if (!mVibrator->supportsAmplitudeControl()) {
+ state.SkipWithMessage("amplitude control unavailable");
return;
}
@@ -328,6 +335,7 @@
int32_t capabilities = 0;
mVibrator->getCapabilities(&capabilities);
if ((capabilities & Aidl::IVibrator::CAP_AMPLITUDE_CONTROL) == 0) {
+ state.SkipWithMessage("amplitude control unavailable");
return;
}
@@ -345,6 +353,7 @@
int32_t capabilities = 0;
mVibrator->getCapabilities(&capabilities);
if ((capabilities & Aidl::IVibrator::CAP_EXTERNAL_CONTROL) == 0) {
+ state.SkipWithMessage("external control unavailable");
return;
}
@@ -361,6 +370,7 @@
mVibrator->getCapabilities(&capabilities);
if ((capabilities & Aidl::IVibrator::CAP_EXTERNAL_CONTROL) == 0 ||
(capabilities & Aidl::IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL) == 0) {
+ state.SkipWithMessage("external amplitude control unavailable");
return;
}
@@ -423,6 +433,7 @@
int32_t capabilities = 0;
mVibrator->getCapabilities(&capabilities);
if ((capabilities & Aidl::IVibrator::CAP_ALWAYS_ON_CONTROL) == 0) {
+ state.SkipWithMessage("always on control unavailable");
return;
}
@@ -433,6 +444,7 @@
std::vector<Aidl::Effect> supported;
mVibrator->getSupportedAlwaysOnEffects(&supported);
if (std::find(supported.begin(), supported.end(), effect) == supported.end()) {
+ state.SkipWithMessage("always on effects unavailable");
return;
}
@@ -448,6 +460,7 @@
int32_t capabilities = 0;
mVibrator->getCapabilities(&capabilities);
if ((capabilities & Aidl::IVibrator::CAP_ALWAYS_ON_CONTROL) == 0) {
+ state.SkipWithMessage("always on control unavailable");
return;
}
@@ -458,6 +471,7 @@
std::vector<Aidl::Effect> supported;
mVibrator->getSupportedAlwaysOnEffects(&supported);
if (std::find(supported.begin(), supported.end(), effect) == supported.end()) {
+ state.SkipWithMessage("always on effects unavailable");
return;
}
@@ -481,6 +495,7 @@
std::vector<Aidl::Effect> supported;
mVibrator->getSupportedEffects(&supported);
if (std::find(supported.begin(), supported.end(), effect) == supported.end()) {
+ state.SkipWithMessage("effects unavailable");
return;
}
@@ -527,6 +542,7 @@
int32_t capabilities = 0;
mVibrator->getCapabilities(&capabilities);
if ((capabilities & Aidl::IVibrator::CAP_COMPOSE_EFFECTS) == 0) {
+ state.SkipWithMessage("compose effects unavailable");
return;
}
@@ -536,6 +552,7 @@
std::vector<Aidl::CompositePrimitive> supported;
mVibrator->getSupportedPrimitives(&supported);
if (std::find(supported.begin(), supported.end(), primitive) == supported.end()) {
+ state.SkipWithMessage("supported primitives unavailable");
return;
}
@@ -548,6 +565,7 @@
int32_t capabilities = 0;
mVibrator->getCapabilities(&capabilities);
if ((capabilities & Aidl::IVibrator::CAP_COMPOSE_EFFECTS) == 0) {
+ state.SkipWithMessage("compose effects unavailable");
return;
}
@@ -559,6 +577,7 @@
std::vector<Aidl::CompositePrimitive> supported;
mVibrator->getSupportedPrimitives(&supported);
if (std::find(supported.begin(), supported.end(), effect.primitive) == supported.end()) {
+ state.SkipWithMessage("supported primitives unavailable");
return;
}
diff --git a/weaver/aidl/Android.bp b/weaver/aidl/Android.bp
index 38d017f..c494d29 100644
--- a/weaver/aidl/Android.bp
+++ b/weaver/aidl/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_android_hardware_backed_security",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/weaver/aidl/default/Android.bp b/weaver/aidl/default/Android.bp
index 494cb1b..2a62b99 100644
--- a/weaver/aidl/default/Android.bp
+++ b/weaver/aidl/default/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_hardware_backed_security",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/weaver/vts/Android.bp b/weaver/vts/Android.bp
index ee03b28..4139a28 100644
--- a/weaver/vts/Android.bp
+++ b/weaver/vts/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_android_hardware_backed_security",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/weaver/vts/VtsHalWeaverTargetTest.cpp b/weaver/vts/VtsHalWeaverTargetTest.cpp
index 754d467..40e9558 100644
--- a/weaver/vts/VtsHalWeaverTargetTest.cpp
+++ b/weaver/vts/VtsHalWeaverTargetTest.cpp
@@ -222,9 +222,8 @@
}
// Starting in Android 14, the system will always use at least one Weaver slot if Weaver is
// supported at all. Make sure we saw at least one.
- // TODO: uncomment after Android 14 is merged into AOSP
- // ASSERT_FALSE(used_slots.empty())
- //<< "Could not determine which Weaver slots are in use by the system";
+ ASSERT_FALSE(used_slots.empty())
+ << "Could not determine which Weaver slots are in use by the system";
// Find the first free slot.
int found = 0;
diff --git a/wifi/1.0/Android.bp b/wifi/1.0/Android.bp
index 94f8462..21a5d15 100644
--- a/wifi/1.0/Android.bp
+++ b/wifi/1.0/Android.bp
@@ -33,4 +33,8 @@
],
gen_java: true,
gen_java_constants: true,
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.wifi",
+ ],
}
diff --git a/wifi/1.1/Android.bp b/wifi/1.1/Android.bp
index 7b4116a..b5e4105 100644
--- a/wifi/1.1/Android.bp
+++ b/wifi/1.1/Android.bp
@@ -21,4 +21,8 @@
"android.hidl.base@1.0",
],
gen_java: true,
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.wifi",
+ ],
}
diff --git a/wifi/1.2/Android.bp b/wifi/1.2/Android.bp
index f0edb81..83b156e 100644
--- a/wifi/1.2/Android.bp
+++ b/wifi/1.2/Android.bp
@@ -27,4 +27,8 @@
"android.hidl.base@1.0",
],
gen_java: true,
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.wifi",
+ ],
}
diff --git a/wifi/1.3/Android.bp b/wifi/1.3/Android.bp
index 030d7f6..2ba612e 100644
--- a/wifi/1.3/Android.bp
+++ b/wifi/1.3/Android.bp
@@ -25,4 +25,8 @@
"android.hidl.base@1.0",
],
gen_java: true,
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.wifi",
+ ],
}
diff --git a/wifi/1.4/Android.bp b/wifi/1.4/Android.bp
index 1523f79..48578f8 100644
--- a/wifi/1.4/Android.bp
+++ b/wifi/1.4/Android.bp
@@ -30,4 +30,8 @@
"android.hidl.base@1.0",
],
gen_java: true,
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.wifi",
+ ],
}
diff --git a/wifi/aidl/Android.bp b/wifi/aidl/Android.bp
index ac95f85..8b01d95 100644
--- a/wifi/aidl/Android.bp
+++ b/wifi/aidl/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -48,6 +49,9 @@
cpp: {
enabled: false,
},
+ rust: {
+ enabled: false,
+ },
},
versions_with_info: [
{
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/CachedScanData.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/CachedScanData.aidl
new file mode 100644
index 0000000..cd4a456
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/CachedScanData.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.wifi;
+@VintfStability
+parcelable CachedScanData {
+ int[] scannedFrequenciesMhz;
+ android.hardware.wifi.CachedScanResult[] cachedScanResults;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/CachedScanResult.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/CachedScanResult.aidl
new file mode 100644
index 0000000..1806b0f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/CachedScanResult.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.wifi;
+@VintfStability
+parcelable CachedScanResult {
+ long timeStampInUs;
+ byte[] ssid;
+ byte[6] bssid;
+ int rssiDbm;
+ int frequencyMhz;
+ android.hardware.wifi.WifiChannelWidthInMhz channelWidthMhz;
+ android.hardware.wifi.WifiRatePreamble preambleType;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl
index 2d7fe03..5ed7517 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl
@@ -84,6 +84,7 @@
void enableStaChannelForPeerNetwork(in int channelCategoryEnableFlag);
void setMloMode(in android.hardware.wifi.IWifiChip.ChipMloMode mode);
@PropagateAllowBlocking android.hardware.wifi.IWifiApIface createApOrBridgedApIface(in android.hardware.wifi.IfaceConcurrencyType iface, in android.hardware.wifi.common.OuiKeyedData[] vendorData);
+ void setVoipMode(in android.hardware.wifi.IWifiChip.VoipMode mode);
const int NO_POWER_CAP_CONSTANT = 0x7FFFFFFF;
@Backing(type="int") @VintfStability
enum FeatureSetMask {
@@ -96,6 +97,7 @@
WIGIG = (1 << 6) /* 64 */,
SET_AFC_CHANNEL_ALLOWANCE = (1 << 7) /* 128 */,
T2LM_NEGOTIATION = (1 << 8) /* 256 */,
+ SET_VOIP_MODE = (1 << 9) /* 512 */,
}
@VintfStability
parcelable ChipConcurrencyCombinationLimit {
@@ -162,6 +164,11 @@
NAN_INSTANT_MODE = (1 << 2) /* 4 */,
}
@Backing(type="int") @VintfStability
+ enum VoipMode {
+ OFF = 0,
+ VOICE = 1,
+ }
+ @Backing(type="int") @VintfStability
enum ChannelCategoryMask {
INDOOR_CHANNEL = (1 << 0) /* 1 */,
DFS_CHANNEL = (1 << 1) /* 2 */,
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIface.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIface.aidl
index 923deff..ccb7876 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIface.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIface.aidl
@@ -61,6 +61,14 @@
void stopRssiMonitoring(in int cmdId);
void stopSendingKeepAlivePackets(in int cmdId);
void setDtimMultiplier(in int multiplier);
+ android.hardware.wifi.CachedScanData getCachedScanData();
+ android.hardware.wifi.TwtCapabilities twtGetCapabilities();
+ void twtSessionSetup(in int cmdId, in android.hardware.wifi.TwtRequest twtRequest);
+ void twtSessionUpdate(in int cmdId, in int sessionId, in android.hardware.wifi.TwtRequest twtRequest);
+ void twtSessionSuspend(in int cmdId, in int sessionId);
+ void twtSessionResume(in int cmdId, in int sessionId);
+ void twtSessionTeardown(in int cmdId, in int sessionId);
+ void twtSessionGetStats(in int cmdId, in int sessionId);
@Backing(type="int") @VintfStability
enum FeatureSetMask {
APF = (1 << 0) /* 1 */,
@@ -77,5 +85,7 @@
TDLS_OFFCHANNEL = (1 << 11) /* 2048 */,
ND_OFFLOAD = (1 << 12) /* 4096 */,
KEEP_ALIVE = (1 << 13) /* 8192 */,
+ ROAMING_MODE_CONTROL = (1 << 14) /* 16384 */,
+ CACHED_SCAN_DATA = (1 << 15) /* 32768 */,
}
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl
index 48b85b0..629ca3d 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl
@@ -38,4 +38,31 @@
oneway void onBackgroundScanFailure(in int cmdId);
oneway void onBackgroundScanResults(in int cmdId, in android.hardware.wifi.StaScanData[] scanDatas);
oneway void onRssiThresholdBreached(in int cmdId, in byte[6] currBssid, in int currRssi);
+ oneway void onTwtFailure(in int cmdId, in android.hardware.wifi.IWifiStaIfaceEventCallback.TwtErrorCode error);
+ oneway void onTwtSessionCreate(in int cmdId, in android.hardware.wifi.TwtSession twtSession);
+ oneway void onTwtSessionUpdate(in int cmdId, in android.hardware.wifi.TwtSession twtSession);
+ oneway void onTwtSessionTeardown(in int cmdId, in int twtSessionId, in android.hardware.wifi.IWifiStaIfaceEventCallback.TwtTeardownReasonCode reasonCode);
+ oneway void onTwtSessionStats(in int cmdId, in int twtSessionId, in android.hardware.wifi.TwtSessionStats twtSessionStats);
+ oneway void onTwtSessionSuspend(in int cmdId, in int twtSessionId);
+ oneway void onTwtSessionResume(in int cmdId, in int twtSessionId);
+ @Backing(type="byte") @VintfStability
+ enum TwtErrorCode {
+ FAILURE_UNKNOWN,
+ ALREADY_RESUMED,
+ ALREADY_SUSPENDED,
+ INVALID_PARAMS,
+ MAX_SESSION_REACHED,
+ NOT_AVAILABLE,
+ NOT_SUPPORTED,
+ PEER_NOT_SUPPORTED,
+ PEER_REJECTED,
+ TIMEOUT,
+ }
+ @Backing(type="byte") @VintfStability
+ enum TwtTeardownReasonCode {
+ UNKNOWN,
+ LOCALLY_REQUESTED,
+ INTERNALLY_INITIATED,
+ PEER_INITIATED,
+ }
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingRequest.aidl
index dd0a5ed..b5f78b0 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingRequest.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingRequest.aidl
@@ -38,4 +38,6 @@
byte[6] peerDiscMacAddr;
android.hardware.wifi.NanBootstrappingMethod requestBootstrappingMethod;
byte[] cookie;
+ boolean isComeback;
+ byte discoverySessionId;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingResponse.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingResponse.aidl
index 6dd9b26..7b17493 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingResponse.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingResponse.aidl
@@ -36,4 +36,5 @@
parcelable NanBootstrappingResponse {
int bootstrappingInstanceId;
boolean acceptRequest;
+ byte discoverySessionId;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequest.aidl
index 5ead651..a3693d6 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequest.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequest.aidl
@@ -45,4 +45,5 @@
char rssiWindowSize;
int macAddressRandomizationIntervalSec;
android.hardware.wifi.NanBandSpecificConfig[3] bandSpecificConfig;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityConfig.aidl
index 635dbce..48e9501 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityConfig.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityConfig.aidl
@@ -39,4 +39,10 @@
byte[32] pmk;
byte[] passphrase;
byte[16] scid;
+ boolean enable16ReplyCountersForTksa;
+ boolean enable16ReplyCountersForGtksa;
+ boolean supportGtkAndIgtk;
+ boolean supportBigtksa;
+ boolean enableNcsBip256;
+ boolean requiresEnhancedFrameProtection;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchInd.aidl
index 317489f..4acc773 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchInd.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchInd.aidl
@@ -51,4 +51,5 @@
byte[] scid;
android.hardware.wifi.NanPairingConfig peerPairingConfig;
android.hardware.wifi.NanIdentityResolutionAttribute peerNira;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingConfirmInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingConfirmInd.aidl
index 8ecf22a..699ecdc 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingConfirmInd.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingConfirmInd.aidl
@@ -40,4 +40,5 @@
android.hardware.wifi.NanPairingRequestType requestType;
boolean enablePairingCache;
android.hardware.wifi.NpkSecurityAssociation npksa;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequest.aidl
index 2a644ae..121b038 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequest.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequest.aidl
@@ -40,4 +40,5 @@
boolean enablePairingCache;
byte[16] pairingIdentityKey;
android.hardware.wifi.NanPairingSecurityConfig securityConfig;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequestInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequestInd.aidl
index 66762b9..57072c0 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequestInd.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequestInd.aidl
@@ -41,4 +41,5 @@
android.hardware.wifi.NanPairingRequestType requestType;
boolean enablePairingCache;
android.hardware.wifi.NanIdentityResolutionAttribute peerNira;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishRequest.aidl
index c49f5f9..bdc8357 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishRequest.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishRequest.aidl
@@ -40,4 +40,5 @@
boolean autoAcceptDataPathRequests;
android.hardware.wifi.NanPairingConfig pairingConfig;
byte[16] identityKey;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl
index a58890c..da81c39 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl
@@ -40,4 +40,5 @@
boolean enablePairingCache;
byte[16] pairingIdentityKey;
android.hardware.wifi.NanPairingSecurityConfig securityConfig;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeRequest.aidl
index 96be096..bf525a9 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeRequest.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeRequest.aidl
@@ -43,4 +43,5 @@
android.hardware.wifi.MacAddress[] intfAddr;
android.hardware.wifi.NanPairingConfig pairingConfig;
byte[16] identityKey;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttCapabilities.aidl
index cf64687..6c64084 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttCapabilities.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttCapabilities.aidl
@@ -42,4 +42,9 @@
android.hardware.wifi.RttPreamble preambleSupport;
android.hardware.wifi.RttBw bwSupport;
byte mcVersion;
+ int azPreambleSupport;
+ int azBwSupport;
+ boolean ntbInitiatorSupported;
+ boolean ntbResponderSupported;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttConfig.aidl
index ccdf2ce..3613616 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttConfig.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttConfig.aidl
@@ -48,4 +48,7 @@
int burstDuration;
android.hardware.wifi.RttPreamble preamble;
android.hardware.wifi.RttBw bw;
+ long ntbMinMeasurementTime;
+ long ntbMaxMeasurementTime;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttPreamble.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttPreamble.aidl
index de26f28..2802464 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttPreamble.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttPreamble.aidl
@@ -34,6 +34,7 @@
package android.hardware.wifi;
@Backing(type="int") @VintfStability
enum RttPreamble {
+ INVALID = 0,
LEGACY = 0x1,
HT = 0x2,
VHT = 0x4,
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResult.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResult.aidl
index 8375dcb..13202ba 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResult.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResult.aidl
@@ -59,4 +59,11 @@
android.hardware.wifi.WifiInformationElement lcr;
int channelFreqMHz;
android.hardware.wifi.RttBw packetBw;
+ byte i2rTxLtfRepetitionCount;
+ byte r2iTxLtfRepetitionCount;
+ long ntbMinMeasurementTime;
+ long ntbMaxMeasurementTime;
+ byte numTxSpatialStreams;
+ byte numRxSpatialStreams;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttType.aidl
index 2b6087a..cb25673 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttType.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttType.aidl
@@ -36,4 +36,6 @@
enum RttType {
ONE_SIDED = 1,
TWO_SIDED = 2,
+ TWO_SIDED_11MC = TWO_SIDED /* 2 */,
+ TWO_SIDED_11AZ_NTB = 3,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingState.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingState.aidl
index 1f3d91f..fd7d567 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingState.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingState.aidl
@@ -36,4 +36,5 @@
enum StaRoamingState {
DISABLED = 0,
ENABLED = 1,
+ AGGRESSIVE = 2,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtCapabilities.aidl
new file mode 100644
index 0000000..75f3e83
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtCapabilities.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.wifi;
+@VintfStability
+parcelable TwtCapabilities {
+ boolean isTwtRequesterSupported;
+ boolean isTwtResponderSupported;
+ boolean isBroadcastTwtSupported;
+ boolean isFlexibleTwtScheduleSupported;
+ int minWakeDurationUs;
+ int maxWakeDurationUs;
+ long minWakeIntervalUs;
+ long maxWakeIntervalUs;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtRequest.aidl
new file mode 100644
index 0000000..1e1c39a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtRequest.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.wifi;
+@VintfStability
+parcelable TwtRequest {
+ int mloLinkId;
+ int minWakeDurationUs;
+ int maxWakeDurationUs;
+ long minWakeIntervalUs;
+ long maxWakeIntervalUs;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSession.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSession.aidl
new file mode 100644
index 0000000..0b88d8e
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSession.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.wifi;
+@VintfStability
+parcelable TwtSession {
+ int sessionId;
+ int mloLinkId;
+ int wakeDurationUs;
+ long wakeIntervalUs;
+ android.hardware.wifi.TwtSession.TwtNegotiationType negotiationType;
+ boolean isTriggerEnabled;
+ boolean isAnnounced;
+ boolean isImplicit;
+ boolean isProtected;
+ boolean isUpdatable;
+ boolean isSuspendable;
+ boolean isResponderPmModeEnabled;
+ @Backing(type="byte") @VintfStability
+ enum TwtNegotiationType {
+ INDIVIDUAL = 0,
+ BROADCAST = 1,
+ }
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSessionStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSessionStats.aidl
new file mode 100644
index 0000000..f62b614
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSessionStats.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.wifi;
+@VintfStability
+parcelable TwtSessionStats {
+ int avgTxPktCount;
+ int avgRxPktCount;
+ int avgTxPktSize;
+ int avgRxPktSize;
+ int avgEospDurationUs;
+ int eospCount;
+}
diff --git a/wifi/aidl/android/hardware/wifi/CachedScanData.aidl b/wifi/aidl/android/hardware/wifi/CachedScanData.aidl
new file mode 100644
index 0000000..feda079
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/CachedScanData.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.CachedScanResult;
+
+/**
+ * Scan data cached in Wifi firmware
+ */
+@VintfStability
+parcelable CachedScanData {
+ /**
+ * List of scanned frequencies in MHz.
+ */
+ int[] scannedFrequenciesMhz;
+
+ /**
+ * List of scan results.
+ */
+ CachedScanResult[] cachedScanResults;
+}
diff --git a/wifi/aidl/android/hardware/wifi/CachedScanResult.aidl b/wifi/aidl/android/hardware/wifi/CachedScanResult.aidl
new file mode 100644
index 0000000..9c9dbc7
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/CachedScanResult.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.WifiChannelWidthInMhz;
+import android.hardware.wifi.WifiRatePreamble;
+
+/**
+ * Scan result cached in Wifi firmware
+ */
+@VintfStability
+parcelable CachedScanResult {
+ /**
+ * Time in micro seconds since boot when the scan was done
+ */
+ long timeStampInUs;
+ /**
+ * SSID of beacon excluding null.
+ */
+ byte[] ssid;
+ /**
+ * BSSID of beacon
+ */
+ byte[6] bssid;
+ /**
+ * Beacon received signal stength indicatior (RSSI), in dbm
+ */
+ int rssiDbm;
+ /**
+ * Frequency of beacon, in MHz
+ */
+ int frequencyMhz;
+ /**
+ * Channel bandwidth of found network
+ */
+ WifiChannelWidthInMhz channelWidthMhz;
+ /**
+ * Supported rate and preamble type
+ */
+ WifiRatePreamble preambleType;
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiChip.aidl b/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
index 733ff62..d12d26c 100644
--- a/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
+++ b/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
@@ -83,6 +83,10 @@
* Chip supports Tid-To-Link mapping negotiation.
*/
T2LM_NEGOTIATION = 1 << 8,
+ /**
+ * Chip supports voip mode setting.
+ */
+ SET_VOIP_MODE = 1 << 9,
}
/**
@@ -385,6 +389,16 @@
}
/**
+ * This enum represents the different VoIP mode that can be set through |setVoipMode|.
+ */
+ @VintfStability
+ @Backing(type="int")
+ enum VoipMode {
+ OFF = 0,
+ VOICE = 1,
+ }
+
+ /**
* Configure the Chip.
* This may NOT be called to reconfigure a chip due to an internal
* limitation. Calling this when chip is already configured in a different
@@ -1173,4 +1187,23 @@
@PropagateAllowBlocking
IWifiApIface createApOrBridgedApIface(
in IfaceConcurrencyType iface, in OuiKeyedData[] vendorData);
+
+ /**
+ * API to set the wifi VoIP mode.
+ *
+ * The VoIP mode is a hint to the HAL to enable or disable Wi-Fi VoIP
+ * optimization. The optimization should be enabled if the mode is NOT set to |OFF|.
+ * Furthermore, HAL should implement relevant optimization techniques based on the
+ * current operational mode.
+ *
+ * Note: Wi-Fi VoIP optimization may trade-off power against Wi-Fi
+ * performance but it provides better voice quility.
+ *
+ * @param mode Voip mode as defined by the enum |VoipMode|
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+ * |WifiStatusCode.ERROR_INVALID_ARGS|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ void setVoipMode(in VoipMode mode);
}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl b/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl
index 6d6afaf..6c5451b 100644
--- a/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl
+++ b/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl
@@ -16,6 +16,7 @@
package android.hardware.wifi;
+import android.hardware.wifi.CachedScanData;
import android.hardware.wifi.IWifiStaIfaceEventCallback;
import android.hardware.wifi.StaApfPacketFilterCapabilities;
import android.hardware.wifi.StaBackgroundScanCapabilities;
@@ -24,6 +25,8 @@
import android.hardware.wifi.StaRoamingCapabilities;
import android.hardware.wifi.StaRoamingConfig;
import android.hardware.wifi.StaRoamingState;
+import android.hardware.wifi.TwtCapabilities;
+import android.hardware.wifi.TwtRequest;
import android.hardware.wifi.WifiBand;
import android.hardware.wifi.WifiDebugRxPacketFateReport;
import android.hardware.wifi.WifiDebugTxPacketFateReport;
@@ -99,6 +102,14 @@
* Support for keep alive packet offload.
*/
KEEP_ALIVE = 1 << 13,
+ /**
+ * Support for configuring roaming mode.
+ */
+ ROAMING_MODE_CONTROL = 1 << 14,
+ /**
+ * Support for cached scan data report.
+ */
+ CACHED_SCAN_DATA = 1 << 15,
}
/**
@@ -552,4 +563,125 @@
* |WifiStatusCode.ERROR_UNKNOWN|
*/
void setDtimMultiplier(in int multiplier);
+
+ /**
+ * Get the cached scan data.
+ *
+ * @return Instance of |CachedScanData|.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ CachedScanData getCachedScanData();
+
+ /**
+ * Get Target Wake Time (TWT) local device capabilities for the station interface.
+ *
+ * @return Instance of |TwtCapabilities|.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ TwtCapabilities twtGetCapabilities();
+
+ /**
+ * Setup a Target Wake Time (TWT) session.
+ *
+ * Supported only if |TwtCapabilities.isTwtRequesterSupported| is set. Results in asynchronous
+ * callback |IWifiStaIfaceEventCallback.onTwtSessionCreate| on success or
+ * |IWifiStaIfaceEventCallback.onTwtFailure| on failure.
+ *
+ * @param cmdId Command Id to use for this invocation. The value 0 is reserved.
+ * @param twtRequest TWT Request parameters.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ void twtSessionSetup(in int cmdId, in TwtRequest twtRequest);
+
+ /**
+ * Update a Target Wake Time (TWT) session.
+ *
+ * Supported only if the TWT session can be updated. See |TwtSession.isUpdatable|. Results in
+ * asynchronous callback |IWifiStaIfaceEventCallback.onTwtSessionUpdate| on success or
+ * |IWifiStaIfaceEventCallback.onTwtFailure| on failure.
+ *
+ * @param cmdId Command Id to use for this invocation. The value 0 is reserved.
+ * @param sessionId TWT session id.
+ * @param twtRequest TWT Request parameters.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ void twtSessionUpdate(in int cmdId, in int sessionId, in TwtRequest twtRequest);
+
+ /**
+ * Suspend a Target Wake Time (TWT) session until a resume is called.
+ *
+ * Supported only if the TWT session supports suspend and resume. See
+ * |TwtSession.isSuspendable|. Results in asynchronous callback
+ * |IWifiStaIfaceEventCallback.onTwtSessionSuspend| on success or
+ * |IWifiStaIfaceEventCallback.onTwtFailure| on failure.
+ *
+ * @param cmdId Command Id to use for this invocation. The value 0 is reserved.
+ * @param sessionId TWT session id.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ void twtSessionSuspend(in int cmdId, in int sessionId);
+
+ /**
+ * Resume a Target Wake Time (TWT) session which is suspended.
+ *
+ * Supported only if the TWT session supports suspend and resume. See
+ * |TwtSession.isSuspendable|. Results in asynchronous callback
+ * |IWifiStaIfaceEventCallback.onTwtSessionResume| on success or
+ * |IWifiStaIfaceEventCallback.onTwtFailure| on failure.
+ *
+ * @param cmdId Command Id to use for this invocation. The value 0 is reserved.
+ * @param sessionId TWT session id.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ void twtSessionResume(in int cmdId, in int sessionId);
+
+ /**
+ * Teardown a Target Wake Time (TWT) session.
+ *
+ * Results in asynchronous callback |IWifiStaIfaceEventCallback.onTwtSessionTeardown| on
+ * success or |IWifiStaIfaceEventCallback.onTwtFailure| on failure.
+ *
+ * @param cmdId Command Id to use for this invocation. The value 0 is reserved.
+ * @param sessionId TWT session id.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ void twtSessionTeardown(in int cmdId, in int sessionId);
+
+ /**
+ * Get stats for a Target Wake Time (TWT) session.
+ *
+ * Results in asynchronous callback |IWifiStaIfaceEventCallback.onTwtSessionStats| on success
+ * or |IWifiStaIfaceEventCallback.onTwtFailure| on failure.
+ *
+ * @param cmdId Command Id to use for this invocation. The value 0 is reserved.
+ * @param sessionId TWT session id.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ void twtSessionGetStats(in int cmdId, in int sessionId);
}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl b/wifi/aidl/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl
index 93a255f..dda7c77 100644
--- a/wifi/aidl/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl
+++ b/wifi/aidl/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl
@@ -18,6 +18,8 @@
import android.hardware.wifi.StaScanData;
import android.hardware.wifi.StaScanResult;
+import android.hardware.wifi.TwtSession;
+import android.hardware.wifi.TwtSessionStats;
@VintfStability
oneway interface IWifiStaIfaceEventCallback {
@@ -61,4 +63,104 @@
* @param currRssi RSSI of the currently connected access point.
*/
void onRssiThresholdBreached(in int cmdId, in byte[6] currBssid, in int currRssi);
+
+ @VintfStability
+ @Backing(type="byte")
+ enum TwtErrorCode {
+ /** Unknown failure */
+ FAILURE_UNKNOWN,
+ /** TWT session is already resumed */
+ ALREADY_RESUMED,
+ /** TWT session is already suspended */
+ ALREADY_SUSPENDED,
+ /** Invalid parameters */
+ INVALID_PARAMS,
+ /** Maximum number of sessions reached */
+ MAX_SESSION_REACHED,
+ /** Requested operation is not available */
+ NOT_AVAILABLE,
+ /** Requested operation is not supported */
+ NOT_SUPPORTED,
+ /** Requested operation is not supported by the peer */
+ PEER_NOT_SUPPORTED,
+ /** Requested operation is rejected by the peer */
+ PEER_REJECTED,
+ /** Requested operation is timed out */
+ TIMEOUT,
+ }
+
+ @VintfStability
+ @Backing(type="byte")
+ enum TwtTeardownReasonCode {
+ /** Unknown reason */
+ UNKNOWN,
+ /** Teardown requested by the framework */
+ LOCALLY_REQUESTED,
+ /** Teardown initiated internally by the firmware or driver */
+ INTERNALLY_INITIATED,
+ /** Teardown initiated by the peer */
+ PEER_INITIATED,
+ }
+
+ /**
+ * Called to indicate a TWT failure. If there is no command associated with this failure cmdId
+ * will be 0.
+ *
+ * @param cmdId Id used to identify the command. The value 0 indicates no associated command.
+ * @param error error code.
+ */
+ void onTwtFailure(in int cmdId, in TwtErrorCode error);
+
+ /**
+ * Called when a Target Wake Time session is created. See |IWifiStaIface.twtSessionSetup|.
+ *
+ * @param cmdId Id used to identify the command.
+ * @param twtSession TWT session.
+ */
+ void onTwtSessionCreate(in int cmdId, in TwtSession twtSession);
+
+ /**
+ * Called when a Target Wake Time session is updated. See |IWifiStaIface.twtSessionUpdate|.
+ *
+ * @param cmdId Id used to identify the command.
+ * @param twtSession TWT session.
+ */
+ void onTwtSessionUpdate(in int cmdId, in TwtSession twtSession);
+
+ /**
+ * Called when the Target Wake Time session is torndown.
+ * See |IWifiStaIface.twtSessionTeardown|.
+ *
+ * @param cmdId Id used to identify the command. The value 0 indicates no associated command.
+ * @param twtSessionId TWT session id.
+ * @param reasonCode reason code for the TWT teardown.
+ */
+ void onTwtSessionTeardown(
+ in int cmdId, in int twtSessionId, in TwtTeardownReasonCode reasonCode);
+
+ /**
+ * Called when TWT session stats available. See |IWifiStaIface.twtSessionGetStats|.
+ *
+ * @param cmdId Id used to identify the command.
+ * @param twtSessionId TWT session id.
+ * @param twtSessionStats TWT session stats.
+ */
+ void onTwtSessionStats(in int cmdId, in int twtSessionId, in TwtSessionStats twtSessionStats);
+
+ /**
+ * Called when the Target Wake Time session is suspended.
+ * See |IWifiStaIface.twtSessionSuspend|.
+ *
+ * @param cmdId Id used to identify the command. The value 0 indicates no associated command.
+ * @param twtSessionId TWT session id.
+ */
+ void onTwtSessionSuspend(in int cmdId, in int twtSessionId);
+
+ /**
+ * Called when the Target Wake Time session is resumed. See |IWifiStaIface.twtSessionResume|.
+ *
+ * @param cmdId Id used to identify the command. The value 0 indicates no associated command.
+ * @param twtSessionId TWT session id.
+ */
+ void onTwtSessionResume(in int cmdId, in int twtSessionId);
}
diff --git a/wifi/aidl/android/hardware/wifi/NanBootstrappingRequest.aidl b/wifi/aidl/android/hardware/wifi/NanBootstrappingRequest.aidl
index 4b74cd9..e23bd23 100644
--- a/wifi/aidl/android/hardware/wifi/NanBootstrappingRequest.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanBootstrappingRequest.aidl
@@ -45,4 +45,16 @@
* Cookie received from previous |NanBootstrappingConfirmInd| for comeback request.
*/
byte[] cookie;
+
+ /**
+ * Identify if it is a request for come back response
+ */
+ boolean isComeback;
+
+ /**
+ * ID of an active publish or subscribe discovery session. Follow-up message is transmitted in
+ * the context of the discovery session. NAN Spec: Service Descriptor Attribute (SDA) / Instance
+ * ID
+ */
+ byte discoverySessionId;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanBootstrappingResponse.aidl b/wifi/aidl/android/hardware/wifi/NanBootstrappingResponse.aidl
index dbe8923..a2ee0e6 100644
--- a/wifi/aidl/android/hardware/wifi/NanBootstrappingResponse.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanBootstrappingResponse.aidl
@@ -29,4 +29,11 @@
* True if accept the request, false otherwise.
*/
boolean acceptRequest;
+
+ /**
+ * ID of an active publish or subscribe discovery session. Follow-up message is transmitted in
+ * the context of the discovery session. NAN Spec: Service Descriptor Attribute (SDA) / Instance
+ * ID
+ */
+ byte discoverySessionId;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanConfigRequest.aidl b/wifi/aidl/android/hardware/wifi/NanConfigRequest.aidl
index 82a7b6e..47561dc 100644
--- a/wifi/aidl/android/hardware/wifi/NanConfigRequest.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanConfigRequest.aidl
@@ -17,6 +17,7 @@
package android.hardware.wifi;
import android.hardware.wifi.NanBandSpecificConfig;
+import android.hardware.wifi.common.OuiKeyedData;
/**
* Configuration parameters of NAN. Used when enabling and re-configuring a NAN cluster.
@@ -79,4 +80,9 @@
* Additional configuration provided per band. Indexed by |NanBandIndex|.
*/
NanBandSpecificConfig[3] bandSpecificConfig;
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanDataPathSecurityConfig.aidl b/wifi/aidl/android/hardware/wifi/NanDataPathSecurityConfig.aidl
index 9a2013b..b6c5eef 100644
--- a/wifi/aidl/android/hardware/wifi/NanDataPathSecurityConfig.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanDataPathSecurityConfig.aidl
@@ -58,4 +58,49 @@
* setting up the Secure Data Path.
*/
byte[16] scid;
+
+ /**
+ * Enables the 16 replay counter for ND-TKSA(NAN Data Pairwise Security Association) and
+ * NM-TKSA(NAN managerment Pairwise Security Association), if set to false will use 4 replay
+ * counter as default
+ * Wi-Fi Aware spec 4.0: 9.5.21.2 Cipher Suite Information attribute
+ */
+ boolean enable16ReplyCountersForTksa;
+
+ /**
+ * Enables the 16 replay counter for GTKSA(Group Transient Key security associations), if set to
+ * false will use 4 replay counter as default.
+ * Wi-Fi Aware spec 4.0: 9.5.21.2 Cipher Suite Information attribute
+ */
+ boolean enable16ReplyCountersForGtksa;
+
+ /**
+ * GTK(Group Transient Key) used to protect group addressed data frames,
+ * IGTK(Integrity Group Transient Key) used to protect multicast management frames, set to true
+ * if supported.
+ * Wi-Fi Aware spec 4.0: 9.5.21.2 Cipher Suite Information attribute
+ */
+ boolean supportGtkAndIgtk;
+
+ /**
+ * BIGTK(Beacon Integrity Group Transient Key) used to protect Beacon frames, set to true if
+ * supported.
+ * Ref: Wi-Fi Aware spec 4.0: 9.5.21.2 Cipher Suite Information attribute
+ */
+ boolean supportBigtksa;
+
+ /**
+ * Enables NCS-BIP-256 for IGTKSA(Integrity Group Transient Key security associations)
+ * and BIGTK(Beacon Integrity Group Transient Key security associations), if set to false will
+ * use NCS-BIP-128 as default
+ * Wi-Fi Aware spec 4.0: 9.5.21.2 Cipher Suite Information attribute
+ */
+ boolean enableNcsBip256;
+
+ /**
+ * Require enhanced frame protection if supported, which includes multicast management frame
+ * protection, group addressed data protection and beacon frame protection.
+ * Wi-Fi Aware spec 4.0: 7.3 frame protection
+ */
+ boolean requiresEnhancedFrameProtection;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanMatchInd.aidl b/wifi/aidl/android/hardware/wifi/NanMatchInd.aidl
index 5a04376..622213c 100644
--- a/wifi/aidl/android/hardware/wifi/NanMatchInd.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanMatchInd.aidl
@@ -19,6 +19,7 @@
import android.hardware.wifi.NanCipherSuiteType;
import android.hardware.wifi.NanIdentityResolutionAttribute;
import android.hardware.wifi.NanPairingConfig;
+import android.hardware.wifi.common.OuiKeyedData;
/**
* Match indication structure.
@@ -137,4 +138,9 @@
* The NIRA from peer for NAN pairing verification
*/
NanIdentityResolutionAttribute peerNira;
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanPairingConfirmInd.aidl b/wifi/aidl/android/hardware/wifi/NanPairingConfirmInd.aidl
index a5670ec..692d3d6 100644
--- a/wifi/aidl/android/hardware/wifi/NanPairingConfirmInd.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanPairingConfirmInd.aidl
@@ -19,6 +19,7 @@
import android.hardware.wifi.NanPairingRequestType;
import android.hardware.wifi.NanStatus;
import android.hardware.wifi.NpkSecurityAssociation;
+import android.hardware.wifi.common.OuiKeyedData;
/**
* NAN pairing confirmation indication structure. Event indication is
@@ -51,4 +52,9 @@
* The security association negotiated for the pairing, can be cached for future verification
*/
NpkSecurityAssociation npksa;
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanPairingRequest.aidl b/wifi/aidl/android/hardware/wifi/NanPairingRequest.aidl
index 0c2080b..950d1e2 100644
--- a/wifi/aidl/android/hardware/wifi/NanPairingRequest.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanPairingRequest.aidl
@@ -18,6 +18,7 @@
import android.hardware.wifi.NanPairingRequestType;
import android.hardware.wifi.NanPairingSecurityConfig;
+import android.hardware.wifi.common.OuiKeyedData;
/**
* NAN pairing initiate request.
@@ -54,4 +55,9 @@
* Security config used for the pairing
*/
NanPairingSecurityConfig securityConfig;
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanPairingRequestInd.aidl b/wifi/aidl/android/hardware/wifi/NanPairingRequestInd.aidl
index ec8548f..7e98bac 100644
--- a/wifi/aidl/android/hardware/wifi/NanPairingRequestInd.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanPairingRequestInd.aidl
@@ -18,6 +18,7 @@
import android.hardware.wifi.NanIdentityResolutionAttribute;
import android.hardware.wifi.NanPairingRequestType;
+import android.hardware.wifi.common.OuiKeyedData;
/**
* NAN pairing request indication message structure.
@@ -58,4 +59,9 @@
* The NIRA from peer for NAN pairing verification
*/
NanIdentityResolutionAttribute peerNira;
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl b/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl
index 956a7df..ae75caf 100644
--- a/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl
@@ -20,6 +20,7 @@
import android.hardware.wifi.NanPairingConfig;
import android.hardware.wifi.NanPublishType;
import android.hardware.wifi.NanTxType;
+import android.hardware.wifi.common.OuiKeyedData;
/**
* Publish request. Specifies a publish discovery operation.
@@ -55,4 +56,9 @@
* The Identity key for pairing, will generate NIRA for verification by the peer
*/
byte[16] identityKey;
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl b/wifi/aidl/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl
index fab2a40..0527f06 100644
--- a/wifi/aidl/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl
@@ -18,6 +18,7 @@
import android.hardware.wifi.NanPairingRequestType;
import android.hardware.wifi.NanPairingSecurityConfig;
+import android.hardware.wifi.common.OuiKeyedData;
/**
* Response to a pairing request from a peer.
@@ -51,4 +52,9 @@
* Security config used for the pairing
*/
NanPairingSecurityConfig securityConfig;
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanSubscribeRequest.aidl b/wifi/aidl/android/hardware/wifi/NanSubscribeRequest.aidl
index 0b246ed..e7094bf 100644
--- a/wifi/aidl/android/hardware/wifi/NanSubscribeRequest.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanSubscribeRequest.aidl
@@ -21,6 +21,7 @@
import android.hardware.wifi.NanPairingConfig;
import android.hardware.wifi.NanSrfType;
import android.hardware.wifi.NanSubscribeType;
+import android.hardware.wifi.common.OuiKeyedData;
/**
* Subscribe request. Specifies a subscribe discovery operation.
@@ -76,4 +77,9 @@
* The Identity key for pairing, will generate NIRA for verification by the peer
*/
byte[16] identityKey;
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl b/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl
index 7c47ed5..c193924 100644
--- a/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl
@@ -18,6 +18,7 @@
import android.hardware.wifi.RttBw;
import android.hardware.wifi.RttPreamble;
+import android.hardware.wifi.common.OuiKeyedData;
/**
* RTT Capabilities.
@@ -33,24 +34,25 @@
*/
boolean rttFtmSupported;
/**
- * Whether initiator supports LCI request. Applies to 2-sided RTT.
+ * Whether initiator supports Location Configuration Information (LCI) request. Applies to
+ * 2-sided RTT.
*/
boolean lciSupported;
/**
- * Whether initiator supports LCR request. Applies to 2-sided RTT.
+ * Whether initiator supports Location Civic Report (LCR) request. Applies to 2-sided RTT.
*/
boolean lcrSupported;
/**
- * Whether 11mc responder mode is supported.
+ * Whether IEEE 802.11mc responder mode is supported.
*/
boolean responderSupported;
/**
- * Bit mask indicating what preamble is supported by initiator.
+ * Bit mask indicating what preamble is supported by IEEE 802.11mc initiator.
* Combination of |RttPreamble| values.
*/
RttPreamble preambleSupport;
/**
- * Bit mask indicating what BW is supported by initiator.
+ * Bit mask indicating what BW is supported by IEEE 802.11mc initiator.
* Combination of |RttBw| values.
*/
RttBw bwSupport;
@@ -59,4 +61,27 @@
* For instance, version 4.0 must be 40 and version 4.3 must be 43 etc.
*/
byte mcVersion;
+ /**
+ * Bit mask indicating what preamble is supported by IEEE 802.11az initiator.
+ * Combination of |RttPreamble| values.
+ */
+ int azPreambleSupport;
+ /**
+ * Bit mask indicating what BW is supported by IEEE 802.11az initiator.
+ * Combination of |RttBw| values.
+ */
+ int azBwSupport;
+ /**
+ * Whether the initiator supports IEEE 802.11az Non-Trigger-based (non-TB) measurement.
+ */
+ boolean ntbInitiatorSupported;
+ /**
+ * Whether IEEE 802.11az Non-Trigger-based (non-TB) responder mode is supported.
+ */
+ boolean ntbResponderSupported;
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/android/hardware/wifi/RttConfig.aidl b/wifi/aidl/android/hardware/wifi/RttConfig.aidl
index fc2c2e0..496ffd2 100644
--- a/wifi/aidl/android/hardware/wifi/RttConfig.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttConfig.aidl
@@ -21,6 +21,7 @@
import android.hardware.wifi.RttPreamble;
import android.hardware.wifi.RttType;
import android.hardware.wifi.WifiChannelInfo;
+import android.hardware.wifi.common.OuiKeyedData;
/**
* RTT configuration.
@@ -32,7 +33,7 @@
*/
byte[6] addr;
/**
- * 1-sided or 2-sided RTT.
+ * 1-sided or 2-sided RTT (IEEE 802.11mc or IEEE 802. 11az).
*/
RttType type;
/**
@@ -47,6 +48,8 @@
* Time interval between bursts (units: 100 ms).
* Applies to 1-sided and 2-sided RTT multi-burst requests.
* Range: 0-31, 0: no preference by initiator (2-sided RTT).
+ *
+ * Note: Applicable to IEEE 802.11mc only.
*/
int burstPeriod;
/**
@@ -60,6 +63,9 @@
* number of RTT results is the following:
* for 1-sided RTT: max num of RTT results = (2^num_burst)*(num_frames_per_burst)
* for 2-sided RTT: max num of RTT results = (2^num_burst)*(num_frames_per_burst - 1)
+ *
+ * Note: Applicable to IEEE 802.11mc only. For IEEE 802.11az refer
+ * |RttConfig.txLtfRepetitionCount|.
*/
int numBurst;
/**
@@ -70,6 +76,8 @@
* equals the number of FTM frames that the
* initiator will request that the responder sends
* in a single frame.
+ *
+ * Note: Applicable to IEEE 802.11mc only.
*/
int numFramesPerBurst;
/**
@@ -95,8 +103,8 @@
*/
boolean mustRequestLcr;
/**
- * Applies to 1-sided and 2-sided RTT. Valid values will
- * be 2-11 and 15 as specified by the 802.11mc std for
+ * Applies to 1-sided and 2-sided IEEE 802.11mc RTT. Valid values will
+ * be 2-11 and 15 as specified by the IEEE 802.11mc std for
* the FTM parameter burst duration. In a multi-burst
* request, if responder overrides with larger value,
* the initiator will return failure. In a single-burst
@@ -113,4 +121,23 @@
* RTT BW to be used in the RTT frames.
*/
RttBw bw;
+ /**
+ * IEEE 802.11az Non-Trigger-based (non-TB) minimum measurement time in units of 100
+ * microseconds.
+ *
+ * Reference: IEEE Std 802.11az-2022 spec, section 9.4.2.298 Ranging Parameters element.
+ */
+ long ntbMinMeasurementTime;
+ /**
+ * IEEE 802.11az Non-Trigger-based (non-TB) maximum measurement time in units of 10
+ * milliseconds.
+ *
+ * Reference: IEEE Std 802.11az-2022 spec, section 9.4.2.298 Ranging Parameters element.
+ */
+ long ntbMaxMeasurementTime;
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/android/hardware/wifi/RttPreamble.aidl b/wifi/aidl/android/hardware/wifi/RttPreamble.aidl
index e460a94..21df171 100644
--- a/wifi/aidl/android/hardware/wifi/RttPreamble.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttPreamble.aidl
@@ -22,6 +22,7 @@
@VintfStability
@Backing(type="int")
enum RttPreamble {
+ INVALID = 0,
LEGACY = 0x1,
HT = 0x2,
VHT = 0x4,
diff --git a/wifi/aidl/android/hardware/wifi/RttResult.aidl b/wifi/aidl/android/hardware/wifi/RttResult.aidl
index 6c45e2c..2f9aefe 100644
--- a/wifi/aidl/android/hardware/wifi/RttResult.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttResult.aidl
@@ -21,6 +21,7 @@
import android.hardware.wifi.RttType;
import android.hardware.wifi.WifiInformationElement;
import android.hardware.wifi.WifiRateInfo;
+import android.hardware.wifi.common.OuiKeyedData;
/**
* RTT results.
@@ -33,6 +34,8 @@
byte[6] addr;
/**
* Burst number in a multi-burst request.
+ *
+ * Note: Applicable to 1-sided RTT and 2-sided IEEE 802.11mc only.
*/
int burstNum;
/**
@@ -45,7 +48,7 @@
int successNumber;
/**
* Maximum number of "FTM frames per burst" supported by
- * the responder STA. Applies to 2-sided RTT only.
+ * the responder STA. Applies to 2-sided IEEE 802.11mc RTT only.
* If reponder overrides with larger value:
* - for single-burst request, initiator will truncate the
* larger value and send a TMR_STOP after receiving as
@@ -59,10 +62,8 @@
*/
RttStatus status;
/**
- * If status is RTT_STATUS_FAIL_BUSY_TRY_LATER,
- * this will be the time provided by the responder as to
- * when the request can be tried again. Applies to 2-sided
- * RTT only. In sec, 1-31 sec.
+ * If status is RTT_STATUS_FAIL_BUSY_TRY_LATER, this will be the time provided by the responder
+ * as to when the request can be tried again. Applies to 2-sided RTT only. In sec, 1-31 sec.
*/
byte retryAfterDuration;
/**
@@ -104,11 +105,13 @@
*/
int distanceInMm;
/**
- * Standard deviation in mm (optional).
+ * Standard deviation in mm.
*/
int distanceSdInMm;
/**
* Difference between max and min distance recorded in mm (optional).
+ *
+ * Note: Only applicable for IEEE 802.11mc
*/
int distanceSpreadInMm;
/**
@@ -116,21 +119,20 @@
*/
long timeStampInUs;
/**
- * Actual time taken by the FW to finish one burst
- * measurement (in ms). Applies to 1-sided and 2-sided RTT.
+ * Actual time taken by the FW to finish one burst measurement (in ms). Applies to 1-sided
+ * and 2-sided IEEE 802.11mc RTT.
*/
int burstDurationInMs;
/**
- * Number of bursts allowed by the responder. Applies
- * to 2-sided RTT only.
+ * Number of bursts allowed by the responder. Applies to 2-sided IEEE 802.11mc RTT only.
*/
int negotiatedBurstNum;
/**
- * For 11mc only.
+ * For IEEE 802.11mc and IEEE 802.11az only.
*/
WifiInformationElement lci;
/**
- * For 11mc only.
+ * For IEEE 802.11mc and IEEE 802.11az only.
*/
WifiInformationElement lcr;
/**
@@ -140,8 +142,75 @@
int channelFreqMHz;
/**
* RTT packet bandwidth.
- * This value is an average bandwidth of the bandwidths of measurement
- * frames. Cap the average close to a specific valid RttBw.
+ * This value is an average bandwidth of the bandwidths of measurement frames. Cap the average
+ * close to a specific valid RttBw.
*/
RttBw packetBw;
+ /**
+ * Multiple transmissions of HE-LTF symbols in an HE (I2R) Ranging NDP. An HE-LTF repetition
+ * value of 1 indicates no repetitions.
+ *
+ * Note: A required field for IEEE 802.11az result.
+ */
+ byte i2rTxLtfRepetitionCount;
+ /**
+ * Multiple transmissions of HE-LTF symbols in an HE (R2I) Ranging NDP. An HE-LTF repetition
+ * value of 1 indicates no repetitions.
+ *
+ * Note: A required field for IEEE 802.11az result.
+ */
+ byte r2iTxLtfRepetitionCount;
+ /**
+ * Minimum non-trigger based (non-TB) dynamic measurement time in units of 100 microseconds
+ * assigned by the IEEE 802.11az responder.
+ *
+ * After initial non-TB negotiation, if the next ranging request for this peer comes in between
+ * [ntbMinMeasurementTime, ntbMaxMeasurementTime], vendor software shall do the NDPA sounding
+ * sequence for dynamic non-TB measurement.
+ *
+ * If the ranging request for this peer comes sooner than minimum measurement time, vendor
+ * software shall return the cached result of the last measurement including the time stamp
+ * |RttResult.timestamp|.
+ *
+ * Reference: IEEE Std 802.11az-2022 spec, section 9.4.2.298 Ranging Parameters element.
+ *
+ * Note: A required field for IEEE 802.11az result.
+ */
+ long ntbMinMeasurementTime;
+ /**
+ * Maximum non-trigger based (non-TB) dynamic measurement time in units of 10 milliseconds
+ * assigned by the IEEE 802.11az responder.
+ *
+ * After initial non-TB negotiation, if the next ranging request for this peer comes in between
+ * [ntbMinMeasurementTime, ntbMaxMeasurementTime], vendor software shall do the NDPA sounding
+ * sequence for dynamic non-TB measurement.
+ *
+ * If the ranging request for this peer comes later than the maximum measurement time, vendor
+ * software shall clean up any existing IEEE 802.11ax non-TB ranging session and re-do the
+ * non-TB ranging negotiation.
+ *
+ * Reference: IEEE Std 802.11az-2022 spec, section 9.4.2.298 Ranging Parameters element.
+ *
+ * Note: A required field for IEEE 802.11az result.
+ */
+ long ntbMaxMeasurementTime;
+ /**
+ * Number of transmit space-time streams used. Value is in the range 1 to 8.
+ *
+ * Note: Maximum limit is ultimately defined by the number of antennas that can be supported.
+ * A required field for IEEE 802.11az result.
+ */
+ byte numTxSpatialStreams;
+ /**
+ * Number of receive space-time streams used. Value is in the range 1 to 8.
+ *
+ * Note: Maximum limit is ultimately defined by the number of antennas that can be supported.
+ * A required field for IEEE 802.11az result.
+ */
+ byte numRxSpatialStreams;
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/android/hardware/wifi/RttType.aidl b/wifi/aidl/android/hardware/wifi/RttType.aidl
index e95a928..3f1a2f1 100644
--- a/wifi/aidl/android/hardware/wifi/RttType.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttType.aidl
@@ -23,5 +23,18 @@
@Backing(type="int")
enum RttType {
ONE_SIDED = 1,
+ /**
+ * Two-sided RTT 11mc type.
+ *
+ * Note: TWO_SIDED was used for IEEE 802.11mc. Use TWO_SIDED_11MC for IEEE 802.11mc instead.
+ */
TWO_SIDED = 2,
+ /**
+ * Two-sided RTT 11mc type is same as two-sided.
+ */
+ TWO_SIDED_11MC = TWO_SIDED,
+ /**
+ * Two-sided RTT 11az non trigger based (non-TB) type.
+ */
+ TWO_SIDED_11AZ_NTB = 3,
}
diff --git a/wifi/aidl/android/hardware/wifi/StaRoamingState.aidl b/wifi/aidl/android/hardware/wifi/StaRoamingState.aidl
index d75d323..6872a17 100644
--- a/wifi/aidl/android/hardware/wifi/StaRoamingState.aidl
+++ b/wifi/aidl/android/hardware/wifi/StaRoamingState.aidl
@@ -32,4 +32,9 @@
* the |StaRoamingConfig| parameters set using |configureRoaming|.
*/
ENABLED = 1,
+ /**
+ * Driver/Firmware is allowed to roam more aggressively. For instance,
+ * roaming can be triggered at higher RSSI thresholds than normal.
+ */
+ AGGRESSIVE = 2,
}
diff --git a/wifi/aidl/android/hardware/wifi/TwtCapabilities.aidl b/wifi/aidl/android/hardware/wifi/TwtCapabilities.aidl
new file mode 100644
index 0000000..28d16f0
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/TwtCapabilities.aidl
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Target Wake Time (TWT) Capabilities supported.
+ *
+ * TWT allows Wi-Fi stations to manage activity in a network by scheduling to operate at different
+ * times. This minimizes the contention and reduces the required amount of time that a station
+ * utilizing a power management mode needs to be awake.
+ *
+ * IEEE 802.11ax standard defines two modes of TWT operation:
+ * - Individual TWT (default mode of operation if TWT requester is supported)
+ * - Broadcast TWT
+ */
+@VintfStability
+parcelable TwtCapabilities {
+ /**
+ * Whether the TWT requester mode supported.
+ */
+ boolean isTwtRequesterSupported;
+ /**
+ * Whether the TWT responder mode supported.
+ */
+ boolean isTwtResponderSupported;
+ /**
+ * Whether the Broadcast TWT mode (TWT scheduling STA) supported.
+ */
+ boolean isBroadcastTwtSupported;
+ /**
+ * Whether supports Flexible TWT schedules.
+ */
+ boolean isFlexibleTwtScheduleSupported;
+ /**
+ * Minimum TWT wake duration in microseconds.
+ */
+ int minWakeDurationUs;
+ /**
+ * Maximum TWT wake duration in microseconds.
+ */
+ int maxWakeDurationUs;
+ /**
+ * Minimum TWT wake interval in microseconds.
+ */
+ long minWakeIntervalUs;
+ /**
+ * Maximum TWT wake interval in microseconds.
+ */
+ long maxWakeIntervalUs;
+}
diff --git a/wifi/aidl/android/hardware/wifi/TwtRequest.aidl b/wifi/aidl/android/hardware/wifi/TwtRequest.aidl
new file mode 100644
index 0000000..6964a39
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/TwtRequest.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Target Wake Time (TWT) Request
+ */
+@VintfStability
+parcelable TwtRequest {
+ /**
+ * MLO Link id in case TWT is requesting for MLO connection. Otherwise -1.
+ */
+ int mloLinkId;
+ /**
+ * Minimum TWT wake duration in microseconds.
+ */
+ int minWakeDurationUs;
+ /**
+ * Maximum TWT wake duration in microseconds.
+ *
+ * As per IEEE 802.11ax spec, section 9.4.2.199 TWT element, the maximum wake duration is
+ * 65280 microseconds.
+ */
+ int maxWakeDurationUs;
+ /**
+ * Minimum TWT wake interval in microseconds.
+ */
+ long minWakeIntervalUs;
+ /**
+ * Maximum TWT wake interval in microseconds.
+ *
+ * As per IEEE 802.11ax spec, section 9.4.2.199 TWT element, the maximum wake interval is
+ * 65535 * 2^31 microseconds.
+ */
+ long maxWakeIntervalUs;
+}
diff --git a/wifi/aidl/android/hardware/wifi/TwtSession.aidl b/wifi/aidl/android/hardware/wifi/TwtSession.aidl
new file mode 100644
index 0000000..2d7e819
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/TwtSession.aidl
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Target Wake Time (TWT) Session
+ */
+@VintfStability
+parcelable TwtSession {
+ @VintfStability
+ @Backing(type="byte")
+ enum TwtNegotiationType {
+ INDIVIDUAL = 0,
+ BROADCAST = 1,
+ }
+
+ /**
+ * An unique identifier for the session.
+ */
+ int sessionId;
+
+ /**
+ * MLO Link id in case of MLO connection. Otherwise -1.
+ */
+ int mloLinkId;
+
+ /**
+ * TWT service period in microseconds.
+ */
+ int wakeDurationUs;
+
+ /**
+ * Time interval in microseconds between two successive TWT service periods.
+ */
+ long wakeIntervalUs;
+
+ /**
+ * TWT negotiation type.
+ */
+ TwtNegotiationType negotiationType;
+
+ /**
+ * Whether the TWT session is trigger enabled or non-trigger enabled.
+ */
+ boolean isTriggerEnabled;
+
+ /**
+ * Whether the TWT session is announced or unannounced.
+ */
+ boolean isAnnounced;
+
+ /**
+ * Whether the TWT session is implicit or explicit.
+ */
+ boolean isImplicit;
+
+ /**
+ * Whether the TWT session is protected or not.
+ */
+ boolean isProtected;
+
+ /**
+ * Whether the TWT session can be updated.
+ */
+ boolean isUpdatable;
+
+ /**
+ * Whether the TWT session can be suspended and then resumed.
+ */
+ boolean isSuspendable;
+
+ /**
+ * Whether AP (TWT responder) intends to go to doze state outside of TWT Service Periods.
+ *
+ * Refer IEEE 802.11 spec, Section 10.47.7 (TWT Sleep Setup).
+ */
+ boolean isResponderPmModeEnabled;
+}
diff --git a/wifi/aidl/android/hardware/wifi/TwtSessionStats.aidl b/wifi/aidl/android/hardware/wifi/TwtSessionStats.aidl
new file mode 100644
index 0000000..ba70426
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/TwtSessionStats.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Target Wake Time (TWT) Session Stats
+ */
+@VintfStability
+parcelable TwtSessionStats {
+ /**
+ * Average number of Tx packets in each wake duration.
+ */
+ int avgTxPktCount;
+
+ /**
+ * Average number of Rx packets in each wake duration.
+ */
+ int avgRxPktCount;
+
+ /**
+ * Average bytes per Tx packets in each wake duration.
+ */
+ int avgTxPktSize;
+
+ /**
+ * Average bytes per Rx packets in each wake duration.
+ */
+ int avgRxPktSize;
+
+ /**
+ * Average End of Service period in microseconds.
+ */
+ int avgEospDurationUs;
+
+ /**
+ * Count of early terminations.
+ */
+ int eospCount;
+}
diff --git a/wifi/aidl/default/Android.bp b/wifi/aidl/default/Android.bp
index 31a3531..362ef1b 100644
--- a/wifi/aidl/default/Android.bp
+++ b/wifi/aidl/default/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_fwk_wifi_hal",
default_applicable_licenses: ["hardware_interfaces_license"],
}
diff --git a/wifi/aidl/default/aidl_struct_util.cpp b/wifi/aidl/default/aidl_struct_util.cpp
index 83e1193..0f0c77e 100644
--- a/wifi/aidl/default/aidl_struct_util.cpp
+++ b/wifi/aidl/default/aidl_struct_util.cpp
@@ -59,6 +59,8 @@
return IWifiChip::FeatureSetMask::P2P_RAND_MAC;
case WIFI_FEATURE_AFC_CHANNEL:
return IWifiChip::FeatureSetMask::SET_AFC_CHANNEL_ALLOWANCE;
+ case WIFI_FEATURE_SET_VOIP_MODE:
+ return IWifiChip::FeatureSetMask::SET_VOIP_MODE;
};
CHECK(false) << "Unknown legacy feature: " << feature;
return {};
@@ -92,6 +94,10 @@
return IWifiStaIface::FeatureSetMask::ND_OFFLOAD;
case WIFI_FEATURE_MKEEP_ALIVE:
return IWifiStaIface::FeatureSetMask::KEEP_ALIVE;
+ case WIFI_FEATURE_ROAMING_MODE_CONTROL:
+ return IWifiStaIface::FeatureSetMask::ROAMING_MODE_CONTROL;
+ case WIFI_FEATURE_CACHED_SCAN_RESULTS:
+ return IWifiStaIface::FeatureSetMask::CACHED_SCAN_DATA;
};
CHECK(false) << "Unknown legacy feature: " << feature;
return {};
@@ -109,7 +115,8 @@
WIFI_FEATURE_INFRA_60G,
WIFI_FEATURE_SET_LATENCY_MODE,
WIFI_FEATURE_P2P_RAND_MAC,
- WIFI_FEATURE_AFC_CHANNEL};
+ WIFI_FEATURE_AFC_CHANNEL,
+ WIFI_FEATURE_SET_VOIP_MODE};
for (const auto feature : features) {
if (feature & legacy_feature_set) {
*aidl_feature_set |= static_cast<uint32_t>(convertLegacyChipFeatureToAidl(feature));
@@ -457,7 +464,8 @@
{WIFI_FEATURE_GSCAN, WIFI_FEATURE_LINK_LAYER_STATS, WIFI_FEATURE_RSSI_MONITOR,
WIFI_FEATURE_CONTROL_ROAMING, WIFI_FEATURE_IE_WHITELIST, WIFI_FEATURE_SCAN_RAND,
WIFI_FEATURE_INFRA_5G, WIFI_FEATURE_HOTSPOT, WIFI_FEATURE_PNO, WIFI_FEATURE_TDLS,
- WIFI_FEATURE_TDLS_OFFCHANNEL, WIFI_FEATURE_CONFIG_NDO, WIFI_FEATURE_MKEEP_ALIVE}) {
+ WIFI_FEATURE_TDLS_OFFCHANNEL, WIFI_FEATURE_CONFIG_NDO, WIFI_FEATURE_MKEEP_ALIVE,
+ WIFI_FEATURE_ROAMING_MODE_CONTROL, WIFI_FEATURE_CACHED_SCAN_RESULTS}) {
if (feature & legacy_feature_set) {
*aidl_feature_set |= static_cast<uint32_t>(convertLegacyStaIfaceFeatureToAidl(feature));
}
@@ -1147,6 +1155,8 @@
return legacy_hal::ROAMING_ENABLE;
case StaRoamingState::DISABLED:
return legacy_hal::ROAMING_DISABLE;
+ case StaRoamingState::AGGRESSIVE:
+ return legacy_hal::ROAMING_AGGRESSIVE;
};
CHECK(false);
}
@@ -2088,6 +2098,17 @@
memcpy(legacy_request->scid, aidl_request.securityConfig.scid.data(), legacy_request->scid_len);
legacy_request->publish_subscribe_id = static_cast<uint8_t>(aidl_request.discoverySessionId);
+ legacy_request->csia_capabilities |=
+ aidl_request.securityConfig.enable16ReplyCountersForTksa ? 0x1 : 0x0;
+ legacy_request->csia_capabilities |=
+ aidl_request.securityConfig.enable16ReplyCountersForGtksa ? 0x8 : 0x0;
+ if (aidl_request.securityConfig.supportGtkAndIgtk) {
+ legacy_request->csia_capabilities |= aidl_request.securityConfig.supportBigtksa ? 0x4 : 0x2;
+ }
+ legacy_request->csia_capabilities |= aidl_request.securityConfig.enableNcsBip256 ? 0x16 : 0x0;
+ legacy_request->gtk_protection =
+ aidl_request.securityConfig.requiresEnhancedFrameProtection ? 1 : 0;
+
return true;
}
@@ -2170,6 +2191,17 @@
memcpy(legacy_request->scid, aidl_request.securityConfig.scid.data(), legacy_request->scid_len);
legacy_request->publish_subscribe_id = static_cast<uint8_t>(aidl_request.discoverySessionId);
+ legacy_request->csia_capabilities |=
+ aidl_request.securityConfig.enable16ReplyCountersForTksa ? 0x1 : 0x0;
+ legacy_request->csia_capabilities |=
+ aidl_request.securityConfig.enable16ReplyCountersForGtksa ? 0x8 : 0x0;
+ if (aidl_request.securityConfig.supportGtkAndIgtk) {
+ legacy_request->csia_capabilities |= aidl_request.securityConfig.supportBigtksa ? 0x4 : 0x2;
+ }
+ legacy_request->csia_capabilities |= aidl_request.securityConfig.enableNcsBip256 ? 0x16 : 0x0;
+ legacy_request->gtk_protection =
+ aidl_request.securityConfig.requiresEnhancedFrameProtection ? 1 : 0;
+
return true;
}
@@ -2394,8 +2426,11 @@
switch (type) {
case RttType::ONE_SIDED:
return legacy_hal::RTT_TYPE_1_SIDED;
- case RttType::TWO_SIDED:
- return legacy_hal::RTT_TYPE_2_SIDED;
+ case RttType::TWO_SIDED_11MC:
+ // Same as RttType::TWO_SIDED
+ return legacy_hal::RTT_TYPE_2_SIDED_11MC;
+ case RttType::TWO_SIDED_11AZ_NTB:
+ return legacy_hal::RTT_TYPE_2_SIDED_11AZ_NTB;
};
CHECK(false);
}
@@ -2404,8 +2439,11 @@
switch (type) {
case legacy_hal::RTT_TYPE_1_SIDED:
return RttType::ONE_SIDED;
- case legacy_hal::RTT_TYPE_2_SIDED:
- return RttType::TWO_SIDED;
+ case legacy_hal::RTT_TYPE_2_SIDED_11MC:
+ // Same as legacy_hal::RTT_TYPE_2_SIDED
+ return RttType::TWO_SIDED_11MC;
+ case legacy_hal::RTT_TYPE_2_SIDED_11AZ_NTB:
+ return RttType::TWO_SIDED_11AZ_NTB;
};
CHECK(false) << "Unknown legacy type: " << type;
}
@@ -2485,6 +2523,8 @@
return legacy_hal::WIFI_RTT_PREAMBLE_HE;
case RttPreamble::EHT:
return legacy_hal::WIFI_RTT_PREAMBLE_EHT;
+ case RttPreamble::INVALID:
+ return legacy_hal::WIFI_RTT_PREAMBLE_INVALID;
};
CHECK(false);
}
@@ -2501,6 +2541,8 @@
return RttPreamble::HE;
case legacy_hal::WIFI_RTT_PREAMBLE_EHT:
return RttPreamble::EHT;
+ case legacy_hal::WIFI_RTT_PREAMBLE_INVALID:
+ return RttPreamble::INVALID;
};
CHECK(false) << "Unknown legacy type: " << type;
}
@@ -2690,6 +2732,20 @@
return true;
}
+bool convertAidlRttConfigToLegacyV3(const RttConfig& aidl_config,
+ legacy_hal::wifi_rtt_config_v3* legacy_config) {
+ if (!legacy_config) {
+ return false;
+ }
+ *legacy_config = {};
+ if (!convertAidlRttConfigToLegacy(aidl_config, &(legacy_config->rtt_config))) {
+ return false;
+ }
+ legacy_config->ntb_min_measurement_time = aidl_config.ntbMinMeasurementTime;
+ legacy_config->ntb_max_measurement_time = aidl_config.ntbMaxMeasurementTime;
+ return true;
+}
+
bool convertAidlVectorOfRttConfigToLegacy(
const std::vector<RttConfig>& aidl_configs,
std::vector<legacy_hal::wifi_rtt_config>* legacy_configs) {
@@ -2699,7 +2755,24 @@
*legacy_configs = {};
for (const auto& aidl_config : aidl_configs) {
legacy_hal::wifi_rtt_config legacy_config;
- if (!convertAidlRttConfigToLegacy(aidl_config, &legacy_config)) {
+ if (!convertAidlRttConfigToLegacy(aidl_config, &(legacy_config))) {
+ return false;
+ }
+ legacy_configs->push_back(legacy_config);
+ }
+ return true;
+}
+
+bool convertAidlVectorOfRttConfigToLegacyV3(
+ const std::vector<RttConfig>& aidl_configs,
+ std::vector<legacy_hal::wifi_rtt_config_v3>* legacy_configs) {
+ if (!legacy_configs) {
+ return false;
+ }
+ *legacy_configs = {};
+ for (const auto& aidl_config : aidl_configs) {
+ legacy_hal::wifi_rtt_config_v3 legacy_config;
+ if (!convertAidlRttConfigToLegacyV3(aidl_config, &legacy_config)) {
return false;
}
legacy_configs->push_back(legacy_config);
@@ -2768,6 +2841,34 @@
return true;
}
+RttPreamble convertLegacyRttPreambleBitmapToAidl(byte legacyPreambleBitmap) {
+ int32_t aidlPreambleBitmap = 0;
+ for (const auto flag : {legacy_hal::WIFI_RTT_PREAMBLE_LEGACY, legacy_hal::WIFI_RTT_PREAMBLE_HT,
+ legacy_hal::WIFI_RTT_PREAMBLE_VHT, legacy_hal::WIFI_RTT_PREAMBLE_HE,
+ legacy_hal::WIFI_RTT_PREAMBLE_EHT}) {
+ if (legacyPreambleBitmap & flag) {
+ aidlPreambleBitmap |= static_cast<std::underlying_type<RttPreamble>::type>(
+ convertLegacyRttPreambleToAidl(flag));
+ }
+ }
+
+ return static_cast<RttPreamble>(aidlPreambleBitmap);
+}
+
+RttBw convertLegacyRttBwBitmapToAidl(byte legacyBwBitmap) {
+ int32_t aidlBwBitmap = 0;
+ for (const auto flag :
+ {legacy_hal::WIFI_RTT_BW_5, legacy_hal::WIFI_RTT_BW_10, legacy_hal::WIFI_RTT_BW_20,
+ legacy_hal::WIFI_RTT_BW_40, legacy_hal::WIFI_RTT_BW_80, legacy_hal::WIFI_RTT_BW_160,
+ legacy_hal::WIFI_RTT_BW_320}) {
+ if (legacyBwBitmap & flag) {
+ aidlBwBitmap |=
+ static_cast<std::underlying_type<RttBw>::type>(convertLegacyRttBwToAidl(flag));
+ }
+ }
+ return static_cast<RttBw>(aidlBwBitmap);
+}
+
bool convertLegacyRttCapabilitiesToAidl(
const legacy_hal::wifi_rtt_capabilities& legacy_capabilities,
RttCapabilities* aidl_capabilities) {
@@ -2780,28 +2881,42 @@
aidl_capabilities->lciSupported = legacy_capabilities.lci_support;
aidl_capabilities->lcrSupported = legacy_capabilities.lcr_support;
aidl_capabilities->responderSupported = legacy_capabilities.responder_supported;
- int32_t preambleSupport = 0;
- for (const auto flag : {legacy_hal::WIFI_RTT_PREAMBLE_LEGACY, legacy_hal::WIFI_RTT_PREAMBLE_HT,
- legacy_hal::WIFI_RTT_PREAMBLE_VHT, legacy_hal::WIFI_RTT_PREAMBLE_HE,
- legacy_hal::WIFI_RTT_PREAMBLE_EHT}) {
- if (legacy_capabilities.preamble_support & flag) {
- preambleSupport |= static_cast<std::underlying_type<RttPreamble>::type>(
- convertLegacyRttPreambleToAidl(flag));
- }
- }
- aidl_capabilities->preambleSupport = static_cast<RttPreamble>(preambleSupport);
- int32_t bwSupport = 0;
- for (const auto flag :
- {legacy_hal::WIFI_RTT_BW_5, legacy_hal::WIFI_RTT_BW_10, legacy_hal::WIFI_RTT_BW_20,
- legacy_hal::WIFI_RTT_BW_40, legacy_hal::WIFI_RTT_BW_80, legacy_hal::WIFI_RTT_BW_160,
- legacy_hal::WIFI_RTT_BW_320}) {
- if (legacy_capabilities.bw_support & flag) {
- bwSupport |=
- static_cast<std::underlying_type<RttBw>::type>(convertLegacyRttBwToAidl(flag));
- }
- }
- aidl_capabilities->bwSupport = static_cast<RttBw>(bwSupport);
+ aidl_capabilities->preambleSupport =
+ convertLegacyRttPreambleBitmapToAidl(legacy_capabilities.preamble_support);
+ aidl_capabilities->bwSupport = convertLegacyRttBwBitmapToAidl(legacy_capabilities.bw_support);
aidl_capabilities->mcVersion = legacy_capabilities.mc_version;
+ // Initialize 11az parameters to default
+ aidl_capabilities->azPreambleSupport = (int)RttPreamble::INVALID;
+ aidl_capabilities->azBwSupport = (int)RttBw::BW_UNSPECIFIED;
+ aidl_capabilities->ntbInitiatorSupported = false;
+ aidl_capabilities->ntbResponderSupported = false;
+ return true;
+}
+
+bool convertLegacyRttCapabilitiesV3ToAidl(
+ const legacy_hal::wifi_rtt_capabilities_v3& legacy_capabilities_v3,
+ RttCapabilities* aidl_capabilities) {
+ if (!aidl_capabilities) {
+ return false;
+ }
+ *aidl_capabilities = {};
+ aidl_capabilities->rttOneSidedSupported =
+ legacy_capabilities_v3.rtt_capab.rtt_one_sided_supported;
+ aidl_capabilities->rttFtmSupported = legacy_capabilities_v3.rtt_capab.rtt_ftm_supported;
+ aidl_capabilities->lciSupported = legacy_capabilities_v3.rtt_capab.lci_support;
+ aidl_capabilities->lcrSupported = legacy_capabilities_v3.rtt_capab.lcr_support;
+ aidl_capabilities->responderSupported = legacy_capabilities_v3.rtt_capab.responder_supported;
+ aidl_capabilities->preambleSupport =
+ convertLegacyRttPreambleBitmapToAidl(legacy_capabilities_v3.rtt_capab.preamble_support);
+ aidl_capabilities->bwSupport =
+ convertLegacyRttBwBitmapToAidl(legacy_capabilities_v3.rtt_capab.bw_support);
+ aidl_capabilities->mcVersion = legacy_capabilities_v3.rtt_capab.mc_version;
+ aidl_capabilities->azPreambleSupport =
+ (int)convertLegacyRttPreambleBitmapToAidl(legacy_capabilities_v3.az_preamble_support);
+ aidl_capabilities->azBwSupport =
+ (int)convertLegacyRttBwBitmapToAidl(legacy_capabilities_v3.az_bw_support);
+ aidl_capabilities->ntbInitiatorSupported = legacy_capabilities_v3.ntb_initiator_supported;
+ aidl_capabilities->ntbResponderSupported = legacy_capabilities_v3.ntb_responder_supported;
return true;
}
@@ -2876,6 +2991,12 @@
}
aidl_result.channelFreqMHz = 0;
aidl_result.packetBw = RttBw::BW_UNSPECIFIED;
+ aidl_result.i2rTxLtfRepetitionCount = 0;
+ aidl_result.r2iTxLtfRepetitionCount = 0;
+ aidl_result.ntbMinMeasurementTime = 0;
+ aidl_result.ntbMaxMeasurementTime = 0;
+ aidl_result.numTxSpatialStreams = 0;
+ aidl_result.numRxSpatialStreams = 0;
aidl_results->push_back(aidl_result);
}
return true;
@@ -2896,6 +3017,39 @@
aidl_result.channelFreqMHz =
legacy_result->frequency != UNSPECIFIED ? legacy_result->frequency : 0;
aidl_result.packetBw = convertLegacyRttBwToAidl(legacy_result->packet_bw);
+ aidl_result.i2rTxLtfRepetitionCount = 0;
+ aidl_result.r2iTxLtfRepetitionCount = 0;
+ aidl_result.ntbMinMeasurementTime = 0;
+ aidl_result.ntbMaxMeasurementTime = 0;
+ aidl_result.numTxSpatialStreams = 0;
+ aidl_result.numRxSpatialStreams = 0;
+ aidl_results->push_back(aidl_result);
+ }
+ return true;
+}
+
+bool convertLegacyVectorOfRttResultV3ToAidl(
+ const std::vector<const legacy_hal::wifi_rtt_result_v3*>& legacy_results,
+ std::vector<RttResult>* aidl_results) {
+ if (!aidl_results) {
+ return false;
+ }
+ *aidl_results = {};
+ for (const auto legacy_result : legacy_results) {
+ RttResult aidl_result;
+ if (!convertLegacyRttResultToAidl(legacy_result->rtt_result.rtt_result, &aidl_result)) {
+ return false;
+ }
+ aidl_result.channelFreqMHz = legacy_result->rtt_result.frequency != UNSPECIFIED
+ ? legacy_result->rtt_result.frequency
+ : 0;
+ aidl_result.packetBw = convertLegacyRttBwToAidl(legacy_result->rtt_result.packet_bw);
+ aidl_result.i2rTxLtfRepetitionCount = legacy_result->i2r_tx_ltf_repetition_count;
+ aidl_result.r2iTxLtfRepetitionCount = legacy_result->r2i_tx_ltf_repetition_count;
+ aidl_result.ntbMinMeasurementTime = legacy_result->ntb_min_measurement_time;
+ aidl_result.ntbMaxMeasurementTime = legacy_result->ntb_max_measurement_time;
+ aidl_result.numTxSpatialStreams = legacy_result->num_tx_sts;
+ aidl_result.numRxSpatialStreams = legacy_result->num_rx_sts;
aidl_results->push_back(aidl_result);
}
return true;
@@ -3178,6 +3332,8 @@
legacy_request->cookie_length = aidl_request.cookie.size();
memcpy(legacy_request->cookie, aidl_request.cookie.data(), legacy_request->cookie_length);
+ legacy_request->publish_subscribe_id = static_cast<uint8_t>(aidl_request.discoverySessionId);
+ legacy_request->comeback = aidl_request.isComeback ? 0x1 : 0x0;
return true;
}
@@ -3195,6 +3351,7 @@
legacy_request->service_instance_id = aidl_request.bootstrappingInstanceId;
legacy_request->rsp_code = aidl_request.acceptRequest ? NAN_BOOTSTRAPPING_REQUEST_ACCEPT
: NAN_BOOTSTRAPPING_REQUEST_REJECT;
+ legacy_request->publish_subscribe_id = static_cast<uint8_t>(aidl_request.discoverySessionId);
return true;
}
@@ -3362,6 +3519,195 @@
return true;
}
+bool convertCachedScanReportToAidl(const legacy_hal::WifiCachedScanReport& report,
+ CachedScanData* aidl_scan_data) {
+ if (!aidl_scan_data) {
+ return false;
+ }
+ *aidl_scan_data = {};
+
+ std::vector<CachedScanResult> aidl_scan_results;
+ for (const auto& result : report.results) {
+ CachedScanResult aidl_scan_result;
+ if (!convertCachedScanResultToAidl(result, report.ts, &aidl_scan_result)) {
+ return false;
+ }
+ aidl_scan_results.push_back(aidl_scan_result);
+ }
+ aidl_scan_data->cachedScanResults = aidl_scan_results;
+
+ aidl_scan_data->scannedFrequenciesMhz = report.scanned_freqs;
+ return true;
+}
+
+bool convertCachedScanResultToAidl(const legacy_hal::wifi_cached_scan_result& legacy_scan_result,
+ uint64_t ts_us, CachedScanResult* aidl_scan_result) {
+ if (!aidl_scan_result) {
+ return false;
+ }
+ *aidl_scan_result = {};
+ aidl_scan_result->timeStampInUs = ts_us - legacy_scan_result.age_ms * 1000;
+ if (aidl_scan_result->timeStampInUs < 0) {
+ aidl_scan_result->timeStampInUs = 0;
+ return false;
+ }
+ size_t max_len_excluding_null = sizeof(legacy_scan_result.ssid) - 1;
+ size_t ssid_len = strnlen((const char*)legacy_scan_result.ssid, max_len_excluding_null);
+ aidl_scan_result->ssid =
+ std::vector<uint8_t>(legacy_scan_result.ssid, legacy_scan_result.ssid + ssid_len);
+ aidl_scan_result->bssid = std::array<uint8_t, 6>();
+ std::copy(legacy_scan_result.bssid, legacy_scan_result.bssid + 6,
+ std::begin(aidl_scan_result->bssid));
+ aidl_scan_result->frequencyMhz = legacy_scan_result.chanspec.primary_frequency;
+ aidl_scan_result->channelWidthMhz =
+ convertLegacyWifiChannelWidthToAidl(legacy_scan_result.chanspec.width);
+ aidl_scan_result->rssiDbm = legacy_scan_result.rssi;
+ aidl_scan_result->preambleType = convertScanResultFlagsToPreambleType(legacy_scan_result.flags);
+ return true;
+}
+
+WifiRatePreamble convertScanResultFlagsToPreambleType(int flags) {
+ if ((flags & WIFI_CACHED_SCAN_RESULT_FLAGS_EHT_OPS_PRESENT) > 0) {
+ return WifiRatePreamble::EHT;
+ }
+ if ((flags & WIFI_CACHED_SCAN_RESULT_FLAGS_HE_OPS_PRESENT) > 0) {
+ return WifiRatePreamble::HE;
+ }
+ if ((flags & WIFI_CACHED_SCAN_RESULT_FLAGS_VHT_OPS_PRESENT) > 0) {
+ return WifiRatePreamble::VHT;
+ }
+ if ((flags & WIFI_CACHED_SCAN_RESULT_FLAGS_HT_OPS_PRESENT) > 0) {
+ return WifiRatePreamble::HT;
+ }
+ return WifiRatePreamble::OFDM;
+}
+
+bool convertTwtCapabilitiesToAidl(legacy_hal::wifi_twt_capabilities legacy_twt_capabs,
+ TwtCapabilities* aidl_twt_capabs) {
+ if (!aidl_twt_capabs) {
+ return false;
+ }
+ aidl_twt_capabs->isTwtRequesterSupported = legacy_twt_capabs.is_twt_requester_supported;
+ aidl_twt_capabs->isTwtResponderSupported = legacy_twt_capabs.is_twt_responder_supported;
+ aidl_twt_capabs->isBroadcastTwtSupported = legacy_twt_capabs.is_flexible_twt_supported;
+ if (legacy_twt_capabs.min_wake_duration_micros > legacy_twt_capabs.max_wake_duration_micros) {
+ return false;
+ }
+ aidl_twt_capabs->minWakeDurationUs = legacy_twt_capabs.min_wake_duration_micros;
+ aidl_twt_capabs->maxWakeDurationUs = legacy_twt_capabs.max_wake_duration_micros;
+ if (legacy_twt_capabs.min_wake_interval_micros > legacy_twt_capabs.max_wake_interval_micros) {
+ return false;
+ }
+ aidl_twt_capabs->minWakeIntervalUs = legacy_twt_capabs.min_wake_interval_micros;
+ aidl_twt_capabs->maxWakeIntervalUs = legacy_twt_capabs.max_wake_interval_micros;
+ return true;
+}
+
+bool convertAidlTwtRequestToLegacy(const TwtRequest aidl_twt_request,
+ legacy_hal::wifi_twt_request* legacy_twt_request) {
+ if (legacy_twt_request == nullptr) {
+ return false;
+ }
+ legacy_twt_request->mlo_link_id = aidl_twt_request.mloLinkId;
+ if (aidl_twt_request.minWakeDurationUs > aidl_twt_request.maxWakeDurationUs) {
+ return false;
+ }
+ legacy_twt_request->min_wake_duration_micros = aidl_twt_request.minWakeDurationUs;
+ legacy_twt_request->max_wake_duration_micros = aidl_twt_request.maxWakeDurationUs;
+ if (aidl_twt_request.minWakeIntervalUs > aidl_twt_request.maxWakeIntervalUs) {
+ return false;
+ }
+ legacy_twt_request->min_wake_interval_micros = aidl_twt_request.minWakeIntervalUs;
+ legacy_twt_request->max_wake_interval_micros = aidl_twt_request.maxWakeIntervalUs;
+ return true;
+}
+
+IWifiStaIfaceEventCallback::TwtErrorCode convertLegacyHalTwtErrorCodeToAidl(
+ legacy_hal::wifi_twt_error_code legacy_error_code) {
+ switch (legacy_error_code) {
+ case WIFI_TWT_ERROR_CODE_TIMEOUT:
+ return IWifiStaIfaceEventCallback::TwtErrorCode::TIMEOUT;
+ case WIFI_TWT_ERROR_CODE_PEER_REJECTED:
+ return IWifiStaIfaceEventCallback::TwtErrorCode::PEER_REJECTED;
+ case WIFI_TWT_ERROR_CODE_PEER_NOT_SUPPORTED:
+ return IWifiStaIfaceEventCallback::TwtErrorCode::PEER_NOT_SUPPORTED;
+ case WIFI_TWT_ERROR_CODE_NOT_SUPPORTED:
+ return IWifiStaIfaceEventCallback::TwtErrorCode::NOT_SUPPORTED;
+ case WIFI_TWT_ERROR_CODE_NOT_AVAILABLE:
+ return IWifiStaIfaceEventCallback::TwtErrorCode::NOT_AVAILABLE;
+ case WIFI_TWT_ERROR_CODE_MAX_SESSION_REACHED:
+ return IWifiStaIfaceEventCallback::TwtErrorCode::MAX_SESSION_REACHED;
+ case WIFI_TWT_ERROR_CODE_INVALID_PARAMS:
+ return IWifiStaIfaceEventCallback::TwtErrorCode::INVALID_PARAMS;
+ case WIFI_TWT_ERROR_CODE_ALREADY_SUSPENDED:
+ return IWifiStaIfaceEventCallback::TwtErrorCode::ALREADY_SUSPENDED;
+ case WIFI_TWT_ERROR_CODE_ALREADY_RESUMED:
+ return IWifiStaIfaceEventCallback::TwtErrorCode::ALREADY_RESUMED;
+ default:
+ return IWifiStaIfaceEventCallback::TwtErrorCode::FAILURE_UNKNOWN;
+ }
+}
+
+IWifiStaIfaceEventCallback::TwtTeardownReasonCode convertLegacyHalTwtReasonCodeToAidl(
+ legacy_hal::wifi_twt_teardown_reason_code legacy_reason_code) {
+ switch (legacy_reason_code) {
+ case WIFI_TWT_TEARDOWN_REASON_CODE_LOCALLY_REQUESTED:
+ return IWifiStaIfaceEventCallback::TwtTeardownReasonCode::LOCALLY_REQUESTED;
+ case WIFI_TWT_TEARDOWN_REASON_CODE_INTERNALLY_INITIATED:
+ return IWifiStaIfaceEventCallback::TwtTeardownReasonCode::INTERNALLY_INITIATED;
+ case WIFI_TWT_TEARDOWN_REASON_CODE_PEER_INITIATED:
+ return IWifiStaIfaceEventCallback::TwtTeardownReasonCode::PEER_INITIATED;
+ default:
+ return IWifiStaIfaceEventCallback::TwtTeardownReasonCode::UNKNOWN;
+ }
+}
+
+bool convertLegacyHalTwtSessionToAidl(legacy_hal::wifi_twt_session twt_session,
+ TwtSession* aidl_twt_session) {
+ if (aidl_twt_session == nullptr) {
+ return false;
+ }
+
+ aidl_twt_session->sessionId = twt_session.session_id;
+ aidl_twt_session->mloLinkId = twt_session.mlo_link_id;
+ aidl_twt_session->wakeDurationUs = twt_session.wake_duration_micros;
+ aidl_twt_session->wakeIntervalUs = twt_session.wake_interval_micros;
+ switch (twt_session.negotiation_type) {
+ case WIFI_TWT_NEGO_TYPE_INDIVIDUAL:
+ aidl_twt_session->negotiationType = TwtSession::TwtNegotiationType::INDIVIDUAL;
+ break;
+ case WIFI_TWT_NEGO_TYPE_BROADCAST:
+ aidl_twt_session->negotiationType = TwtSession::TwtNegotiationType::BROADCAST;
+ break;
+ default:
+ return false;
+ }
+ aidl_twt_session->isTriggerEnabled = twt_session.is_trigger_enabled;
+ aidl_twt_session->isAnnounced = twt_session.is_announced;
+ aidl_twt_session->isImplicit = twt_session.is_implicit;
+ aidl_twt_session->isProtected = twt_session.is_protected;
+ aidl_twt_session->isUpdatable = twt_session.is_updatable;
+ aidl_twt_session->isSuspendable = twt_session.is_suspendable;
+ aidl_twt_session->isResponderPmModeEnabled = twt_session.is_responder_pm_mode_enabled;
+ return true;
+}
+
+bool convertLegacyHalTwtSessionStatsToAidl(legacy_hal::wifi_twt_session_stats twt_stats,
+ TwtSessionStats* aidl_twt_stats) {
+ if (aidl_twt_stats == nullptr) {
+ return false;
+ }
+
+ aidl_twt_stats->avgTxPktCount = twt_stats.avg_pkt_num_tx;
+ aidl_twt_stats->avgRxPktCount = twt_stats.avg_pkt_num_rx;
+ aidl_twt_stats->avgTxPktSize = twt_stats.avg_tx_pkt_size;
+ aidl_twt_stats->avgRxPktSize = twt_stats.avg_rx_pkt_size;
+ aidl_twt_stats->avgEospDurationUs = twt_stats.avg_eosp_dur_us;
+ aidl_twt_stats->eospCount = twt_stats.eosp_count;
+
+ return true;
+}
+
} // namespace aidl_struct_util
} // namespace wifi
} // namespace hardware
diff --git a/wifi/aidl/default/aidl_struct_util.h b/wifi/aidl/default/aidl_struct_util.h
index e4ff963..7089363 100644
--- a/wifi/aidl/default/aidl_struct_util.h
+++ b/wifi/aidl/default/aidl_struct_util.h
@@ -148,6 +148,10 @@
// RTT controller conversion methods.
bool convertAidlVectorOfRttConfigToLegacy(const std::vector<RttConfig>& aidl_configs,
std::vector<legacy_hal::wifi_rtt_config>* legacy_configs);
+bool convertAidlVectorOfRttConfigToLegacyV3(
+ const std::vector<RttConfig>& aidl_configs,
+ std::vector<legacy_hal::wifi_rtt_config_v3>* legacy_configs);
+
bool convertAidlRttLciInformationToLegacy(const RttLciInformation& aidl_info,
legacy_hal::wifi_lci_information* legacy_info);
bool convertAidlRttLcrInformationToLegacy(const RttLcrInformation& aidl_info,
@@ -161,12 +165,19 @@
bool convertLegacyRttCapabilitiesToAidl(
const legacy_hal::wifi_rtt_capabilities& legacy_capabilities,
RttCapabilities* aidl_capabilities);
+bool convertLegacyRttCapabilitiesV3ToAidl(
+ const legacy_hal::wifi_rtt_capabilities_v3& legacy_capabilities_v3,
+ RttCapabilities* aidl_capabilities);
+
bool convertLegacyVectorOfRttResultToAidl(
const std::vector<const legacy_hal::wifi_rtt_result*>& legacy_results,
std::vector<RttResult>* aidl_results);
bool convertLegacyVectorOfRttResultV2ToAidl(
const std::vector<const legacy_hal::wifi_rtt_result_v2*>& legacy_results,
std::vector<RttResult>* aidl_results);
+bool convertLegacyVectorOfRttResultV3ToAidl(
+ const std::vector<const legacy_hal::wifi_rtt_result_v3*>& legacy_results,
+ std::vector<RttResult>* aidl_results);
uint32_t convertAidlWifiBandToLegacyMacBand(WifiBand band);
uint32_t convertAidlWifiIfaceModeToLegacy(uint32_t aidl_iface_mask);
uint32_t convertAidlUsableChannelFilterToLegacy(uint32_t aidl_filter_mask);
@@ -202,6 +213,23 @@
const legacy_hal::NanBootstrappingConfirmInd& legacy_ind,
NanBootstrappingConfirmInd* aidl_ind);
uint32_t convertAidlChannelCategoryToLegacy(uint32_t aidl_channel_category_mask);
+bool convertCachedScanReportToAidl(const legacy_hal::WifiCachedScanReport& report,
+ CachedScanData* aidl_scan_data);
+bool convertCachedScanResultToAidl(const legacy_hal::wifi_cached_scan_result& legacy_scan_result,
+ uint64_t ts_us, CachedScanResult* aidl_scan_result);
+WifiRatePreamble convertScanResultFlagsToPreambleType(int flags);
+bool convertTwtCapabilitiesToAidl(const legacy_hal::wifi_twt_capabilities legacy_twt_capabs,
+ TwtCapabilities* aidl_twt_capabs);
+bool convertAidlTwtRequestToLegacy(const TwtRequest aidl_twt_request,
+ legacy_hal::wifi_twt_request* legacy_twt_request);
+IWifiStaIfaceEventCallback::TwtErrorCode convertLegacyHalTwtErrorCodeToAidl(
+ legacy_hal::wifi_twt_error_code legacy_error_code);
+IWifiStaIfaceEventCallback::TwtTeardownReasonCode convertLegacyHalTwtReasonCodeToAidl(
+ legacy_hal::wifi_twt_teardown_reason_code legacy_reason_code);
+bool convertLegacyHalTwtSessionToAidl(legacy_hal::wifi_twt_session twt_session,
+ TwtSession* aidl_twt_session);
+bool convertLegacyHalTwtSessionStatsToAidl(legacy_hal::wifi_twt_session_stats twt_stats,
+ TwtSessionStats* aidl_twt_stats);
} // namespace aidl_struct_util
} // namespace wifi
} // namespace hardware
diff --git a/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp b/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp
index 995a13d..2a030ee 100644
--- a/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp
+++ b/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp
@@ -35,6 +35,12 @@
0x2c, 0x00, 0x00, 0x41, 0x06, 0x03, 0x06, 0x00, 0x80};
byte LCR[] = {0x27, 0xE, 0x1, 0x00, 0xB, 0x01, 0x00, 0x0b, 0x00, 0x09,
0x55, 0x53, 0x18, 0x05, 0x39, 0x34, 0x30, 0x34, 0x33};
+
+constexpr int kNumScanResult = 2;
+constexpr int kRssi[] = {-60, -70};
+constexpr uint8_t kBssid[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0};
+constexpr uint8_t kSsidLen = 6;
+constexpr char kSsid[] = {'a', 'b', 'c', 'd', 'e', '\0'};
} // namespace
namespace aidl {
@@ -883,6 +889,51 @@
}
}
+TEST_F(AidlStructUtilTest, convertCachedScanReportToAidl) {
+ legacy_hal::WifiCachedScanReport hw_report;
+
+ hw_report.ts = 10000000;
+ std::vector<int> scanned_freqs{5260, 2437, 5200};
+ std::vector<wifi_cached_scan_result> results;
+ hw_report.scanned_freqs = scanned_freqs;
+
+ for (int i = 0; i < kNumScanResult; i++) {
+ wifi_cached_scan_result result;
+ result.age_ms = i * 1000;
+ result.capability = i;
+ memcpy(result.ssid, kSsid, kSsidLen);
+ result.ssid_len = kSsidLen;
+ memcpy(result.bssid, kBssid, 6);
+ result.flags = WIFI_CACHED_SCAN_RESULT_FLAGS_HE_OPS_PRESENT;
+ result.rssi = kRssi[i];
+ result.chanspec = {legacy_hal::WIFI_CHAN_WIDTH_40, 0, 0, i};
+ results.push_back(result);
+ }
+ hw_report.results = results;
+
+ CachedScanData aidl_data;
+ aidl_struct_util::convertCachedScanReportToAidl(hw_report, &aidl_data);
+
+ EXPECT_EQ(scanned_freqs.size(), aidl_data.scannedFrequenciesMhz.size());
+ EXPECT_EQ(scanned_freqs[2], aidl_data.scannedFrequenciesMhz[2]);
+ EXPECT_EQ(5260, aidl_data.scannedFrequenciesMhz[0]);
+ EXPECT_EQ(kNumScanResult, (int)aidl_data.cachedScanResults.size());
+ for (int i = 0; i < kNumScanResult; i++) {
+ EXPECT_EQ(hw_report.results[i].rssi, aidl_data.cachedScanResults[i].rssiDbm);
+ EXPECT_EQ(i, aidl_data.cachedScanResults[i].frequencyMhz);
+ int64_t expected_ts = 10000000 - i * 1000 * 1000;
+ EXPECT_EQ(expected_ts, aidl_data.cachedScanResults[i].timeStampInUs);
+ EXPECT_EQ(WifiRatePreamble::HE, aidl_data.cachedScanResults[i].preambleType);
+ EXPECT_EQ(WifiChannelWidthInMhz::WIDTH_40, aidl_data.cachedScanResults[i].channelWidthMhz);
+ for (int k = 0; k < 6; k++) {
+ EXPECT_EQ(kBssid[k], aidl_data.cachedScanResults[i].bssid[k]);
+ }
+ for (int k = 0; k < kSsidLen; k++) {
+ EXPECT_EQ(kSsid[k], aidl_data.cachedScanResults[i].ssid[k]);
+ }
+ }
+}
+
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/aidl/default/wifi_chip.cpp b/wifi/aidl/default/wifi_chip.cpp
index d72775c..9b9c565 100644
--- a/wifi/aidl/default/wifi_chip.cpp
+++ b/wifi/aidl/default/wifi_chip.cpp
@@ -20,6 +20,7 @@
#include <android-base/unique_fd.h>
#include <cutils/properties.h>
#include <fcntl.h>
+#include <hardware_legacy/wifi_hal.h>
#include <net/if.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
@@ -605,6 +606,11 @@
&WifiChip::setMloModeInternal, in_mode);
}
+ndk::ScopedAStatus WifiChip::setVoipMode(const VoipMode in_mode) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::setVoipModeInternal, in_mode);
+}
+
void WifiChip::invalidateAndRemoveAllIfaces() {
invalidateAndClearBridgedApAll();
invalidateAndClearAll(ap_ifaces_);
@@ -1913,6 +1919,23 @@
return createWifiStatusFromLegacyError(legacy_hal_.lock()->setMloMode(mode));
}
+ndk::ScopedAStatus WifiChip::setVoipModeInternal(const WifiChip::VoipMode in_mode) {
+ const auto ifname = getFirstActiveWlanIfaceName();
+ wifi_voip_mode mode;
+ switch (in_mode) {
+ case WifiChip::VoipMode::VOICE:
+ mode = wifi_voip_mode::WIFI_VOIP_MODE_VOICE;
+ break;
+ case WifiChip::VoipMode::OFF:
+ mode = wifi_voip_mode::WIFI_VOIP_MODE_OFF;
+ break;
+ default:
+ PLOG(ERROR) << "Error: invalid mode: " << toString(in_mode);
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ return createWifiStatusFromLegacyError(legacy_hal_.lock()->setVoipMode(ifname, mode));
+}
+
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/aidl/default/wifi_chip.h b/wifi/aidl/default/wifi_chip.h
index c6517db..ffd507f 100644
--- a/wifi/aidl/default/wifi_chip.h
+++ b/wifi/aidl/default/wifi_chip.h
@@ -158,6 +158,7 @@
int32_t in_channelCategoryEnableFlag) override;
binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
ndk::ScopedAStatus setMloMode(const ChipMloMode in_mode) override;
+ ndk::ScopedAStatus setVoipMode(const VoipMode in_mode) override;
private:
void invalidateAndRemoveAllIfaces();
@@ -269,6 +270,7 @@
getSupportedRadioCombinationsInternal();
std::pair<WifiChipCapabilities, ndk::ScopedAStatus> getWifiChipCapabilitiesInternal();
ndk::ScopedAStatus setMloModeInternal(const ChipMloMode in_mode);
+ ndk::ScopedAStatus setVoipModeInternal(const VoipMode in_mode);
void retrieveDynamicIfaceCombination();
void setWeakPtr(std::weak_ptr<WifiChip> ptr);
diff --git a/wifi/aidl/default/wifi_legacy_hal.cpp b/wifi/aidl/default/wifi_legacy_hal.cpp
index 209670b..55d6f59 100644
--- a/wifi/aidl/default/wifi_legacy_hal.cpp
+++ b/wifi/aidl/default/wifi_legacy_hal.cpp
@@ -183,10 +183,13 @@
on_rtt_results_internal_callback;
std::function<void(wifi_request_id, unsigned num_results, wifi_rtt_result_v2* rtt_results_v2[])>
on_rtt_results_internal_callback_v2;
+std::function<void(wifi_request_id, unsigned num_results, wifi_rtt_result_v3* rtt_results_v3[])>
+ on_rtt_results_internal_callback_v3;
void invalidateRttResultsCallbacks() {
on_rtt_results_internal_callback = nullptr;
on_rtt_results_internal_callback_v2 = nullptr;
+ on_rtt_results_internal_callback_v3 = nullptr;
};
void onAsyncRttResults(wifi_request_id id, unsigned num_results, wifi_rtt_result* rtt_results[]) {
@@ -206,6 +209,15 @@
}
}
+void onAsyncRttResultsV3(wifi_request_id id, unsigned num_results,
+ wifi_rtt_result_v3* rtt_results_v3[]) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_rtt_results_internal_callback_v3) {
+ on_rtt_results_internal_callback_v3(id, num_results, rtt_results_v3);
+ invalidateRttResultsCallbacks();
+ }
+}
+
// Callbacks for the various NAN operations.
// NOTE: These have very little conversions to perform before invoking the user
// callbacks.
@@ -439,11 +451,82 @@
// Callback to report cached scan results
std::function<void(wifi_cached_scan_report*)> on_cached_scan_results_internal_callback;
void onSyncCachedScanResults(wifi_cached_scan_report* cache_report) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
if (on_cached_scan_results_internal_callback) {
on_cached_scan_results_internal_callback(cache_report);
}
}
+// Callback to be invoked for TWT failure
+std::function<void((wifi_request_id, wifi_twt_error_code error_code))>
+ on_twt_failure_internal_callback;
+void onAsyncTwtError(wifi_request_id id, wifi_twt_error_code error_code) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_twt_failure_internal_callback) {
+ on_twt_failure_internal_callback(id, error_code);
+ }
+}
+
+// Callback to be invoked for TWT session creation
+std::function<void((wifi_request_id, wifi_twt_session twt_session))>
+ on_twt_session_create_internal_callback;
+void onAsyncTwtSessionCreate(wifi_request_id id, wifi_twt_session twt_session) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_twt_session_create_internal_callback) {
+ on_twt_session_create_internal_callback(id, twt_session);
+ }
+}
+
+// Callback to be invoked for TWT session update
+std::function<void((wifi_request_id, wifi_twt_session twt_session))>
+ on_twt_session_update_internal_callback;
+void onAsyncTwtSessionUpdate(wifi_request_id id, wifi_twt_session twt_session) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_twt_session_update_internal_callback) {
+ on_twt_session_update_internal_callback(id, twt_session);
+ }
+}
+
+// Callback to be invoked for TWT session teardown
+std::function<void(
+ (wifi_request_id, int twt_session_id, wifi_twt_teardown_reason_code reason_code))>
+ on_twt_session_teardown_internal_callback;
+void onAsyncTwtSessionTeardown(wifi_request_id id, int twt_session_id,
+ wifi_twt_teardown_reason_code reason_code) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_twt_session_teardown_internal_callback) {
+ on_twt_session_teardown_internal_callback(id, twt_session_id, reason_code);
+ }
+}
+
+// Callback to be invoked for TWT session get stats
+std::function<void((wifi_request_id, int twt_session_id, wifi_twt_session_stats stats))>
+ on_twt_session_stats_internal_callback;
+void onAsyncTwtSessionStats(wifi_request_id id, int twt_session_id, wifi_twt_session_stats stats) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_twt_session_stats_internal_callback) {
+ on_twt_session_stats_internal_callback(id, twt_session_id, stats);
+ }
+}
+
+// Callback to be invoked for TWT session suspend
+std::function<void((wifi_request_id, int twt_session_id))> on_twt_session_suspend_internal_callback;
+void onAsyncTwtSessionSuspend(wifi_request_id id, int twt_session_id) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_twt_session_suspend_internal_callback) {
+ on_twt_session_suspend_internal_callback(id, twt_session_id);
+ }
+}
+
+// Callback to be invoked for TWT session resume
+std::function<void((wifi_request_id, int twt_session_id))> on_twt_session_resume_internal_callback;
+void onAsyncTwtSessionResume(wifi_request_id id, int twt_session_id) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_twt_session_resume_internal_callback) {
+ on_twt_session_resume_internal_callback(id, twt_session_id);
+ }
+}
+
// End of the free-standing "C" style callbacks.
WifiLegacyHal::WifiLegacyHal(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
@@ -1251,6 +1334,38 @@
return status;
}
+wifi_error WifiLegacyHal::startRttRangeRequestV3(
+ const std::string& iface_name, wifi_request_id id,
+ const std::vector<wifi_rtt_config_v3>& rtt_configs,
+ const on_rtt_results_callback_v3& on_results_user_callback_v3) {
+ if (on_rtt_results_internal_callback_v3) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+
+ on_rtt_results_internal_callback_v3 = [on_results_user_callback_v3](
+ wifi_request_id id, unsigned num_results,
+ wifi_rtt_result_v3* rtt_results_v3[]) {
+ if (num_results > 0 && !rtt_results_v3) {
+ LOG(ERROR) << "Unexpected nullptr in RTT v3 results";
+ return;
+ }
+ std::vector<const wifi_rtt_result_v3*> rtt_results_vec_v3;
+ std::copy_if(rtt_results_v3, rtt_results_v3 + num_results,
+ back_inserter(rtt_results_vec_v3),
+ [](wifi_rtt_result_v3* rtt_result_v3) { return rtt_result_v3 != nullptr; });
+ on_results_user_callback_v3(id, rtt_results_vec_v3);
+ };
+
+ std::vector<wifi_rtt_config_v3> rtt_configs_internal(rtt_configs);
+ wifi_error status = global_func_table_.wifi_rtt_range_request_v3(
+ id, getIfaceHandle(iface_name), rtt_configs.size(), rtt_configs_internal.data(),
+ {onAsyncRttResultsV3});
+ if (status != WIFI_SUCCESS) {
+ invalidateRttResultsCallbacks();
+ }
+ return status;
+}
+
wifi_error WifiLegacyHal::startRttRangeRequest(
const std::string& iface_name, wifi_request_id id,
const std::vector<wifi_rtt_config>& rtt_configs,
@@ -1327,6 +1442,14 @@
return {status, rtt_caps};
}
+std::pair<wifi_error, wifi_rtt_capabilities_v3> WifiLegacyHal::getRttCapabilitiesV3(
+ const std::string& iface_name) {
+ wifi_rtt_capabilities_v3 rtt_caps_v3;
+ wifi_error status = global_func_table_.wifi_get_rtt_capabilities_v3(getIfaceHandle(iface_name),
+ &rtt_caps_v3);
+ return {status, rtt_caps_v3};
+}
+
std::pair<wifi_error, wifi_rtt_responder> WifiLegacyHal::getRttResponderInfo(
const std::string& iface_name) {
wifi_rtt_responder rtt_responder;
@@ -1736,6 +1859,103 @@
return global_func_table_.wifi_set_voip_mode(getIfaceHandle(iface_name), mode);
}
+std::pair<wifi_twt_capabilities, wifi_error> WifiLegacyHal::twtGetCapabilities(
+ const std::string& ifaceName) {
+ wifi_twt_capabilities capabs = {};
+ wifi_error status =
+ global_func_table_.wifi_twt_get_capabilities(getIfaceHandle(ifaceName), &capabs);
+ return {capabs, status};
+}
+
+wifi_error WifiLegacyHal::twtSessionSetup(
+ const std::string& ifaceName, uint32_t cmdId, const wifi_twt_request& request,
+ const on_twt_failure& on_twt_failure_user_callback,
+ const on_twt_session_create& on_twt_session_create_user_callback,
+ const on_twt_session_update& on_twt_session_update_user_callback,
+ const on_twt_session_teardown& on_twt_session_teardown_user_callback,
+ const on_twt_session_stats& on_twt_session_stats_user_callback,
+ const on_twt_session_suspend& on_twt_session_suspend_user_callback,
+ const on_twt_session_resume& on_twt_session_resume_user_callback) {
+ if (on_twt_failure_internal_callback || on_twt_session_create_internal_callback ||
+ on_twt_session_update_internal_callback || on_twt_session_teardown_internal_callback ||
+ on_twt_session_stats_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+
+ on_twt_failure_internal_callback = [on_twt_failure_user_callback](
+ wifi_request_id id, wifi_twt_error_code error_code) {
+ on_twt_failure_user_callback(id, error_code);
+ };
+
+ on_twt_session_create_internal_callback = [on_twt_session_create_user_callback](
+ wifi_request_id id,
+ wifi_twt_session twt_session) {
+ on_twt_session_create_user_callback(id, twt_session);
+ };
+
+ on_twt_session_update_internal_callback = [on_twt_session_update_user_callback](
+ wifi_request_id id,
+ wifi_twt_session twt_session) {
+ on_twt_session_update_user_callback(id, twt_session);
+ };
+
+ on_twt_session_teardown_internal_callback = [on_twt_session_teardown_user_callback](
+ wifi_request_id id, int session_id,
+ wifi_twt_teardown_reason_code reason_code) {
+ on_twt_session_teardown_user_callback(id, session_id, reason_code);
+ };
+
+ on_twt_session_stats_internal_callback = [on_twt_session_stats_user_callback](
+ wifi_request_id id, int session_id,
+ wifi_twt_session_stats stats) {
+ on_twt_session_stats_user_callback(id, session_id, stats);
+ };
+
+ on_twt_session_suspend_internal_callback = [on_twt_session_suspend_user_callback](
+ wifi_request_id id, int session_id) {
+ on_twt_session_suspend_user_callback(id, session_id);
+ };
+
+ on_twt_session_resume_internal_callback = [on_twt_session_resume_user_callback](
+ wifi_request_id id, int session_id) {
+ on_twt_session_resume_user_callback(id, session_id);
+ };
+
+ return global_func_table_.wifi_twt_session_setup(
+ cmdId, getIfaceHandle(ifaceName), request,
+ {onAsyncTwtError, onAsyncTwtSessionCreate, onAsyncTwtSessionUpdate,
+ onAsyncTwtSessionTeardown, onAsyncTwtSessionStats, onAsyncTwtSessionSuspend,
+ onAsyncTwtSessionResume});
+}
+
+wifi_error WifiLegacyHal::twtSessionUpdate(const std::string& ifaceName, uint32_t cmdId,
+ uint32_t sessionId, const wifi_twt_request& request) {
+ return global_func_table_.wifi_twt_session_update(cmdId, getIfaceHandle(ifaceName), sessionId,
+ request);
+}
+
+wifi_error WifiLegacyHal::twtSessionSuspend(const std::string& ifaceName, uint32_t cmdId,
+ uint32_t sessionId) {
+ return global_func_table_.wifi_twt_session_suspend(cmdId, getIfaceHandle(ifaceName), sessionId);
+}
+
+wifi_error WifiLegacyHal::twtSessionResume(const std::string& ifaceName, uint32_t cmdId,
+ uint32_t sessionId) {
+ return global_func_table_.wifi_twt_session_resume(cmdId, getIfaceHandle(ifaceName), sessionId);
+}
+
+wifi_error WifiLegacyHal::twtSessionTeardown(const std::string& ifaceName, uint32_t cmdId,
+ uint32_t sessionId) {
+ return global_func_table_.wifi_twt_session_teardown(cmdId, getIfaceHandle(ifaceName),
+ sessionId);
+}
+
+wifi_error WifiLegacyHal::twtSessionGetStats(const std::string& ifaceName, uint32_t cmdId,
+ uint32_t sessionId) {
+ return global_func_table_.wifi_twt_session_get_stats(cmdId, getIfaceHandle(ifaceName),
+ sessionId);
+}
+
wifi_error WifiLegacyHal::twtRegisterHandler(const std::string& iface_name,
const TwtCallbackHandlers& user_callbacks) {
on_twt_event_setup_response_callback = user_callbacks.on_setup_response;
@@ -1858,13 +2078,16 @@
return global_func_table_.wifi_enable_tx_power_limits(getIfaceHandle(iface_name), enable);
}
-wifi_error WifiLegacyHal::getWifiCachedScanResults(
- const std::string& iface_name, const CachedScanResultsCallbackHandlers& handler) {
- on_cached_scan_results_internal_callback = handler.on_cached_scan_results;
-
+wifi_error WifiLegacyHal::getWifiCachedScanResults(const std::string& iface_name,
+ WifiCachedScanReport& report) {
+ on_cached_scan_results_internal_callback = [&report](wifi_cached_scan_report* report_ptr) {
+ report.results.assign(report_ptr->results, report_ptr->results + report_ptr->result_cnt);
+ report.scanned_freqs.assign(report_ptr->scanned_freq_list,
+ report_ptr->scanned_freq_list + report_ptr->scanned_freq_num);
+ report.ts = report_ptr->ts;
+ };
wifi_error status = global_func_table_.wifi_get_cached_scan_results(getIfaceHandle(iface_name),
{onSyncCachedScanResults});
-
on_cached_scan_results_internal_callback = nullptr;
return status;
}
@@ -1934,6 +2157,7 @@
on_twt_event_info_frame_received_callback = nullptr;
on_twt_event_device_notify_callback = nullptr;
on_chre_nan_rtt_internal_callback = nullptr;
+ on_cached_scan_results_internal_callback = nullptr;
}
} // namespace legacy_hal
diff --git a/wifi/aidl/default/wifi_legacy_hal.h b/wifi/aidl/default/wifi_legacy_hal.h
index 5168a8b..121d1b5 100644
--- a/wifi/aidl/default/wifi_legacy_hal.h
+++ b/wifi/aidl/default/wifi_legacy_hal.h
@@ -186,6 +186,7 @@
using ::NanTxType;
using ::NpkSecurityAssociation;
using ::PASN;
+using ::ROAMING_AGGRESSIVE;
using ::ROAMING_DISABLE;
using ::ROAMING_ENABLE;
using ::RTT_PEER_AP;
@@ -214,6 +215,8 @@
using ::RTT_STATUS_SUCCESS;
using ::RTT_TYPE_1_SIDED;
using ::RTT_TYPE_2_SIDED;
+using ::RTT_TYPE_2_SIDED_11AZ_NTB;
+using ::RTT_TYPE_2_SIDED_11MC;
using ::RX_PKT_FATE_DRV_DROP_FILTER;
using ::RX_PKT_FATE_DRV_DROP_INVALID;
using ::RX_PKT_FATE_DRV_DROP_NOBUFS;
@@ -256,6 +259,7 @@
using ::WIFI_BAND_BG;
using ::WIFI_BAND_UNSPECIFIED;
using ::wifi_cached_scan_report;
+using ::wifi_cached_scan_result;
using ::wifi_cached_scan_results;
using ::WIFI_CHAN_WIDTH_10;
using ::WIFI_CHAN_WIDTH_160;
@@ -349,16 +353,20 @@
using ::WIFI_RTT_BW_80;
using ::WIFI_RTT_BW_UNSPECIFIED;
using ::wifi_rtt_capabilities;
+using ::wifi_rtt_capabilities_v3;
using ::wifi_rtt_config;
+using ::wifi_rtt_config_v3;
using ::wifi_rtt_preamble;
using ::WIFI_RTT_PREAMBLE_EHT;
using ::WIFI_RTT_PREAMBLE_HE;
using ::WIFI_RTT_PREAMBLE_HT;
+using ::WIFI_RTT_PREAMBLE_INVALID;
using ::WIFI_RTT_PREAMBLE_LEGACY;
using ::WIFI_RTT_PREAMBLE_VHT;
using ::wifi_rtt_responder;
using ::wifi_rtt_result;
using ::wifi_rtt_result_v2;
+using ::wifi_rtt_result_v3;
using ::wifi_rtt_status;
using ::wifi_rtt_type;
using ::wifi_rx_packet_fate;
@@ -368,6 +376,13 @@
using ::WIFI_SCAN_FLAG_INTERRUPTED;
using ::wifi_scan_result;
using ::WIFI_SUCCESS;
+using ::wifi_twt_capabilities;
+using ::wifi_twt_error_code;
+using ::wifi_twt_events;
+using ::wifi_twt_request;
+using ::wifi_twt_session;
+using ::wifi_twt_session_stats;
+using ::wifi_twt_teardown_reason_code;
using ::wifi_tx_packet_fate;
using ::wifi_tx_report;
using ::wifi_usable_channel;
@@ -422,6 +437,12 @@
bool valid;
};
+struct WifiCachedScanReport {
+ uint64_t ts;
+ std::vector<int> scanned_freqs;
+ std::vector<wifi_cached_scan_result> results;
+};
+
#pragma GCC diagnostic pop
// The |WLAN_DRIVER_WAKE_REASON_CNT.cmd_event_wake_cnt| and
@@ -485,6 +506,8 @@
std::function<void(wifi_request_id, const std::vector<const wifi_rtt_result*>&)>;
using on_rtt_results_callback_v2 =
std::function<void(wifi_request_id, const std::vector<const wifi_rtt_result_v2*>&)>;
+using on_rtt_results_callback_v3 =
+ std::function<void(wifi_request_id, const std::vector<const wifi_rtt_result_v3*>&)>;
// Callback for ring buffer data.
using on_ring_buffer_data_callback = std::function<void(
@@ -532,12 +555,23 @@
std::function<void(chre_nan_rtt_state)> on_wifi_chre_nan_rtt_state;
};
-// Cached Scan Results response and event callbacks struct.
-struct CachedScanResultsCallbackHandlers {
+using on_cached_scan_results_callback = std::function<void(wifi_cached_scan_report*)>;
+
+struct CachedScanResultsCallbfackHandlers {
// Callback for Cached Scan Results
std::function<void(wifi_cached_scan_report*)> on_cached_scan_results;
};
+using on_twt_failure = std::function<void(wifi_request_id id, wifi_twt_error_code error_code)>;
+using on_twt_session_create = std::function<void(wifi_request_id id, wifi_twt_session twt_session)>;
+using on_twt_session_update = std::function<void(wifi_request_id id, wifi_twt_session twt_session)>;
+using on_twt_session_teardown = std::function<void(wifi_request_id id, int session_id,
+ wifi_twt_teardown_reason_code reason_code)>;
+using on_twt_session_stats =
+ std::function<void(wifi_request_id id, int session_id, wifi_twt_session_stats stats)>;
+using on_twt_session_suspend = std::function<void(wifi_request_id id, int session_id)>;
+using on_twt_session_resume = std::function<void(wifi_request_id id, int session_id)>;
+
/**
* Class that encapsulates all legacy HAL interactions.
* This class manages the lifetime of the event loop thread used by legacy HAL.
@@ -659,9 +693,15 @@
const std::vector<wifi_rtt_config>& rtt_configs,
const on_rtt_results_callback& on_results_callback,
const on_rtt_results_callback_v2& on_results_callback_v2);
+ wifi_error startRttRangeRequestV3(const std::string& iface_name, wifi_request_id id,
+ const std::vector<wifi_rtt_config_v3>& rtt_configs,
+ const on_rtt_results_callback_v3& on_results_callback);
+
wifi_error cancelRttRangeRequest(const std::string& iface_name, wifi_request_id id,
const std::vector<std::array<uint8_t, ETH_ALEN>>& mac_addrs);
std::pair<wifi_error, wifi_rtt_capabilities> getRttCapabilities(const std::string& iface_name);
+ std::pair<wifi_error, wifi_rtt_capabilities_v3> getRttCapabilitiesV3(
+ const std::string& iface_name);
std::pair<wifi_error, wifi_rtt_responder> getRttResponderInfo(const std::string& iface_name);
wifi_error enableRttResponder(const std::string& iface_name, wifi_request_id id,
const wifi_channel_info& channel_hint, uint32_t max_duration_secs,
@@ -738,19 +778,39 @@
wifi_error setVoipMode(const std::string& iface_name, wifi_voip_mode mode);
+ // TWT functions
+ std::pair<wifi_twt_capabilities, wifi_error> twtGetCapabilities(const std::string& ifaceName);
+ wifi_error twtSessionSetup(const std::string& ifaceName, uint32_t cmdId,
+ const wifi_twt_request& request,
+ const on_twt_failure& on_twt_failure_user_callback,
+ const on_twt_session_create& on_twt_session_create_user_callback,
+ const on_twt_session_update& on_twt_session_update_user_callback,
+ const on_twt_session_teardown& on_twt_session_teardown_user_callback,
+ const on_twt_session_stats& on_twt_session_stats_user_callback,
+ const on_twt_session_suspend& on_twt_session_suspend_user_callback,
+ const on_twt_session_resume& on_twt_session_resume_user_callback);
+ wifi_error twtSessionUpdate(const std::string& ifaceName, uint32_t cmdId, uint32_t sessionId,
+ const wifi_twt_request& request);
+ wifi_error twtSessionSuspend(const std::string& ifaceName, uint32_t cmdId, uint32_t sessionId);
+ wifi_error twtSessionResume(const std::string& ifaceName, uint32_t cmdId, uint32_t sessionId);
+ wifi_error twtSessionTeardown(const std::string& ifaceName, uint32_t cmdId, uint32_t sessionId);
+ wifi_error twtSessionGetStats(const std::string& ifaceName, uint32_t cmdId, uint32_t sessionId);
+
+ // Note: Following TWT functions are deprecated
+ // Deprecated
wifi_error twtRegisterHandler(const std::string& iface_name,
const TwtCallbackHandlers& handler);
-
+ // Deprecated by twtGetCapabilities
std::pair<wifi_error, TwtCapabilitySet> twtGetCapability(const std::string& iface_name);
-
+ // Deprecated by twtSessionSetup
wifi_error twtSetupRequest(const std::string& iface_name, const TwtSetupRequest& msg);
-
+ // Deprecated by twtSessionTeardown
wifi_error twtTearDownRequest(const std::string& iface_name, const TwtTeardownRequest& msg);
-
+ // Deprecated by twtSessionSuspend and twtSessionResume
wifi_error twtInfoFrameRequest(const std::string& iface_name, const TwtInfoFrameRequest& msg);
-
+ // Deprecated by twtSessionGetStats
std::pair<wifi_error, TwtStats> twtGetStats(const std::string& iface_name, uint8_t configId);
-
+ // Deprecated
wifi_error twtClearStats(const std::string& iface_name, uint8_t configId);
wifi_error setScanMode(const std::string& iface_name, bool enable);
@@ -776,7 +836,7 @@
wifi_error enableWifiTxPowerLimits(const std::string& iface_name, bool enable);
wifi_error getWifiCachedScanResults(const std::string& iface_name,
- const CachedScanResultsCallbackHandlers& handler);
+ WifiCachedScanReport& report);
std::pair<wifi_error, wifi_chip_capabilities> getWifiChipCapabilities();
wifi_error enableStaChannelForPeerNetwork(uint32_t channelCategoryEnableFlag);
wifi_error setMloMode(wifi_mlo_mode mode);
diff --git a/wifi/aidl/default/wifi_legacy_hal_stubs.cpp b/wifi/aidl/default/wifi_legacy_hal_stubs.cpp
index b5196c9..3e4afd0 100644
--- a/wifi/aidl/default/wifi_legacy_hal_stubs.cpp
+++ b/wifi/aidl/default/wifi_legacy_hal_stubs.cpp
@@ -179,6 +179,15 @@
populateStubFor(&hal_fn->wifi_set_scan_mode);
populateStubFor(&hal_fn->wifi_set_mlo_mode);
populateStubFor(&hal_fn->wifi_get_supported_iface_concurrency_matrix);
+ populateStubFor(&hal_fn->wifi_get_rtt_capabilities_v3);
+ populateStubFor(&hal_fn->wifi_rtt_range_request_v3);
+ populateStubFor(&hal_fn->wifi_twt_get_capabilities);
+ populateStubFor(&hal_fn->wifi_twt_session_setup);
+ populateStubFor(&hal_fn->wifi_twt_session_update);
+ populateStubFor(&hal_fn->wifi_twt_session_suspend);
+ populateStubFor(&hal_fn->wifi_twt_session_resume);
+ populateStubFor(&hal_fn->wifi_twt_session_teardown);
+ populateStubFor(&hal_fn->wifi_twt_session_get_stats);
return true;
}
diff --git a/wifi/aidl/default/wifi_rtt_controller.cpp b/wifi/aidl/default/wifi_rtt_controller.cpp
index a5f6768..9dee45c 100644
--- a/wifi/aidl/default/wifi_rtt_controller.cpp
+++ b/wifi/aidl/default/wifi_rtt_controller.cpp
@@ -136,11 +136,45 @@
ndk::ScopedAStatus WifiRttController::rangeRequestInternal(
int32_t cmd_id, const std::vector<RttConfig>& rtt_configs) {
+ // Try 11mc & 11az ranging (v3)
+ std::vector<legacy_hal::wifi_rtt_config_v3> legacy_configs_v3;
+ if (!aidl_struct_util::convertAidlVectorOfRttConfigToLegacyV3(rtt_configs,
+ &legacy_configs_v3)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ std::weak_ptr<WifiRttController> weak_ptr_this = weak_ptr_this_;
+ const auto& on_results_callback_v3 =
+ [weak_ptr_this](legacy_hal::wifi_request_id id,
+ const std::vector<const legacy_hal::wifi_rtt_result_v3*>& results) {
+ const auto shared_ptr_this = weak_ptr_this.lock();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "v3 Callback invoked on an invalid object";
+ return;
+ }
+ std::vector<RttResult> aidl_results;
+ if (!aidl_struct_util::convertLegacyVectorOfRttResultV3ToAidl(results,
+ &aidl_results)) {
+ LOG(ERROR) << "Failed to convert rtt results v3 to AIDL structs";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onResults(id, aidl_results).isOk()) {
+ LOG(ERROR) << "Failed to invoke the v3 callback";
+ }
+ }
+ };
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRttRangeRequestV3(
+ ifname_, cmd_id, legacy_configs_v3, on_results_callback_v3);
+
+ if (legacy_status != legacy_hal::WIFI_ERROR_NOT_SUPPORTED) {
+ return createWifiStatusFromLegacyError(legacy_status);
+ }
+
+ // Fallback to 11mc ranging.
std::vector<legacy_hal::wifi_rtt_config> legacy_configs;
if (!aidl_struct_util::convertAidlVectorOfRttConfigToLegacy(rtt_configs, &legacy_configs)) {
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
}
- std::weak_ptr<WifiRttController> weak_ptr_this = weak_ptr_this_;
const auto& on_results_callback =
[weak_ptr_this](legacy_hal::wifi_request_id id,
const std::vector<const legacy_hal::wifi_rtt_result*>& results) {
@@ -181,7 +215,7 @@
}
}
};
- legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRttRangeRequest(
+ legacy_status = legacy_hal_.lock()->startRttRangeRequest(
ifname_, cmd_id, legacy_configs, on_results_callback, on_results_callback_v2);
return createWifiStatusFromLegacyError(legacy_status);
}
@@ -201,13 +235,29 @@
std::pair<RttCapabilities, ndk::ScopedAStatus> WifiRttController::getCapabilitiesInternal() {
legacy_hal::wifi_error legacy_status;
- legacy_hal::wifi_rtt_capabilities legacy_caps;
- std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getRttCapabilities(ifname_);
+ legacy_hal::wifi_rtt_capabilities_v3 legacy_caps_v3;
+ std::tie(legacy_status, legacy_caps_v3) = legacy_hal_.lock()->getRttCapabilitiesV3(ifname_);
+ // Try v3 API first, if it is not supported fallback.
+ if (legacy_status == legacy_hal::WIFI_ERROR_NOT_SUPPORTED) {
+ legacy_hal::wifi_rtt_capabilities legacy_caps;
+ std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getRttCapabilities(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {RttCapabilities{}, createWifiStatusFromLegacyError(legacy_status)};
+ }
+
+ RttCapabilities aidl_caps;
+ if (!aidl_struct_util::convertLegacyRttCapabilitiesToAidl(legacy_caps, &aidl_caps)) {
+ return {RttCapabilities{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
+ return {aidl_caps, ndk::ScopedAStatus::ok()};
+ }
+
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
return {RttCapabilities{}, createWifiStatusFromLegacyError(legacy_status)};
}
+
RttCapabilities aidl_caps;
- if (!aidl_struct_util::convertLegacyRttCapabilitiesToAidl(legacy_caps, &aidl_caps)) {
+ if (!aidl_struct_util::convertLegacyRttCapabilitiesV3ToAidl(legacy_caps_v3, &aidl_caps)) {
return {RttCapabilities{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
}
return {aidl_caps, ndk::ScopedAStatus::ok()};
diff --git a/wifi/aidl/default/wifi_sta_iface.cpp b/wifi/aidl/default/wifi_sta_iface.cpp
index 800813f..f0509dc 100644
--- a/wifi/aidl/default/wifi_sta_iface.cpp
+++ b/wifi/aidl/default/wifi_sta_iface.cpp
@@ -219,6 +219,49 @@
&WifiStaIface::setDtimMultiplierInternal, in_multiplier);
}
+ndk::ScopedAStatus WifiStaIface::getCachedScanData(CachedScanData* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getCachedScanDataInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtGetCapabilities(TwtCapabilities* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::twtGetCapabilitiesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionSetup(int32_t in_cmdId,
+ const TwtRequest& in_twtRequest) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::twtSessionSetupInternal, in_cmdId, in_twtRequest);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionUpdate(int32_t in_cmdId, int32_t in_sessionId,
+ const TwtRequest& in_twtRequest) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::twtSessionUpdateInternal, in_cmdId, in_sessionId,
+ in_twtRequest);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionSuspend(int32_t in_cmdId, int32_t in_sessionId) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::twtSessionSuspendInternal, in_cmdId, in_sessionId);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionResume(int32_t in_cmdId, int32_t in_sessionId) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::twtSessionResumeInternal, in_cmdId, in_sessionId);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionTeardown(int32_t in_cmdId, int32_t in_sessionId) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::twtSessionTeardownInternal, in_cmdId, in_sessionId);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionGetStats(int32_t in_cmdId, int32_t in_sessionId) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::twtSessionGetStatsInternal, in_cmdId, in_sessionId);
+}
+
std::pair<std::string, ndk::ScopedAStatus> WifiStaIface::getNameInternal() {
return {ifname_, ndk::ScopedAStatus::ok()};
}
@@ -540,6 +583,209 @@
return createWifiStatusFromLegacyError(legacy_status);
}
+std::pair<CachedScanData, ndk::ScopedAStatus> WifiStaIface::getCachedScanDataInternal() {
+ legacy_hal::WifiCachedScanReport cached_scan_report;
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->getWifiCachedScanResults(ifname_, cached_scan_report);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {CachedScanData{}, createWifiStatusFromLegacyError(legacy_status)};
+ }
+ CachedScanData aidl_scan_data;
+ if (!aidl_struct_util::convertCachedScanReportToAidl(cached_scan_report, &aidl_scan_data)) {
+ return {CachedScanData{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
+
+ return {aidl_scan_data, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<TwtCapabilities, ndk::ScopedAStatus> WifiStaIface::twtGetCapabilitiesInternal() {
+ legacy_hal::wifi_twt_capabilities legacyHaltwtCapabilities;
+ legacy_hal::wifi_error legacy_status;
+ std::tie(legacyHaltwtCapabilities, legacy_status) =
+ legacy_hal_.lock()->twtGetCapabilities(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {TwtCapabilities{}, createWifiStatusFromLegacyError(legacy_status)};
+ }
+ TwtCapabilities aidlTwtCapabilities;
+ if (!aidl_struct_util::convertTwtCapabilitiesToAidl(legacyHaltwtCapabilities,
+ &aidlTwtCapabilities)) {
+ return {TwtCapabilities{}, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
+ }
+ return {aidlTwtCapabilities, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionSetupInternal(int32_t cmdId,
+ const TwtRequest& aidlTwtRequest) {
+ legacy_hal::wifi_twt_request legacyHalTwtRequest;
+ if (!aidl_struct_util::convertAidlTwtRequestToLegacy(aidlTwtRequest, &legacyHalTwtRequest)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ std::weak_ptr<WifiStaIface> weak_ptr_this = weak_ptr_this_;
+
+ // onTwtFailure callback
+ const auto& on_twt_failure = [weak_ptr_this](legacy_hal::wifi_request_id id,
+ legacy_hal::wifi_twt_error_code error_code) {
+ const auto shared_ptr_this = weak_ptr_this.lock();
+ IWifiStaIfaceEventCallback::TwtErrorCode aidl_error_code =
+ aidl_struct_util::convertLegacyHalTwtErrorCodeToAidl(error_code);
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onTwtFailure(id, aidl_error_code).isOk()) {
+ LOG(ERROR) << "Failed to invoke onTwtFailure callback";
+ }
+ }
+ };
+ // onTwtSessionCreate callback
+ const auto& on_twt_session_create = [weak_ptr_this](legacy_hal::wifi_request_id id,
+ legacy_hal::wifi_twt_session twt_session) {
+ const auto shared_ptr_this = weak_ptr_this.lock();
+ TwtSession aidl_twt_session;
+ if (!aidl_struct_util::convertLegacyHalTwtSessionToAidl(twt_session, &aidl_twt_session)) {
+ LOG(ERROR) << "convertLegacyHalTwtSessionToAidl failed";
+ return;
+ }
+
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onTwtSessionCreate(id, aidl_twt_session).isOk()) {
+ LOG(ERROR) << "Failed to invoke onTwtSessionCreate callback";
+ }
+ }
+ };
+ // onTwtSessionUpdate callback
+ const auto& on_twt_session_update = [weak_ptr_this](legacy_hal::wifi_request_id id,
+ legacy_hal::wifi_twt_session twt_session) {
+ const auto shared_ptr_this = weak_ptr_this.lock();
+ TwtSession aidl_twt_session;
+ if (!aidl_struct_util::convertLegacyHalTwtSessionToAidl(twt_session, &aidl_twt_session)) {
+ LOG(ERROR) << "convertLegacyHalTwtSessionToAidl failed";
+ return;
+ }
+
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onTwtSessionUpdate(id, aidl_twt_session).isOk()) {
+ LOG(ERROR) << "Failed to invoke onTwtSessionUpdate callback";
+ }
+ }
+ };
+ // onTwtSessionTeardown callback
+ const auto& on_twt_session_teardown =
+ [weak_ptr_this](legacy_hal::wifi_request_id id, int session_id,
+ legacy_hal::wifi_twt_teardown_reason_code reason_code) {
+ const auto shared_ptr_this = weak_ptr_this.lock();
+ IWifiStaIfaceEventCallback::TwtTeardownReasonCode aidl_reason_code =
+ aidl_struct_util::convertLegacyHalTwtReasonCodeToAidl(reason_code);
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onTwtSessionTeardown(id, session_id, aidl_reason_code).isOk()) {
+ LOG(ERROR) << "Failed to invoke onTwtSessionTeardown callback";
+ }
+ }
+ };
+ // onTwtSessionStats callback
+ const auto& on_twt_session_stats = [weak_ptr_this](legacy_hal::wifi_request_id id,
+ int session_id,
+ legacy_hal::wifi_twt_session_stats stats) {
+ const auto shared_ptr_this = weak_ptr_this.lock();
+ TwtSessionStats aidl_session_stats;
+ if (!aidl_struct_util::convertLegacyHalTwtSessionStatsToAidl(stats, &aidl_session_stats)) {
+ LOG(ERROR) << "convertLegacyHalTwtSessionStatsToAidl failed";
+ return;
+ }
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onTwtSessionStats(id, session_id, aidl_session_stats).isOk()) {
+ LOG(ERROR) << "Failed to invoke onTwtSessionStats callback";
+ }
+ }
+ };
+ // onTwtSessionSuspend callback
+ const auto& on_twt_session_suspend = [weak_ptr_this](legacy_hal::wifi_request_id id,
+ int session_id) {
+ const auto shared_ptr_this = weak_ptr_this.lock();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onTwtSessionSuspend(id, session_id).isOk()) {
+ LOG(ERROR) << "Failed to invoke onTwtSessionSuspend callback";
+ }
+ }
+ };
+ // onTwtSessionResume callback
+ const auto& on_twt_session_resume = [weak_ptr_this](legacy_hal::wifi_request_id id,
+ int session_id) {
+ const auto shared_ptr_this = weak_ptr_this.lock();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onTwtSessionResume(id, session_id).isOk()) {
+ LOG(ERROR) << "Failed to invoke onTwtSessionResume callback";
+ }
+ }
+ };
+
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->twtSessionSetup(
+ ifname_, cmdId, legacyHalTwtRequest, on_twt_failure, on_twt_session_create,
+ on_twt_session_update, on_twt_session_teardown, on_twt_session_stats,
+ on_twt_session_suspend, on_twt_session_resume);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionUpdateInternal(int32_t cmdId, int32_t sessionId,
+ const TwtRequest& aidlTwtRequest) {
+ legacy_hal::wifi_twt_request legacyHalTwtRequest;
+ if (!aidl_struct_util::convertAidlTwtRequestToLegacy(aidlTwtRequest, &legacyHalTwtRequest)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->twtSessionUpdate(ifname_, cmdId, sessionId, legacyHalTwtRequest);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionSuspendInternal(int32_t cmdId, int32_t sessionId) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->twtSessionSuspend(ifname_, cmdId, sessionId);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionResumeInternal(int32_t cmdId, int32_t sessionId) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->twtSessionResume(ifname_, cmdId, sessionId);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionTeardownInternal(int32_t cmdId, int32_t sessionId) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->twtSessionTeardown(ifname_, cmdId, sessionId);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionGetStatsInternal(int32_t cmdId, int32_t sessionId) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->twtSessionGetStats(ifname_, cmdId, sessionId);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/aidl/default/wifi_sta_iface.h b/wifi/aidl/default/wifi_sta_iface.h
index 3d7ec4d..eb8f745 100644
--- a/wifi/aidl/default/wifi_sta_iface.h
+++ b/wifi/aidl/default/wifi_sta_iface.h
@@ -90,6 +90,15 @@
ndk::ScopedAStatus getFactoryMacAddress(std::array<uint8_t, 6>* _aidl_return) override;
ndk::ScopedAStatus setScanMode(bool in_enable) override;
ndk::ScopedAStatus setDtimMultiplier(int32_t in_multiplier) override;
+ ndk::ScopedAStatus getCachedScanData(CachedScanData* _aidl_return) override;
+ ndk::ScopedAStatus twtGetCapabilities(TwtCapabilities* _aidl_return) override;
+ ndk::ScopedAStatus twtSessionSetup(int in_cmdId, const TwtRequest& in_twtRequest) override;
+ ndk::ScopedAStatus twtSessionUpdate(int in_cmdId, int32_t in_sessionId,
+ const TwtRequest& in_twtRequest) override;
+ ndk::ScopedAStatus twtSessionSuspend(int in_cmdId, int32_t in_sessionId) override;
+ ndk::ScopedAStatus twtSessionResume(int in_cmdId, int32_t in_sessionId) override;
+ ndk::ScopedAStatus twtSessionTeardown(int in_cmdId, int32_t in_sessionId) override;
+ ndk::ScopedAStatus twtSessionGetStats(int in_cmdId, int32_t in_sessionId) override;
private:
// Corresponding worker functions for the AIDL methods.
@@ -130,6 +139,15 @@
std::pair<std::array<uint8_t, 6>, ndk::ScopedAStatus> getFactoryMacAddressInternal();
ndk::ScopedAStatus setScanModeInternal(bool enable);
ndk::ScopedAStatus setDtimMultiplierInternal(const int multiplier);
+ std::pair<CachedScanData, ndk::ScopedAStatus> getCachedScanDataInternal();
+ std::pair<TwtCapabilities, ndk::ScopedAStatus> twtGetCapabilitiesInternal();
+ ndk::ScopedAStatus twtSessionSetupInternal(int cmdId, const TwtRequest& twtRequest);
+ ndk::ScopedAStatus twtSessionUpdateInternal(int cmdId, int32_t sessionId,
+ const TwtRequest& twtRequest);
+ ndk::ScopedAStatus twtSessionSuspendInternal(int cmdId, int32_t sessionId);
+ ndk::ScopedAStatus twtSessionResumeInternal(int cmdId, int32_t sessionId);
+ ndk::ScopedAStatus twtSessionTeardownInternal(int cmdId, int32_t sessionId);
+ ndk::ScopedAStatus twtSessionGetStatsInternal(int cmdId, int32_t sessionId);
void setWeakPtr(std::weak_ptr<WifiStaIface> ptr);
diff --git a/wifi/aidl/vts/functional/Android.bp b/wifi/aidl/vts/functional/Android.bp
index 1277182..9994d09 100644
--- a/wifi/aidl/vts/functional/Android.bp
+++ b/wifi/aidl/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -39,7 +40,8 @@
],
static_libs: [
"VtsHalWifiTargetTestUtil",
- "android.hardware.wifi-V1-ndk",
+ "android.hardware.wifi.common-V1-ndk",
+ "android.hardware.wifi-V2-ndk",
"libwifi-system-iface",
],
test_suites: [
@@ -64,7 +66,8 @@
],
static_libs: [
"VtsHalWifiTargetTestUtil",
- "android.hardware.wifi-V1-ndk",
+ "android.hardware.wifi.common-V1-ndk",
+ "android.hardware.wifi-V2-ndk",
"libwifi-system-iface",
],
test_suites: [
@@ -89,7 +92,8 @@
],
static_libs: [
"VtsHalWifiTargetTestUtil",
- "android.hardware.wifi-V1-ndk",
+ "android.hardware.wifi.common-V1-ndk",
+ "android.hardware.wifi-V2-ndk",
"libwifi-system-iface",
],
test_suites: [
@@ -114,7 +118,8 @@
],
static_libs: [
"VtsHalWifiTargetTestUtil",
- "android.hardware.wifi-V1-ndk",
+ "android.hardware.wifi.common-V1-ndk",
+ "android.hardware.wifi-V2-ndk",
"libwifi-system-iface",
],
test_suites: [
@@ -139,7 +144,8 @@
],
static_libs: [
"VtsHalWifiTargetTestUtil",
- "android.hardware.wifi-V1-ndk",
+ "android.hardware.wifi.common-V1-ndk",
+ "android.hardware.wifi-V2-ndk",
"libwifi-system-iface",
],
test_suites: [
@@ -163,7 +169,8 @@
"libnativehelper",
],
static_libs: [
- "android.hardware.wifi-V1-ndk",
+ "android.hardware.wifi.common-V1-ndk",
+ "android.hardware.wifi-V2-ndk",
"libwifi-system-iface",
],
}
diff --git a/wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp
index 740f833..a1b9ce1 100644
--- a/wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp
+++ b/wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp
@@ -872,6 +872,36 @@
EXPECT_EQ(instances_after_remove.size(), 1);
}
+/*
+ * SetVoipMode_off
+ * Tests the setVoipMode() API with VoIP mode OFF.
+ */
+TEST_P(WifiChipAidlTest, SetVoipMode_off) {
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+ int32_t features = getChipFeatureSet(wifi_chip_);
+ if (features & static_cast<int32_t>(IWifiChip::FeatureSetMask::SET_VOIP_MODE)) {
+ auto status = wifi_chip_->setVoipMode(IWifiChip::VoipMode::OFF);
+ EXPECT_TRUE(status.isOk());
+ } else {
+ GTEST_SKIP() << "setVoipMode() is not supported by vendor.";
+ }
+}
+
+/*
+ * SetVoipMode_voice
+ * Tests the setVoipMode() API with VoIP mode VOICE.
+ */
+TEST_P(WifiChipAidlTest, SetVoipMode_voice) {
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+ int32_t features = getChipFeatureSet(wifi_chip_);
+ if (features & static_cast<int32_t>(IWifiChip::FeatureSetMask::SET_VOIP_MODE)) {
+ auto status = wifi_chip_->setVoipMode(IWifiChip::VoipMode::VOICE);
+ EXPECT_TRUE(status.isOk());
+ } else {
+ GTEST_SKIP() << "setVoipMode() is not supported by vendor.";
+ }
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipAidlTest);
INSTANTIATE_TEST_SUITE_P(WifiTest, WifiChipAidlTest,
testing::ValuesIn(android::getAidlHalInstanceNames(IWifi::descriptor)),
diff --git a/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
index 1ea1237..e456e49 100644
--- a/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
+++ b/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
@@ -69,21 +69,22 @@
std::shared_ptr<IWifiStaIface> wifi_sta_iface_;
- // Checks if the MdnsOffloadManagerService is installed.
- bool isMdnsOffloadServicePresent() {
- int status =
- // --query-flags MATCH_SYSTEM_ONLY(1048576) will only return matched service
- // installed on system or system_ext partition. The MdnsOffloadManagerService should
- // be installed on system_ext partition.
- // NOLINTNEXTLINE(cert-env33-c)
- system("pm query-services --query-flags 1048576"
- " com.android.tv.mdnsoffloadmanager/"
- "com.android.tv.mdnsoffloadmanager.MdnsOffloadManagerService"
- " | egrep -q mdnsoffloadmanager");
- return status == 0;
+ // Checks if the mDNS Offload is supported by any NIC.
+ bool isMdnsOffloadPresentInNIC() {
+ return testing::deviceSupportsFeature("com.google.android.tv.mdns_offload");
}
- // Detected panel TV device by using ro.oem.key1 property.
+ bool doesDeviceSupportFullNetworkingUnder2w() {
+ return testing::deviceSupportsFeature("com.google.android.tv.full_networking_under_2w");
+ }
+
+ // Detect TV devices.
+ bool isTvDevice() {
+ return testing::deviceSupportsFeature("android.software.leanback") ||
+ testing::deviceSupportsFeature("android.hardware.type.television");
+ }
+
+ // Detect Panel TV devices by using ro.oem.key1 property.
// https://docs.partner.android.com/tv/build/platform/props-vars/ro-oem-key1
bool isPanelTvDevice() {
const std::string oem_key1 = getPropertyString("ro.oem.key1");
@@ -144,10 +145,23 @@
*/
// @VsrTest = 5.3.12
TEST_P(WifiStaIfaceAidlTest, CheckApfIsSupported) {
- // Flat panel TV devices that support MDNS offload do not have to implement APF if the WiFi
- // chipset does not have sufficient RAM to do so.
- if (isPanelTvDevice() && isMdnsOffloadServicePresent()) {
- GTEST_SKIP() << "Panel TV supports mDNS offload. It is not required to support APF";
+ const std::string oem_key1 = getPropertyString("ro.oem.key1");
+ if (isTvDevice()) {
+ // Flat panel TV devices that support MDNS offload do not have to implement APF if the WiFi
+ // chipset does not have sufficient RAM to do so.
+ if (isPanelTvDevice() && isMdnsOffloadPresentInNIC()) {
+ GTEST_SKIP() << "Panel TV supports mDNS offload. It is not required to support APF";
+ }
+ // For TV devices declaring the
+ // com.google.android.tv.full_networking_under_2w feature, this indicates
+ // the device can meet the <= 2W standby power requirement while
+ // continuously processing network packets on the CPU, even in standby mode.
+ // In these cases, APF support is strongly recommended rather than being
+ // mandatory.
+ if (doesDeviceSupportFullNetworkingUnder2w()) {
+ GTEST_SKIP() << "TV Device meets the <= 2W standby power demand requirement. It is not "
+ "required to support APF.";
+ }
}
int vendor_api_level = property_get_int32("ro.vendor.api_level", 0);
// Before VSR 14, APF support is optional.
diff --git a/wifi/common/aidl/Android.bp b/wifi/common/aidl/Android.bp
index 1913451..a941869 100644
--- a/wifi/common/aidl/Android.bp
+++ b/wifi/common/aidl/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -43,5 +44,8 @@
cpp: {
enabled: false,
},
+ rust: {
+ enabled: false,
+ },
},
}
diff --git a/wifi/hostapd/1.0/Android.bp b/wifi/hostapd/1.0/Android.bp
index afcd45c..38083e7 100644
--- a/wifi/hostapd/1.0/Android.bp
+++ b/wifi/hostapd/1.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -21,4 +22,8 @@
"android.hidl.base@1.0",
],
gen_java: true,
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.wifi",
+ ],
}
diff --git a/wifi/hostapd/1.0/vts/functional/Android.bp b/wifi/hostapd/1.0/vts/functional/Android.bp
index daf5b60..a44ae6d 100644
--- a/wifi/hostapd/1.0/vts/functional/Android.bp
+++ b/wifi/hostapd/1.0/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -28,7 +29,7 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["hostapd_hidl_test_utils.cpp"],
export_include_dirs: [
- "."
+ ".",
],
static_libs: [
"VtsHalWifiV1_0TargetTestUtil",
@@ -57,5 +58,8 @@
"libwifi-system",
"libwifi-system-iface",
],
- test_suites: ["general-tests", "vts"],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
}
diff --git a/wifi/hostapd/1.1/Android.bp b/wifi/hostapd/1.1/Android.bp
index f5f2fbe..27b8079 100644
--- a/wifi/hostapd/1.1/Android.bp
+++ b/wifi/hostapd/1.1/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -22,4 +23,8 @@
"android.hidl.base@1.0",
],
gen_java: true,
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.wifi",
+ ],
}
diff --git a/wifi/hostapd/1.1/vts/functional/Android.bp b/wifi/hostapd/1.1/vts/functional/Android.bp
index 999a6a7..196730e 100644
--- a/wifi/hostapd/1.1/vts/functional/Android.bp
+++ b/wifi/hostapd/1.1/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/wifi/hostapd/1.2/Android.bp b/wifi/hostapd/1.2/Android.bp
index 4ca41aa..15446af 100644
--- a/wifi/hostapd/1.2/Android.bp
+++ b/wifi/hostapd/1.2/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -23,4 +24,8 @@
"android.hidl.base@1.0",
],
gen_java: true,
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.wifi",
+ ],
}
diff --git a/wifi/hostapd/1.2/vts/functional/Android.bp b/wifi/hostapd/1.2/vts/functional/Android.bp
index 26edab5..411110b 100644
--- a/wifi/hostapd/1.2/vts/functional/Android.bp
+++ b/wifi/hostapd/1.2/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/wifi/hostapd/1.3/Android.bp b/wifi/hostapd/1.3/Android.bp
index f75b5e2..5598327 100644
--- a/wifi/hostapd/1.3/Android.bp
+++ b/wifi/hostapd/1.3/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/wifi/hostapd/1.3/vts/functional/Android.bp b/wifi/hostapd/1.3/vts/functional/Android.bp
index 78cd4af..50ecc28 100644
--- a/wifi/hostapd/1.3/vts/functional/Android.bp
+++ b/wifi/hostapd/1.3/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/wifi/hostapd/aidl/Android.bp b/wifi/hostapd/aidl/Android.bp
index 54895c1..94bf9e2 100644
--- a/wifi/hostapd/aidl/Android.bp
+++ b/wifi/hostapd/aidl/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -27,6 +28,9 @@
srcs: [
"android/hardware/wifi/hostapd/*.aidl",
],
+ imports: [
+ "android.hardware.wifi.common-V1",
+ ],
stability: "vintf",
backend: {
java: {
@@ -36,10 +40,19 @@
"com.android.wifi",
],
min_sdk_version: "30",
+ lint: {
+ baseline_filename: "lint-baseline.xml",
+ },
},
ndk: {
gen_trace: true,
},
+ cpp: {
+ enabled: false,
+ },
+ rust: {
+ enabled: false,
+ },
},
versions_with_info: [
{
@@ -47,5 +60,4 @@
imports: [],
},
],
-
}
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/ApInfo.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/ApInfo.aidl
index ca20f37..1a66105 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/ApInfo.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/ApInfo.aidl
@@ -40,4 +40,5 @@
android.hardware.wifi.hostapd.ChannelBandwidth channelBandwidth;
android.hardware.wifi.hostapd.Generation generation;
byte[] apIfaceInstanceMacAddress;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IfaceParams.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IfaceParams.aidl
index 0c88a39..64367bb 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IfaceParams.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IfaceParams.aidl
@@ -37,4 +37,5 @@
String name;
android.hardware.wifi.hostapd.HwModeParams hwModeParams;
android.hardware.wifi.hostapd.ChannelParams[] channelParams;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/ApInfo.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/ApInfo.aidl
index a6fe63b..f2b2ee6 100644
--- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/ApInfo.aidl
+++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/ApInfo.aidl
@@ -16,6 +16,7 @@
package android.hardware.wifi.hostapd;
+import android.hardware.wifi.common.OuiKeyedData;
import android.hardware.wifi.hostapd.ChannelBandwidth;
import android.hardware.wifi.hostapd.Generation;
@@ -57,4 +58,9 @@
* MAC Address of the apIfaceInstance.
*/
byte[] apIfaceInstanceMacAddress;
+
+ /**
+ * Optional vendor-specific information.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IfaceParams.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IfaceParams.aidl
index a8abec3..3f8ee39 100644
--- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IfaceParams.aidl
+++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IfaceParams.aidl
@@ -16,6 +16,7 @@
package android.hardware.wifi.hostapd;
+import android.hardware.wifi.common.OuiKeyedData;
import android.hardware.wifi.hostapd.ChannelParams;
import android.hardware.wifi.hostapd.HwModeParams;
@@ -36,4 +37,8 @@
* The list of the channel params for the dual interfaces.
*/
ChannelParams[] channelParams;
+ /**
+ * Optional vendor-specific configuration parameters.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/hostapd/aidl/lint-baseline.xml b/wifi/hostapd/aidl/lint-baseline.xml
index 657622e..4329e12 100644
--- a/wifi/hostapd/aidl/lint-baseline.xml
+++ b/wifi/hostapd/aidl/lint-baseline.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-dev" type="baseline" dependencies="true" variant="all" version="8.0.0-dev">
+<issues format="6" by="lint 8.4.0-alpha01" type="baseline" client="" dependencies="true" name="" variant="all" version="8.4.0-alpha01">
<issue
id="NewApi"
@@ -7,8 +7,8 @@
errorLine1=" this.markVintfStability();"
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
- file="out/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V1-java-source/gen/android/hardware/wifi/hostapd/IHostapd.java"
- line="55"
+ file="out/soong/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V1-java-source/gen/android/hardware/wifi/hostapd/IHostapd.java"
+ line="57"
column="12"/>
</issue>
@@ -18,8 +18,8 @@
errorLine1=" this.markVintfStability();"
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
- file="out/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V1-java-source/gen/android/hardware/wifi/hostapd/IHostapdCallback.java"
- line="46"
+ file="out/soong/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V1-java-source/gen/android/hardware/wifi/hostapd/IHostapdCallback.java"
+ line="48"
column="12"/>
</issue>
@@ -29,8 +29,8 @@
errorLine1=" this.markVintfStability();"
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
- file="out/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V2-java-source/gen/android/hardware/wifi/hostapd/IHostapd.java"
- line="117"
+ file="out/soong/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V2-java-source/gen/android/hardware/wifi/hostapd/IHostapd.java"
+ line="119"
column="12"/>
</issue>
@@ -40,9 +40,27 @@
errorLine1=" this.markVintfStability();"
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
- file="out/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V2-java-source/gen/android/hardware/wifi/hostapd/IHostapdCallback.java"
- line="62"
+ file="out/soong/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V2-java-source/gen/android/hardware/wifi/hostapd/IHostapdCallback.java"
+ line="64"
column="12"/>
</issue>
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/soong/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V3-java-source/gen/android/hardware/wifi/hostapd/IHostapd.java"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/soong/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V3-java-source/gen/android/hardware/wifi/hostapd/IHostapdCallback.java"/>
+ </issue>
+
</issues>
\ No newline at end of file
diff --git a/wifi/hostapd/aidl/vts/functional/Android.bp b/wifi/hostapd/aidl/vts/functional/Android.bp
index ff35056..9fbbf4b 100644
--- a/wifi/hostapd/aidl/vts/functional/Android.bp
+++ b/wifi/hostapd/aidl/vts/functional/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -36,7 +37,8 @@
"android.hardware.wifi@1.4",
"android.hardware.wifi@1.5",
"android.hardware.wifi@1.6",
- "android.hardware.wifi-V1-ndk",
+ "android.hardware.wifi.common-V1-ndk",
+ "android.hardware.wifi-V2-ndk",
"libwifi-system",
"libwifi-system-iface",
"VtsHalWifiTargetTestUtil",
diff --git a/wifi/netlinkinterceptor/aidl/Android.bp b/wifi/netlinkinterceptor/aidl/Android.bp
index 2f7f34f..8c04e31 100644
--- a/wifi/netlinkinterceptor/aidl/Android.bp
+++ b/wifi/netlinkinterceptor/aidl/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/wifi/netlinkinterceptor/aidl/default/Android.bp b/wifi/netlinkinterceptor/aidl/default/Android.bp
index c3a0c03..6bdd9fc 100644
--- a/wifi/netlinkinterceptor/aidl/default/Android.bp
+++ b/wifi/netlinkinterceptor/aidl/default/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.h b/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.h
index 0178c90..915b5ff 100644
--- a/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.h
+++ b/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.h
@@ -18,6 +18,7 @@
#include <libnl++/Socket.h>
+#include <atomic>
#include <mutex>
#include <thread>
diff --git a/wifi/netlinkinterceptor/libnlinterceptor/Android.bp b/wifi/netlinkinterceptor/libnlinterceptor/Android.bp
index 671cd85..9b278b6 100644
--- a/wifi/netlinkinterceptor/libnlinterceptor/Android.bp
+++ b/wifi/netlinkinterceptor/libnlinterceptor/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/wifi/netlinkinterceptor/vts/functional/Android.bp b/wifi/netlinkinterceptor/vts/functional/Android.bp
index 80608a7..30766c0 100644
--- a/wifi/netlinkinterceptor/vts/functional/Android.bp
+++ b/wifi/netlinkinterceptor/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/wifi/supplicant/1.0/Android.bp b/wifi/supplicant/1.0/Android.bp
index 66e9353..3449e40 100644
--- a/wifi/supplicant/1.0/Android.bp
+++ b/wifi/supplicant/1.0/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -31,4 +32,8 @@
"android.hidl.base@1.0",
],
gen_java: true,
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.wifi",
+ ],
}
diff --git a/wifi/supplicant/1.0/vts/functional/Android.bp b/wifi/supplicant/1.0/vts/functional/Android.bp
index 2d86822..353e57b 100644
--- a/wifi/supplicant/1.0/vts/functional/Android.bp
+++ b/wifi/supplicant/1.0/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/wifi/supplicant/1.1/Android.bp b/wifi/supplicant/1.1/Android.bp
index c624374..e2582e5 100644
--- a/wifi/supplicant/1.1/Android.bp
+++ b/wifi/supplicant/1.1/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -23,4 +24,8 @@
"android.hidl.base@1.0",
],
gen_java: true,
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.wifi",
+ ],
}
diff --git a/wifi/supplicant/1.1/vts/functional/Android.bp b/wifi/supplicant/1.1/vts/functional/Android.bp
index 68cda33..215c1ca 100644
--- a/wifi/supplicant/1.1/vts/functional/Android.bp
+++ b/wifi/supplicant/1.1/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/wifi/supplicant/1.2/Android.bp b/wifi/supplicant/1.2/Android.bp
index d5d937f..c7ce010 100644
--- a/wifi/supplicant/1.2/Android.bp
+++ b/wifi/supplicant/1.2/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -26,4 +27,8 @@
"android.hidl.base@1.0",
],
gen_java: true,
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.wifi",
+ ],
}
diff --git a/wifi/supplicant/1.2/vts/functional/Android.bp b/wifi/supplicant/1.2/vts/functional/Android.bp
index ec3ca22..65a17a8 100644
--- a/wifi/supplicant/1.2/vts/functional/Android.bp
+++ b/wifi/supplicant/1.2/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/wifi/supplicant/1.3/Android.bp b/wifi/supplicant/1.3/Android.bp
index fbe7f75..bbb17c2 100644
--- a/wifi/supplicant/1.3/Android.bp
+++ b/wifi/supplicant/1.3/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -27,4 +28,8 @@
"android.hidl.base@1.0",
],
gen_java: true,
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.wifi",
+ ],
}
diff --git a/wifi/supplicant/1.3/vts/functional/Android.bp b/wifi/supplicant/1.3/vts/functional/Android.bp
index 4b56336..609de11 100644
--- a/wifi/supplicant/1.3/vts/functional/Android.bp
+++ b/wifi/supplicant/1.3/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/wifi/supplicant/1.4/Android.bp b/wifi/supplicant/1.4/Android.bp
index c988fdb..4b94823 100644
--- a/wifi/supplicant/1.4/Android.bp
+++ b/wifi/supplicant/1.4/Android.bp
@@ -1,6 +1,7 @@
// This file is autogenerated by hidl-gen -Landroidbp.
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/wifi/supplicant/1.4/vts/functional/Android.bp b/wifi/supplicant/1.4/vts/functional/Android.bp
index 57ee830..def3b86 100644
--- a/wifi/supplicant/1.4/vts/functional/Android.bp
+++ b/wifi/supplicant/1.4/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
diff --git a/wifi/supplicant/aidl/Android.bp b/wifi/supplicant/aidl/Android.bp
index 76b0902..59cfa6f 100644
--- a/wifi/supplicant/aidl/Android.bp
+++ b/wifi/supplicant/aidl/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -27,6 +28,9 @@
srcs: [
"android/hardware/wifi/supplicant/*.aidl",
],
+ imports: [
+ "android.hardware.wifi.common-V1",
+ ],
stability: "vintf",
backend: {
java: {
@@ -45,6 +49,12 @@
ndk: {
gen_trace: true,
},
+ cpp: {
+ enabled: false,
+ },
+ rust: {
+ enabled: false,
+ },
},
versions_with_info: [
{
@@ -58,5 +68,4 @@
],
frozen: false,
-
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
index 553cbc8..a0dd32f 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
@@ -40,4 +40,5 @@
int maxNumberRxSpatialStreams;
android.hardware.wifi.supplicant.LegacyMode legacyMode;
boolean apTidToLinkMapNegotiationSupported;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
index 19e6728..0b068e0 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
@@ -35,18 +35,33 @@
@VintfStability
interface ISupplicantP2pIface {
void addBonjourService(in byte[] query, in byte[] response);
+ /**
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use createGroupOwner.
+ */
void addGroup(in boolean persistent, in int persistentNetworkId);
+ /**
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use addGroupWithConfigurationParams.
+ */
void addGroupWithConfig(in byte[] ssid, in String pskPassphrase, in boolean persistent, in int freq, in byte[] peerAddress, in boolean joinExistingGroup);
@PropagateAllowBlocking android.hardware.wifi.supplicant.ISupplicantP2pNetwork addNetwork();
void addUpnpService(in int version, in String serviceName);
void cancelConnect();
void cancelServiceDiscovery(in long identifier);
void cancelWps(in String groupIfName);
+ /**
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use configureExtListenWithParams.
+ */
void configureExtListen(in int periodInMillis, in int intervalInMillis);
+ /**
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use connectWithParams.
+ */
String connect(in byte[] peerAddress, in android.hardware.wifi.supplicant.WpsProvisionMethod provisionMethod, in String preSelectedPin, in boolean joinExistingGroup, in boolean persistent, in int goIntent);
byte[] createNfcHandoverRequestMessage();
byte[] createNfcHandoverSelectMessage();
void enableWfd(in boolean enable);
+ /**
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use findWithParams.
+ */
void find(in int timeoutInSec);
void flush();
void flushServices();
@@ -93,8 +108,19 @@
String startWpsPinDisplay(in String groupIfName, in byte[] bssid);
void startWpsPinKeypad(in String groupIfName, in String pin);
void stopFind();
+ /**
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use findWithParams.
+ */
void findOnSocialChannels(in int timeoutInSec);
+ /**
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use findWithParams.
+ */
void findOnSpecificFrequency(in int freqInHz, in int timeoutInSec);
void setVendorElements(in android.hardware.wifi.supplicant.P2pFrameTypeMask frameTypeMask, in byte[] vendorElemBytes);
void configureEapolIpAddressAllocationParams(in int ipAddressGo, in int ipAddressMask, in int ipAddressStart, in int ipAddressEnd);
+ String connectWithParams(in android.hardware.wifi.supplicant.P2pConnectInfo connectInfo);
+ void findWithParams(in android.hardware.wifi.supplicant.P2pDiscoveryInfo discoveryInfo);
+ void configureExtListenWithParams(in android.hardware.wifi.supplicant.P2pExtListenInfo extListenInfo);
+ void addGroupWithConfigurationParams(in android.hardware.wifi.supplicant.P2pAddGroupConfigurationParams groupConfigurationParams);
+ void createGroupOwner(in android.hardware.wifi.supplicant.P2pCreateGroupOwnerInfo groupOwnerInfo);
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
index 80d8546..65ad4c1 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
@@ -34,17 +34,29 @@
package android.hardware.wifi.supplicant;
@VintfStability
interface ISupplicantP2pIfaceCallback {
+ /**
+ * @deprecated This callback is deprecated from AIDL v3, newer HAL should call onDeviceFoundWithParams.
+ */
oneway void onDeviceFound(in byte[] srcAddress, in byte[] p2pDeviceAddress, in byte[] primaryDeviceType, in String deviceName, in android.hardware.wifi.supplicant.WpsConfigMethods configMethods, in byte deviceCapabilities, in android.hardware.wifi.supplicant.P2pGroupCapabilityMask groupCapabilities, in byte[] wfdDeviceInfo);
oneway void onDeviceLost(in byte[] p2pDeviceAddress);
oneway void onFindStopped();
oneway void onGoNegotiationCompleted(in android.hardware.wifi.supplicant.P2pStatusCode status);
+ /**
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use onGoNegotiationRequestWithParams.
+ */
oneway void onGoNegotiationRequest(in byte[] srcAddress, in android.hardware.wifi.supplicant.WpsDevPasswordId passwordId);
oneway void onGroupFormationFailure(in String failureReason);
oneway void onGroupFormationSuccess();
oneway void onGroupRemoved(in String groupIfname, in boolean isGroupOwner);
oneway void onGroupStarted(in String groupIfname, in boolean isGroupOwner, in byte[] ssid, in int frequency, in byte[] psk, in String passphrase, in byte[] goDeviceAddress, in boolean isPersistent);
+ /**
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use onInvitationReceivedWithParams.
+ */
oneway void onInvitationReceived(in byte[] srcAddress, in byte[] goDeviceAddress, in byte[] bssid, in int persistentNetworkId, in int operatingFrequency);
oneway void onInvitationResult(in byte[] bssid, in android.hardware.wifi.supplicant.P2pStatusCode status);
+ /**
+ * @deprecated This callback is deprecated from AIDL v3, newer HAL should call onProvisionDiscoveryCompletedEvent.
+ */
oneway void onProvisionDiscoveryCompleted(in byte[] p2pDeviceAddress, in boolean isRequest, in android.hardware.wifi.supplicant.P2pProvDiscStatusCode status, in android.hardware.wifi.supplicant.WpsConfigMethods configMethods, in String generatedPin);
oneway void onR2DeviceFound(in byte[] srcAddress, in byte[] p2pDeviceAddress, in byte[] primaryDeviceType, in String deviceName, in android.hardware.wifi.supplicant.WpsConfigMethods configMethods, in byte deviceCapabilities, in android.hardware.wifi.supplicant.P2pGroupCapabilityMask groupCapabilities, in byte[] wfdDeviceInfo, in byte[] wfdR2DeviceInfo);
oneway void onServiceDiscoveryResponse(in byte[] srcAddress, in char updateIndicator, in byte[] tlvs);
@@ -57,8 +69,15 @@
*/
oneway void onStaDeauthorized(in byte[] srcAddress, in byte[] p2pDeviceAddress);
oneway void onGroupFrequencyChanged(in String groupIfname, in int frequency);
+ /**
+ * @deprecated This callback is deprecated from AIDL v3, newer HAL should call onDeviceFoundWithParams.
+ */
oneway void onDeviceFoundWithVendorElements(in byte[] srcAddress, in byte[] p2pDeviceAddress, in byte[] primaryDeviceType, in String deviceName, in android.hardware.wifi.supplicant.WpsConfigMethods configMethods, in byte deviceCapabilities, in android.hardware.wifi.supplicant.P2pGroupCapabilityMask groupCapabilities, in byte[] wfdDeviceInfo, in byte[] wfdR2DeviceInfo, in byte[] vendorElemBytes);
oneway void onGroupStartedWithParams(in android.hardware.wifi.supplicant.P2pGroupStartedEventParams groupStartedEventParams);
oneway void onPeerClientJoined(in android.hardware.wifi.supplicant.P2pPeerClientJoinedEventParams clientJoinedEventParams);
oneway void onPeerClientDisconnected(in android.hardware.wifi.supplicant.P2pPeerClientDisconnectedEventParams clientDisconnectedEventParams);
+ oneway void onProvisionDiscoveryCompletedEvent(in android.hardware.wifi.supplicant.P2pProvisionDiscoveryCompletedEventParams provisionDiscoveryCompletedEventParams);
+ oneway void onDeviceFoundWithParams(in android.hardware.wifi.supplicant.P2pDeviceFoundEventParams deviceFoundEventParams);
+ oneway void onGoNegotiationRequestWithParams(in android.hardware.wifi.supplicant.P2pGoNegotiationReqEventParams params);
+ oneway void onInvitationReceivedWithParams(in android.hardware.wifi.supplicant.P2pInvitationEventParams params);
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
index 1616b26..917668e 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
@@ -54,6 +54,9 @@
android.hardware.wifi.supplicant.IfaceType getType();
android.hardware.wifi.supplicant.WpaDriverCapabilitiesMask getWpaDriverCapabilities();
void initiateAnqpQuery(in byte[] macAddress, in android.hardware.wifi.supplicant.AnqpInfoId[] infoElements, in android.hardware.wifi.supplicant.Hs20AnqpSubtypes[] subTypes);
+ /**
+ * @deprecated No longer in use.
+ */
void initiateHs20IconQuery(in byte[] macAddress, in String fileName);
void initiateTdlsDiscover(in byte[] macAddress);
void initiateTdlsSetup(in byte[] macAddress);
@@ -98,5 +101,7 @@
android.hardware.wifi.supplicant.SignalPollResult[] getSignalPollResults();
android.hardware.wifi.supplicant.QosPolicyScsRequestStatus[] addQosPolicyRequestForScs(in android.hardware.wifi.supplicant.QosPolicyScsData[] qosPolicyData);
android.hardware.wifi.supplicant.QosPolicyScsRequestStatus[] removeQosPolicyForScs(in byte[] scsPolicyIds);
+ void configureMscs(in android.hardware.wifi.supplicant.MscsParams params);
+ void disableMscs();
const int MAX_POLICIES_PER_QOS_SCS_REQUEST = 16;
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
index 1c23223..9fa8f56 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
@@ -53,6 +53,9 @@
oneway void onExtRadioWorkStart(in int id);
oneway void onExtRadioWorkTimeout(in int id);
oneway void onHs20DeauthImminentNotice(in byte[] bssid, in int reasonCode, in int reAuthDelayInSec, in String url);
+ /**
+ * @deprecated This callback is deprecated from AIDL v3.
+ */
oneway void onHs20IconQueryDone(in byte[] bssid, in String fileName, in byte[] data);
oneway void onHs20SubscriptionRemediation(in byte[] bssid, in android.hardware.wifi.supplicant.OsuMethod osuMethod, in String url);
oneway void onHs20TermsAndConditionsAcceptanceRequestedNotification(in byte[] bssid, in String url);
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
index bfc05a4..488037f 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
@@ -129,6 +129,8 @@
void setRoamingConsortiumSelection(in byte[] selectedRcoi);
void setMinimumTlsVersionEapPhase1Param(android.hardware.wifi.supplicant.TlsVersion tlsVersion);
void setStrictConservativePeerMode(in boolean enable);
+ void disableEht();
+ void setVendorData(in android.hardware.wifi.common.OuiKeyedData[] vendorData);
const int SSID_MAX_LEN_IN_BYTES = 32;
const int PSK_PASSPHRASE_MIN_LEN_IN_BYTES = 8;
const int PSK_PASSPHRASE_MAX_LEN_IN_BYTES = 63;
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/KeyMgmtMask.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
index 35d51bc..06c22cb 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
@@ -51,4 +51,5 @@
WAPI_CERT = (1 << 13) /* 8192 */,
FILS_SHA256 = (1 << 18) /* 262144 */,
FILS_SHA384 = (1 << 19) /* 524288 */,
+ PASN = (1 << 25) /* 33554432 */,
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MscsParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MscsParams.aidl
new file mode 100644
index 0000000..aeed408
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MscsParams.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.wifi.supplicant;
+@VintfStability
+parcelable MscsParams {
+ byte upBitmap;
+ byte upLimit;
+ int streamTimeoutUs;
+ byte frameClassifierMask;
+ @Backing(type="int") @VintfStability
+ enum FrameClassifierFields {
+ IP_VERSION = (1 << 0) /* 1 */,
+ SRC_IP_ADDR = (1 << 1) /* 2 */,
+ DST_IP_ADDR = (1 << 2) /* 4 */,
+ SRC_PORT = (1 << 3) /* 8 */,
+ DST_PORT = (1 << 4) /* 16 */,
+ DSCP = (1 << 5) /* 32 */,
+ PROTOCOL_NEXT_HDR = (1 << 6) /* 64 */,
+ FLOW_LABEL = (1 << 7) /* 128 */,
+ }
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MsduDeliveryInfo.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MsduDeliveryInfo.aidl
new file mode 100644
index 0000000..792e08d
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MsduDeliveryInfo.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.wifi.supplicant;
+@VintfStability
+parcelable MsduDeliveryInfo {
+ android.hardware.wifi.supplicant.MsduDeliveryInfo.DeliveryRatio deliveryRatio;
+ byte countExponent;
+ @Backing(type="byte") @VintfStability
+ enum DeliveryRatio {
+ RATIO_95 = 1,
+ RATIO_96 = 2,
+ RATIO_97 = 3,
+ RATIO_98 = 4,
+ RATIO_99 = 5,
+ RATIO_99_9 = 6,
+ RATIO_99_99 = 7,
+ RATIO_99_999 = 8,
+ RATIO_99_9999 = 9,
+ }
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pAddGroupConfigurationParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pAddGroupConfigurationParams.aidl
new file mode 100644
index 0000000..ff73f84
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pAddGroupConfigurationParams.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.wifi.supplicant;
+@VintfStability
+parcelable P2pAddGroupConfigurationParams {
+ byte[] ssid;
+ String passphrase;
+ boolean isPersistent;
+ int frequencyMHzOrBand;
+ byte[6] goInterfaceAddress;
+ boolean joinExistingGroup;
+ int keyMgmtMask;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pConnectInfo.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pConnectInfo.aidl
new file mode 100644
index 0000000..f4662de
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pConnectInfo.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.wifi.supplicant;
+@VintfStability
+parcelable P2pConnectInfo {
+ byte[6] peerAddress;
+ android.hardware.wifi.supplicant.WpsProvisionMethod provisionMethod;
+ String preSelectedPin;
+ boolean joinExistingGroup;
+ boolean persistent;
+ int goIntent;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pCreateGroupOwnerInfo.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pCreateGroupOwnerInfo.aidl
new file mode 100644
index 0000000..4451fb5
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pCreateGroupOwnerInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.wifi.supplicant;
+@VintfStability
+parcelable P2pCreateGroupOwnerInfo {
+ boolean persistent;
+ int persistentNetworkId;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl
new file mode 100644
index 0000000..ee8e6dc
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.wifi.supplicant;
+@VintfStability
+parcelable P2pDeviceFoundEventParams {
+ byte[6] srcAddress;
+ byte[6] p2pDeviceAddress;
+ byte[] primaryDeviceType;
+ String deviceName;
+ int configMethods;
+ byte deviceCapabilities;
+ int groupCapabilities;
+ byte[] wfdDeviceInfo;
+ byte[] wfdR2DeviceInfo;
+ byte[] vendorElemBytes;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pDiscoveryInfo.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pDiscoveryInfo.aidl
new file mode 100644
index 0000000..5b7dd3f
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pDiscoveryInfo.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.wifi.supplicant;
+@VintfStability
+parcelable P2pDiscoveryInfo {
+ android.hardware.wifi.supplicant.P2pScanType scanType;
+ int frequencyMhz;
+ int timeoutInSec;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pExtListenInfo.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pExtListenInfo.aidl
new file mode 100644
index 0000000..b4d8e9d
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pExtListenInfo.aidl
@@ -0,0 +1,40 @@
+/**
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.wifi.supplicant;
+@VintfStability
+parcelable P2pExtListenInfo {
+ int periodMs;
+ int intervalMs;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGoNegotiationReqEventParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGoNegotiationReqEventParams.aidl
new file mode 100644
index 0000000..ba10b3e
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGoNegotiationReqEventParams.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.wifi.supplicant;
+@VintfStability
+parcelable P2pGoNegotiationReqEventParams {
+ byte[6] srcAddress;
+ android.hardware.wifi.supplicant.WpsDevPasswordId passwordId;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
index 5465a86..e19ae44 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
@@ -45,4 +45,5 @@
byte[6] goInterfaceAddress;
boolean isP2pClientEapolIpAddressInfoPresent;
android.hardware.wifi.supplicant.P2pClientEapolIpAddressInfo p2pClientIpInfo;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pInvitationEventParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pInvitationEventParams.aidl
new file mode 100644
index 0000000..541ee4f
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pInvitationEventParams.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.wifi.supplicant;
+@VintfStability
+parcelable P2pInvitationEventParams {
+ byte[6] srcAddress;
+ byte[6] goDeviceAddress;
+ byte[6] bssid;
+ int persistentNetworkId;
+ int operatingFrequencyMHz;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pPeerClientDisconnectedEventParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pPeerClientDisconnectedEventParams.aidl
index 90e9f5e..5c7c393 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pPeerClientDisconnectedEventParams.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pPeerClientDisconnectedEventParams.aidl
@@ -37,4 +37,5 @@
String groupInterfaceName;
byte[6] clientInterfaceAddress;
byte[6] clientDeviceAddress;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl
index 800f5b3..40c8ff6 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl
@@ -38,4 +38,5 @@
byte[6] clientInterfaceAddress;
byte[6] clientDeviceAddress;
int clientIpAddress;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl
new file mode 100644
index 0000000..46366cc
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.wifi.supplicant;
+@VintfStability
+parcelable P2pProvisionDiscoveryCompletedEventParams {
+ byte[6] p2pDeviceAddress;
+ boolean isRequest;
+ android.hardware.wifi.supplicant.P2pProvDiscStatusCode status;
+ int configMethods;
+ String generatedPin;
+ String groupInterfaceName;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pScanType.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pScanType.aidl
new file mode 100644
index 0000000..ff3efd2
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pScanType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum P2pScanType {
+ FULL,
+ SOCIAL,
+ SPECIFIC_FREQ,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosCharacteristics.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosCharacteristics.aidl
new file mode 100644
index 0000000..dacac8c
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosCharacteristics.aidl
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.hardware.wifi.supplicant;
+@VintfStability
+parcelable QosCharacteristics {
+ int minServiceIntervalUs;
+ int maxServiceIntervalUs;
+ int minDataRateKbps;
+ int delayBoundUs;
+ int optionalFieldMask;
+ char maxMsduSizeOctets;
+ int serviceStartTimeUs;
+ byte serviceStartTimeLinkId;
+ int meanDataRateKbps;
+ int burstSizeOctets;
+ char msduLifetimeMs;
+ android.hardware.wifi.supplicant.MsduDeliveryInfo msduDeliveryInfo;
+ @Backing(type="int") @VintfStability
+ enum QosCharacteristicsMask {
+ MAX_MSDU_SIZE = (1 << 0) /* 1 */,
+ SERVICE_START_TIME = (1 << 1) /* 2 */,
+ SERVICE_START_TIME_LINK_ID = (1 << 2) /* 4 */,
+ MEAN_DATA_RATE = (1 << 3) /* 8 */,
+ BURST_SIZE = (1 << 4) /* 16 */,
+ MSDU_LIFETIME = (1 << 5) /* 32 */,
+ MSDU_DELIVERY_INFO = (1 << 6) /* 64 */,
+ }
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsData.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
index 4e5e8ae..20be616 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
@@ -22,4 +22,11 @@
byte policyId;
byte userPriority;
android.hardware.wifi.supplicant.QosPolicyClassifierParams classifierParams;
+ android.hardware.wifi.supplicant.QosPolicyScsData.LinkDirection direction;
+ @nullable android.hardware.wifi.supplicant.QosCharacteristics QosCharacteristics;
+ @Backing(type="byte") @VintfStability
+ enum LinkDirection {
+ DOWNLINK,
+ UPLINK,
+ }
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
index 4921a67..64a515f 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
@@ -16,6 +16,7 @@
package android.hardware.wifi.supplicant;
+import android.hardware.wifi.common.OuiKeyedData;
import android.hardware.wifi.supplicant.LegacyMode;
import android.hardware.wifi.supplicant.WifiTechnology;
@@ -48,4 +49,9 @@
* Indicates the AP support for TID-to-link mapping negotiation.
*/
boolean apTidToLinkMapNegotiationSupported;
+ /**
+ * Additional vendor-specific data. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
index e58422c..1230793 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
@@ -16,11 +16,17 @@
package android.hardware.wifi.supplicant;
+import android.hardware.wifi.common.OuiKeyedData;
import android.hardware.wifi.supplicant.FreqRange;
import android.hardware.wifi.supplicant.ISupplicantP2pIfaceCallback;
import android.hardware.wifi.supplicant.ISupplicantP2pNetwork;
import android.hardware.wifi.supplicant.IfaceType;
import android.hardware.wifi.supplicant.MiracastMode;
+import android.hardware.wifi.supplicant.P2pAddGroupConfigurationParams;
+import android.hardware.wifi.supplicant.P2pConnectInfo;
+import android.hardware.wifi.supplicant.P2pCreateGroupOwnerInfo;
+import android.hardware.wifi.supplicant.P2pDiscoveryInfo;
+import android.hardware.wifi.supplicant.P2pExtListenInfo;
import android.hardware.wifi.supplicant.P2pFrameTypeMask;
import android.hardware.wifi.supplicant.P2pGroupCapabilityMask;
import android.hardware.wifi.supplicant.WpsConfigMethods;
@@ -48,6 +54,9 @@
* negotiation with a specific peer). This is also known as autonomous
* group owner. Optional |persistentNetworkId| may be used to specify
* restart of a persistent group.
+ * <p>
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use
+ * createGroupOwner.
*
* @param persistent Used to request a persistent group to be formed.
* @param persistentNetworkId Used to specify the restart of a persistent
@@ -70,6 +79,9 @@
* whose network name and group owner's MAC address matches the specified SSID
* and peer address without WPS process. If peerAddress is 00:00:00:00:00:00, the first found
* group whose network name matches the specified SSID is joined.
+ * <p>
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use
+ * addGroupWithConfigurationParams.
*
* @param ssid The SSID of this group.
* @param pskPassphrase The passphrase of this group.
@@ -162,6 +174,9 @@
* (with interval obviously having to be larger than or equal to duration).
* If the P2P module is not idle at the time the Extended Listen Timing
* timeout occurs, the Listen State operation must be skipped.
+ * <p>
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use
+ * configureExtListenWithParams.
*
* @param periodInMillis Period in milliseconds.
* @param intervalInMillis Interval in milliseconds.
@@ -176,6 +191,9 @@
* Start P2P group formation with a discovered P2P peer. This includes
* optional group owner negotiation, group interface setup, provisioning,
* and establishing data connection.
+ * <p>
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use
+ * connectWithParams.
*
* @param peerAddress MAC address of the device to connect to.
* @param provisionMethod Provisioning method to use.
@@ -236,6 +254,9 @@
/**
* Initiate a P2P service discovery with an optional timeout.
+ * <p>
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use
+ * findWithParams.
*
* @param timeoutInSec Max time to be spent is performing discovery.
* Set to 0 to indefinitely continue discovery until an explicit
@@ -782,8 +803,9 @@
/**
* Initiate a P2P device discovery only on social channels.
- *
- * Full P2P discovery is performed through |ISupplicantP2pIface.find| method.
+ * <p>
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use
+ * findWithParams.
*
* @param timeoutInSec The maximum amount of time that should be spent in performing device
* discovery.
@@ -798,8 +820,9 @@
/**
* Initiate a P2P device discovery on a specific frequency.
- *
- * Full P2P discovery is performed through |ISupplicantP2pIface.find| method.
+ * <p>
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use
+ * findWithParams.
*
* @param freqInHz the frequency to be scanned.
* @param timeoutInSec Max time to be spent is performing discovery.
@@ -845,4 +868,74 @@
*/
void configureEapolIpAddressAllocationParams(
in int ipAddressGo, in int ipAddressMask, in int ipAddressStart, in int ipAddressEnd);
+
+ /**
+ * Start P2P group formation with a discovered P2P peer. This includes
+ * optional group owner negotiation, group interface setup, provisioning,
+ * and establishing data connection.
+ *
+ * @param connectInfo Parameters associated with this connection request.
+ * @return Pin generated, if |provisionMethod| uses one of the
+ * generated |PIN*| methods.
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+ */
+ String connectWithParams(in P2pConnectInfo connectInfo);
+
+ /**
+ * Initiate a P2P service discovery with an optional timeout.
+ *
+ * @param discoveryInfo Parameters associated with this discovery request.
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+ * |SupplicantStatusCode.FAILURE_IFACE_DISABLED|
+ */
+ void findWithParams(in P2pDiscoveryInfo discoveryInfo);
+
+ /**
+ * Configure Extended Listen Timing.
+ *
+ * If enabled, listen state must be entered every |intervalMs| for at
+ * least |periodMs|. Both values have acceptable range of 1-65535
+ * (note that the interval must be larger than or equal to the duration).
+ * If the P2P module is not idle at the time the Extended Listen Timing
+ * timeout occurs, the Listen State operation must be skipped.
+ *
+ * @param extListenInfo Parameters to configure extended listening timing.
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+ */
+ void configureExtListenWithParams(in P2pExtListenInfo extListenInfo);
+
+ /**
+ * Set up a P2P group owner or join a group as a group client with the
+ * specified configuration. The group configurations required to establish
+ * a connection(SSID, password, channel, etc) are shared out of band.
+ * So the connection process doesn't require a P2P provision discovery or
+ * invitation message exchange.
+ *
+ * @param groupConfigurationParams Parameters associated with this add group operation.
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+ */
+ void addGroupWithConfigurationParams(
+ in P2pAddGroupConfigurationParams groupConfigurationParams);
+
+ /**
+ * Set up a P2P group owner on this device. This is also known as autonomous
+ * group owner. The connection process requires P2P provision discovery
+ * message or invitation message exchange.
+ *
+ * @param groupOwnerInfo Parameters associated with this create group owner operation.
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+ */
+ void createGroupOwner(in P2pCreateGroupOwnerInfo groupOwnerInfo);
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
index 810fe48..44a5465 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
@@ -16,11 +16,15 @@
package android.hardware.wifi.supplicant;
+import android.hardware.wifi.supplicant.P2pDeviceFoundEventParams;
+import android.hardware.wifi.supplicant.P2pGoNegotiationReqEventParams;
import android.hardware.wifi.supplicant.P2pGroupCapabilityMask;
import android.hardware.wifi.supplicant.P2pGroupStartedEventParams;
+import android.hardware.wifi.supplicant.P2pInvitationEventParams;
import android.hardware.wifi.supplicant.P2pPeerClientDisconnectedEventParams;
import android.hardware.wifi.supplicant.P2pPeerClientJoinedEventParams;
import android.hardware.wifi.supplicant.P2pProvDiscStatusCode;
+import android.hardware.wifi.supplicant.P2pProvisionDiscoveryCompletedEventParams;
import android.hardware.wifi.supplicant.P2pStatusCode;
import android.hardware.wifi.supplicant.WpsConfigMethods;
import android.hardware.wifi.supplicant.WpsDevPasswordId;
@@ -37,6 +41,9 @@
oneway interface ISupplicantP2pIfaceCallback {
/**
* Used to indicate that a P2P device has been found.
+ * <p>
+ * @deprecated This callback is deprecated from AIDL v3, newer HAL should call
+ * onDeviceFoundWithParams.
*
* @param srcAddress MAC address of the device found. This must either
* be the P2P device address or the P2P interface address.
@@ -83,6 +90,10 @@
* @param srcAddress MAC address of the device that initiated the GO
* negotiation request.
* @param passwordId Type of password.
+ *
+ * <p>
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use
+ * onGoNegotiationRequestWithParams.
*/
void onGoNegotiationRequest(in byte[] srcAddress, in WpsDevPasswordId passwordId);
@@ -130,6 +141,9 @@
* @param bssid Bssid of the group.
* @param persistentNetworkId Persistent network Id of the group.
* @param operatingFrequency Frequency on which the invitation was received.
+ * <p>
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use
+ * onInvitationReceivedWithParams.
*/
void onInvitationReceived(in byte[] srcAddress, in byte[] goDeviceAddress, in byte[] bssid,
in int persistentNetworkId, in int operatingFrequency);
@@ -144,6 +158,9 @@
/**
* Used to indicate the completion of a P2P provision discovery request.
+ * <p>
+ * @deprecated This callback is deprecated from AIDL v3, newer HAL should call
+ * onProvisionDiscoveryCompletedEvent.
*
* @param p2pDeviceAddress P2P device address.
* @param isRequest Whether we received or sent the provision discovery.
@@ -224,6 +241,9 @@
/**
* Used to indicate that a P2P device has been found.
+ * <p>
+ * @deprecated This callback is deprecated from AIDL v3, newer HAL should call
+ * onDeviceFoundWithParams.
*
* @param srcAddress MAC address of the device found. This must either
* be the P2P device address for a peer which is not in a group,
@@ -275,4 +295,34 @@
*/
void onPeerClientDisconnected(
in P2pPeerClientDisconnectedEventParams clientDisconnectedEventParams);
+
+ /**
+ * Used to indicate the completion of a P2P provision discovery request.
+ *
+ * @param provisionDiscoveryCompletedEventParams Parameters associated with
+ * P2P provision discovery frame notification.
+ */
+ void onProvisionDiscoveryCompletedEvent(
+ in P2pProvisionDiscoveryCompletedEventParams provisionDiscoveryCompletedEventParams);
+
+ /**
+ * Used to indicate that a P2P device has been found.
+ *
+ * @param deviceFoundEventParams Parameters associated with the device found event.
+ */
+ void onDeviceFoundWithParams(in P2pDeviceFoundEventParams deviceFoundEventParams);
+
+ /**
+ * Used to indicate the reception of a P2P Group Owner negotiation request.
+ *
+ * @param params Parameters associated with the GO negotiation request event.
+ */
+ void onGoNegotiationRequestWithParams(in P2pGoNegotiationReqEventParams params);
+
+ /**
+ * Used to indicate the reception of a P2P invitation.
+ *
+ * @param params Parameters associated with the invitation request event.
+ */
+ void onInvitationReceivedWithParams(in P2pInvitationEventParams params);
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
index 06ab8fb..fb1673e 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
@@ -29,6 +29,7 @@
import android.hardware.wifi.supplicant.IfaceType;
import android.hardware.wifi.supplicant.KeyMgmtMask;
import android.hardware.wifi.supplicant.MloLinksInfo;
+import android.hardware.wifi.supplicant.MscsParams;
import android.hardware.wifi.supplicant.QosPolicyScsData;
import android.hardware.wifi.supplicant.QosPolicyScsRequestStatus;
import android.hardware.wifi.supplicant.QosPolicyStatus;
@@ -304,6 +305,8 @@
* The icon data fetched must be returned in the
* |ISupplicantStaIfaceCallback.onHs20IconQueryDone| callback.
*
+ * @deprecated No longer in use.
+ *
* @param macAddress MAC address of the access point.
* @param fileName Name of the file to request from the access point.
* @throws ServiceSpecificException with one of the following values:
@@ -850,4 +853,28 @@
* being processed. Supplicant will only handle one request at a time.
*/
QosPolicyScsRequestStatus[] removeQosPolicyForScs(in byte[] scsPolicyIds);
+
+ /**
+ * Enable Mirrored Stream Classification Service (MSCS) and configure using
+ * the provided configuration values.
+ *
+ * If MSCS has already been enabled/configured, this will overwrite the
+ * existing configuration.
+ *
+ * @param params |MscsParams| object containing the configuration.
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_ARGS_INVALID| if the configuration is invalid.
+ * |SupplicantStatusCode.FAILURE_UNKNOWN| if the configuration could not be set.
+ */
+ void configureMscs(in MscsParams params);
+
+ /**
+ * Disable Mirrored Stream Classification Service (MSCS).
+ *
+ * If MSCS is enabled/configured, this will send a remove request to the AP.
+ *
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|
+ */
+ void disableMscs();
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
index 17a220d..172fcda 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
@@ -198,6 +198,8 @@
/**
* Used to indicate the result of Hotspot 2.0 Icon query.
*
+ * @deprecated This callback is deprecated from AIDL v3.
+ *
* @param bssid BSSID of the access point.
* @param fileName Name of the file that was requested.
* @param data Icon data fetched from the access point.
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
index 750cf72..fc7babf 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
@@ -16,6 +16,7 @@
package android.hardware.wifi.supplicant;
+import android.hardware.wifi.common.OuiKeyedData;
import android.hardware.wifi.supplicant.AuthAlgMask;
import android.hardware.wifi.supplicant.DppConnectionKeys;
import android.hardware.wifi.supplicant.EapMethod;
@@ -1141,4 +1142,27 @@
* |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
*/
void setStrictConservativePeerMode(in boolean enable);
+
+ /**
+ * Disables Extremely High Throughput (EHT) mode, aka Wi-Fi 7 support, for the network. When
+ * EHT is disabled, the device ceases to transmit EHT related Information Elements (IEs),
+ * including multi-link IEs and EHT capability, in subsequent messages such as (Re)Association
+ * requests to the Access Point (AP).
+ *
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+ */
+ void disableEht();
+
+ /**
+ * Set additional vendor-provided configuration data.
+ *
+ * @param vendorData List of |OuiKeyedData| containing the vendor-provided
+ * configuration data.
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+ */
+ void setVendorData(in OuiKeyedData[] vendorData);
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
index f0c3345..8758645 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
@@ -71,4 +71,8 @@
* FILS shared key authentication with sha-384
*/
FILS_SHA384 = 1 << 19,
+ /**
+ * Pre-Association Security Negotiation (PASN) Key management
+ */
+ PASN = 1 << 25,
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MscsParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MscsParams.aidl
new file mode 100644
index 0000000..b1731ac
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MscsParams.aidl
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * Mirrored Stream Classification Service (MSCS) parameters.
+ * Refer to section 3.1 of the Wi-Fi QoS Management Specification v3.0.
+ */
+@VintfStability
+parcelable MscsParams {
+ /**
+ * Bitmap indicating which User Priorities should be classified using MSCS.
+ * The least significant bit corresponds to UP 0, and the most significant
+ * bit to UP 7. Setting a bit to 1 indicates that UP should be used.
+ */
+ byte upBitmap;
+
+ /**
+ * Maximum user priority that can be assigned using the MSCS service.
+ * Value must be between 0 and 7 (inclusive).
+ */
+ byte upLimit;
+
+ /**
+ * Stream timeout in μs. Must be equivalent to 60 sec or less.
+ */
+ int streamTimeoutUs;
+
+ /**
+ * Bitmask of available fields for a Type 4 TCLAS frame classifier.
+ * See Figures 9-309 and 9-310 in the IEEE Std 802.11-2020 Standard.
+ */
+ @VintfStability
+ @Backing(type="int")
+ enum FrameClassifierFields {
+ IP_VERSION = 1 << 0,
+ SRC_IP_ADDR = 1 << 1,
+ DST_IP_ADDR = 1 << 2,
+ SRC_PORT = 1 << 3,
+ DST_PORT = 1 << 4,
+ DSCP = 1 << 5,
+ /** Indicates Protocol if using IPv4, or Next Header if using IPv6. */
+ PROTOCOL_NEXT_HDR = 1 << 6,
+ /** Only applicable if using IPv6. */
+ FLOW_LABEL = 1 << 7,
+ }
+
+ /**
+ * Bitmask of |FrameClassifierFields| for a Type 4 TCLAS frame classifier.
+ */
+ byte frameClassifierMask;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MsduDeliveryInfo.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MsduDeliveryInfo.aidl
new file mode 100644
index 0000000..8065f63
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MsduDeliveryInfo.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * MSDU delivery information.
+ * See Section 9.4.2.316 of the IEEE P802.11be/D4.0 Standard.
+ */
+@VintfStability
+parcelable MsduDeliveryInfo {
+ /**
+ * Enums for the |deliveryRatio| field.
+ * See Table 9-404t of the IEEE P802.11be/D4.0 Standard.
+ */
+ @VintfStability
+ @Backing(type="byte")
+ enum DeliveryRatio {
+ RATIO_95 = 1, // 95%
+ RATIO_96 = 2, // 96%
+ RATIO_97 = 3, // 97%
+ RATIO_98 = 4, // 98%
+ RATIO_99 = 5, // 99%
+ RATIO_99_9 = 6, // 99.9%
+ RATIO_99_99 = 7, // 99.99%
+ RATIO_99_999 = 8, // 99.999%
+ RATIO_99_9999 = 9, // 99.9999%
+ }
+
+ /**
+ * Percentage of the MSDUs that are expected to be delivered successfully.
+ */
+ DeliveryRatio deliveryRatio;
+
+ /**
+ * Exponent from which the number of incoming MSDUs is computed. The number of incoming
+ * MSDUs is 10^countExponent, and is used to determine the MSDU delivery ratio.
+ * Must be a number between 0 and 15 (inclusive).
+ */
+ byte countExponent;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pAddGroupConfigurationParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pAddGroupConfigurationParams.aidl
new file mode 100644
index 0000000..15f2733
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pAddGroupConfigurationParams.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.hardware.wifi.supplicant;
+
+import android.hardware.wifi.common.OuiKeyedData;
+import android.hardware.wifi.supplicant.KeyMgmtMask;
+
+/**
+ * Request parameters used for |ISupplicantP2pIface.addGroupWithConfigurationParams|
+ */
+@VintfStability
+parcelable P2pAddGroupConfigurationParams {
+ /** The SSID of the group. */
+ byte[] ssid;
+
+ /** The passphrase used to secure the group. */
+ String passphrase;
+
+ /** Whether this group is persisted. Only applied on the group owner side */
+ boolean isPersistent;
+
+ /**
+ * The required frequency or band of the group.
+ * Only applied on the group owner side.
+ * The following values are supported:
+ * 0: automatic channel selection,
+ * 2: for 2.4GHz channels
+ * 5: for 5GHz channels
+ * 6: for 6GHz channels
+ * specific frequency in MHz, i.e., 2412, 5500, etc.
+ * If an invalid band or unsupported frequency are specified,
+ * |ISupplicantP2pIface.addGroupWithConfigurationParams| fails
+ */
+ int frequencyMHzOrBand;
+
+ /**
+ * The MAC Address of the P2P interface of the Peer GO device.
+ * This field is valid only for the group client side.
+ * If the MAC is "00:00:00:00:00:00", the device must try to find a peer GO device
+ * whose network name matches the specified SSID.
+ */
+ byte[6] goInterfaceAddress;
+
+ /*
+ * True if join a group as a group client; false to create a group as a group owner
+ */
+ boolean joinExistingGroup;
+
+ /**
+ * The authentication Key management mask for the connection. Combination of |KeyMgmtMask|
+ * values. The supported authentication key management types are WPA_PSK, SAE and PASN.
+ *
+ */
+ int keyMgmtMask;
+
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pConnectInfo.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pConnectInfo.aidl
new file mode 100644
index 0000000..f09b476
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pConnectInfo.aidl
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.common.OuiKeyedData;
+import android.hardware.wifi.supplicant.WpsProvisionMethod;
+
+/**
+ * Request parameters used for |ISupplicantP2pIface.connectWithParams|
+ */
+@VintfStability
+parcelable P2pConnectInfo {
+ /**
+ * MAC address of the device to connect to.
+ */
+ byte[6] peerAddress;
+
+ /**
+ * Provisioning method to use.
+ */
+ WpsProvisionMethod provisionMethod;
+
+ /**
+ * Pin to be used, if |provisionMethod| uses one of the
+ * preselected |PIN*| methods.
+ */
+ String preSelectedPin;
+
+ /**
+ * Indicates that this is a command to join an existing group as a client.
+ * This means that the group owner negotiation step can be skipped.
+ * This must send a Provision Discovery Request message to the
+ * target group owner before associating for WPS provisioning.
+ */
+ boolean joinExistingGroup;
+
+ /**
+ * Used to request a persistent group to be formed.
+ */
+ boolean persistent;
+
+ /**
+ * Used to override the default Intent for this group owner
+ * negotiation (Values from 1-15). Refer to section 4.1.6 in
+ * Wi-Fi Peer-to-Peer (P2P) Technical Specification Version 1.7.
+ */
+ int goIntent;
+
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pCreateGroupOwnerInfo.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pCreateGroupOwnerInfo.aidl
new file mode 100644
index 0000000..51e6ed9
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pCreateGroupOwnerInfo.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.hardware.wifi.supplicant;
+
+import android.hardware.wifi.common.OuiKeyedData;
+
+/**
+ * Parameters used for |ISupplicantP2pIface.createGroupOwner|
+ */
+@VintfStability
+parcelable P2pCreateGroupOwnerInfo {
+ /**
+ * Used to request a persistent group to be formed.
+ */
+ boolean persistent;
+
+ /**
+ * Optional parameter. Used to specify the restart of a persistent
+ * group. Set to UINT32_MAX for a non-persistent group.
+ */
+ int persistentNetworkId;
+
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl
new file mode 100644
index 0000000..15917b6
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.common.OuiKeyedData;
+
+/**
+ * Parameters passed as a part of a P2P Device found event.
+ */
+@VintfStability
+parcelable P2pDeviceFoundEventParams {
+ /**
+ * MAC address of the device found. This must either be the P2P device address
+ * for a peer which is not in a group, or the P2P interface address for
+ * a peer which is a Group Owner.
+ */
+ byte[6] srcAddress;
+
+ /**
+ * P2P device address.
+ */
+ byte[6] p2pDeviceAddress;
+
+ /**
+ * Type of device. Refer to section B.1 of the Wifi P2P Technical
+ * specification v1.2.
+ */
+ byte[] primaryDeviceType;
+
+ /**
+ * Name of the device.
+ */
+ String deviceName;
+
+ /**
+ * Mask of |WpsConfigMethods| indicating the WPS configuration methods
+ * supported by the device.
+ */
+ int configMethods;
+
+ /**
+ * Refer to section 4.1.4 of the Wifi P2P Technical specification v1.2.
+ */
+ byte deviceCapabilities;
+
+ /**
+ * Mask of |P2pGroupCapabilityMask| indicating the group capabilities.
+ * Refer to section 4.1.4 of the Wifi P2P Technical specification v1.2.
+ */
+ int groupCapabilities;
+
+ /**
+ * WFD device info as described in section 5.1.2 of the WFD technical
+ * specification v1.0.0.
+ */
+ byte[] wfdDeviceInfo;
+
+ /**
+ * WFD R2 device info as described in section 5.1.12 of WFD technical
+ * specification v2.1.
+ */
+ byte[] wfdR2DeviceInfo;
+
+ /**
+ * Vendor-specific information element bytes. The format of an
+ * information element is EID (1 byte) + Length (1 Byte) + Payload which is
+ * defined in Section 9.4.4 TLV encodings of 802.11-2016 IEEE Standard for
+ * Information technology. The length indicates the size of the payload.
+ * Multiple information elements may be appended within the byte array.
+ */
+ byte[] vendorElemBytes;
+
+ /**
+ * Optional vendor-specific data.
+ * Null value indicates that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pDiscoveryInfo.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pDiscoveryInfo.aidl
new file mode 100644
index 0000000..ddb8a3d
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pDiscoveryInfo.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.common.OuiKeyedData;
+import android.hardware.wifi.supplicant.P2pScanType;
+
+/**
+ * Request parameters used for |ISupplicantP2pIface.findWithParams|
+ */
+@VintfStability
+parcelable P2pDiscoveryInfo {
+ /**
+ * P2P scan type.
+ */
+ P2pScanType scanType;
+
+ /**
+ * Frequency to scan in MHz. Only valid the scan type is |P2pScanType.SPECIFIC_FREQ|
+ */
+ int frequencyMhz;
+
+ /**
+ * Max time, in seconds, to be spent in performing discovery.
+ * Set to 0 to indefinitely continue discovery until an explicit
+ * |stopFind| is sent.
+ */
+ int timeoutInSec;
+
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pExtListenInfo.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pExtListenInfo.aidl
new file mode 100644
index 0000000..1086c94
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pExtListenInfo.aidl
@@ -0,0 +1,39 @@
+/**
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.common.OuiKeyedData;
+
+/**
+ * Parameters used to configure the P2P Extended Listen Interval.
+ */
+@VintfStability
+parcelable P2pExtListenInfo {
+ /**
+ * Period in milliseconds.
+ */
+ int periodMs;
+ /**
+ * Interval in milliseconds.
+ */
+ int intervalMs;
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGoNegotiationReqEventParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGoNegotiationReqEventParams.aidl
new file mode 100644
index 0000000..3480734
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGoNegotiationReqEventParams.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.hardware.wifi.supplicant;
+
+import android.hardware.wifi.common.OuiKeyedData;
+import android.hardware.wifi.supplicant.WpsDevPasswordId;
+
+/**
+ * Parameters used for |ISupplicantP2pIfaceCallback.onGoNegotiationRequestWithParams|
+ */
+@VintfStability
+parcelable P2pGoNegotiationReqEventParams {
+ /**
+ * MAC address of the device that sent the Go negotiation request.
+ */
+ byte[6] srcAddress;
+
+ /**
+ * Type of password.
+ */
+ WpsDevPasswordId passwordId;
+
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
index 96f1e16..9db7a1e 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
@@ -16,6 +16,7 @@
package android.hardware.wifi.supplicant;
+import android.hardware.wifi.common.OuiKeyedData;
import android.hardware.wifi.supplicant.P2pClientEapolIpAddressInfo;
/**
@@ -63,4 +64,10 @@
* The value is undefined if isP2pClientEapolIpAddressInfoPresent is false.
*/
P2pClientEapolIpAddressInfo p2pClientIpInfo;
+
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pInvitationEventParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pInvitationEventParams.aidl
new file mode 100644
index 0000000..4295c40
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pInvitationEventParams.aidl
@@ -0,0 +1,56 @@
+/*
+ * 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.hardware.wifi.supplicant;
+
+import android.hardware.wifi.common.OuiKeyedData;
+
+/**
+ * Parameters used for |ISupplicantP2pIfaceCallback.onInvitationReceivedWithParams|
+ */
+@VintfStability
+parcelable P2pInvitationEventParams {
+ /**
+ * MAC address of the device that sent the invitation.
+ */
+ byte[6] srcAddress;
+
+ /**
+ * P2P device MAC Address of the group owner.
+ */
+ byte[6] goDeviceAddress;
+
+ /**
+ * BSSID of the group.
+ */
+ byte[6] bssid;
+
+ /**
+ * Persistent network ID of the group.
+ */
+ int persistentNetworkId;
+
+ /**
+ * Frequency on which the invitation was received.
+ */
+ int operatingFrequencyMHz;
+
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pPeerClientDisconnectedEventParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pPeerClientDisconnectedEventParams.aidl
index 936efd1..6e3350f 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pPeerClientDisconnectedEventParams.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pPeerClientDisconnectedEventParams.aidl
@@ -16,6 +16,8 @@
package android.hardware.wifi.supplicant;
+import android.hardware.wifi.common.OuiKeyedData;
+
/**
* Parameters passed as a part of P2P peer client disconnected event.
*/
@@ -29,4 +31,10 @@
/** P2P device interface MAC address of the client that disconnected. */
byte[6] clientDeviceAddress;
+
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl
index 7eae2e5..4f46d70 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl
@@ -16,6 +16,8 @@
package android.hardware.wifi.supplicant;
+import android.hardware.wifi.common.OuiKeyedData;
+
/**
* Parameters passed as a part of P2P peer client joined event.
*/
@@ -39,4 +41,10 @@
* The value is set to zero if the IP address is not allocated via EAPOL exchange.
*/
int clientIpAddress;
+
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl
new file mode 100644
index 0000000..05152a9
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.common.OuiKeyedData;
+import android.hardware.wifi.supplicant.P2pProvDiscStatusCode;
+
+/**
+ * Parameters passed as a part of P2P provision discovery frame notification.
+ */
+@VintfStability
+parcelable P2pProvisionDiscoveryCompletedEventParams {
+ /**
+ * P2P device interface MAC address of the device who sent the request or responded to our
+ * request.
+ */
+ byte[6] p2pDeviceAddress;
+ /** True if this is a request, false if this is a response. */
+ boolean isRequest;
+ /** Status of the provision discovery */
+ P2pProvDiscStatusCode status;
+ /** Mask of |WpsConfigMethods| indicating the supported methods */
+ int configMethods;
+ /** 8-digit pin generated */
+ String generatedPin;
+ /**
+ * Interface name of this device group owner. (For ex: p2p-p2p0-1)
+ * This field is filled only when the provision discovery request is received
+ * with P2P Group ID attribute. i.e., when the peer device is joining this
+ * device operating P2P group.
+ * Refer to WFA Wi-Fi_Direct_Specification_v1.9 section 3.2.1 for more details.
+ */
+ String groupInterfaceName;
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
+}
diff --git a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pScanType.aidl
similarity index 61%
copy from health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
copy to wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pScanType.aidl
index aba6cc3..1ab14c4 100644
--- a/health/2.0/utils/libhealthstoragedefault/StorageHealthDefault.cpp
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pScanType.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,12 +13,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "include/StorageHealthDefault.h"
-void get_storage_info(std::vector<struct StorageInfo>&) {
- // Use defaults.
-}
+package android.hardware.wifi.supplicant;
-void get_disk_stats(std::vector<struct DiskStats>&) {
- // Use defaults
+/**
+ * Scan types used in P2P.
+ */
+@VintfStability
+@Backing(type="int")
+enum P2pScanType {
+ /**
+ * All channels.
+ */
+ FULL,
+ /**
+ * Social channels.
+ */
+ SOCIAL,
+ /**
+ * Specific channel.
+ */
+ SPECIFIC_FREQ,
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosCharacteristics.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosCharacteristics.aidl
new file mode 100644
index 0000000..be5ef91
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosCharacteristics.aidl
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.MsduDeliveryInfo;
+
+/**
+ * Additional QoS parameters as defined in Section 9.4.2.316
+ * of the IEEE P802.11be/D4.0 Standard.
+ */
+@VintfStability
+parcelable QosCharacteristics {
+ /**
+ * Unsigned integer specifying the minimum interval (in microseconds) between the start of
+ * two consecutive service periods (SPs) that are allocated for frame exchanges.
+ * The value must be non-zero.
+ */
+ int minServiceIntervalUs;
+
+ /**
+ * Unsigned integer specifying the maximum interval (in microseconds) between the start of two
+ * consecutive SPs that are allocated for frame exchanges. The value must be non-zero.
+ */
+ int maxServiceIntervalUs;
+
+ /**
+ * Unsigned integer specifying the lowest data rate (in kilobits/sec)
+ * for the transport of MSDUs or A-MSDUs belonging to the traffic flow.
+ * The value must be non-zero.
+ */
+ int minDataRateKbps;
+
+ /**
+ * Unsigned integer specifying the maximum amount of time (in microseconds)
+ * targeted to transport an MSDU or A-MSDU belonging to the traffic flow.
+ * The value must be non-zero.
+ */
+ int delayBoundUs;
+
+ /**
+ * Enum values indicating which optional fields are provided.
+ * See Figure 9-1001au of the IEEE P802.11be/D4.0 Standard.
+ */
+ @VintfStability
+ @Backing(type="int")
+ enum QosCharacteristicsMask {
+ MAX_MSDU_SIZE = 1 << 0,
+ SERVICE_START_TIME = 1 << 1,
+ SERVICE_START_TIME_LINK_ID = 1 << 2,
+ MEAN_DATA_RATE = 1 << 3,
+ BURST_SIZE = 1 << 4,
+ MSDU_LIFETIME = 1 << 5,
+ MSDU_DELIVERY_INFO = 1 << 6,
+ }
+
+ /**
+ * Mask of |QosCharacteristicsMask| indicating which optional fields are provided.
+ */
+ int optionalFieldMask;
+
+ /**
+ * Unsigned 16-bit value specifying the maximum size (in octets) of an MSDU
+ * belonging to the traffic flow. The value must be non-zero if provided.
+ */
+ char maxMsduSizeOctets;
+
+ /**
+ * Unsigned integer specifying the anticipated time (in microseconds) when
+ * the traffic starts for the associated TID.
+ */
+ int serviceStartTimeUs;
+
+ /**
+ * The four LSBs indicate the link identifier that corresponds to the link for which the
+ * TSF timer is used to indicate the Service Start Time. The four MSBs should not be used.
+ * This field is present if |serviceStartTimeUs| is included and is not present otherwise.
+ */
+ byte serviceStartTimeLinkId;
+
+ /**
+ * Unsigned integer indicating the data rate specified (in kilobits/sec) for transport of MSDUs
+ * or A-MSDUs belonging to the traffic flow. The value must be non-zero if provided.
+ */
+ int meanDataRateKbps;
+
+ /**
+ * Unsigned integer specififying the maximum burst (in octets) of the MSDUs or A-MSDUs
+ * belonging to the traffic flow that arrive at the MAC SAP within any time duration equal
+ * to the value specified in the |delayBound| field. The value must be non-zero if provided.
+ */
+ int burstSizeOctets;
+
+ /**
+ * Unsigned 16-bit integer specifying the maximum amount of time (in milliseconds) since the
+ * arrival of the MSDU at the MAC data service interface beyond which the MSDU is not useful
+ * even if received by the receiver. The amount of time specified in this field is larger than
+ * or equal to the amount of time specified in the |delayBound| field, if present. The value
+ * must be non-zero if provided.
+ */
+ char msduLifetimeMs;
+
+ /**
+ * MSDU delivery information. See |MsduDeliveryInfo| for more details.
+ */
+ MsduDeliveryInfo msduDeliveryInfo;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsData.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
index 86a4dac..76f5a9a 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
@@ -1,5 +1,6 @@
package android.hardware.wifi.supplicant;
+import android.hardware.wifi.supplicant.QosCharacteristics;
import android.hardware.wifi.supplicant.QosPolicyClassifierParams;
/**
@@ -21,4 +22,24 @@
* QoS policy SCS classifier type information.
*/
QosPolicyClassifierParams classifierParams;
+
+ /**
+ * Enum values for the |direction| field.
+ */
+ @VintfStability
+ @Backing(type="byte")
+ enum LinkDirection {
+ DOWNLINK,
+ UPLINK, // Only applies to trigger-based traffic (Wi-Fi 6+)
+ }
+
+ /**
+ * Direction of data described by this element.
+ */
+ LinkDirection direction;
+
+ /**
+ * Additional parameters available in QoS R3.
+ */
+ @nullable QosCharacteristics QosCharacteristics;
}
diff --git a/wifi/supplicant/aidl/vts/functional/Android.bp b/wifi/supplicant/aidl/vts/functional/Android.bp
index 4eec180..4166850 100644
--- a/wifi/supplicant/aidl/vts/functional/Android.bp
+++ b/wifi/supplicant/aidl/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_wifi_hal",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "hardware_interfaces_license"
@@ -42,6 +43,7 @@
"android.hardware.wifi@1.3",
"android.hardware.wifi@1.4",
"android.hardware.wifi@1.5",
+ "android.hardware.wifi.common-V1-ndk",
"android.hardware.wifi.supplicant@1.0",
"android.hardware.wifi.supplicant@1.1",
"android.hardware.wifi.supplicant-V3-ndk",
@@ -50,7 +52,8 @@
"VtsHalWifiV1_0TargetTestUtil",
"VtsHalWifiV1_5TargetTestUtil",
"VtsHalWifiSupplicantV1_0TargetTestUtil",
- "android.hardware.wifi-V1-ndk",
+ "android.hardware.wifi.common-V1-ndk",
+ "android.hardware.wifi-V2-ndk",
"VtsHalWifiTargetTestUtil",
],
test_suites: [
@@ -78,6 +81,7 @@
"android.hardware.wifi@1.3",
"android.hardware.wifi@1.4",
"android.hardware.wifi@1.5",
+ "android.hardware.wifi.common-V1-ndk",
"android.hardware.wifi.supplicant@1.0",
"android.hardware.wifi.supplicant@1.1",
"android.hardware.wifi.supplicant-V3-ndk",
@@ -86,7 +90,8 @@
"VtsHalWifiV1_0TargetTestUtil",
"VtsHalWifiV1_5TargetTestUtil",
"VtsHalWifiSupplicantV1_0TargetTestUtil",
- "android.hardware.wifi-V1-ndk",
+ "android.hardware.wifi.common-V1-ndk",
+ "android.hardware.wifi-V2-ndk",
"VtsHalWifiTargetTestUtil",
],
test_suites: [
@@ -114,6 +119,7 @@
"android.hardware.wifi@1.3",
"android.hardware.wifi@1.4",
"android.hardware.wifi@1.5",
+ "android.hardware.wifi.common-V1-ndk",
"android.hardware.wifi.supplicant@1.0",
"android.hardware.wifi.supplicant@1.1",
"android.hardware.wifi.supplicant-V3-ndk",
@@ -122,7 +128,8 @@
"VtsHalWifiV1_0TargetTestUtil",
"VtsHalWifiV1_5TargetTestUtil",
"VtsHalWifiSupplicantV1_0TargetTestUtil",
- "android.hardware.wifi-V1-ndk",
+ "android.hardware.wifi.common-V1-ndk",
+ "android.hardware.wifi-V2-ndk",
"VtsHalWifiTargetTestUtil",
],
test_suites: [
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
index d3dd2e0..82e3128 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
@@ -35,12 +35,22 @@
using aidl::android::hardware::wifi::supplicant::ISupplicant;
using aidl::android::hardware::wifi::supplicant::ISupplicantP2pIface;
using aidl::android::hardware::wifi::supplicant::MiracastMode;
+using aidl::android::hardware::wifi::supplicant::P2pAddGroupConfigurationParams;
+using aidl::android::hardware::wifi::supplicant::P2pConnectInfo;
+using aidl::android::hardware::wifi::supplicant::P2pCreateGroupOwnerInfo;
+using aidl::android::hardware::wifi::supplicant::P2pDeviceFoundEventParams;
+using aidl::android::hardware::wifi::supplicant::P2pDiscoveryInfo;
+using aidl::android::hardware::wifi::supplicant::P2pExtListenInfo;
using aidl::android::hardware::wifi::supplicant::P2pFrameTypeMask;
+using aidl::android::hardware::wifi::supplicant::P2pGoNegotiationReqEventParams;
using aidl::android::hardware::wifi::supplicant::P2pGroupCapabilityMask;
using aidl::android::hardware::wifi::supplicant::P2pGroupStartedEventParams;
+using aidl::android::hardware::wifi::supplicant::P2pInvitationEventParams;
using aidl::android::hardware::wifi::supplicant::P2pPeerClientDisconnectedEventParams;
using aidl::android::hardware::wifi::supplicant::P2pPeerClientJoinedEventParams;
using aidl::android::hardware::wifi::supplicant::P2pProvDiscStatusCode;
+using aidl::android::hardware::wifi::supplicant::P2pProvisionDiscoveryCompletedEventParams;
+using aidl::android::hardware::wifi::supplicant::P2pScanType;
using aidl::android::hardware::wifi::supplicant::P2pStatusCode;
using aidl::android::hardware::wifi::supplicant::SupplicantStatusCode;
using aidl::android::hardware::wifi::supplicant::WpsConfigMethods;
@@ -65,6 +75,7 @@
const uint32_t kTestGroupFreq = 0;
const bool kTestGroupPersistent = false;
const bool kTestGroupIsJoin = false;
+const auto& kTestVendorDataOptional = generateOuiKeyedDataListOptional(5);
} // namespace
@@ -193,6 +204,23 @@
override {
return ndk::ScopedAStatus::ok();
}
+ ::ndk::ScopedAStatus onProvisionDiscoveryCompletedEvent(
+ const P2pProvisionDiscoveryCompletedEventParams&
+ /* provisionDiscoveryCompletedEventParams */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onDeviceFoundWithParams(
+ const P2pDeviceFoundEventParams& /* deviceFoundEventParams */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onGoNegotiationRequestWithParams(
+ const P2pGoNegotiationReqEventParams& /* goNegotiationReqEventParams */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onInvitationReceivedWithParams(
+ const P2pInvitationEventParams& /* invitationEventParams */) override {
+ return ndk::ScopedAStatus::ok();
+ }
};
class SupplicantP2pIfaceAidlTest : public testing::TestWithParam<std::string> {
@@ -201,6 +229,7 @@
initializeService();
supplicant_ = getSupplicant(GetParam().c_str());
ASSERT_NE(supplicant_, nullptr);
+ ASSERT_TRUE(supplicant_->getInterfaceVersion(&interface_version_).isOk());
ASSERT_TRUE(supplicant_
->setDebugParams(DebugLevel::EXCESSIVE,
true, // show timestamps
@@ -226,6 +255,7 @@
protected:
std::shared_ptr<ISupplicant> supplicant_;
std::shared_ptr<ISupplicantP2pIface> p2p_iface_;
+ int interface_version_;
};
/*
@@ -508,6 +538,43 @@
}
/*
+ * CreateGroupOwner
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, CreateGroupOwner) {
+ if (interface_version_ < 3) {
+ GTEST_SKIP() << "createGroupOwner is available as of Supplicant V3";
+ }
+
+ P2pCreateGroupOwnerInfo info;
+ info.persistent = false;
+ info.persistentNetworkId = kTestNetworkId;
+ info.vendorData = kTestVendorDataOptional;
+
+ EXPECT_TRUE(p2p_iface_->createGroupOwner(info).isOk());
+}
+
+/*
+ * AddGroupWithConfigurationParams
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, AddGroupWithConfigurationParams) {
+ if (interface_version_ < 3) {
+ GTEST_SKIP() << "addGroupWithConfigurationParams is available as of Supplicant V3";
+ }
+
+ P2pAddGroupConfigurationParams params;
+ params.ssid = kTestSsid;
+ params.passphrase = kTestPassphrase;
+ params.isPersistent = kTestGroupPersistent;
+ params.frequencyMHzOrBand = kTestGroupFreq;
+ params.goInterfaceAddress = vecToArrayMacAddr(kTestZeroMacAddr);
+ params.joinExistingGroup = kTestGroupIsJoin;
+ params.keyMgmtMask = 0;
+ params.vendorData = kTestVendorDataOptional;
+
+ EXPECT_TRUE(p2p_iface_->addGroupWithConfigurationParams(params).isOk());
+}
+
+/*
* Find
*/
TEST_P(SupplicantP2pIfaceAidlTest, Find) {
@@ -529,6 +596,34 @@
}
/*
+ * FindWithParams
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, FindWithParams) {
+ if (interface_version_ < 3) {
+ GTEST_SKIP() << "findWithParams is available as of Supplicant V3";
+ }
+
+ P2pDiscoveryInfo discoveryParams;
+ discoveryParams.timeoutInSec = kTestFindTimeout;
+ discoveryParams.vendorData = kTestVendorDataOptional;
+
+ discoveryParams.scanType = P2pScanType::FULL;
+ EXPECT_TRUE(p2p_iface_->findWithParams(discoveryParams).isOk());
+ EXPECT_TRUE(p2p_iface_->stopFind().isOk());
+ sleep(1);
+
+ discoveryParams.scanType = P2pScanType::SOCIAL;
+ EXPECT_TRUE(p2p_iface_->findWithParams(discoveryParams).isOk());
+ EXPECT_TRUE(p2p_iface_->stopFind().isOk());
+ sleep(1);
+
+ discoveryParams.scanType = P2pScanType::SPECIFIC_FREQ;
+ discoveryParams.frequencyMhz = 2412;
+ EXPECT_TRUE(p2p_iface_->findWithParams(discoveryParams).isOk());
+ EXPECT_TRUE(p2p_iface_->stopFind().isOk());
+}
+
+/*
* StopFind
*/
TEST_P(SupplicantP2pIfaceAidlTest, StopFind) {
@@ -555,6 +650,27 @@
}
/*
+ * ConnectWithParams
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, ConnectWithParams) {
+ if (interface_version_ < 3) {
+ GTEST_SKIP() << "connectWithParams is available as of Supplicant V3";
+ }
+
+ P2pConnectInfo connectInfo;
+ connectInfo.peerAddress = vecToArrayMacAddr(kTestMacAddr);
+ connectInfo.provisionMethod = WpsProvisionMethod::PBC;
+ connectInfo.preSelectedPin = kTestConnectPin;
+ connectInfo.joinExistingGroup = true;
+ connectInfo.persistent = false;
+ connectInfo.goIntent = kTestConnectGoIntent;
+ connectInfo.vendorData = kTestVendorDataOptional;
+
+ std::string pin;
+ EXPECT_TRUE(p2p_iface_->connectWithParams(connectInfo, &pin).isOk());
+}
+
+/*
* CancelConnect
*/
TEST_P(SupplicantP2pIfaceAidlTest, CancelConnect) {
@@ -614,6 +730,22 @@
}
/*
+ * ConfigureExtListenWithParams
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, ConfigureExtListenWithParams) {
+ if (interface_version_ < 3) {
+ GTEST_SKIP() << "configureExtListenWithParams is available as of Supplicant V3";
+ }
+
+ P2pExtListenInfo info;
+ info.periodMs = 400;
+ info.intervalMs = 400;
+ info.vendorData = kTestVendorDataOptional;
+
+ EXPECT_TRUE(p2p_iface_->configureExtListenWithParams(info).isOk());
+}
+
+/*
* FlushServices
*/
TEST_P(SupplicantP2pIfaceAidlTest, FlushServices) {
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
index 973b56a..a541f8f 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
@@ -72,6 +72,7 @@
const KeyMgmtMask kTestKeyMgmt =
static_cast<KeyMgmtMask>(static_cast<uint32_t>(KeyMgmtMask::WPA_PSK) |
static_cast<uint32_t>(KeyMgmtMask::WPA_EAP));
+const auto& kTestVendorData = generateOuiKeyedDataList(5);
} // namespace
@@ -110,6 +111,7 @@
initializeService();
supplicant_ = getSupplicant(GetParam().c_str());
ASSERT_NE(supplicant_, nullptr);
+ ASSERT_TRUE(supplicant_->getInterfaceVersion(&interface_version_).isOk());
ASSERT_TRUE(supplicant_
->setDebugParams(DebugLevel::EXCESSIVE,
true, // show timestamps
@@ -131,6 +133,7 @@
std::shared_ptr<ISupplicant> supplicant_;
std::shared_ptr<ISupplicantStaIface> sta_iface_;
std::shared_ptr<ISupplicantStaNetwork> sta_network_;
+ int interface_version_;
void removeNetwork() {
ASSERT_NE(sta_iface_, nullptr);
@@ -822,6 +825,26 @@
tlsV13Supported);
}
+/*
+ * disableEht
+ */
+TEST_P(SupplicantStaNetworkAidlTest, DisableEht) {
+ if (interface_version_ < 3) {
+ GTEST_SKIP() << "disableEht is available as of Supplicant V3";
+ }
+ EXPECT_TRUE(sta_network_->disableEht().isOk());
+}
+
+/*
+ * SetVendorData
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetVendorData) {
+ if (interface_version_ < 3) {
+ GTEST_SKIP() << "setVendorData is available as of Supplicant V3";
+ }
+ EXPECT_TRUE(sta_network_->setVendorData(kTestVendorData).isOk());
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaNetworkAidlTest);
INSTANTIATE_TEST_SUITE_P(Supplicant, SupplicantStaNetworkAidlTest,
testing::ValuesIn(android::getAidlHalInstanceNames(
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h b/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
index f2cb3f6..51793fd 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
@@ -16,14 +16,18 @@
#pragma once
+#include <android/persistable_bundle_aidl.h>
+
#include "supplicant_aidl_test_utils.h"
#include "supplicant_legacy_test_utils.h"
+using aidl::android::hardware::wifi::common::OuiKeyedData;
using aidl::android::hardware::wifi::supplicant::IfaceInfo;
using aidl::android::hardware::wifi::supplicant::ISupplicant;
using aidl::android::hardware::wifi::supplicant::ISupplicantP2pIface;
using aidl::android::hardware::wifi::supplicant::ISupplicantStaIface;
using aidl::android::hardware::wifi::supplicant::KeyMgmtMask;
+using aidl::android::os::PersistableBundle;
std::string getStaIfaceName() {
std::array<char, PROPERTY_VALUE_MAX> buffer;
@@ -91,3 +95,42 @@
}
return supplicant;
}
+
+std::array<uint8_t, 6> vecToArrayMacAddr(std::vector<uint8_t> vectorAddr) {
+ std::array<uint8_t, 6> arrayAddr;
+ std::copy(vectorAddr.begin(), vectorAddr.begin() + 6, arrayAddr.begin());
+ return arrayAddr;
+}
+
+OuiKeyedData generateOuiKeyedData(int oui) {
+ PersistableBundle bundle;
+ bundle.putString("stringKey", "stringValue");
+ bundle.putInt("intKey", 12345);
+
+ OuiKeyedData data;
+ data.oui = oui;
+ data.vendorData = bundle;
+ return data;
+}
+
+std::vector<OuiKeyedData> generateOuiKeyedDataList(int size) {
+ std::vector<OuiKeyedData> dataList;
+ for (int i = 0; i < size; i++) {
+ dataList.push_back(generateOuiKeyedData(i + 1));
+ }
+ return dataList;
+}
+
+// Wraps generateOuiKeyedData result in std::optional
+std::optional<OuiKeyedData> generateOuiKeyedDataOptional(int oui) {
+ return std::optional<OuiKeyedData>{generateOuiKeyedData(oui)};
+}
+
+// Generate OuiKeyedData list fully wrapped in std::optional
+std::optional<std::vector<std::optional<OuiKeyedData>>> generateOuiKeyedDataListOptional(int size) {
+ std::vector<std::optional<OuiKeyedData>> dataList;
+ for (int i = 0; i < size; i++) {
+ dataList.push_back(generateOuiKeyedDataOptional(i + 1));
+ }
+ return std::optional<std::vector<std::optional<OuiKeyedData>>>{dataList};
+}