Merge "Clarifiy ADR states in documentation"
diff --git a/Android.bp b/Android.bp
index 9e1df13..00ba1e2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -15,7 +15,6 @@
cc_defaults {
name: "VtsHalTargetTestDefaults",
defaults: [
- "vts_target_tests_defaults",
"hidl_defaults",
],
diff --git a/audio/7.0/IDevice.hal b/audio/7.0/IDevice.hal
index eecd92e..e30e545 100644
--- a/audio/7.0/IDevice.hal
+++ b/audio/7.0/IDevice.hal
@@ -117,7 +117,7 @@
AudioIoHandle ioHandle,
DeviceAddress device,
AudioConfig config,
- bitfield<AudioOutputFlag> flags,
+ vec<AudioInOutFlag> flags,
SourceMetadata sourceMetadata) generates (
Result retval,
IStreamOut outStream,
@@ -142,7 +142,7 @@
AudioIoHandle ioHandle,
DeviceAddress device,
AudioConfig config,
- bitfield<AudioInputFlag> flags,
+ vec<AudioInOutFlag> flags,
SinkMetadata sinkMetadata) generates (
Result retval,
IStreamIn inStream,
diff --git a/audio/7.0/IStream.hal b/audio/7.0/IStream.hal
index 789cb1d..4fe8218 100644
--- a/audio/7.0/IStream.hal
+++ b/audio/7.0/IStream.hal
@@ -44,49 +44,23 @@
getBufferSize() generates (uint64_t bufferSize);
/**
- * Return supported native sampling rates of the stream for a given format.
- * A supported native sample rate is a sample rate that can be efficiently
- * played by the hardware (typically without sample-rate conversions).
+ * Return supported audio profiles for this particular stream. This method
+ * is normally called for streams opened on devices that use dynamic
+ * profiles, e.g. HDMI and USB interfaces. Please note that supported
+ * profiles of the stream may differ from the capabilities of the connected
+ * physical device.
*
- * This function is only called for dynamic profile. If called for
- * non-dynamic profile is should return NOT_SUPPORTED or the same list
- * as in audio_policy_configuration.xml.
- *
- * Calling this method is equivalent to getting
- * AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES on the legacy HAL.
- *
- *
- * @param format audio format for which the sample rates are supported.
- * @return retval operation completion status.
- * Must be OK if the format is supported.
- * @return sampleRateHz supported sample rates.
- */
- getSupportedSampleRates(AudioFormat format)
- generates (Result retval, vec<uint32_t> sampleRates);
-
- /**
- * Return supported channel masks of the stream. Calling this method is
- * equivalent to getting AUDIO_PARAMETER_STREAM_SUP_CHANNELS on the legacy
- * HAL.
- *
- * @param format audio format for which the channel masks are supported.
- * @return retval operation completion status.
- * Must be OK if the format is supported.
- * @return masks supported audio masks.
- */
- getSupportedChannelMasks(AudioFormat format)
- generates (Result retval, vec<vec<AudioChannelMask>> masks);
-
- /**
- * Return supported audio formats of the stream. Calling this method is
- * equivalent to getting AUDIO_PARAMETER_STREAM_SUP_FORMATS on the legacy
- * HAL.
+ * For devices with fixed configurations, e.g. built-in audio devices, all
+ * the profiles are specified in the audio_policy_configuration.xml
+ * file. For such devices, this method must return the configuration from
+ * the config file, or NOT_SUPPORTED retval.
*
* @return retval operation completion status.
- * @return formats supported audio formats.
+ * @return formats supported audio profiles.
* Must be non empty if retval is OK.
*/
- getSupportedFormats() generates (Result retval, vec<AudioFormat> formats);
+ getSupportedProfiles()
+ generates (Result retval, vec<AudioProfile> profiles);
/**
* Retrieves basic stream configuration: sample rate, audio format,
@@ -94,18 +68,18 @@
*
* @return config basic stream configuration.
*/
- getAudioProperties() generates (AudioBasicConfig config);
+ getAudioProperties() generates (AudioConfigBase config);
/**
* Sets stream parameters. Only sets parameters that are specified.
- * See the description of AudioBasicConfig for the details.
+ * See the description of AudioConfigBase for the details.
*
* Optional method. If implemented, only called on a stopped stream.
*
* @param config basic stream configuration.
* @return retval operation completion status.
*/
- setAudioProperties(AudioBasicConfig config) generates (Result retval);
+ setAudioProperties(AudioConfigBase config) generates (Result retval);
/**
* Applies audio effect to the stream.
diff --git a/audio/7.0/IStreamOut.hal b/audio/7.0/IStreamOut.hal
index 38d750f..0951a9e 100644
--- a/audio/7.0/IStreamOut.hal
+++ b/audio/7.0/IStreamOut.hal
@@ -271,8 +271,6 @@
* timestamp must correspond to N rather than N+M. The terms 'recent' and
* 'small' are not defined. They reflect the quality of the implementation.
*
- * Optional method
- *
* @return retval operation completion status.
* @return frames count of presented audio frames.
* @return timeStamp associated clock time.
diff --git a/audio/7.0/config/api/current.txt b/audio/7.0/config/api/current.txt
index fd9a8ef..453ed16 100644
--- a/audio/7.0/config/api/current.txt
+++ b/audio/7.0/config/api/current.txt
@@ -44,10 +44,12 @@
enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_CALL_MONO;
enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO;
enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_NONE;
enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT0POINT2;
enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1;
enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1POINT2;
enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT0POINT2;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT1;
enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT1POINT2;
enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1;
enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1POINT2;
@@ -70,6 +72,8 @@
enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A;
enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO_HAPTIC_AB;
enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_SURROUND;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_TRI;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_TRI_BACK;
}
public enum AudioContentType {
@@ -87,6 +91,7 @@
enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET;
enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_AUX_DIGITAL;
enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BACK_MIC;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLE_HEADSET;
enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_BLE;
enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
@@ -117,6 +122,8 @@
enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_AUX_DIGITAL;
enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_AUX_LINE;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLE_HEADSET;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLE_SPEAKER;
enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
@@ -191,7 +198,6 @@
enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_HD;
enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_TWSP;
enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_CELT;
- enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DEFAULT;
enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DOLBY_TRUEHD;
enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DSD;
enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DTS;
@@ -206,9 +212,11 @@
enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_HE_AAC_V1;
enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_HE_AAC_V2;
enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_IEC61937;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LC3;
enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LDAC;
enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LHDC;
enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LHDC_LL;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT;
enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT_1_0;
enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT_2_0;
enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT_2_1;
@@ -228,6 +236,42 @@
enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_WMA_PRO;
}
+ public enum AudioGainMode {
+ method public String getRawName();
+ enum_constant public static final audio.policy.configuration.V7_0.AudioGainMode AUDIO_GAIN_MODE_CHANNELS;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioGainMode AUDIO_GAIN_MODE_JOINT;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioGainMode AUDIO_GAIN_MODE_RAMP;
+ }
+
+ public enum AudioInOutFlag {
+ method public String getRawName();
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_DIRECT;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_FAST;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_HW_AV_SYNC;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_HW_HOTWORD;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_MMAP_NOIRQ;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_NONE;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_RAW;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_SYNC;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_VOIP_TX;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_DIRECT;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_DIRECT_PCM;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_FAST;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_HW_AV_SYNC;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_INCALL_MUSIC;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_MMAP_NOIRQ;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_NONE;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_NON_BLOCKING;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_PRIMARY;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_RAW;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_SYNC;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_TTS;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_VOIP_RX;
+ }
+
public class AudioPolicyConfiguration {
ctor public AudioPolicyConfiguration();
method public audio.policy.configuration.V7_0.GlobalConfiguration getGlobalConfiguration();
@@ -264,6 +308,7 @@
enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_ALARM;
enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_ASSISTANT;
enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_BLUETOOTH_SCO;
+ enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_CALL_ASSISTANT;
enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_DTMF;
enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_ENFORCED_AUDIBLE;
enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_MUSIC;
@@ -337,13 +382,6 @@
enum_constant public static final audio.policy.configuration.V7_0.EngineSuffix configurable;
}
- public enum GainMode {
- method public String getRawName();
- enum_constant public static final audio.policy.configuration.V7_0.GainMode AUDIO_GAIN_MODE_CHANNELS;
- enum_constant public static final audio.policy.configuration.V7_0.GainMode AUDIO_GAIN_MODE_JOINT;
- enum_constant public static final audio.policy.configuration.V7_0.GainMode AUDIO_GAIN_MODE_RAMP;
- }
-
public class Gains {
ctor public Gains();
method public java.util.List<audio.policy.configuration.V7_0.Gains.Gain> getGain();
@@ -357,7 +395,7 @@
method public int getMaxValueMB();
method public int getMinRampMs();
method public int getMinValueMB();
- method public audio.policy.configuration.V7_0.GainMode getMode();
+ method public java.util.List<audio.policy.configuration.V7_0.AudioGainMode> getMode();
method public String getName();
method public int getStepValueMB();
method public boolean getUseForVolume();
@@ -367,7 +405,7 @@
method public void setMaxValueMB(int);
method public void setMinRampMs(int);
method public void setMinValueMB(int);
- method public void setMode(audio.policy.configuration.V7_0.GainMode);
+ method public void setMode(java.util.List<audio.policy.configuration.V7_0.AudioGainMode>);
method public void setName(String);
method public void setStepValueMB(int);
method public void setUseForVolume(boolean);
@@ -396,7 +434,7 @@
public static class MixPorts.MixPort {
ctor public MixPorts.MixPort();
- method public String getFlags();
+ method public java.util.List<audio.policy.configuration.V7_0.AudioInOutFlag> getFlags();
method public audio.policy.configuration.V7_0.Gains getGains();
method public long getMaxActiveCount();
method public long getMaxOpenCount();
@@ -404,7 +442,7 @@
method public java.util.List<audio.policy.configuration.V7_0.AudioUsage> getPreferredUsage();
method public java.util.List<audio.policy.configuration.V7_0.Profile> getProfile();
method public audio.policy.configuration.V7_0.Role getRole();
- method public void setFlags(String);
+ method public void setFlags(java.util.List<audio.policy.configuration.V7_0.AudioInOutFlag>);
method public void setGains(audio.policy.configuration.V7_0.Gains);
method public void setMaxActiveCount(long);
method public void setMaxOpenCount(long);
diff --git a/audio/7.0/config/audio_policy_configuration.xsd b/audio/7.0/config/audio_policy_configuration.xsd
index 4555a88..6784828 100644
--- a/audio/7.0/config/audio_policy_configuration.xsd
+++ b/audio/7.0/config/audio_policy_configuration.xsd
@@ -155,16 +155,46 @@
<xs:element name="item" type="xs:token" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
- <xs:simpleType name="audioInOutFlags">
+ <xs:simpleType name="audioInOutFlag">
<xs:annotation>
<xs:documentation xml:lang="en">
- "|" separated list of audio_output_flags_t or audio_input_flags_t.
+ The flags indicate suggested stream attributes supported by the profile.
+ Use of AUDIO_{INPUT|OUTPUT}_FLAG_NONE in the XML file isn't required
+ as empty flag lists are allowed. However these constants are useful for
+ representing an empty enum value.
</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
- <xs:pattern value="|[_A-Z]+(\|[_A-Z]+)*"/>
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_NONE" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_DIRECT" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_PRIMARY" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_FAST" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_DEEP_BUFFER" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_NON_BLOCKING" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_HW_AV_SYNC" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_TTS" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_RAW" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_SYNC" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_DIRECT_PCM" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_MMAP_NOIRQ" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_VOIP_RX" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_INCALL_MUSIC" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_NONE" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_FAST" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_HW_HOTWORD" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_RAW" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_SYNC" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_MMAP_NOIRQ" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_VOIP_TX" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_HW_AV_SYNC" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_DIRECT" />
</xs:restriction>
</xs:simpleType>
+ <xs:simpleType name="audioInOutFlags">
+ <xs:list itemType="audioInOutFlag" />
+ </xs:simpleType>
<xs:simpleType name="role">
<xs:restriction base="xs:string">
<xs:enumeration value="sink"/>
@@ -226,8 +256,8 @@
<xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP"/>
<xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES"/>
<xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER"/>
- <xs:enumeration value="AUDIO_DEVICE_OUT_AUX_DIGITAL"/>
<xs:enumeration value="AUDIO_DEVICE_OUT_HDMI"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_AUX_DIGITAL"/>
<xs:enumeration value="AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET"/>
<xs:enumeration value="AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET"/>
<xs:enumeration value="AUDIO_DEVICE_OUT_USB_ACCESSORY"/>
@@ -246,6 +276,8 @@
<xs:enumeration value="AUDIO_DEVICE_OUT_USB_HEADSET"/>
<xs:enumeration value="AUDIO_DEVICE_OUT_HEARING_AID"/>
<xs:enumeration value="AUDIO_DEVICE_OUT_ECHO_CANCELLER"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BLE_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BLE_SPEAKER"/>
<xs:enumeration value="AUDIO_DEVICE_OUT_DEFAULT"/>
<xs:enumeration value="AUDIO_DEVICE_OUT_STUB"/>
@@ -254,8 +286,8 @@
<xs:enumeration value="AUDIO_DEVICE_IN_BUILTIN_MIC"/>
<xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET"/>
<xs:enumeration value="AUDIO_DEVICE_IN_WIRED_HEADSET"/>
- <xs:enumeration value="AUDIO_DEVICE_IN_AUX_DIGITAL"/>
<xs:enumeration value="AUDIO_DEVICE_IN_HDMI"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_AUX_DIGITAL"/>
<xs:enumeration value="AUDIO_DEVICE_IN_VOICE_CALL"/>
<xs:enumeration value="AUDIO_DEVICE_IN_TELEPHONY_RX"/>
<xs:enumeration value="AUDIO_DEVICE_IN_BACK_MIC"/>
@@ -277,6 +309,7 @@
<xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_BLE"/>
<xs:enumeration value="AUDIO_DEVICE_IN_HDMI_ARC"/>
<xs:enumeration value="AUDIO_DEVICE_IN_ECHO_REFERENCE"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_BLE_HEADSET"/>
<xs:enumeration value="AUDIO_DEVICE_IN_DEFAULT"/>
<xs:enumeration value="AUDIO_DEVICE_IN_STUB"/>
</xs:restriction>
@@ -296,7 +329,6 @@
</xs:simpleType>
<xs:simpleType name="audioFormat">
<xs:restriction base="xs:string">
- <xs:enumeration value="AUDIO_FORMAT_DEFAULT" />
<xs:enumeration value="AUDIO_FORMAT_PCM_16_BIT" />
<xs:enumeration value="AUDIO_FORMAT_PCM_8_BIT"/>
<xs:enumeration value="AUDIO_FORMAT_PCM_32_BIT"/>
@@ -317,22 +349,14 @@
<xs:enumeration value="AUDIO_FORMAT_AAC_LD"/>
<xs:enumeration value="AUDIO_FORMAT_AAC_HE_V2"/>
<xs:enumeration value="AUDIO_FORMAT_AAC_ELD"/>
- <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_MAIN"/>
- <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_LC"/>
- <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_SSR"/>
- <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_LTP"/>
- <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_HE_V1"/>
- <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_SCALABLE"/>
- <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_ERLC"/>
- <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_LD"/>
- <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_HE_V2"/>
- <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_ELD"/>
- <xs:enumeration value="AUDIO_FORMAT_VORBIS"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_XHE"/>
<xs:enumeration value="AUDIO_FORMAT_HE_AAC_V1"/>
<xs:enumeration value="AUDIO_FORMAT_HE_AAC_V2"/>
+ <xs:enumeration value="AUDIO_FORMAT_VORBIS"/>
<xs:enumeration value="AUDIO_FORMAT_OPUS"/>
<xs:enumeration value="AUDIO_FORMAT_AC3"/>
<xs:enumeration value="AUDIO_FORMAT_E_AC3"/>
+ <xs:enumeration value="AUDIO_FORMAT_E_AC3_JOC"/>
<xs:enumeration value="AUDIO_FORMAT_DTS"/>
<xs:enumeration value="AUDIO_FORMAT_DTS_HD"/>
<xs:enumeration value="AUDIO_FORMAT_IEC61937"/>
@@ -352,17 +376,26 @@
<xs:enumeration value="AUDIO_FORMAT_ALAC"/>
<xs:enumeration value="AUDIO_FORMAT_APE"/>
<xs:enumeration value="AUDIO_FORMAT_AAC_ADTS"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_MAIN"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_LC"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_SSR"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_LTP"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_HE_V1"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_SCALABLE"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_ERLC"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_LD"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_HE_V2"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_ELD"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_XHE"/>
<xs:enumeration value="AUDIO_FORMAT_SBC"/>
<xs:enumeration value="AUDIO_FORMAT_APTX"/>
<xs:enumeration value="AUDIO_FORMAT_APTX_HD"/>
<xs:enumeration value="AUDIO_FORMAT_AC4"/>
<xs:enumeration value="AUDIO_FORMAT_LDAC"/>
- <xs:enumeration value="AUDIO_FORMAT_E_AC3_JOC"/>
+ <xs:enumeration value="AUDIO_FORMAT_MAT"/>
<xs:enumeration value="AUDIO_FORMAT_MAT_1_0"/>
<xs:enumeration value="AUDIO_FORMAT_MAT_2_0"/>
<xs:enumeration value="AUDIO_FORMAT_MAT_2_1"/>
- <xs:enumeration value="AUDIO_FORMAT_AAC_XHE"/>
- <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_XHE"/>
<xs:enumeration value="AUDIO_FORMAT_AAC_LATM"/>
<xs:enumeration value="AUDIO_FORMAT_AAC_LATM_LC"/>
<xs:enumeration value="AUDIO_FORMAT_AAC_LATM_HE_V1"/>
@@ -372,6 +405,7 @@
<xs:enumeration value="AUDIO_FORMAT_LHDC"/>
<xs:enumeration value="AUDIO_FORMAT_LHDC_LL"/>
<xs:enumeration value="AUDIO_FORMAT_APTX_TWSP"/>
+ <xs:enumeration value="AUDIO_FORMAT_LC3"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="extendableAudioFormat">
@@ -440,9 +474,13 @@
</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_CHANNEL_NONE"/>
<xs:enumeration value="AUDIO_CHANNEL_OUT_MONO"/>
<xs:enumeration value="AUDIO_CHANNEL_OUT_STEREO"/>
<xs:enumeration value="AUDIO_CHANNEL_OUT_2POINT1"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_TRI"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_TRI_BACK"/>
+ <xs:enumeration value="AUDIO_CHANNEL_OUT_3POINT1"/>
<xs:enumeration value="AUDIO_CHANNEL_OUT_2POINT0POINT2"/>
<xs:enumeration value="AUDIO_CHANNEL_OUT_2POINT1POINT2"/>
<xs:enumeration value="AUDIO_CHANNEL_OUT_3POINT0POINT2"/>
@@ -513,19 +551,27 @@
<xs:attribute name="samplingRates" type="samplingRates" use="optional"/>
<xs:attribute name="channelMasks" type="channelMasks" use="optional"/>
</xs:complexType>
- <xs:simpleType name="gainMode">
+ <xs:simpleType name="audioGainMode">
<xs:restriction base="xs:string">
<xs:enumeration value="AUDIO_GAIN_MODE_JOINT"/>
<xs:enumeration value="AUDIO_GAIN_MODE_CHANNELS"/>
<xs:enumeration value="AUDIO_GAIN_MODE_RAMP"/>
</xs:restriction>
</xs:simpleType>
+ <xs:simpleType name="audioGainModeMaskUnrestricted">
+ <xs:list itemType="audioGainMode" />
+ </xs:simpleType>
+ <xs:simpleType name='audioGainModeMask'>
+ <xs:restriction base='audioGainModeMaskUnrestricted'>
+ <xs:minLength value='1' />
+ </xs:restriction>
+ </xs:simpleType>
<xs:complexType name="gains">
<xs:sequence>
<xs:element name="gain" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="name" type="xs:token" use="required"/>
- <xs:attribute name="mode" type="gainMode" use="required"/>
+ <xs:attribute name="mode" type="audioGainModeMask" use="required"/>
<xs:attribute name="channel_mask" type="audioChannelMask" use="optional"/>
<xs:attribute name="minValueMB" type="xs:int" use="optional"/>
<xs:attribute name="maxValueMB" type="xs:int" use="optional"/>
@@ -645,6 +691,7 @@
<xs:enumeration value="AUDIO_STREAM_ASSISTANT"/>
<xs:enumeration value="AUDIO_STREAM_REROUTING"/>
<xs:enumeration value="AUDIO_STREAM_PATCH"/>
+ <xs:enumeration value="AUDIO_STREAM_CALL_ASSISTANT"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="audioSource">
diff --git a/audio/7.0/config/update_audio_policy_config.sh b/audio/7.0/config/update_audio_policy_config.sh
index 8714b5f..051a0df 100755
--- a/audio/7.0/config/update_audio_policy_config.sh
+++ b/audio/7.0/config/update_audio_policy_config.sh
@@ -128,6 +128,7 @@
for F in $SOURCE_FILES; do
updateFile ${F} "channelMasks" ","
updateFile ${F} "samplingRates" ","
+ updateFile ${F} "flags" "|"
done;
updateIncludes() {
diff --git a/audio/7.0/types.hal b/audio/7.0/types.hal
index 15ca492..7c050c1 100644
--- a/audio/7.0/types.hal
+++ b/audio/7.0/types.hal
@@ -30,7 +30,6 @@
NOT_SUPPORTED
};
-@export(name="audio_drain_type_t", value_prefix="AUDIO_DRAIN_")
enum AudioDrain : int32_t {
/** drain() returns when all data has been played. */
ALL,
@@ -315,7 +314,7 @@
* Behavior when the values for speed and / or pitch are out
* of applicable range.
*/
-@export(name="audio_timestretch_fallback_mode_t", value_prefix="AUDIO_TIMESTRETCH_FALLBACK_")
+@export(name="", value_prefix="HAL_AUDIO_TIMESTRETCH_FALLBACK_")
enum TimestretchFallbackMode : int32_t {
// Need to be in sync with AUDIO_FALLBACK_MODE_* constants in
// frameworks/base/media/java/android/media/PlaybackParams.java
@@ -357,56 +356,15 @@
};
/**
- * The audio output flags serve two purposes:
+ * The audio flags serve two purposes:
*
- * - when an output stream is created they indicate its attributes;
+ * - when a stream is created they indicate its attributes;
*
- * - when present in an output profile descriptor listed for a particular audio
- * hardware module, they indicate that an output stream can be opened that
+ * - when present in a profile descriptor listed for a particular audio
+ * hardware module, they indicate that a stream can be opened that
* supports the attributes indicated by the flags.
+ *
+ * See 'audioIoFlag' in audio_policy_configuration.xsd for the
+ * list of allowed values.
*/
-@export(name="audio_output_flags_t", value_prefix="AUDIO_OUTPUT_FLAG_")
-enum AudioOutputFlag : int32_t {
- NONE = 0x0, // no attributes
- DIRECT = 0x1, // this output directly connects a track
- // to one output stream: no software mixer
- PRIMARY = 0x2, // this output is the primary output of the device. It is
- // unique and must be present. It is opened by default and
- // receives routing, audio mode and volume controls related
- // to voice calls.
- FAST = 0x4, // output supports "fast tracks", defined elsewhere
- DEEP_BUFFER = 0x8, // use deep audio buffers
- COMPRESS_OFFLOAD = 0x10, // offload playback of compressed streams to
- // hardware codec
- NON_BLOCKING = 0x20, // use non-blocking write
- HW_AV_SYNC = 0x40, // output uses a hardware A/V sync
- TTS = 0x80, // output for streams transmitted through speaker at a
- // sample rate high enough to accommodate lower-range
- // ultrasonic p/b
- RAW = 0x100, // minimize signal processing
- SYNC = 0x200, // synchronize I/O streams
- IEC958_NONAUDIO = 0x400, // Audio stream contains compressed audio in SPDIF
- // data bursts, not PCM.
- DIRECT_PCM = 0x2000, // Audio stream containing PCM data that needs
- // to pass through compress path for DSP post proc.
- MMAP_NOIRQ = 0x4000, // output operates in MMAP no IRQ mode.
- VOIP_RX = 0x8000, // preferred output for VoIP calls.
- /** preferred output for call music */
- INCALL_MUSIC = 0x10000,
-};
-
-/**
- * The audio input flags are analogous to audio output flags.
- */
-@export(name="audio_input_flags_t", value_prefix="AUDIO_INPUT_FLAG_")
-enum AudioInputFlag : int32_t {
- NONE = 0x0, // no attributes
- FAST = 0x1, // prefer an input that supports "fast tracks"
- HW_HOTWORD = 0x2, // prefer an input that captures from hw hotword source
- RAW = 0x4, // minimize signal processing
- SYNC = 0x8, // synchronize I/O streams
- MMAP_NOIRQ = 0x10, // input operates in MMAP no IRQ mode.
- VOIP_TX = 0x20, // preferred input for VoIP calls.
- HW_AV_SYNC = 0x40, // input connected to an output that uses a hardware A/V sync
- DIRECT = 0x80, // for acquiring encoded streams
-};
+typedef string AudioInOutFlag;
diff --git a/audio/README b/audio/README
deleted file mode 100644
index afafbe3..0000000
--- a/audio/README
+++ /dev/null
@@ -1,36 +0,0 @@
-Directory structure of the audio HIDL related code.
-
-Run `common/all-versions/copyHAL.sh` to create a new version of the audio HAL
-based on an existing one.
-
-audio
-|-- 2.0 <== core 2.0 HIDL API. .hal can not be moved into the core directory
-| because that would change its namespace and include path
-|-- 4.0 <== Version 4.0 of the core API
-|
-|-- ...
-|
-|-- common <== code common to audio core and effect API
-| |-- 2.0 <== HIDL API of V2
-| |-- 4.0
-| |-- ...
-| `-- all-versions <== code common to all version of both core and effect API
-| |-- default <== implementation shared code between core and effect impl
-| |-- test <== utilities used by tests
-| `-- util <== utilities used by both implementation and tests
-|
-|-- core <== VTS and default implementation of the core API (not HIDL, see /audio/2.0))
-| `-- all-versions <== Code is version independent through #if and separate files
-| |-- default <== code that wraps the legacy API
-| `-- vts <== vts of core API
-| |-- 2.0 <== 2.0 specific tests and helpers
-| |-- 4.0
-| |-- ...
-|
-`-- effect <== idem for the effect API
- |-- 2.0
- |-- 4.0
- |-- ...
- `-- all-versions
- |-- default
- `-- vts
diff --git a/audio/README.md b/audio/README.md
new file mode 100644
index 0000000..b77b9ba
--- /dev/null
+++ b/audio/README.md
@@ -0,0 +1,53 @@
+# Audio HAL
+
+Directory structure of the audio HAL related code.
+
+Run `common/all-versions/copyHAL.sh` to create a new version of the audio HAL
+based on an existing one.
+
+## Directory Structure
+
+* `2.0` -- version 2.0 of the core HIDL API. Note that `.hal` files
+ can not be moved into the `core` directory because that would change
+ its namespace and include path.
+ - `config` -- the XSD schema for the Audio Policy Manager
+ configuration file.
+* `4.0` -- version 4.0 of the core HIDL API.
+* ...
+* `common` -- common types for audio core and effect HIDL API.
+ - `2.0` -- version 2.0 of the common types HIDL API.
+ - `4.0` -- version 4.0.
+ - ...
+ - `7.0` -- version 7.0.
+ - `example` -- example implementation of the core and effect
+ V7.0 API. It represents a "fake" audio HAL that doesn't
+ actually communicate with hardware.
+ - `all-versions` -- code common to all version of both core and effect API.
+ - `default` -- shared code of the default implementation.
+ - `service` -- vendor HAL service for hosting the default
+ implementation.
+ - `test` -- utilities used by tests.
+ - `util` -- utilities used by both implementation and tests.
+* `core` -- VTS tests and the default implementation of the core API
+ (not HIDL API, it's in `audio/N.M`).
+ - `7.0` -- code specific to version V7.0 of the core HIDL API
+ - `all-versions` -- the code is common between all versions,
+ version-specific parts are enclosed into conditional directives
+ of preprocessor or reside in dedicated files.
+ - `default` -- code that wraps the legacy API (from
+ `hardware/libhardware`).
+ - `vts` VTS tests for the core HIDL API.
+* `effect` -- same for the effect HIDL API.
+ - `2.0`
+ - `config` -- the XSD schema for the Audio Effects configuration
+ file.
+ - `4.0`
+ - ...
+ - `all-versions`
+ - `default`
+ - `vts`
+* `policy` -- Configurable Audio Policy schemes.
+ - `1.0` -- note that versions of CAP are not linked to the versions
+ of audio HAL.
+ - `vts` -- VTS tests for validating actual configuration files.
+ - `xml` -- XSD schemas for CAP configuration files.
diff --git a/audio/common/7.0/Android.bp b/audio/common/7.0/Android.bp
index e24871c..1c016b4 100644
--- a/audio/common/7.0/Android.bp
+++ b/audio/common/7.0/Android.bp
@@ -16,9 +16,12 @@
cc_library {
name: "android.hardware.audio.common@7.0-enums",
vendor_available: true,
- generated_sources: ["audio_policy_configuration_V7_0"],
generated_headers: ["audio_policy_configuration_V7_0"],
+ generated_sources: ["audio_policy_configuration_V7_0"],
header_libs: ["libxsdc-utils"],
+ export_generated_headers: ["audio_policy_configuration_V7_0"],
+ export_header_lib_headers: ["libxsdc-utils"],
+ export_include_dirs: ["enums/include"],
shared_libs: [
"libbase",
"liblog",
diff --git a/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h b/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h
new file mode 100644
index 0000000..cedcab3
--- /dev/null
+++ b/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AUDIO_POLICY_CONFIGURATION_V7_0_ENUMS_H
+#define AUDIO_POLICY_CONFIGURATION_V7_0_ENUMS_H
+
+#include <sys/types.h>
+
+#include <audio_policy_configuration_V7_0.h>
+
+namespace audio::policy::configuration::V7_0 {
+
+static inline size_t getChannelCount(AudioChannelMask mask) {
+ switch (mask) {
+ case AudioChannelMask::AUDIO_CHANNEL_NONE:
+ return 0;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_MONO:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_1:
+ return 1;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO_HAPTIC_A:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_HAPTIC_AB:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_STEREO:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_FRONT_BACK:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_VOICE_CALL_MONO:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_2:
+ return 2;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT1:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO_HAPTIC_AB:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_TRI:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_TRI_BACK:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_3:
+ return 3;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT0POINT2:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_3POINT1:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD_BACK:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD_SIDE:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_SURROUND:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO_HAPTIC_AB:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_2POINT0POINT2:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_4:
+ return 4;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT1POINT2:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_3POINT0POINT2:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_PENTA:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_2POINT1POINT2:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_3POINT0POINT2:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_5:
+ return 5;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_3POINT1POINT2:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1_BACK:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1_SIDE:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_6:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_3POINT1POINT2:
+ case AudioChannelMask::AUDIO_CHANNEL_IN_5POINT1:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_6:
+ return 6;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_6POINT1:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_7:
+ return 7;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1POINT2:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_7POINT1:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_8:
+ return 8;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_9:
+ return 9;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1POINT4:
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_7POINT1POINT2:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_10:
+ return 10;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_11:
+ return 11;
+ case AudioChannelMask::AUDIO_CHANNEL_OUT_7POINT1POINT4:
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_12:
+ return 12;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_13:
+ return 13;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_14:
+ return 14;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_15:
+ return 15;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_16:
+ return 16;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_17:
+ return 17;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_18:
+ return 18;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_19:
+ return 19;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_20:
+ return 20;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_21:
+ return 21;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_22:
+ return 22;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_23:
+ return 23;
+ case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_24:
+ return 24;
+ case AudioChannelMask::UNKNOWN:
+ return 0;
+ // No default to make sure all cases are covered.
+ }
+ // This is to avoid undefined behavior if 'mask' isn't a valid enum value.
+ return 0;
+}
+
+static inline ssize_t getChannelCount(const std::string& mask) {
+ return getChannelCount(stringToAudioChannelMask(mask));
+}
+
+static inline bool isOutputDevice(AudioDevice device) {
+ switch (device) {
+ case AudioDevice::UNKNOWN:
+ case AudioDevice::AUDIO_DEVICE_NONE:
+ return false;
+ case AudioDevice::AUDIO_DEVICE_OUT_EARPIECE:
+ case AudioDevice::AUDIO_DEVICE_OUT_SPEAKER:
+ case AudioDevice::AUDIO_DEVICE_OUT_WIRED_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
+ case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_SCO:
+ case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
+ case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
+ case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
+ case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
+ case AudioDevice::AUDIO_DEVICE_OUT_AUX_DIGITAL:
+ case AudioDevice::AUDIO_DEVICE_OUT_HDMI:
+ case AudioDevice::AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_OUT_USB_ACCESSORY:
+ case AudioDevice::AUDIO_DEVICE_OUT_USB_DEVICE:
+ case AudioDevice::AUDIO_DEVICE_OUT_REMOTE_SUBMIX:
+ case AudioDevice::AUDIO_DEVICE_OUT_TELEPHONY_TX:
+ case AudioDevice::AUDIO_DEVICE_OUT_LINE:
+ case AudioDevice::AUDIO_DEVICE_OUT_HDMI_ARC:
+ case AudioDevice::AUDIO_DEVICE_OUT_SPDIF:
+ case AudioDevice::AUDIO_DEVICE_OUT_FM:
+ case AudioDevice::AUDIO_DEVICE_OUT_AUX_LINE:
+ case AudioDevice::AUDIO_DEVICE_OUT_SPEAKER_SAFE:
+ case AudioDevice::AUDIO_DEVICE_OUT_IP:
+ case AudioDevice::AUDIO_DEVICE_OUT_BUS:
+ case AudioDevice::AUDIO_DEVICE_OUT_PROXY:
+ case AudioDevice::AUDIO_DEVICE_OUT_USB_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_OUT_HEARING_AID:
+ case AudioDevice::AUDIO_DEVICE_OUT_ECHO_CANCELLER:
+ case AudioDevice::AUDIO_DEVICE_OUT_BLE_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_OUT_BLE_SPEAKER:
+ case AudioDevice::AUDIO_DEVICE_OUT_DEFAULT:
+ case AudioDevice::AUDIO_DEVICE_OUT_STUB:
+ return true;
+ case AudioDevice::AUDIO_DEVICE_IN_COMMUNICATION:
+ case AudioDevice::AUDIO_DEVICE_IN_AMBIENT:
+ case AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC:
+ case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_IN_WIRED_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_IN_AUX_DIGITAL:
+ case AudioDevice::AUDIO_DEVICE_IN_HDMI:
+ case AudioDevice::AUDIO_DEVICE_IN_VOICE_CALL:
+ case AudioDevice::AUDIO_DEVICE_IN_TELEPHONY_RX:
+ case AudioDevice::AUDIO_DEVICE_IN_BACK_MIC:
+ case AudioDevice::AUDIO_DEVICE_IN_REMOTE_SUBMIX:
+ case AudioDevice::AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_IN_USB_ACCESSORY:
+ case AudioDevice::AUDIO_DEVICE_IN_USB_DEVICE:
+ case AudioDevice::AUDIO_DEVICE_IN_FM_TUNER:
+ case AudioDevice::AUDIO_DEVICE_IN_TV_TUNER:
+ case AudioDevice::AUDIO_DEVICE_IN_LINE:
+ case AudioDevice::AUDIO_DEVICE_IN_SPDIF:
+ case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_A2DP:
+ case AudioDevice::AUDIO_DEVICE_IN_LOOPBACK:
+ case AudioDevice::AUDIO_DEVICE_IN_IP:
+ case AudioDevice::AUDIO_DEVICE_IN_BUS:
+ case AudioDevice::AUDIO_DEVICE_IN_PROXY:
+ case AudioDevice::AUDIO_DEVICE_IN_USB_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_BLE:
+ case AudioDevice::AUDIO_DEVICE_IN_HDMI_ARC:
+ case AudioDevice::AUDIO_DEVICE_IN_ECHO_REFERENCE:
+ case AudioDevice::AUDIO_DEVICE_IN_BLE_HEADSET:
+ case AudioDevice::AUDIO_DEVICE_IN_DEFAULT:
+ case AudioDevice::AUDIO_DEVICE_IN_STUB:
+ return false;
+ // No default to make sure all cases are covered.
+ }
+ // This is to avoid undefined behavior if 'device' isn't a valid enum value.
+ return false;
+}
+
+static inline bool isOutputDevice(const std::string& device) {
+ return isOutputDevice(stringToAudioDevice(device));
+}
+
+} // namespace audio::policy::configuration::V7_0
+
+#endif // AUDIO_POLICY_CONFIGURATION_V7_0_ENUMS_H
diff --git a/audio/common/7.0/example/Android.bp b/audio/common/7.0/example/Android.bp
new file mode 100644
index 0000000..03c1cd8
--- /dev/null
+++ b/audio/common/7.0/example/Android.bp
@@ -0,0 +1,45 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_binary {
+ name: "android.hardware.audio@7.0-service.example",
+ vendor: true,
+ relative_install_path: "hw",
+ init_rc: ["android.hardware.audio@7.0-service.example.rc"],
+ vintf_fragments: ["android.hardware.audio@7.0-service.example.xml"],
+ srcs: [
+ "DevicesFactory.cpp",
+ "Effect.cpp",
+ "EffectsFactory.cpp",
+ "EqualizerEffect.cpp",
+ "LoudnessEnhancerEffect.cpp",
+ "service.cpp",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ shared_libs: [
+ "libcutils",
+ "libhidlbase",
+ "liblog",
+ "libxml2",
+ "libutils",
+ "android.hardware.audio@7.0",
+ "android.hardware.audio.common@7.0",
+ "android.hardware.audio.common@7.0-enums",
+ "android.hardware.audio.effect@7.0",
+ ],
+}
diff --git a/audio/common/7.0/example/DevicesFactory.cpp b/audio/common/7.0/example/DevicesFactory.cpp
new file mode 100644
index 0000000..ddd5fef
--- /dev/null
+++ b/audio/common/7.0/example/DevicesFactory.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "DevicesFactory7.0"
+#include <log/log.h>
+
+#include "DevicesFactory.h"
+
+using ::android::hardware::hidl_string;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+namespace android::hardware::audio::V7_0::implementation {
+
+Return<void> DevicesFactory::openDevice(const hidl_string& device, openDevice_cb _hidl_cb) {
+ (void)device;
+ _hidl_cb(Result::INVALID_ARGUMENTS, nullptr);
+ return Void();
+}
+
+Return<void> DevicesFactory::openPrimaryDevice(openPrimaryDevice_cb _hidl_cb) {
+ _hidl_cb(Result::INVALID_ARGUMENTS, nullptr);
+ return Void();
+}
+
+} // namespace android::hardware::audio::V7_0::implementation
diff --git a/audio/common/7.0/example/DevicesFactory.h b/audio/common/7.0/example/DevicesFactory.h
new file mode 100644
index 0000000..00f665c
--- /dev/null
+++ b/audio/common/7.0/example/DevicesFactory.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/audio/7.0/IDevicesFactory.h>
+
+namespace android::hardware::audio::V7_0::implementation {
+
+class DevicesFactory : public IDevicesFactory {
+ public:
+ DevicesFactory() = default;
+
+ ::android::hardware::Return<void> openDevice(const ::android::hardware::hidl_string& device,
+ openDevice_cb _hidl_cb) override;
+
+ ::android::hardware::Return<void> openPrimaryDevice(openPrimaryDevice_cb _hidl_cb) override;
+};
+
+} // namespace android::hardware::audio::V7_0::implementation
diff --git a/audio/common/7.0/example/Effect.cpp b/audio/common/7.0/example/Effect.cpp
new file mode 100644
index 0000000..423754d
--- /dev/null
+++ b/audio/common/7.0/example/Effect.cpp
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "EffectsFactory7.0"
+#include <log/log.h>
+
+#include <audio_policy_configuration_V7_0.h>
+
+#include "Effect.h"
+
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using namespace ::android::hardware::audio::common::V7_0;
+// Make an alias for enumerations generated from the APM config XSD.
+namespace xsd {
+using namespace ::audio::policy::configuration::V7_0;
+}
+
+namespace android::hardware::audio::effect::V7_0::implementation {
+
+Return<Result> Effect::init() {
+ return Result::OK;
+}
+
+Return<Result> Effect::setConfig(
+ const EffectConfig& config,
+ const ::android::sp<IEffectBufferProviderCallback>& inputBufferProvider,
+ const ::android::sp<IEffectBufferProviderCallback>& outputBufferProvider) {
+ (void)config;
+ (void)inputBufferProvider;
+ (void)outputBufferProvider;
+ return Result::OK;
+}
+
+Return<Result> Effect::reset() {
+ return Result::OK;
+}
+
+Return<Result> Effect::enable() {
+ if (!mEnabled) {
+ mEnabled = true;
+ return Result::OK;
+ } else {
+ return Result::NOT_SUPPORTED;
+ }
+}
+
+Return<Result> Effect::disable() {
+ if (mEnabled) {
+ mEnabled = false;
+ return Result::OK;
+ } else {
+ return Result::NOT_SUPPORTED;
+ }
+}
+
+Return<Result> Effect::setDevice(const DeviceAddress& device) {
+ (void)device;
+ return Result::OK;
+}
+
+Return<void> Effect::setAndGetVolume(const hidl_vec<uint32_t>& volumes,
+ setAndGetVolume_cb _hidl_cb) {
+ (void)volumes;
+ _hidl_cb(Result::OK, hidl_vec<uint32_t>{});
+ return Void();
+}
+
+Return<Result> Effect::volumeChangeNotification(const hidl_vec<uint32_t>& volumes) {
+ (void)volumes;
+ return Result::OK;
+}
+
+Return<Result> Effect::setAudioMode(AudioMode mode) {
+ (void)mode;
+ return Result::OK;
+}
+
+Return<Result> Effect::setConfigReverse(
+ const EffectConfig& config,
+ const ::android::sp<IEffectBufferProviderCallback>& inputBufferProvider,
+ const ::android::sp<IEffectBufferProviderCallback>& outputBufferProvider) {
+ (void)config;
+ (void)inputBufferProvider;
+ (void)outputBufferProvider;
+ return Result::OK;
+}
+
+Return<Result> Effect::setInputDevice(const DeviceAddress& device) {
+ (void)device;
+ return Result::OK;
+}
+
+Return<void> Effect::getConfig(getConfig_cb _hidl_cb) {
+ const EffectConfig config = {{} /* inputCfg */,
+ // outputCfg
+ {{} /* buffer */,
+ 48000 /* samplingRateHz */,
+ toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO),
+ toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT),
+ EffectBufferAccess::ACCESS_ACCUMULATE,
+ 0 /* mask */}};
+ _hidl_cb(Result::OK, config);
+ return Void();
+}
+
+Return<void> Effect::getConfigReverse(getConfigReverse_cb _hidl_cb) {
+ _hidl_cb(Result::OK, EffectConfig{});
+ return Void();
+}
+
+Return<void> Effect::getSupportedAuxChannelsConfigs(uint32_t maxConfigs,
+ getSupportedAuxChannelsConfigs_cb _hidl_cb) {
+ (void)maxConfigs;
+ _hidl_cb(Result::OK, hidl_vec<EffectAuxChannelsConfig>{});
+ return Void();
+}
+
+Return<void> Effect::getAuxChannelsConfig(getAuxChannelsConfig_cb _hidl_cb) {
+ _hidl_cb(Result::OK, EffectAuxChannelsConfig{});
+ return Void();
+}
+
+Return<Result> Effect::setAuxChannelsConfig(const EffectAuxChannelsConfig& config) {
+ (void)config;
+ return Result::OK;
+}
+
+Return<Result> Effect::setAudioSource(const hidl_string& source) {
+ (void)source;
+ return Result::OK;
+}
+
+Return<Result> Effect::offload(const EffectOffloadParameter& param) {
+ (void)param;
+ return Result::OK;
+}
+
+Return<void> Effect::getDescriptor(getDescriptor_cb _hidl_cb) {
+ _hidl_cb(Result::OK, mDescriptor);
+ return Void();
+}
+
+Return<void> Effect::prepareForProcessing(prepareForProcessing_cb _hidl_cb) {
+ _hidl_cb(Result::OK, MQDescriptor<Result, kSynchronizedReadWrite>{});
+ return Void();
+}
+
+Return<Result> Effect::setProcessBuffers(const AudioBuffer& inBuffer,
+ const AudioBuffer& outBuffer) {
+ (void)inBuffer;
+ (void)outBuffer;
+ return Result::OK;
+}
+
+Return<void> Effect::command(uint32_t commandId, const hidl_vec<uint8_t>& data,
+ uint32_t resultMaxSize, command_cb _hidl_cb) {
+ (void)commandId;
+ (void)data;
+ (void)resultMaxSize;
+ _hidl_cb(-EINVAL, hidl_vec<uint8_t>{});
+ return Void();
+}
+
+Return<Result> Effect::setParameter(const hidl_vec<uint8_t>& parameter,
+ const hidl_vec<uint8_t>& value) {
+ (void)parameter;
+ (void)value;
+ return Result::OK;
+}
+
+Return<void> Effect::getParameter(const hidl_vec<uint8_t>& parameter, uint32_t valueMaxSize,
+ getParameter_cb _hidl_cb) {
+ (void)parameter;
+ (void)valueMaxSize;
+ _hidl_cb(Result::OK, hidl_vec<uint8_t>{});
+ return Void();
+}
+
+Return<void> Effect::getSupportedConfigsForFeature(uint32_t featureId, uint32_t maxConfigs,
+ uint32_t configSize,
+ getSupportedConfigsForFeature_cb _hidl_cb) {
+ (void)featureId;
+ (void)maxConfigs;
+ (void)configSize;
+ _hidl_cb(Result::OK, 0, hidl_vec<uint8_t>{});
+ return Void();
+}
+
+Return<void> Effect::getCurrentConfigForFeature(uint32_t featureId, uint32_t configSize,
+ getCurrentConfigForFeature_cb _hidl_cb) {
+ (void)featureId;
+ (void)configSize;
+ _hidl_cb(Result::OK, hidl_vec<uint8_t>{});
+ return Void();
+}
+
+Return<Result> Effect::setCurrentConfigForFeature(uint32_t featureId,
+ const hidl_vec<uint8_t>& configData) {
+ (void)featureId;
+ (void)configData;
+ return Result::OK;
+}
+
+Return<Result> Effect::close() {
+ return Result::OK;
+}
+
+} // namespace android::hardware::audio::effect::V7_0::implementation
diff --git a/audio/common/7.0/example/Effect.h b/audio/common/7.0/example/Effect.h
new file mode 100644
index 0000000..fa7f41b
--- /dev/null
+++ b/audio/common/7.0/example/Effect.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/audio/effect/7.0/IEffect.h>
+
+namespace android::hardware::audio::effect::V7_0::implementation {
+
+class Effect : public IEffect {
+ public:
+ explicit Effect(const EffectDescriptor& descriptor) : mDescriptor(descriptor) {}
+
+ ::android::hardware::Return<Result> init() override;
+ ::android::hardware::Return<Result> setConfig(
+ const EffectConfig& config,
+ const ::android::sp<IEffectBufferProviderCallback>& inputBufferProvider,
+ const ::android::sp<IEffectBufferProviderCallback>& outputBufferProvider) override;
+ ::android::hardware::Return<Result> reset() override;
+ ::android::hardware::Return<Result> enable() override;
+ ::android::hardware::Return<Result> disable() override;
+ ::android::hardware::Return<Result> setDevice(
+ const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override;
+ ::android::hardware::Return<void> setAndGetVolume(
+ const ::android::hardware::hidl_vec<uint32_t>& volumes,
+ setAndGetVolume_cb _hidl_cb) override;
+ ::android::hardware::Return<Result> volumeChangeNotification(
+ const ::android::hardware::hidl_vec<uint32_t>& volumes) override;
+ ::android::hardware::Return<Result> setAudioMode(
+ ::android::hardware::audio::common::V7_0::AudioMode mode) override;
+ ::android::hardware::Return<Result> setConfigReverse(
+ const EffectConfig& config,
+ const ::android::sp<IEffectBufferProviderCallback>& inputBufferProvider,
+ const ::android::sp<IEffectBufferProviderCallback>& outputBufferProvider) override;
+ ::android::hardware::Return<Result> setInputDevice(
+ const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override;
+ ::android::hardware::Return<void> getConfig(getConfig_cb _hidl_cb) override;
+ ::android::hardware::Return<void> getConfigReverse(getConfigReverse_cb _hidl_cb) override;
+ ::android::hardware::Return<void> getSupportedAuxChannelsConfigs(
+ uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override;
+ ::android::hardware::Return<void> getAuxChannelsConfig(
+ getAuxChannelsConfig_cb _hidl_cb) override;
+ ::android::hardware::Return<Result> setAuxChannelsConfig(
+ const EffectAuxChannelsConfig& config) override;
+ ::android::hardware::Return<Result> setAudioSource(
+ const ::android::hardware::hidl_string& source) override;
+ ::android::hardware::Return<Result> offload(const EffectOffloadParameter& param) override;
+ ::android::hardware::Return<void> getDescriptor(getDescriptor_cb _hidl_cb) override;
+ ::android::hardware::Return<void> prepareForProcessing(
+ prepareForProcessing_cb _hidl_cb) override;
+ ::android::hardware::Return<Result> setProcessBuffers(const AudioBuffer& inBuffer,
+ const AudioBuffer& outBuffer) override;
+ ::android::hardware::Return<void> command(uint32_t commandId,
+ const ::android::hardware::hidl_vec<uint8_t>& data,
+ uint32_t resultMaxSize, command_cb _hidl_cb) override;
+ ::android::hardware::Return<Result> setParameter(
+ const ::android::hardware::hidl_vec<uint8_t>& parameter,
+ const ::android::hardware::hidl_vec<uint8_t>& value) override;
+ ::android::hardware::Return<void> getParameter(
+ const ::android::hardware::hidl_vec<uint8_t>& parameter, uint32_t valueMaxSize,
+ getParameter_cb _hidl_cb) override;
+ ::android::hardware::Return<void> getSupportedConfigsForFeature(
+ uint32_t featureId, uint32_t maxConfigs, uint32_t configSize,
+ getSupportedConfigsForFeature_cb _hidl_cb) override;
+ ::android::hardware::Return<void> getCurrentConfigForFeature(
+ uint32_t featureId, uint32_t configSize,
+ getCurrentConfigForFeature_cb _hidl_cb) override;
+ ::android::hardware::Return<Result> setCurrentConfigForFeature(
+ uint32_t featureId, const ::android::hardware::hidl_vec<uint8_t>& configData) override;
+ ::android::hardware::Return<Result> close() override;
+
+ private:
+ const EffectDescriptor mDescriptor;
+ bool mEnabled = false;
+};
+
+} // namespace android::hardware::audio::effect::V7_0::implementation
diff --git a/audio/common/7.0/example/EffectsFactory.cpp b/audio/common/7.0/example/EffectsFactory.cpp
new file mode 100644
index 0000000..7d333ae
--- /dev/null
+++ b/audio/common/7.0/example/EffectsFactory.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "EffectsFactory7.0"
+#include <log/log.h>
+
+#include "EffectsFactory.h"
+#include "EqualizerEffect.h"
+#include "LoudnessEnhancerEffect.h"
+
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using namespace ::android::hardware::audio::common::V7_0;
+
+namespace android::hardware::audio::effect::V7_0::implementation {
+
+Return<void> EffectsFactory::getAllDescriptors(getAllDescriptors_cb _hidl_cb) {
+ hidl_vec<EffectDescriptor> descriptors;
+ descriptors.resize(2);
+ descriptors[0] = EqualizerEffect::getDescriptor();
+ descriptors[1] = LoudnessEnhancerEffect::getDescriptor();
+ _hidl_cb(Result::OK, descriptors);
+ return Void();
+}
+
+Return<void> EffectsFactory::getDescriptor(const Uuid& uuid, getDescriptor_cb _hidl_cb) {
+ if (auto desc = EqualizerEffect::getDescriptor(); uuid == desc.type || uuid == desc.uuid) {
+ _hidl_cb(Result::OK, desc);
+ } else if (auto desc = LoudnessEnhancerEffect::getDescriptor();
+ uuid == desc.type || uuid == desc.uuid) {
+ _hidl_cb(Result::OK, desc);
+ } else {
+ _hidl_cb(Result::INVALID_ARGUMENTS, EffectDescriptor{});
+ }
+ return Void();
+}
+
+Return<void> EffectsFactory::createEffect(const Uuid& uuid, int32_t session, int32_t ioHandle,
+ int32_t device, createEffect_cb _hidl_cb) {
+ (void)session;
+ (void)ioHandle;
+ (void)device;
+ if (auto desc = EqualizerEffect::getDescriptor(); uuid == desc.type || uuid == desc.uuid) {
+ _hidl_cb(Result::OK, new EqualizerEffect(), 0);
+ } else if (auto desc = LoudnessEnhancerEffect::getDescriptor();
+ uuid == desc.type || uuid == desc.uuid) {
+ _hidl_cb(Result::OK, new LoudnessEnhancerEffect(), 0);
+ } else {
+ _hidl_cb(Result::INVALID_ARGUMENTS, nullptr, 0);
+ }
+ return Void();
+}
+
+Return<void> EffectsFactory::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) {
+ (void)fd;
+ (void)options;
+ return Void();
+}
+
+} // namespace android::hardware::audio::effect::V7_0::implementation
diff --git a/audio/common/7.0/example/EffectsFactory.h b/audio/common/7.0/example/EffectsFactory.h
new file mode 100644
index 0000000..8fec70c
--- /dev/null
+++ b/audio/common/7.0/example/EffectsFactory.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/audio/effect/7.0/IEffectsFactory.h>
+
+namespace android::hardware::audio::effect::V7_0::implementation {
+
+class EffectsFactory : public IEffectsFactory {
+ public:
+ EffectsFactory() = default;
+
+ ::android::hardware::Return<void> getAllDescriptors(getAllDescriptors_cb _hidl_cb) override;
+ ::android::hardware::Return<void> getDescriptor(
+ const ::android::hardware::audio::common::V7_0::Uuid& uuid,
+ getDescriptor_cb _hidl_cb) override;
+ ::android::hardware::Return<void> createEffect(
+ const ::android::hardware::audio::common::V7_0::Uuid& uuid, int32_t session,
+ int32_t ioHandle, int32_t device, createEffect_cb _hidl_cb) override;
+ ::android::hardware::Return<void>
+ debug(const ::android::hardware::hidl_handle& fd,
+ const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& options) override;
+};
+
+} // namespace android::hardware::audio::effect::V7_0::implementation
diff --git a/audio/common/7.0/example/EqualizerEffect.cpp b/audio/common/7.0/example/EqualizerEffect.cpp
new file mode 100644
index 0000000..c93c5a9
--- /dev/null
+++ b/audio/common/7.0/example/EqualizerEffect.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <limits>
+
+#define LOG_TAG "EffectsFactory7.0"
+#include <log/log.h>
+
+#include "EqualizerEffect.h"
+
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using namespace ::android::hardware::audio::common::V7_0;
+
+namespace android::hardware::audio::effect::V7_0::implementation {
+
+const EffectDescriptor& EqualizerEffect::getDescriptor() {
+ // Note: for VTS tests only 'type' and 'uuid' fields are required.
+ // The actual implementation must provide meaningful values
+ // for all fields of the descriptor.
+ static const EffectDescriptor descriptor = {
+ .type =
+ {// Same UUID as AudioEffect.EFFECT_TYPE_EQUALIZER in Java.
+ 0x0bed4300, 0xddd6, 0x11db, 0x8f34,
+ std::array<uint8_t, 6>{{0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}},
+ .uuid = {0, 0, 0, 1, std::array<uint8_t, 6>{{0, 0, 0, 0, 0, 0}}}};
+ return descriptor;
+}
+
+EqualizerEffect::EqualizerEffect() : mEffect(new Effect(getDescriptor())) {
+ mProperties.bandLevels.resize(kNumBands);
+}
+
+Return<void> EqualizerEffect::getNumBands(getNumBands_cb _hidl_cb) {
+ _hidl_cb(Result::OK, kNumBands);
+ return Void();
+}
+
+Return<void> EqualizerEffect::getLevelRange(getLevelRange_cb _hidl_cb) {
+ _hidl_cb(Result::OK, std::numeric_limits<int16_t>::min(), std::numeric_limits<int16_t>::max());
+ return Void();
+}
+
+Return<Result> EqualizerEffect::setBandLevel(uint16_t band, int16_t level) {
+ if (band < kNumBands) {
+ mProperties.bandLevels[band] = level;
+ return Result::OK;
+ } else {
+ return Result::INVALID_ARGUMENTS;
+ }
+}
+
+Return<void> EqualizerEffect::getBandLevel(uint16_t band, getBandLevel_cb _hidl_cb) {
+ if (band < kNumBands) {
+ _hidl_cb(Result::OK, mProperties.bandLevels[band]);
+ } else {
+ _hidl_cb(Result::INVALID_ARGUMENTS, 0);
+ }
+ return Void();
+}
+
+Return<void> EqualizerEffect::getBandCenterFrequency(uint16_t band,
+ getBandCenterFrequency_cb _hidl_cb) {
+ (void)band;
+ _hidl_cb(Result::OK, 0);
+ return Void();
+}
+
+Return<void> EqualizerEffect::getBandFrequencyRange(uint16_t band,
+ getBandFrequencyRange_cb _hidl_cb) {
+ (void)band;
+ _hidl_cb(Result::OK, 0, 1);
+ return Void();
+}
+
+Return<void> EqualizerEffect::getBandForFrequency(uint32_t freq, getBandForFrequency_cb _hidl_cb) {
+ (void)freq;
+ _hidl_cb(Result::OK, 0);
+ return Void();
+}
+
+Return<void> EqualizerEffect::getPresetNames(getPresetNames_cb _hidl_cb) {
+ hidl_vec<hidl_string> presetNames;
+ presetNames.resize(kNumPresets);
+ presetNames[0] = "default";
+ _hidl_cb(Result::OK, presetNames);
+ return Void();
+}
+
+Return<Result> EqualizerEffect::setCurrentPreset(uint16_t preset) {
+ if (preset < kNumPresets) {
+ mProperties.curPreset = preset;
+ return Result::OK;
+ } else {
+ return Result::INVALID_ARGUMENTS;
+ }
+}
+
+Return<void> EqualizerEffect::getCurrentPreset(getCurrentPreset_cb _hidl_cb) {
+ _hidl_cb(Result::OK, mProperties.curPreset);
+ return Void();
+}
+
+Return<Result> EqualizerEffect::setAllProperties(
+ const IEqualizerEffect::AllProperties& properties) {
+ mProperties = properties;
+ return Result::OK;
+}
+
+Return<void> EqualizerEffect::getAllProperties(getAllProperties_cb _hidl_cb) {
+ _hidl_cb(Result::OK, mProperties);
+ return Void();
+}
+
+} // namespace android::hardware::audio::effect::V7_0::implementation
diff --git a/audio/common/7.0/example/EqualizerEffect.h b/audio/common/7.0/example/EqualizerEffect.h
new file mode 100644
index 0000000..11853c3
--- /dev/null
+++ b/audio/common/7.0/example/EqualizerEffect.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/audio/effect/7.0/IEqualizerEffect.h>
+
+#include "Effect.h"
+
+namespace android::hardware::audio::effect::V7_0::implementation {
+
+class EqualizerEffect : public IEqualizerEffect {
+ public:
+ static const EffectDescriptor& getDescriptor();
+
+ EqualizerEffect();
+
+ // Methods from IEffect interface.
+ ::android::hardware::Return<Result> init() override { return mEffect->init(); }
+ ::android::hardware::Return<Result> setConfig(
+ const EffectConfig& config,
+ const ::android::sp<IEffectBufferProviderCallback>& inputBufferProvider,
+ const ::android::sp<IEffectBufferProviderCallback>& outputBufferProvider) override {
+ return mEffect->setConfig(config, inputBufferProvider, outputBufferProvider);
+ }
+ ::android::hardware::Return<Result> reset() override { return mEffect->reset(); }
+ ::android::hardware::Return<Result> enable() override { return mEffect->enable(); }
+ ::android::hardware::Return<Result> disable() override { return mEffect->disable(); }
+ ::android::hardware::Return<Result> setDevice(
+ const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override {
+ return mEffect->setDevice(device);
+ }
+ ::android::hardware::Return<void> setAndGetVolume(
+ const ::android::hardware::hidl_vec<uint32_t>& volumes,
+ setAndGetVolume_cb _hidl_cb) override {
+ return mEffect->setAndGetVolume(volumes, _hidl_cb);
+ }
+ ::android::hardware::Return<Result> volumeChangeNotification(
+ const ::android::hardware::hidl_vec<uint32_t>& volumes) override {
+ return mEffect->volumeChangeNotification(volumes);
+ }
+ ::android::hardware::Return<Result> setAudioMode(
+ ::android::hardware::audio::common::V7_0::AudioMode mode) override {
+ return mEffect->setAudioMode(mode);
+ }
+ ::android::hardware::Return<Result> setConfigReverse(
+ const EffectConfig& config,
+ const ::android::sp<IEffectBufferProviderCallback>& inputBufferProvider,
+ const ::android::sp<IEffectBufferProviderCallback>& outputBufferProvider) override {
+ return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider);
+ }
+ ::android::hardware::Return<Result> setInputDevice(
+ const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override {
+ return mEffect->setInputDevice(device);
+ }
+ ::android::hardware::Return<void> getConfig(getConfig_cb _hidl_cb) override {
+ return mEffect->getConfig(_hidl_cb);
+ }
+ ::android::hardware::Return<void> getConfigReverse(getConfigReverse_cb _hidl_cb) override {
+ return mEffect->getConfigReverse(_hidl_cb);
+ }
+ ::android::hardware::Return<void> getSupportedAuxChannelsConfigs(
+ uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override {
+ return mEffect->getSupportedAuxChannelsConfigs(maxConfigs, _hidl_cb);
+ }
+ ::android::hardware::Return<void> getAuxChannelsConfig(
+ getAuxChannelsConfig_cb _hidl_cb) override {
+ return mEffect->getAuxChannelsConfig(_hidl_cb);
+ }
+ ::android::hardware::Return<Result> setAuxChannelsConfig(
+ const EffectAuxChannelsConfig& config) override {
+ return mEffect->setAuxChannelsConfig(config);
+ }
+ ::android::hardware::Return<Result> setAudioSource(
+ const ::android::hardware::hidl_string& source) override {
+ return mEffect->setAudioSource(source);
+ }
+ ::android::hardware::Return<Result> offload(const EffectOffloadParameter& param) override {
+ return mEffect->offload(param);
+ }
+ ::android::hardware::Return<void> getDescriptor(getDescriptor_cb _hidl_cb) override {
+ return mEffect->getDescriptor(_hidl_cb);
+ }
+ ::android::hardware::Return<void> prepareForProcessing(
+ prepareForProcessing_cb _hidl_cb) override {
+ return mEffect->prepareForProcessing(_hidl_cb);
+ }
+ ::android::hardware::Return<Result> setProcessBuffers(const AudioBuffer& inBuffer,
+ const AudioBuffer& outBuffer) override {
+ return mEffect->setProcessBuffers(inBuffer, outBuffer);
+ }
+ ::android::hardware::Return<void> command(uint32_t commandId,
+ const ::android::hardware::hidl_vec<uint8_t>& data,
+ uint32_t resultMaxSize,
+ command_cb _hidl_cb) override {
+ return mEffect->command(commandId, data, resultMaxSize, _hidl_cb);
+ }
+ ::android::hardware::Return<Result> setParameter(
+ const ::android::hardware::hidl_vec<uint8_t>& parameter,
+ const ::android::hardware::hidl_vec<uint8_t>& value) override {
+ return mEffect->setParameter(parameter, value);
+ }
+ ::android::hardware::Return<void> getParameter(
+ const ::android::hardware::hidl_vec<uint8_t>& parameter, uint32_t valueMaxSize,
+ getParameter_cb _hidl_cb) override {
+ return mEffect->getParameter(parameter, valueMaxSize, _hidl_cb);
+ }
+ ::android::hardware::Return<void> getSupportedConfigsForFeature(
+ uint32_t featureId, uint32_t maxConfigs, uint32_t configSize,
+ getSupportedConfigsForFeature_cb _hidl_cb) override {
+ return mEffect->getSupportedConfigsForFeature(featureId, maxConfigs, configSize, _hidl_cb);
+ }
+ ::android::hardware::Return<void> getCurrentConfigForFeature(
+ uint32_t featureId, uint32_t configSize,
+ getCurrentConfigForFeature_cb _hidl_cb) override {
+ return mEffect->getCurrentConfigForFeature(featureId, configSize, _hidl_cb);
+ }
+ ::android::hardware::Return<Result> setCurrentConfigForFeature(
+ uint32_t featureId, const ::android::hardware::hidl_vec<uint8_t>& configData) override {
+ return mEffect->setCurrentConfigForFeature(featureId, configData);
+ }
+ ::android::hardware::Return<Result> close() override { return mEffect->close(); }
+
+ // Methods from IEqualizerEffect interface.
+ ::android::hardware::Return<void> getNumBands(getNumBands_cb _hidl_cb) override;
+ ::android::hardware::Return<void> getLevelRange(getLevelRange_cb _hidl_cb) override;
+ ::android::hardware::Return<Result> setBandLevel(uint16_t band, int16_t level) override;
+ ::android::hardware::Return<void> getBandLevel(uint16_t band,
+ getBandLevel_cb _hidl_cb) override;
+ ::android::hardware::Return<void> getBandCenterFrequency(
+ uint16_t band, getBandCenterFrequency_cb _hidl_cb) override;
+ ::android::hardware::Return<void> getBandFrequencyRange(
+ uint16_t band, getBandFrequencyRange_cb _hidl_cb) override;
+ ::android::hardware::Return<void> getBandForFrequency(uint32_t freq,
+ getBandForFrequency_cb _hidl_cb) override;
+ ::android::hardware::Return<void> getPresetNames(getPresetNames_cb _hidl_cb) override;
+ ::android::hardware::Return<Result> setCurrentPreset(uint16_t preset) override;
+ ::android::hardware::Return<void> getCurrentPreset(getCurrentPreset_cb _hidl_cb) override;
+ ::android::hardware::Return<Result> setAllProperties(
+ const IEqualizerEffect::AllProperties& properties) override;
+ ::android::hardware::Return<void> getAllProperties(getAllProperties_cb _hidl_cb) override;
+
+ private:
+ static constexpr size_t kNumBands = 1;
+ static constexpr size_t kNumPresets = 1;
+ sp<Effect> mEffect;
+ IEqualizerEffect::AllProperties mProperties{};
+};
+
+} // namespace android::hardware::audio::effect::V7_0::implementation
diff --git a/audio/common/7.0/example/LoudnessEnhancerEffect.cpp b/audio/common/7.0/example/LoudnessEnhancerEffect.cpp
new file mode 100644
index 0000000..38269b3
--- /dev/null
+++ b/audio/common/7.0/example/LoudnessEnhancerEffect.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "EffectsFactory7.0"
+#include <log/log.h>
+
+#include "LoudnessEnhancerEffect.h"
+
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using namespace ::android::hardware::audio::common::V7_0;
+
+namespace android::hardware::audio::effect::V7_0::implementation {
+
+const EffectDescriptor& LoudnessEnhancerEffect::getDescriptor() {
+ // Note: for VTS tests only 'type' and 'uuid' fields are required.
+ // The actual implementation must provide meaningful values
+ // for all fields of the descriptor.
+ static const EffectDescriptor descriptor = {
+ .type =
+ {// Same UUID as AudioEffect.EFFECT_TYPE_LOUDNESS_ENHANCER in Java.
+ 0xfe3199be, 0xaed0, 0x413f, 0x87bb,
+ std::array<uint8_t, 6>{{0x11, 0x26, 0x0e, 0xb6, 0x3c, 0xf1}}},
+ .uuid = {0, 0, 0, 2, std::array<uint8_t, 6>{{0, 0, 0, 0, 0, 0}}}};
+ return descriptor;
+} // namespace android::hardware::audio::effect::V7_0::implementation
+
+LoudnessEnhancerEffect::LoudnessEnhancerEffect() : mEffect(new Effect(getDescriptor())) {}
+
+Return<Result> LoudnessEnhancerEffect::setTargetGain(int32_t targetGainMb) {
+ mTargetGainMb = targetGainMb;
+ return Result::OK;
+}
+
+Return<void> LoudnessEnhancerEffect::getTargetGain(getTargetGain_cb _hidl_cb) {
+ _hidl_cb(Result::OK, mTargetGainMb);
+ return Void();
+}
+
+} // namespace android::hardware::audio::effect::V7_0::implementation
diff --git a/audio/common/7.0/example/LoudnessEnhancerEffect.h b/audio/common/7.0/example/LoudnessEnhancerEffect.h
new file mode 100644
index 0000000..1af0d9f
--- /dev/null
+++ b/audio/common/7.0/example/LoudnessEnhancerEffect.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/audio/effect/7.0/ILoudnessEnhancerEffect.h>
+
+#include "Effect.h"
+
+namespace android::hardware::audio::effect::V7_0::implementation {
+
+class LoudnessEnhancerEffect : public ILoudnessEnhancerEffect {
+ public:
+ static const EffectDescriptor& getDescriptor();
+
+ LoudnessEnhancerEffect();
+
+ // Methods from IEffect interface.
+ ::android::hardware::Return<Result> init() override { return mEffect->init(); }
+ ::android::hardware::Return<Result> setConfig(
+ const EffectConfig& config,
+ const ::android::sp<IEffectBufferProviderCallback>& inputBufferProvider,
+ const ::android::sp<IEffectBufferProviderCallback>& outputBufferProvider) override {
+ return mEffect->setConfig(config, inputBufferProvider, outputBufferProvider);
+ }
+ ::android::hardware::Return<Result> reset() override { return mEffect->reset(); }
+ ::android::hardware::Return<Result> enable() override { return mEffect->enable(); }
+ ::android::hardware::Return<Result> disable() override { return mEffect->disable(); }
+ ::android::hardware::Return<Result> setDevice(
+ const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override {
+ return mEffect->setDevice(device);
+ }
+ ::android::hardware::Return<void> setAndGetVolume(
+ const ::android::hardware::hidl_vec<uint32_t>& volumes,
+ setAndGetVolume_cb _hidl_cb) override {
+ return mEffect->setAndGetVolume(volumes, _hidl_cb);
+ }
+ ::android::hardware::Return<Result> volumeChangeNotification(
+ const ::android::hardware::hidl_vec<uint32_t>& volumes) override {
+ return mEffect->volumeChangeNotification(volumes);
+ }
+ ::android::hardware::Return<Result> setAudioMode(
+ ::android::hardware::audio::common::V7_0::AudioMode mode) override {
+ return mEffect->setAudioMode(mode);
+ }
+ ::android::hardware::Return<Result> setConfigReverse(
+ const EffectConfig& config,
+ const ::android::sp<IEffectBufferProviderCallback>& inputBufferProvider,
+ const ::android::sp<IEffectBufferProviderCallback>& outputBufferProvider) override {
+ return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider);
+ }
+ ::android::hardware::Return<Result> setInputDevice(
+ const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override {
+ return mEffect->setInputDevice(device);
+ }
+ ::android::hardware::Return<void> getConfig(getConfig_cb _hidl_cb) override {
+ return mEffect->getConfig(_hidl_cb);
+ }
+ ::android::hardware::Return<void> getConfigReverse(getConfigReverse_cb _hidl_cb) override {
+ return mEffect->getConfigReverse(_hidl_cb);
+ }
+ ::android::hardware::Return<void> getSupportedAuxChannelsConfigs(
+ uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override {
+ return mEffect->getSupportedAuxChannelsConfigs(maxConfigs, _hidl_cb);
+ }
+ ::android::hardware::Return<void> getAuxChannelsConfig(
+ getAuxChannelsConfig_cb _hidl_cb) override {
+ return mEffect->getAuxChannelsConfig(_hidl_cb);
+ }
+ ::android::hardware::Return<Result> setAuxChannelsConfig(
+ const EffectAuxChannelsConfig& config) override {
+ return mEffect->setAuxChannelsConfig(config);
+ }
+ ::android::hardware::Return<Result> setAudioSource(
+ const ::android::hardware::hidl_string& source) override {
+ return mEffect->setAudioSource(source);
+ }
+ ::android::hardware::Return<Result> offload(const EffectOffloadParameter& param) override {
+ return mEffect->offload(param);
+ }
+ ::android::hardware::Return<void> getDescriptor(getDescriptor_cb _hidl_cb) override {
+ return mEffect->getDescriptor(_hidl_cb);
+ }
+ ::android::hardware::Return<void> prepareForProcessing(
+ prepareForProcessing_cb _hidl_cb) override {
+ return mEffect->prepareForProcessing(_hidl_cb);
+ }
+ ::android::hardware::Return<Result> setProcessBuffers(const AudioBuffer& inBuffer,
+ const AudioBuffer& outBuffer) override {
+ return mEffect->setProcessBuffers(inBuffer, outBuffer);
+ }
+ ::android::hardware::Return<void> command(uint32_t commandId,
+ const ::android::hardware::hidl_vec<uint8_t>& data,
+ uint32_t resultMaxSize,
+ command_cb _hidl_cb) override {
+ return mEffect->command(commandId, data, resultMaxSize, _hidl_cb);
+ }
+ ::android::hardware::Return<Result> setParameter(
+ const ::android::hardware::hidl_vec<uint8_t>& parameter,
+ const ::android::hardware::hidl_vec<uint8_t>& value) override {
+ return mEffect->setParameter(parameter, value);
+ }
+ ::android::hardware::Return<void> getParameter(
+ const ::android::hardware::hidl_vec<uint8_t>& parameter, uint32_t valueMaxSize,
+ getParameter_cb _hidl_cb) override {
+ return mEffect->getParameter(parameter, valueMaxSize, _hidl_cb);
+ }
+ ::android::hardware::Return<void> getSupportedConfigsForFeature(
+ uint32_t featureId, uint32_t maxConfigs, uint32_t configSize,
+ getSupportedConfigsForFeature_cb _hidl_cb) override {
+ return mEffect->getSupportedConfigsForFeature(featureId, maxConfigs, configSize, _hidl_cb);
+ }
+ ::android::hardware::Return<void> getCurrentConfigForFeature(
+ uint32_t featureId, uint32_t configSize,
+ getCurrentConfigForFeature_cb _hidl_cb) override {
+ return mEffect->getCurrentConfigForFeature(featureId, configSize, _hidl_cb);
+ }
+ ::android::hardware::Return<Result> setCurrentConfigForFeature(
+ uint32_t featureId, const ::android::hardware::hidl_vec<uint8_t>& configData) override {
+ return mEffect->setCurrentConfigForFeature(featureId, configData);
+ }
+ ::android::hardware::Return<Result> close() override { return mEffect->close(); }
+
+ // Methods from ILoudnessEnhancerEffect interface.
+ ::android::hardware::Return<Result> setTargetGain(int32_t targetGainMb) override;
+ ::android::hardware::Return<void> getTargetGain(getTargetGain_cb _hidl_cb) override;
+
+ private:
+ sp<Effect> mEffect;
+ int32_t mTargetGainMb = 0;
+};
+
+} // namespace android::hardware::audio::effect::V7_0::implementation
diff --git a/audio/common/7.0/example/android.hardware.audio@7.0-service.example.rc b/audio/common/7.0/example/android.hardware.audio@7.0-service.example.rc
new file mode 100644
index 0000000..cf8b51f
--- /dev/null
+++ b/audio/common/7.0/example/android.hardware.audio@7.0-service.example.rc
@@ -0,0 +1,7 @@
+service vendor.audio-hal-7-0 /vendor/bin/hw/android.hardware.audio@7.0-service.example
+ class hal
+ user audioserver
+ group audio
+ capabilities BLOCK_SUSPEND
+ ioprio rt 4
+ task_profiles ProcessCapacityHigh HighPerformance
diff --git a/audio/common/7.0/example/android.hardware.audio@7.0-service.example.xml b/audio/common/7.0/example/android.hardware.audio@7.0-service.example.xml
new file mode 100644
index 0000000..b91b061
--- /dev/null
+++ b/audio/common/7.0/example/android.hardware.audio@7.0-service.example.xml
@@ -0,0 +1,20 @@
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.audio</name>
+ <transport>hwbinder</transport>
+ <version>7.0</version>
+ <interface>
+ <name>IDevicesFactory</name>
+ <instance>example</instance>
+ </interface>
+ </hal>
+ <hal format="hidl">
+ <name>android.hardware.audio.effect</name>
+ <transport>hwbinder</transport>
+ <version>7.0</version>
+ <interface>
+ <name>IEffectsFactory</name>
+ <instance>example</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/audio/common/7.0/example/service.cpp b/audio/common/7.0/example/service.cpp
new file mode 100644
index 0000000..641e2c9
--- /dev/null
+++ b/audio/common/7.0/example/service.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.audio@7.0-service.example"
+#include <hidl/HidlTransportSupport.h>
+#include <log/log.h>
+
+#include "DevicesFactory.h"
+#include "EffectsFactory.h"
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+using namespace android;
+
+status_t registerDevicesFactoryService() {
+ sp<::android::hardware::audio::V7_0::IDevicesFactory> devicesFactory =
+ new ::android::hardware::audio::V7_0::implementation::DevicesFactory();
+ status_t status = devicesFactory->registerAsService("example");
+ ALOGE_IF(status != OK, "Error registering devices factory as service: %d", status);
+ return status;
+}
+
+status_t registerEffectsFactoryService() {
+ sp<::android::hardware::audio::effect::V7_0::IEffectsFactory> devicesFactory =
+ new ::android::hardware::audio::effect::V7_0::implementation::EffectsFactory();
+ status_t status = devicesFactory->registerAsService("example");
+ ALOGE_IF(status != OK, "Error registering effects factory as service: %d", status);
+ return status;
+}
+
+int main() {
+ configureRpcThreadpool(1, true);
+ status_t status = registerDevicesFactoryService();
+ if (status != OK) {
+ return status;
+ }
+ status = registerEffectsFactoryService();
+ if (status != OK) {
+ return status;
+ }
+ joinRpcThreadpool();
+
+ return 1;
+}
diff --git a/audio/common/7.0/types.hal b/audio/common/7.0/types.hal
index 94d0af7..631d524 100644
--- a/audio/common/7.0/types.hal
+++ b/audio/common/7.0/types.hal
@@ -78,6 +78,7 @@
*/
typedef int32_t AudioSession;
+@export(name="", value_prefix="HAL_AUDIO_SESSION_")
enum AudioSessionConsts : int32_t {
/**
* Session for effects attached to a particular sink or source audio device
@@ -106,25 +107,38 @@
/**
* Audio channel mask indicates presence of particular channels.
+ * Note that every value is already a mask comprised of individual
+ * channels.
* See 'audioChannelMask' in audio_policy_configuration.xsd for the
* list of allowed values.
*/
typedef string AudioChannelMask;
/**
- * Basic configuration applicable to any stream of audio.
+ * Base configuration attributes applicable to any stream of audio.
*/
-struct AudioBasicConfig {
+struct AudioConfigBase {
+ AudioFormat format; // 'DEFAULT' means 'unspecified'
uint32_t sampleRateHz; // 0 means 'unspecified'
vec<AudioChannelMask> channelMask; // empty means 'unspecified'
- AudioFormat format; // 'DEFAULT' means 'unspecified'
+};
+
+/**
+ * Configurations supported for a certain audio format.
+ */
+struct AudioProfile {
+ AudioFormat format;
+ /** List of the sample rates (in Hz) supported by the profile. */
+ vec<uint32_t> sampleRates;
+ /** List of channel masks supported by the profile. */
+ vec<AudioChannelMask> channelMasks;
};
/**
* Major modes for a mobile device. The current mode setting affects audio
* routing.
*/
-@export(name="audio_mode_t", value_prefix="AUDIO_MODE_")
+@export(name="", value_prefix="HAL_AUDIO_MODE_")
enum AudioMode : int32_t {
NORMAL = 0,
RINGTONE = 1,
@@ -137,17 +151,20 @@
};
/**
+ * Audio device specifies type (or category) of audio I/O device
+ * (e.g. speaker or headphones).
+ * See 'audioDevice' in audio_policy_configuration.xsd for the
+ * list of allowed values.
+ */
+typedef string AudioDevice;
+
+/**
* Specifies a device address in case when several devices of the same type
* can be connected (e.g. BT A2DP, USB).
*/
struct DeviceAddress {
- /**
- * Audio device specifies type (or category) of audio I/O device
- * (e.g. speaker or headphones).
- * See 'audioDevice' in audio_policy_configuration.xsd for the
- * list of allowed values.
- */
- string deviceType;
+ /** The type of the device. */
+ AudioDevice deviceType;
safe_union Address {
/**
* The address may be left unspecified if 'device' specifies
@@ -206,10 +223,31 @@
};
/**
+ * Enumeration of metadata types permitted for use by
+ * encapsulation mode audio streams.
+ */
+@export(name="audio_encapsulation_metadata_type_t", value_prefix="AUDIO_ENCAPSULATION_METADATA_TYPE_")
+enum AudioEncapsulationMetadataType : int32_t {
+ /**
+ * No metadata.
+ */
+ NONE = 0,
+ /**
+ * Encapsulation metadata type for framework tuner information.
+ */
+ FRAMEWORK_TUNER = 1,
+ /**
+ * Encapsulation metadata type for DVB AD descriptor.
+ * This metadata is formatted per ETSI TS 101 154 Table E.1: AD_descriptor.
+ */
+ DVB_AD_DESCRIPTOR = 2,
+};
+
+/**
* Additional information about the stream passed to hardware decoders.
*/
struct AudioOffloadInfo {
- AudioBasicConfig base;
+ AudioConfigBase base;
AudioStreamType streamType;
uint32_t bitRatePerSecond;
int64_t durationMicroseconds; // -1 if unknown
@@ -227,7 +265,7 @@
* Commonly used audio stream configuration parameters.
*/
struct AudioConfig {
- AudioBasicConfig base;
+ AudioConfigBase base;
AudioOffloadInfo offloadInfo;
uint64_t frameCount;
};
@@ -280,21 +318,18 @@
/**
* Type of gain control exposed by an audio port.
+ * See 'audioGainMode' in audio_policy_configuration.xsd for the
+ * list of allowed values.
*/
-@export(name="", value_prefix="AUDIO_GAIN_MODE_")
-enum AudioGainMode : uint32_t {
- JOINT = 0x1, // supports joint channel gain control
- CHANNELS = 0x2, // supports separate channel gain control
- RAMP = 0x4 // supports gain ramps
-};
+typedef string AudioGainMode;
/**
* An audio_gain struct is a representation of a gain stage.
* A gain stage is always attached to an audio port.
*/
struct AudioGain {
- bitfield<AudioGainMode> mode;
- vec<AudioChannelMask> channelMask; // channels which gain an be controlled
+ vec<AudioGainMode> mode; // modes of operation
+ AudioChannelMask channelMask; // channels which gain can be controlled
int32_t minValue; // minimum gain value in millibels
int32_t maxValue; // maximum gain value in millibels
int32_t defaultValue; // default gain value in millibels
@@ -309,8 +344,8 @@
*/
struct AudioGainConfig {
int32_t index; // index of the corresponding AudioGain in AudioPort.gains
- AudioGainMode mode;
- vec<AudioChannelMask> channelMask; // channels which gain value follows
+ vec<AudioGainMode> mode; // modes of operation
+ AudioChannelMask channelMask; // channels which gain value follows
/**
* Gain values in millibels for each channel ordered from LSb to MSb in
* channel mask. The number of values is 1 in joint mode or
@@ -372,9 +407,9 @@
/**
* Basic parameters: sampling rate, format, channel mask. Only some of the
* parameters (or none) may be set. See the documentation of the
- * AudioBasicConfig struct.
+ * AudioConfigBase struct.
*/
- AudioBasicConfig config;
+ AudioConfigBase config;
/** Associated gain control. */
safe_union OptionalGain {
Monostate unspecified;
@@ -401,13 +436,6 @@
*/
string name;
/** List of audio profiles supported by the port. */
- struct AudioProfile {
- AudioFormat format;
- /** List of the sample rates supported by the profile. */
- vec<uint32_t> sampleRates;
- /** List of channel masks supported by the profile. */
- vec<AudioChannelMask> channelMasks;
- };
vec<AudioProfile> profiles;
/** List of gain controls attached to the port. */
vec<AudioGain> gains;
diff --git a/audio/common/all-versions/default/VersionUtils.h b/audio/common/all-versions/default/VersionUtils.h
index e7755b1..9bfca0c 100644
--- a/audio/common/all-versions/default/VersionUtils.h
+++ b/audio/common/all-versions/default/VersionUtils.h
@@ -31,7 +31,7 @@
typedef common::CPP_VERSION::AudioChannelMask AudioChannelBitfield;
typedef common::CPP_VERSION::AudioOutputFlag AudioOutputFlagBitfield;
typedef common::CPP_VERSION::AudioInputFlag AudioInputFlagBitfield;
-#elif MAJOR_VERSION >= 4
+#elif MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6
typedef hidl_bitfield<common::CPP_VERSION::AudioDevice> AudioDeviceBitfield;
typedef hidl_bitfield<common::CPP_VERSION::AudioChannelMask> AudioChannelBitfield;
typedef hidl_bitfield<common::CPP_VERSION::AudioOutputFlag> AudioOutputFlagBitfield;
diff --git a/audio/common/all-versions/default/service/service.cpp b/audio/common/all-versions/default/service/service.cpp
index 147d062..710ddce 100644
--- a/audio/common/all-versions/default/service/service.cpp
+++ b/audio/common/all-versions/default/service/service.cpp
@@ -87,7 +87,8 @@
},
{
"Bluetooth Audio API",
- "android.hardware.bluetooth.audio@2.0::IBluetoothAudioProvidersFactory"
+ "android.hardware.bluetooth.audio@2.1::IBluetoothAudioProvidersFactory",
+ "android.hardware.bluetooth.audio@2.0::IBluetoothAudioProvidersFactory",
},
// remove the old HIDL when Bluetooth Audio Hal V2 has offloading supported
{
diff --git a/audio/core/all-versions/default/Conversions.cpp b/audio/core/all-versions/default/Conversions.cpp
index eddff55..0b6ad80 100644
--- a/audio/core/all-versions/default/Conversions.cpp
+++ b/audio/core/all-versions/default/Conversions.cpp
@@ -31,7 +31,7 @@
// HAL assumes that the address is NUL-terminated.
char halAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN];
memset(halAddress, 0, sizeof(halAddress));
- uint32_t halDevice = static_cast<uint32_t>(address.device);
+ audio_devices_t halDevice = static_cast<audio_devices_t>(address.device);
if (getAudioDeviceOutAllA2dpSet().count(halDevice) > 0 ||
halDevice == AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
snprintf(halAddress, sizeof(halAddress), "%02X:%02X:%02X:%02X:%02X:%02X",
diff --git a/audio/core/all-versions/default/StreamOut.cpp b/audio/core/all-versions/default/StreamOut.cpp
index 1519c48..007eb45 100644
--- a/audio/core/all-versions/default/StreamOut.cpp
+++ b/audio/core/all-versions/default/StreamOut.cpp
@@ -496,11 +496,11 @@
}
Return<Result> StreamOut::drain(AudioDrain type) {
+ audio_drain_type_t halDrainType =
+ type == AudioDrain::EARLY_NOTIFY ? AUDIO_DRAIN_EARLY_NOTIFY : AUDIO_DRAIN_ALL;
return mStream->drain != NULL
- ? Stream::analyzeStatus(
- "drain",
- mStream->drain(mStream, static_cast<audio_drain_type_t>(type)),
- {ENOSYS} /*ignore*/)
+ ? Stream::analyzeStatus("drain", mStream->drain(mStream, halDrainType),
+ {ENOSYS} /*ignore*/)
: Result::NOT_SUPPORTED;
}
diff --git a/audio/core/all-versions/default/include/core/default/Device.h b/audio/core/all-versions/default/include/core/default/Device.h
index b0e72d9..907acd7 100644
--- a/audio/core/all-versions/default/include/core/default/Device.h
+++ b/audio/core/all-versions/default/include/core/default/Device.h
@@ -43,8 +43,10 @@
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
+#if MAJOR_VERSION <= 6
using ::android::hardware::audio::common::CPP_VERSION::implementation::AudioInputFlagBitfield;
using ::android::hardware::audio::common::CPP_VERSION::implementation::AudioOutputFlagBitfield;
+#endif
using namespace ::android::hardware::audio::common::CPP_VERSION;
using namespace ::android::hardware::audio::CPP_VERSION;
diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
index b0eb2e0..2466fd1 100644
--- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
@@ -16,6 +16,13 @@
#include "AudioPrimaryHidlHalTest.h"
+#if MAJOR_VERSION >= 7
+#include <audio_policy_configuration_V7_0.h>
+#include <xsdc/XsdcSupport.h>
+
+using android::xsdc_enum_range;
+#endif
+
TEST_P(AudioHidlTest, OpenPrimaryDeviceUsingGetDevice) {
doc::test("Calling openDevice(\"primary\") should return the primary device.");
if (getDeviceName() != DeviceManager::kPrimaryDevice) {
@@ -53,14 +60,29 @@
"Make sure getMicrophones always succeeds"
"and getActiveMicrophones always succeeds when recording from these microphones.");
AudioConfig config{};
+#if MAJOR_VERSION <= 6
config.channelMask = mkEnumBitfield(AudioChannelMask::IN_MONO);
config.sampleRateHz = 8000;
config.format = AudioFormat::PCM_16_BIT;
auto flags = hidl_bitfield<AudioInputFlag>(AudioInputFlag::NONE);
const SinkMetadata initMetadata = {{{.source = AudioSource::MIC, .gain = 1}}};
+#elif MAJOR_VERSION >= 7
+ config.base.channelMask.resize(1);
+ config.base.channelMask[0] = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO);
+ config.base.sampleRateHz = 8000;
+ config.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT);
+ hidl_vec<hidl_string> flags;
+ const SinkMetadata initMetadata = {
+ {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC), .gain = 1}}};
+#endif
EventFlag* efGroup;
for (auto microphone : microphones) {
+#if MAJOR_VERSION <= 6
if (microphone.deviceAddress.device != AudioDevice::IN_BUILTIN_MIC) {
+#elif MAJOR_VERSION >= 7
+ if (xsd::stringToAudioDevice(microphone.deviceAddress.deviceType) !=
+ xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC) {
+#endif
continue;
}
sp<IStreamIn> stream;
@@ -81,16 +103,16 @@
size_t frameSize = stream->getFrameSize();
size_t frameCount = stream->getBufferSize() / frameSize;
ASSERT_OK(stream->prepareForReading(
- frameSize, frameCount, [&](auto r, auto& c, auto& d, auto&, auto&) {
- readRes = r;
- if (readRes == Result::OK) {
- commandMQ.reset(new CommandMQ(c));
- dataMQ.reset(new DataMQ(d));
- if (dataMQ->isValid() && dataMQ->getEventFlagWord()) {
- EventFlag::createEventFlag(dataMQ->getEventFlagWord(), &efGroup);
+ frameSize, frameCount, [&](auto r, auto& c, auto& d, auto&, auto) {
+ readRes = r;
+ if (readRes == Result::OK) {
+ commandMQ.reset(new CommandMQ(c));
+ dataMQ.reset(new DataMQ(d));
+ if (dataMQ->isValid() && dataMQ->getEventFlagWord()) {
+ EventFlag::createEventFlag(dataMQ->getEventFlagWord(), &efGroup);
+ }
}
- }
- }));
+ }));
ASSERT_OK(readRes);
IStreamIn::ReadParameters params;
params.command = IStreamIn::ReadCommand::READ;
@@ -116,13 +138,24 @@
TEST_P(AudioHidlDeviceTest, SetConnectedState) {
doc::test("Check that the HAL can be notified of device connection and deconnection");
+#if MAJOR_VERSION <= 6
using AD = AudioDevice;
for (auto deviceType : {AD::OUT_HDMI, AD::OUT_WIRED_HEADPHONE, AD::IN_USB_HEADSET}) {
+#elif MAJOR_VERSION >= 7
+ using AD = xsd::AudioDevice;
+ for (auto deviceType :
+ {toString(AD::AUDIO_DEVICE_OUT_HDMI), toString(AD::AUDIO_DEVICE_OUT_WIRED_HEADPHONE),
+ toString(AD::AUDIO_DEVICE_IN_USB_HEADSET)}) {
+#endif
SCOPED_TRACE("device=" + ::testing::PrintToString(deviceType));
for (bool state : {true, false}) {
SCOPED_TRACE("state=" + ::testing::PrintToString(state));
DeviceAddress address = {};
+#if MAJOR_VERSION <= 6
address.device = deviceType;
+#elif MAJOR_VERSION >= 7
+ address.deviceType = deviceType;
+#endif
auto ret = getDevice()->setConnectedState(address, state);
ASSERT_TRUE(ret.isOk());
if (ret == Result::NOT_SUPPORTED) {
@@ -148,7 +181,11 @@
}
// The stream was constructed with one device, thus getDevices must only return one
ASSERT_EQ(1U, devices.size());
+#if MAJOR_VERSION <= 6
AudioDevice device = devices[0].device;
+#elif MAJOR_VERSION >= 7
+ auto device = devices[0].deviceType;
+#endif
ASSERT_TRUE(device == expectedDevice)
<< "Expected: " << ::testing::PrintToString(expectedDevice)
<< "\n Actual: " << ::testing::PrintToString(device);
@@ -156,12 +193,22 @@
TEST_IO_STREAM(GetDevices, "Check that the stream device == the one it was opened with",
areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported")
+#if MAJOR_VERSION <= 6
: testGetDevices(stream.get(), address.device))
+#elif MAJOR_VERSION >= 7
+ : testGetDevices(stream.get(), address.deviceType))
+#endif
static void testSetDevices(IStream* stream, const DeviceAddress& address) {
DeviceAddress otherAddress = address;
+#if MAJOR_VERSION <= 6
otherAddress.device = (address.device & AudioDevice::BIT_IN) == 0 ? AudioDevice::OUT_SPEAKER
: AudioDevice::IN_BUILTIN_MIC;
+#elif MAJOR_VERSION >= 7
+ otherAddress.deviceType = xsd::isOutputDevice(address.deviceType)
+ ? toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_SPEAKER)
+ : toString(xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC);
+#endif
EXPECT_RESULT(okOrNotSupported, stream->setDevices({otherAddress}));
ASSERT_RESULT(okOrNotSupported,
@@ -186,11 +233,19 @@
TEST_P(InputStreamTest, updateSinkMetadata) {
doc::test("The HAL should not crash on metadata change");
+#if MAJOR_VERSION <= 6
hidl_enum_range<AudioSource> range;
+#elif MAJOR_VERSION >= 7
+ xsdc_enum_range<audio::policy::configuration::V7_0::AudioSource> range;
+#endif
// Test all possible track configuration
- for (AudioSource source : range) {
+ for (auto source : range) {
for (float volume : {0.0, 0.5, 1.0}) {
+#if MAJOR_VERSION <= 6
const SinkMetadata metadata = {{{.source = source, .gain = volume}}};
+#elif MAJOR_VERSION >= 7
+ const SinkMetadata metadata = {{{.source = toString(source), .gain = volume}}};
+#endif
ASSERT_OK(stream->updateSinkMetadata(metadata))
<< "source=" << toString(source) << ", volume=" << volume;
}
@@ -213,13 +268,22 @@
TEST_P(OutputStreamTest, updateSourceMetadata) {
doc::test("The HAL should not crash on metadata change");
+#if MAJOR_VERSION <= 6
hidl_enum_range<AudioUsage> usageRange;
hidl_enum_range<AudioContentType> contentRange;
+#elif MAJOR_VERSION >= 7
+ xsdc_enum_range<audio::policy::configuration::V7_0::AudioUsage> usageRange;
+ xsdc_enum_range<audio::policy::configuration::V7_0::AudioContentType> contentRange;
+#endif
// Test all possible track configuration
for (auto usage : usageRange) {
for (auto content : contentRange) {
for (float volume : {0.0, 0.5, 1.0}) {
+#if MAJOR_VERSION <= 6
const SourceMetadata metadata = {{{usage, content, volume}}};
+#elif MAJOR_VERSION >= 7
+ const SourceMetadata metadata = {{{toString(usage), toString(content), volume}}};
+#endif
ASSERT_OK(stream->updateSourceMetadata(metadata))
<< "usage=" << toString(usage) << ", content=" << toString(content)
<< ", volume=" << volume;
@@ -227,12 +291,26 @@
}
}
+ // clang-format off
// Set many track of different configuration
ASSERT_OK(stream->updateSourceMetadata(
+#if MAJOR_VERSION <= 6
{{{AudioUsage::MEDIA, AudioContentType::MUSIC, 0.1},
{AudioUsage::VOICE_COMMUNICATION, AudioContentType::SPEECH, 1.0},
{AudioUsage::ALARM, AudioContentType::SONIFICATION, 0.0},
- {AudioUsage::ASSISTANT, AudioContentType::UNKNOWN, 0.3}}}));
+ {AudioUsage::ASSISTANT, AudioContentType::UNKNOWN, 0.3}}}
+#elif MAJOR_VERSION >= 7
+ {{{toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA),
+ toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), 0.1},
+ {toString(xsd::AudioUsage::AUDIO_USAGE_VOICE_COMMUNICATION),
+ toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SPEECH), 1.0},
+ {toString(xsd::AudioUsage::AUDIO_USAGE_ALARM),
+ toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SONIFICATION), 0.0},
+ {toString(xsd::AudioUsage::AUDIO_USAGE_ASSISTANT),
+ toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_UNKNOWN), 0.3}}}
+#endif
+ ));
+ // clang-format on
// Set no metadata as if all stream track had stopped
ASSERT_OK(stream->updateSourceMetadata({}));
diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h
index 7a52d0e..81a1f7b 100644
--- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h
+++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h
@@ -56,6 +56,7 @@
}
};
+#if MAJOR_VERSION <= 6
struct GetSupported {
static auto getFormat(IStream* stream) {
auto ret = stream->getFormat();
@@ -80,7 +81,7 @@
EXPECT_OK(stream->getSupportedFormats(returnIn(capabilities)));
return Result::OK;
}
-#elif MAJOR_VERSION >= 6
+#else // MAJOR_VERSION == 6
static Result formats(IStream* stream, hidl_vec<AudioFormat>& capabilities) {
Result res;
EXPECT_OK(stream->getSupportedFormats(returnIn(res, capabilities)));
@@ -88,6 +89,7 @@
}
#endif
};
+#endif // MAJOR_VERSION <= 6
template <class T>
auto dump(T t, hidl_handle handle) {
diff --git a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
index 54d4bbd..bd8de2d 100644
--- a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
@@ -17,6 +17,7 @@
// pull in all the <= 5.0 tests
#include "5.0/AudioPrimaryHidlHalTest.cpp"
+#if MAJOR_VERSION <= 6
const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
static std::vector<DeviceConfigParameter> parameters = [] {
std::vector<DeviceConfigParameter> result;
@@ -28,8 +29,8 @@
const auto& channels = profile->getChannels();
const auto& sampleRates = profile->getSampleRates();
auto configs = ConfigHelper::combineAudioConfig(
- vector<audio_channel_mask_t>(channels.begin(), channels.end()),
- vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
+ std::vector<audio_channel_mask_t>(channels.begin(), channels.end()),
+ std::vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
profile->getFormat());
auto flags = ioProfile->getFlags();
for (auto& config : configs) {
@@ -46,8 +47,8 @@
config.offloadInfo.bufferSize = 256; // arbitrary value
config.offloadInfo.usage = AudioUsage::MEDIA;
result.emplace_back(device, config,
- AudioOutputFlag(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
- AUDIO_OUTPUT_FLAG_DIRECT));
+ AudioOutputFlag(AudioOutputFlag::COMPRESS_OFFLOAD |
+ AudioOutputFlag::DIRECT));
} else {
if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) { // ignore the flag
flags &= ~AUDIO_OUTPUT_FLAG_PRIMARY;
@@ -74,8 +75,8 @@
const auto& channels = profile->getChannels();
const auto& sampleRates = profile->getSampleRates();
auto configs = ConfigHelper::combineAudioConfig(
- vector<audio_channel_mask_t>(channels.begin(), channels.end()),
- vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
+ std::vector<audio_channel_mask_t>(channels.begin(), channels.end()),
+ std::vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
profile->getFormat());
for (const auto& config : configs) {
result.emplace_back(device, config, AudioInputFlag(ioProfile->getFlags()));
@@ -87,13 +88,22 @@
}();
return parameters;
}
+#endif // MAJOR_VERSION <= 6
TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedOutputStreams) {
doc::test("Verify that a device can't be closed if there are streams opened");
+#if MAJOR_VERSION <= 6
DeviceAddress address{.device = AudioDevice::OUT_DEFAULT};
- AudioConfig config{};
- auto flags = hidl_bitfield<AudioOutputFlag>(AudioOutputFlag::NONE);
SourceMetadata initMetadata = {{{AudioUsage::MEDIA, AudioContentType::MUSIC, 1 /* gain */}}};
+ auto flags = hidl_bitfield<AudioOutputFlag>(AudioOutputFlag::NONE);
+#elif MAJOR_VERSION >= 7
+ DeviceAddress address{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_DEFAULT)};
+ SourceMetadata initMetadata = {
+ {{toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA),
+ toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), 1 /* gain */}}};
+ hidl_vec<AudioInOutFlag> flags;
+#endif
+ AudioConfig config{};
sp<IStreamOut> stream;
StreamHelper<IStreamOut> helper(stream);
AudioConfig suggestedConfig{};
@@ -111,14 +121,20 @@
TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedInputStreams) {
doc::test("Verify that a device can't be closed if there are streams opened");
- auto module = getCachedPolicyConfig().getModuleFromName(getDeviceName());
- if (module->getInputProfiles().empty()) {
+ if (!getCachedPolicyConfig().haveInputProfilesInModule(getDeviceName())) {
GTEST_SKIP() << "Device doesn't have input profiles";
}
+#if MAJOR_VERSION <= 6
DeviceAddress address{.device = AudioDevice::IN_DEFAULT};
- AudioConfig config{};
- auto flags = hidl_bitfield<AudioInputFlag>(AudioInputFlag::NONE);
SinkMetadata initMetadata = {{{.source = AudioSource::MIC, .gain = 1}}};
+ auto flags = hidl_bitfield<AudioInputFlag>(AudioInputFlag::NONE);
+#elif MAJOR_VERSION >= 7
+ DeviceAddress address{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_DEFAULT)};
+ SinkMetadata initMetadata = {
+ {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC), .gain = 1}}};
+ hidl_vec<AudioInOutFlag> flags;
+#endif
+ AudioConfig config{};
sp<IStreamIn> stream;
StreamHelper<IStreamIn> helper(stream);
AudioConfig suggestedConfig{};
@@ -137,9 +153,8 @@
TEST_P(AudioPatchHidlTest, UpdatePatchInvalidHandle) {
doc::test("Verify that passing an invalid handle to updateAudioPatch is checked");
AudioPatchHandle ignored;
- ASSERT_OK(getDevice()->updateAudioPatch(
- static_cast<int32_t>(AudioHandleConsts::AUDIO_PATCH_HANDLE_NONE),
- hidl_vec<AudioPortConfig>(), hidl_vec<AudioPortConfig>(), returnIn(res, ignored)));
+ ASSERT_OK(getDevice()->updateAudioPatch(AudioPatchHandle{}, hidl_vec<AudioPortConfig>(),
+ hidl_vec<AudioPortConfig>(), returnIn(res, ignored)));
ASSERT_RESULT(Result::INVALID_ARGUMENTS, res);
}
diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
index 33efa6f..63eaea8 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -16,3 +16,101 @@
// pull in all the <= 6.0 tests
#include "6.0/AudioPrimaryHidlHalTest.cpp"
+
+static std::vector<AudioConfig> combineAudioConfig(std::vector<xsd::AudioChannelMask> channelMasks,
+ std::vector<int64_t> sampleRates,
+ const std::string& format) {
+ std::vector<AudioConfig> configs;
+ configs.reserve(channelMasks.size() * sampleRates.size());
+ for (auto channelMask : channelMasks) {
+ for (auto sampleRate : sampleRates) {
+ AudioConfig config{};
+ // leave offloadInfo to 0
+ config.base.channelMask.resize(1);
+ config.base.channelMask[0] = toString(channelMask);
+ config.base.sampleRateHz = sampleRate;
+ config.base.format = format;
+ configs.push_back(config);
+ }
+ }
+ return configs;
+}
+
+const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
+ static std::vector<DeviceConfigParameter> parameters = [] {
+ std::vector<DeviceConfigParameter> result;
+ const std::vector<AudioInOutFlag> offloadFlags = {
+ toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD),
+ toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_DIRECT)};
+ for (const auto& device : getDeviceParameters()) {
+ auto module =
+ getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
+ for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
+ if (mixPort.getRole() != xsd::Role::source) continue; // not an output profile
+ auto xsdFlags = mixPort.getFlags();
+ const bool isOffload =
+ std::find(xsdFlags.begin(), xsdFlags.end(),
+ xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) !=
+ xsdFlags.end();
+ std::vector<AudioInOutFlag> flags;
+ if (!isOffload) {
+ for (auto flag : xsdFlags) {
+ if (flag != xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_PRIMARY) {
+ flags.push_back(toString(flag));
+ }
+ }
+ } else {
+ flags = offloadFlags;
+ }
+ for (const auto& profile : mixPort.getProfile()) {
+ auto configs =
+ combineAudioConfig(profile.getChannelMasks(),
+ profile.getSamplingRates(), profile.getFormat());
+ for (auto& config : configs) {
+ // Some combinations of flags declared in the config file require special
+ // treatment.
+ if (isOffload) {
+ config.offloadInfo.base = config.base;
+ config.offloadInfo.streamType =
+ toString(xsd::AudioStreamType::AUDIO_STREAM_MUSIC);
+ config.offloadInfo.usage = toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA);
+ config.offloadInfo.bitRatePerSecond = 320;
+ config.offloadInfo.durationMicroseconds = -1;
+ config.offloadInfo.bitWidth = 16;
+ config.offloadInfo.bufferSize = 256; // arbitrary value
+ }
+ result.emplace_back(device, config, flags);
+ }
+ }
+ }
+ }
+ return result;
+ }();
+ return parameters;
+}
+
+const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters() {
+ static std::vector<DeviceConfigParameter> parameters = [] {
+ std::vector<DeviceConfigParameter> result;
+ for (const auto& device : getDeviceParameters()) {
+ auto module =
+ getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
+ for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
+ if (mixPort.getRole() != xsd::Role::sink) continue; // not an input profile
+ std::vector<AudioInOutFlag> flags;
+ std::transform(mixPort.getFlags().begin(), mixPort.getFlags().end(), flags.begin(),
+ [](auto flag) { return toString(flag); });
+ for (const auto& profile : mixPort.getProfile()) {
+ auto configs =
+ combineAudioConfig(profile.getChannelMasks(),
+ profile.getSamplingRates(), profile.getFormat());
+ for (const auto& config : configs) {
+ result.emplace_back(device, config, flags);
+ }
+ }
+ }
+ }
+ return result;
+ }();
+ return parameters;
+}
diff --git a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h
new file mode 100644
index 0000000..d790b34
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+// Note: it is assumed that this file is included from AudioPrimaryHidlTest.h
+// and thus it doesn't have all '#include' and 'using' directives required
+// for a standalone compilation.
+
+namespace xsd {
+using Module = Modules::Module;
+}
+
+class PolicyConfig {
+ public:
+ explicit PolicyConfig(const std::string& configFileName)
+ : mConfigFileName{configFileName},
+ mFilePath{findExistingConfigurationFile(mConfigFileName)},
+ mConfig{xsd::read(mFilePath.c_str())} {
+ if (mConfig) {
+ mStatus = OK;
+ mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice);
+ for (const auto& module : mConfig->getFirstModules()->get_module()) {
+ auto attachedDevices = module.getFirstAttachedDevices()->getItem();
+ if (!attachedDevices.empty()) {
+ mModulesWithDevicesNames.insert(module.getName());
+ }
+ }
+ }
+ }
+ status_t getStatus() const { return mStatus; }
+ std::string getError() const {
+ if (mFilePath.empty()) {
+ return std::string{"Could not find "} + mConfigFileName +
+ " file in: " + testing::PrintToString(android::audio_get_configuration_paths());
+ } else {
+ return "Invalid config file: " + mFilePath;
+ }
+ }
+ const std::string& getFilePath() const { return mFilePath; }
+ const xsd::Module* getModuleFromName(const std::string& name) const {
+ if (mConfig) {
+ for (const auto& module : mConfig->getFirstModules()->get_module()) {
+ if (module.getName() == name) return &module;
+ }
+ }
+ return nullptr;
+ }
+ const xsd::Module* getPrimaryModule() const { return mPrimaryModule; }
+ const std::set<std::string>& getModulesWithDevicesNames() const {
+ return mModulesWithDevicesNames;
+ }
+ bool haveInputProfilesInModule(const std::string& name) const {
+ auto module = getModuleFromName(name);
+ for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
+ if (mixPort.getRole() == xsd::Role::sink) return true;
+ }
+ return false;
+ }
+
+ private:
+ static std::string findExistingConfigurationFile(const std::string& fileName) {
+ for (const auto& location : android::audio_get_configuration_paths()) {
+ std::string path = location + '/' + fileName;
+ if (access(path.c_str(), F_OK) == 0) {
+ return path;
+ }
+ }
+ return std::string{};
+ }
+
+ const std::string mConfigFileName;
+ const std::string mFilePath;
+ std::optional<xsd::AudioPolicyConfiguration> mConfig;
+ status_t mStatus = NO_INIT;
+ const xsd::Module* mPrimaryModule;
+ std::set<std::string> mModulesWithDevicesNames;
+};
diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp
index 6ac9b20..c7bfe08 100644
--- a/audio/core/all-versions/vts/functional/Android.bp
+++ b/audio/core/all-versions/vts/functional/Android.bp
@@ -19,9 +19,6 @@
defaults: ["VtsHalTargetTestDefaults"],
static_libs: [
"android.hardware.audio.common.test.utility",
- "libaudiofoundation",
- "libaudiopolicycomponents",
- "libmedia_helper",
"libxml2",
],
shared_libs: [
@@ -44,6 +41,9 @@
"2.0/AudioPrimaryHidlHalTest.cpp",
],
static_libs: [
+ "libaudiofoundation",
+ "libaudiopolicycomponents",
+ "libmedia_helper",
"android.hardware.audio@2.0",
"android.hardware.audio.common@2.0",
],
@@ -67,6 +67,9 @@
"4.0/AudioPrimaryHidlHalTest.cpp",
],
static_libs: [
+ "libaudiofoundation",
+ "libaudiopolicycomponents",
+ "libmedia_helper",
"android.hardware.audio@4.0",
"android.hardware.audio.common@4.0",
],
@@ -90,6 +93,9 @@
"5.0/AudioPrimaryHidlHalTest.cpp",
],
static_libs: [
+ "libaudiofoundation",
+ "libaudiopolicycomponents",
+ "libmedia_helper",
"android.hardware.audio@5.0",
"android.hardware.audio.common@5.0",
],
@@ -113,6 +119,9 @@
"6.0/AudioPrimaryHidlHalTest.cpp",
],
static_libs: [
+ "libaudiofoundation",
+ "libaudiopolicycomponents",
+ "libmedia_helper",
"android.hardware.audio@6.0",
"android.hardware.audio.common@6.0",
],
@@ -130,7 +139,6 @@
}
cc_test {
- enabled: false,
name: "VtsHalAudioV7_0TargetTest",
defaults: ["VtsHalAudioTargetTest_defaults"],
srcs: [
@@ -139,6 +147,7 @@
static_libs: [
"android.hardware.audio@7.0",
"android.hardware.audio.common@7.0",
+ "android.hardware.audio.common@7.0-enums",
],
cflags: [
"-DMAJOR_VERSION=7",
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index 01bdd69..0a9d5ee 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -42,8 +42,11 @@
#include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
#include PATH(android/hardware/audio/FILE_VERSION/types.h)
#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+#if MAJOR_VERSION >= 7
+#include <audio_policy_configuration_V7_0-enums.h>
+#include <audio_policy_configuration_V7_0.h>
+#endif
-#include <Serializer.h>
#include <fmq/EventFlag.h>
#include <fmq/MessageQueue.h>
#include <hidl/GtestPrinter.h>
@@ -63,14 +66,6 @@
#include "4.0/AudioPrimaryHidlHalUtils.h"
#endif
-using std::initializer_list;
-using std::list;
-using std::string;
-using std::to_string;
-using std::vector;
-
-using ::android::AudioPolicyConfig;
-using ::android::HwModule;
using ::android::NO_INIT;
using ::android::OK;
using ::android::sp;
@@ -93,6 +88,12 @@
using namespace ::android::hardware::audio::common::CPP_VERSION;
using namespace ::android::hardware::audio::common::test::utility;
using namespace ::android::hardware::audio::CPP_VERSION;
+#if MAJOR_VERSION >= 7
+// Make an alias for enumerations generated from the APM config XSD.
+namespace xsd {
+using namespace ::audio::policy::configuration::CPP_VERSION;
+}
+#endif
// Typical accepted results from interface methods
static auto okOrNotSupported = {Result::OK, Result::NOT_SUPPORTED};
@@ -103,8 +104,12 @@
static auto invalidArgsOrNotSupported = {Result::INVALID_ARGUMENTS, Result::NOT_SUPPORTED};
static auto invalidStateOrNotSupported = {Result::INVALID_STATE, Result::NOT_SUPPORTED};
-#define AUDIO_PRIMARY_HIDL_HAL_TEST
#include "DeviceManager.h"
+#if MAJOR_VERSION <= 6
+#include "PolicyConfig.h"
+#elif MAJOR_VERSION >= 7
+#include "7.0/PolicyConfig.h"
+#endif
class HidlTest : public ::testing::Test {
public:
@@ -136,83 +141,16 @@
////////////////////////// Audio policy configuration ////////////////////////
//////////////////////////////////////////////////////////////////////////////
-static constexpr char kConfigFileName[] = "audio_policy_configuration.xml";
-
// Stringify the argument.
#define QUOTE(x) #x
#define STRINGIFY(x) QUOTE(x)
-struct PolicyConfigData {
- android::HwModuleCollection hwModules;
- android::DeviceVector availableOutputDevices;
- android::DeviceVector availableInputDevices;
- sp<android::DeviceDescriptor> defaultOutputDevice;
-};
-
-class PolicyConfig : private PolicyConfigData, public AudioPolicyConfig {
- public:
- PolicyConfig()
- : AudioPolicyConfig(hwModules, availableOutputDevices, availableInputDevices,
- defaultOutputDevice) {
- for (const auto& location : android::audio_get_configuration_paths()) {
- std::string path = location + '/' + kConfigFileName;
- if (access(path.c_str(), F_OK) == 0) {
- mFilePath = path;
- break;
- }
- }
- mStatus = android::deserializeAudioPolicyFile(mFilePath.c_str(), this);
- if (mStatus == OK) {
- mPrimaryModule = getHwModules().getModuleFromName(DeviceManager::kPrimaryDevice);
- // Available devices are not 'attached' to modules at this moment.
- // Need to go over available devices and find their module.
- for (const auto& device : availableOutputDevices) {
- for (const auto& module : hwModules) {
- if (module->getDeclaredDevices().indexOf(device) >= 0) {
- mModulesWithDevicesNames.insert(module->getName());
- break;
- }
- }
- }
- for (const auto& device : availableInputDevices) {
- for (const auto& module : hwModules) {
- if (module->getDeclaredDevices().indexOf(device) >= 0) {
- mModulesWithDevicesNames.insert(module->getName());
- break;
- }
- }
- }
- }
- }
- status_t getStatus() const { return mStatus; }
- std::string getError() const {
- if (mFilePath.empty()) {
- return std::string{"Could not find "} + kConfigFileName +
- " file in: " + testing::PrintToString(android::audio_get_configuration_paths());
- } else {
- return "Invalid config file: " + mFilePath;
- }
- }
- const std::string& getFilePath() const { return mFilePath; }
- sp<const HwModule> getModuleFromName(const std::string& name) const {
- return getHwModules().getModuleFromName(name.c_str());
- }
- sp<const HwModule> getPrimaryModule() const { return mPrimaryModule; }
- const std::set<std::string>& getModulesWithDevicesNames() const {
- return mModulesWithDevicesNames;
- }
-
- private:
- status_t mStatus = NO_INIT;
- std::string mFilePath;
- sp<HwModule> mPrimaryModule = nullptr;
- std::set<std::string> mModulesWithDevicesNames;
-};
+static constexpr char kConfigFileName[] = "audio_policy_configuration.xml";
// Cached policy config after parsing for faster test startup
const PolicyConfig& getCachedPolicyConfig() {
static std::unique_ptr<PolicyConfig> policyConfig = [] {
- auto config = std::make_unique<PolicyConfig>();
+ auto config = std::make_unique<PolicyConfig>(kConfigFileName);
return config;
}();
return *policyConfig;
@@ -449,9 +387,10 @@
* The getter and/or the setter may return NOT_SUPPORTED if optionality == OPTIONAL.
*/
template <Optionality optionality = REQUIRED, class IUTGetter, class Getter, class Setter>
- void testAccessors(IUTGetter iutGetter, const string& propertyName,
- const Initial expectedInitial, list<Property> valuesToTest, Setter setter,
- Getter getter, const vector<Property>& invalidValues = {}) {
+ void testAccessors(IUTGetter iutGetter, const std::string& propertyName,
+ const Initial expectedInitial, std::list<Property> valuesToTest,
+ Setter setter, Getter getter,
+ const std::vector<Property>& invalidValues = {}) {
const auto expectedResults = {Result::OK,
optionality == OPTIONAL ? Result::NOT_SUPPORTED : Result::OK};
@@ -495,9 +434,9 @@
EXPECT_RESULT(expectedResults, ((this->*iutGetter)().get()->*setter)(initialValue));
}
template <Optionality optionality = REQUIRED, class Getter, class Setter>
- void testAccessors(const string& propertyName, const Initial expectedInitial,
- list<Property> valuesToTest, Setter setter, Getter getter,
- const vector<Property>& invalidValues = {}) {
+ void testAccessors(const std::string& propertyName, const Initial expectedInitial,
+ std::list<Property> valuesToTest, Setter setter, Getter getter,
+ const std::vector<Property>& invalidValues = {}) {
testAccessors<optionality>(&BaseTestClass::getDevice, propertyName, expectedInitial,
valuesToTest, setter, getter, invalidValues);
}
@@ -573,9 +512,13 @@
// Nesting a tuple in another tuple allows to use GTest Combine function to generate
// all combinations of devices and configs.
enum { PARAM_DEVICE, PARAM_CONFIG, PARAM_FLAGS };
+#if MAJOR_VERSION <= 6
enum { INDEX_INPUT, INDEX_OUTPUT };
using DeviceConfigParameter =
std::tuple<DeviceParameter, AudioConfig, std::variant<AudioInputFlag, AudioOutputFlag>>;
+#elif MAJOR_VERSION >= 7
+using DeviceConfigParameter = std::tuple<DeviceParameter, AudioConfig, std::vector<AudioInOutFlag>>;
+#endif
#if MAJOR_VERSION >= 6
const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters();
@@ -583,8 +526,8 @@
#endif
#if MAJOR_VERSION >= 4
-static string SanitizeStringForGTestName(const string& s) {
- string result = s;
+static std::string SanitizeStringForGTestName(const std::string& s) {
+ std::string result = s;
for (size_t i = 0; i < result.size(); i++) {
// gtest test names must only contain alphanumeric characters
if (!std::isalnum(result[i])) result[i] = '_';
@@ -598,43 +541,57 @@
* As the only parameter changing are channel mask and sample rate,
* only print those ones in the test name.
*/
-static string DeviceConfigParameterToString(
+static std::string DeviceConfigParameterToString(
const testing::TestParamInfo<DeviceConfigParameter>& info) {
const AudioConfig& config = std::get<PARAM_CONFIG>(info.param);
const auto deviceName = DeviceParameterToString(::testing::TestParamInfo<DeviceParameter>{
std::get<PARAM_DEVICE>(info.param), info.index});
- return (deviceName.empty() ? "" : deviceName + "_") + to_string(info.index) + "__" +
- to_string(config.sampleRateHz) + "_" +
- // "MONO" is more clear than "FRONT_LEFT"
- ((config.channelMask == mkEnumBitfield(AudioChannelMask::OUT_MONO) ||
- config.channelMask == mkEnumBitfield(AudioChannelMask::IN_MONO))
- ? "MONO"
+ const auto devicePart =
+ (deviceName.empty() ? "" : deviceName + "_") + std::to_string(info.index);
+ // The types had changed a lot between versions 2, 4..6 and 7. Use separate
+ // code sections for easier understanding.
#if MAJOR_VERSION == 2
- : ::testing::PrintToString(config.channelMask)
-#elif MAJOR_VERSION >= 4
- // In V4 and above the channel mask is a bitfield.
- // Printing its value using HIDL's toString for a bitfield emits a lot of extra
- // text due to overlapping constant values. Instead, we print the bitfield value
- // as if it was a single value + its hex representation
- : SanitizeStringForGTestName(
- ::testing::PrintToString(AudioChannelMask(config.channelMask)) + "_" +
- toHexString(config.channelMask))
+ const auto configPart =
+ std::to_string(config.sampleRateHz) + "_" +
+ // "MONO" is more clear than "FRONT_LEFT"
+ (config.channelMask == AudioChannelMask::OUT_MONO ||
+ config.channelMask == AudioChannelMask::IN_MONO
+ ? "MONO"
+ : ::testing::PrintToString(config.channelMask)) +
+ "_" +
+ std::visit([](auto&& arg) -> std::string { return ::testing::PrintToString(arg); },
+ std::get<PARAM_FLAGS>(info.param));
+#elif MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6
+ const auto configPart =
+ std::to_string(config.sampleRateHz) + "_" +
+ // "MONO" is more clear than "FRONT_LEFT"
+ (config.channelMask == mkEnumBitfield(AudioChannelMask::OUT_MONO) ||
+ config.channelMask == mkEnumBitfield(AudioChannelMask::IN_MONO)
+ ? "MONO"
+ // In V4 and above the channel mask is a bitfield.
+ // Printing its value using HIDL's toString for a bitfield emits a lot of extra
+ // text due to overlapping constant values. Instead, we print the bitfield
+ // value as if it was a single value + its hex representation
+ : SanitizeStringForGTestName(
+ ::testing::PrintToString(AudioChannelMask(config.channelMask)) +
+ "_" + toHexString(config.channelMask))) +
+ "_" +
+ SanitizeStringForGTestName(std::visit(
+ [](auto&& arg) -> std::string {
+ using T = std::decay_t<decltype(arg)>;
+ // Need to use FQN of toString to avoid confusing the compiler
+ return ::android::hardware::audio::common::CPP_VERSION::toString<T>(
+ hidl_bitfield<T>(arg));
+ },
+ std::get<PARAM_FLAGS>(info.param)));
+#elif MAJOR_VERSION >= 7
+ const auto configPart =
+ std::to_string(config.base.sampleRateHz) + "_" +
+ // The channel masks and flags are vectors of strings, just need to sanitize them.
+ SanitizeStringForGTestName(::testing::PrintToString(config.base.channelMask)) + "_" +
+ SanitizeStringForGTestName(::testing::PrintToString(std::get<PARAM_FLAGS>(info.param)));
#endif
- ) +
- "_" +
-#if MAJOR_VERSION == 2
- std::visit([](auto&& arg) -> std::string { return ::testing::PrintToString(arg); },
- std::get<PARAM_FLAGS>(info.param));
-#elif MAJOR_VERSION >= 4
- SanitizeStringForGTestName(std::visit(
- [](auto&& arg) -> std::string {
- using T = std::decay_t<decltype(arg)>;
- // Need to use FQN of toString to avoid confusing the compiler
- return ::android::hardware::audio::common::CPP_VERSION::toString<T>(
- hidl_bitfield<T>(arg));
- },
- std::get<PARAM_FLAGS>(info.param)));
-#endif
+ return devicePart + "__" + configPart;
}
class AudioHidlTestWithDeviceConfigParameter
@@ -660,7 +617,7 @@
AudioOutputFlag getOutputFlags() const {
return std::get<INDEX_OUTPUT>(std::get<PARAM_FLAGS>(GetParam()));
}
-#elif MAJOR_VERSION >= 4
+#elif MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6
hidl_bitfield<AudioInputFlag> getInputFlags() const {
return hidl_bitfield<AudioInputFlag>(
std::get<INDEX_INPUT>(std::get<PARAM_FLAGS>(GetParam())));
@@ -669,10 +626,17 @@
return hidl_bitfield<AudioOutputFlag>(
std::get<INDEX_OUTPUT>(std::get<PARAM_FLAGS>(GetParam())));
}
+#elif MAJOR_VERSION >= 7
+ hidl_vec<AudioInOutFlag> getInputFlags() const { return std::get<PARAM_FLAGS>(GetParam()); }
+ hidl_vec<AudioInOutFlag> getOutputFlags() const { return std::get<PARAM_FLAGS>(GetParam()); }
#endif
};
+#if MAJOR_VERSION <= 6
+#define AUDIO_PRIMARY_HIDL_HAL_TEST
#include "ConfigHelper.h"
+#undef AUDIO_PRIMARY_HIDL_HAL_TEST
+#endif
//////////////////////////////////////////////////////////////////////////////
///////////////////////////// getInputBufferSize /////////////////////////////
@@ -839,7 +803,7 @@
AudioConfig* suggestedConfigPtr) {
// FIXME: Open a stream without an IOHandle
// This is not required to be accepted by hal implementations
- AudioIoHandle ioHandle = (AudioIoHandle)AudioHandleConsts::AUDIO_IO_HANDLE_NONE;
+ AudioIoHandle ioHandle{};
AudioConfig suggestedConfig{};
bool retryWithSuggestedConfig = true;
if (suggestedConfigPtr == nullptr) {
@@ -932,7 +896,11 @@
class OutputStreamTest : public OpenStreamTest<IStreamOut> {
void SetUp() override {
ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
+#if MAJOR_VERSION <= 6
address.device = AudioDevice::OUT_DEFAULT;
+#elif MAJOR_VERSION >= 7
+ address.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_DEFAULT);
+#endif
const AudioConfig& config = getConfig();
auto flags = getOutputFlags();
testOpen(
@@ -946,13 +914,19 @@
},
config);
}
-#if MAJOR_VERSION >= 4
+#if MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6
- protected:
+ protected:
const SourceMetadata initMetadata = {
{ { AudioUsage::MEDIA,
AudioContentType::MUSIC,
1 /* gain */ } }};
+#elif MAJOR_VERSION >= 7
+ protected:
+ const SourceMetadata initMetadata = {
+ { { toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA),
+ toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC),
+ 1 /* gain */ } }};
#endif
};
TEST_P(OutputStreamTest, OpenOutputStreamTest) {
@@ -995,7 +969,11 @@
class InputStreamTest : public OpenStreamTest<IStreamIn> {
void SetUp() override {
ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
+#if MAJOR_VERSION <= 6
address.device = AudioDevice::IN_DEFAULT;
+#elif MAJOR_VERSION <= 7
+ address.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_DEFAULT);
+#endif
const AudioConfig& config = getConfig();
auto flags = getInputFlags();
testOpen(
@@ -1009,8 +987,11 @@
protected:
#if MAJOR_VERSION == 2
const AudioSource initMetadata = AudioSource::DEFAULT;
-#elif MAJOR_VERSION >= 4
- const SinkMetadata initMetadata = {{{.source = AudioSource::DEFAULT, .gain = 1}}};
+#elif MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6
+ const SinkMetadata initMetadata = {{ {.source = AudioSource::DEFAULT, .gain = 1 } }};
+#elif MAJOR_VERSION >= 7
+ const SinkMetadata initMetadata = {
+ {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_DEFAULT), .gain = 1}}};
#endif
};
@@ -1067,6 +1048,7 @@
TEST_IO_STREAM(GetFrameCount, "Check that getting stream frame count does not crash the HAL.",
ASSERT_TRUE(stream->getFrameCount().isOk()))
+#if MAJOR_VERSION <= 6
TEST_IO_STREAM(GetSampleRate, "Check that the stream sample rate == the one it was opened with",
ASSERT_EQ(audioConfig.sampleRateHz, extract(stream->getSampleRate())))
@@ -1075,6 +1057,7 @@
TEST_IO_STREAM(GetFormat, "Check that the stream format == the one it was opened with",
ASSERT_EQ(audioConfig.format, extract(stream->getFormat())))
+#endif
// TODO: for now only check that the framesize is not incoherent
TEST_IO_STREAM(GetFrameSize, "Check that the stream frame size == the one it was opened with",
@@ -1084,7 +1067,7 @@
ASSERT_GE(extract(stream->getBufferSize()), extract(stream->getFrameSize())));
template <class Property, class CapabilityGetter>
-static void testCapabilityGetter(const string& name, IStream* stream,
+static void testCapabilityGetter(const std::string& name, IStream* stream,
CapabilityGetter capabilityGetter,
Return<Property> (IStream::*getter)(),
Return<Result> (IStream::*setter)(Property),
@@ -1120,6 +1103,7 @@
}
}
+#if MAJOR_VERSION <= 6
TEST_IO_STREAM(SupportedSampleRate, "Check that the stream sample rate is declared as supported",
testCapabilityGetter("getSupportedSampleRate", stream.get(),
&GetSupported::sampleRates, &IStream::getSampleRate,
@@ -1137,19 +1121,71 @@
TEST_IO_STREAM(SupportedFormat, "Check that the stream format is declared as supported",
testCapabilityGetter("getSupportedFormat", stream.get(), &GetSupported::formats,
&IStream::getFormat, &IStream::setFormat))
+#else
+static void testGetSupportedProfiles(IStream* stream) {
+ Result res;
+ hidl_vec<AudioProfile> profiles;
+ auto ret = stream->getSupportedProfiles(returnIn(res, profiles));
+ EXPECT_TRUE(ret.isOk());
+ if (res == Result::OK) {
+ EXPECT_GT(profiles.size(), 0);
+ } else {
+ EXPECT_EQ(Result::NOT_SUPPORTED, res);
+ }
+}
+
+TEST_IO_STREAM(GetSupportedProfiles, "Try to call optional method GetSupportedProfiles",
+ testGetSupportedProfiles(stream.get()))
+
+static void testSetAudioProperties(IStream* stream) {
+ Result res;
+ hidl_vec<AudioProfile> profiles;
+ auto ret = stream->getSupportedProfiles(returnIn(res, profiles));
+ EXPECT_TRUE(ret.isOk());
+ if (res == Result::NOT_SUPPORTED) {
+ GTEST_SKIP() << "Retrieving supported profiles is not implemented";
+ }
+ for (const auto& profile : profiles) {
+ for (const auto& sampleRate : profile.sampleRates) {
+ for (const auto& channelMask : profile.channelMasks) {
+ AudioConfigBase config{.format = profile.format,
+ .sampleRateHz = sampleRate,
+ .channelMask = {{channelMask}}};
+ auto ret = stream->setAudioProperties(config);
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::OK, ret) << config.format << "; " << config.sampleRateHz << "; "
+ << toString(config.channelMask);
+ }
+ }
+ }
+}
+
+TEST_IO_STREAM(SetAudioProperties, "Call setAudioProperties for all supported profiles",
+ testSetAudioProperties(stream.get()))
+#endif
static void testGetAudioProperties(IStream* stream, AudioConfig expectedConfig) {
+#if MAJOR_VERSION <= 6
uint32_t sampleRateHz;
auto mask = mkEnumBitfield<AudioChannelMask>({});
AudioFormat format;
- stream->getAudioProperties(returnIn(sampleRateHz, mask, format));
+ auto ret = stream->getAudioProperties(returnIn(sampleRateHz, mask, format));
+ EXPECT_TRUE(ret.isOk());
// FIXME: the qcom hal it does not currently negotiate the sampleRate &
// channel mask
EXPECT_EQ(expectedConfig.sampleRateHz, sampleRateHz);
EXPECT_EQ(expectedConfig.channelMask, mask);
EXPECT_EQ(expectedConfig.format, format);
+#elif MAJOR_VERSION >= 7
+ AudioConfigBase actualConfig{};
+ auto ret = stream->getAudioProperties(returnIn(actualConfig));
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(expectedConfig.base.sampleRateHz, actualConfig.sampleRateHz);
+ EXPECT_EQ(expectedConfig.base.channelMask, actualConfig.channelMask);
+ EXPECT_EQ(expectedConfig.base.format, actualConfig.format);
+#endif
}
TEST_IO_STREAM(GetAudioProperties,
@@ -1160,7 +1196,7 @@
ASSERT_RESULT(okOrNotSupportedOrInvalidArgs, stream->setHwAvSync(666)))
static void checkGetNoParameter(IStream* stream, hidl_vec<hidl_string> keys,
- initializer_list<Result> expectedResults) {
+ std::initializer_list<Result> expectedResults) {
hidl_vec<ParameterValue> parameters;
Result res;
ASSERT_OK(Parameters::get(stream, keys, returnIn(res, parameters)));
@@ -1271,7 +1307,11 @@
return;
}
ASSERT_OK(res);
+#if MAJOR_VERSION <= 6
ASSERT_EQ(AudioSource::DEFAULT, source);
+#elif MAJOR_VERSION >= 7
+ ASSERT_EQ(xsd::AudioSource::AUDIO_SOURCE_DEFAULT, xsd::stringToAudioSource(source));
+#endif
}
static void testUnitaryGain(std::function<Return<Result>(float)> setGain) {
@@ -1286,7 +1326,7 @@
}
static void testOptionalUnitaryGain(std::function<Return<Result>(float)> setGain,
- string debugName) {
+ std::string debugName) {
auto result = setGain(1);
ASSERT_IS_OK(result);
if (result == Result::NOT_SUPPORTED) {
@@ -1306,7 +1346,7 @@
Result res;
// Ignore output parameters as the call should fail
ASSERT_OK(stream->prepareForReading(frameSize, framesCount,
- [&res](auto r, auto&, auto&, auto&, auto&) { res = r; }));
+ [&res](auto r, auto&, auto&, auto&, auto) { res = r; }));
EXPECT_RESULT(Result::INVALID_ARGUMENTS, res);
}
@@ -1371,7 +1411,7 @@
Result res;
// Ignore output parameters as the call should fail
ASSERT_OK(stream->prepareForWriting(frameSize, framesCount,
- [&res](auto r, auto&, auto&, auto&, auto&) { res = r; }));
+ [&res](auto r, auto&, auto&, auto&, auto) { res = r; }));
EXPECT_RESULT(Result::INVALID_ARGUMENTS, res);
}
diff --git a/audio/core/all-versions/vts/functional/ConfigHelper.h b/audio/core/all-versions/vts/functional/ConfigHelper.h
index 8ef2b43..1a1dbea 100644
--- a/audio/core/all-versions/vts/functional/ConfigHelper.h
+++ b/audio/core/all-versions/vts/functional/ConfigHelper.h
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#pragma once
+
// Code in this file uses 'getCachedPolicyConfig'
#ifndef AUDIO_PRIMARY_HIDL_HAL_TEST
#error Must be included from AudioPrimaryHidlTest.h
@@ -46,32 +48,32 @@
}
// Cache result ?
- static const vector<AudioConfig> getRequiredSupportPlaybackAudioConfig() {
+ static const std::vector<AudioConfig> getRequiredSupportPlaybackAudioConfig() {
return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
{8000, 11025, 16000, 22050, 32000, 44100},
{AudioFormat::PCM_16_BIT});
}
- static const vector<AudioConfig> getRecommendedSupportPlaybackAudioConfig() {
+ static const std::vector<AudioConfig> getRecommendedSupportPlaybackAudioConfig() {
return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
{24000, 48000}, {AudioFormat::PCM_16_BIT});
}
- static const vector<AudioConfig> getRequiredSupportCaptureAudioConfig() {
+ static const std::vector<AudioConfig> getRequiredSupportCaptureAudioConfig() {
if (!primaryHasMic()) return {};
return combineAudioConfig({AudioChannelMask::IN_MONO}, {8000, 11025, 16000, 44100},
{AudioFormat::PCM_16_BIT});
}
- static const vector<AudioConfig> getRecommendedSupportCaptureAudioConfig() {
+ static const std::vector<AudioConfig> getRecommendedSupportCaptureAudioConfig() {
if (!primaryHasMic()) return {};
return combineAudioConfig({AudioChannelMask::IN_STEREO}, {22050, 48000},
{AudioFormat::PCM_16_BIT});
}
- static vector<AudioConfig> combineAudioConfig(vector<audio_channel_mask_t> channelMasks,
- vector<uint32_t> sampleRates,
- audio_format_t format) {
- vector<AudioConfig> configs;
+ static std::vector<AudioConfig> combineAudioConfig(
+ std::vector<audio_channel_mask_t> channelMasks, std::vector<uint32_t> sampleRates,
+ audio_format_t format) {
+ std::vector<AudioConfig> configs;
configs.reserve(channelMasks.size() * sampleRates.size());
for (auto channelMask : channelMasks) {
for (auto sampleRate : sampleRates) {
@@ -86,10 +88,10 @@
return configs;
}
- static vector<AudioConfig> combineAudioConfig(vector<AudioChannelMask> channelMasks,
- vector<uint32_t> sampleRates,
- vector<AudioFormat> formats) {
- vector<AudioConfig> configs;
+ static std::vector<AudioConfig> combineAudioConfig(std::vector<AudioChannelMask> channelMasks,
+ std::vector<uint32_t> sampleRates,
+ std::vector<AudioFormat> formats) {
+ std::vector<AudioConfig> configs;
configs.reserve(channelMasks.size() * sampleRates.size() * formats.size());
for (auto channelMask : channelMasks) {
for (auto sampleRate : sampleRates) {
diff --git a/audio/core/all-versions/vts/functional/DeviceManager.h b/audio/core/all-versions/vts/functional/DeviceManager.h
index 0c0727f..6efed79 100644
--- a/audio/core/all-versions/vts/functional/DeviceManager.h
+++ b/audio/core/all-versions/vts/functional/DeviceManager.h
@@ -14,10 +14,11 @@
* limitations under the License.
*/
-// Code in this file uses 'environment'
-#ifndef AUDIO_PRIMARY_HIDL_HAL_TEST
-#error Must be included from AudioPrimaryHidlTest.h
-#endif
+#pragma once
+
+// Note: it is assumed that this file is included from AudioPrimaryHidlTest.h
+// and thus it doesn't have all '#include' and 'using' directives required
+// for a standalone compilation.
template <class Derived, class Key, class Interface>
class InterfaceManager {
diff --git a/audio/core/all-versions/vts/functional/PolicyConfig.h b/audio/core/all-versions/vts/functional/PolicyConfig.h
new file mode 100644
index 0000000..c9e0c0d
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/PolicyConfig.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+// Note: it is assumed that this file is included from AudioPrimaryHidlTest.h
+// and thus it doesn't have all '#include' and 'using' directives required
+// for a standalone compilation.
+
+#include <Serializer.h>
+
+struct PolicyConfigData {
+ android::HwModuleCollection hwModules;
+ android::DeviceVector availableOutputDevices;
+ android::DeviceVector availableInputDevices;
+ sp<android::DeviceDescriptor> defaultOutputDevice;
+};
+
+class PolicyConfig : private PolicyConfigData, public android::AudioPolicyConfig {
+ public:
+ explicit PolicyConfig(const std::string& configFileName)
+ : android::AudioPolicyConfig(hwModules, availableOutputDevices, availableInputDevices,
+ defaultOutputDevice),
+ mConfigFileName{configFileName} {
+ for (const auto& location : android::audio_get_configuration_paths()) {
+ std::string path = location + '/' + mConfigFileName;
+ if (access(path.c_str(), F_OK) == 0) {
+ mFilePath = path;
+ break;
+ }
+ }
+ mStatus = android::deserializeAudioPolicyFile(mFilePath.c_str(), this);
+ if (mStatus == OK) {
+ mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice);
+ // Available devices are not 'attached' to modules at this moment.
+ // Need to go over available devices and find their module.
+ for (const auto& device : availableOutputDevices) {
+ for (const auto& module : hwModules) {
+ if (module->getDeclaredDevices().indexOf(device) >= 0) {
+ mModulesWithDevicesNames.insert(module->getName());
+ break;
+ }
+ }
+ }
+ for (const auto& device : availableInputDevices) {
+ for (const auto& module : hwModules) {
+ if (module->getDeclaredDevices().indexOf(device) >= 0) {
+ mModulesWithDevicesNames.insert(module->getName());
+ break;
+ }
+ }
+ }
+ }
+ }
+ status_t getStatus() const { return mStatus; }
+ std::string getError() const {
+ if (mFilePath.empty()) {
+ return std::string{"Could not find "} + mConfigFileName +
+ " file in: " + testing::PrintToString(android::audio_get_configuration_paths());
+ } else {
+ return "Invalid config file: " + mFilePath;
+ }
+ }
+ const std::string& getFilePath() const { return mFilePath; }
+ sp<const android::HwModule> getModuleFromName(const std::string& name) const {
+ return getHwModules().getModuleFromName(name.c_str());
+ }
+ sp<const android::HwModule> getPrimaryModule() const { return mPrimaryModule; }
+ const std::set<std::string>& getModulesWithDevicesNames() const {
+ return mModulesWithDevicesNames;
+ }
+ bool haveInputProfilesInModule(const std::string& name) const {
+ auto module = getModuleFromName(name);
+ return module && !module->getInputProfiles().empty();
+ }
+
+ private:
+ const std::string mConfigFileName;
+ status_t mStatus = NO_INIT;
+ std::string mFilePath;
+ sp<const android::HwModule> mPrimaryModule = nullptr;
+ std::set<std::string> mModulesWithDevicesNames;
+};
diff --git a/audio/effect/all-versions/vts/functional/Android.bp b/audio/effect/all-versions/vts/functional/Android.bp
index 7cdb18f..f4a7283 100644
--- a/audio/effect/all-versions/vts/functional/Android.bp
+++ b/audio/effect/all-versions/vts/functional/Android.bp
@@ -118,7 +118,6 @@
}
cc_test {
- enabled: false,
name: "VtsHalAudioEffectV7_0TargetTest",
defaults: ["VtsHalAudioEffectTargetTest_default"],
// Use test_config for vts suite.
@@ -126,6 +125,7 @@
test_config: "VtsHalAudioEffectV7_0TargetTest.xml",
static_libs: [
"android.hardware.audio.common@7.0",
+ "android.hardware.audio.common@7.0-enums",
"android.hardware.audio.effect@7.0",
],
data: [
diff --git a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
index 4787c09..b64f105 100644
--- a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
@@ -16,7 +16,9 @@
#define LOG_TAG "AudioEffectHidlHalTest"
#include <android-base/logging.h>
+#if MAJOR_VERSION <= 6
#include <system/audio.h>
+#endif
#include PATH(android/hardware/audio/effect/FILE_VERSION/IEffect.h)
#include PATH(android/hardware/audio/effect/FILE_VERSION/IEffectsFactory.h)
@@ -25,6 +27,10 @@
#include PATH(android/hardware/audio/effect/FILE_VERSION/types.h)
#include <android/hidl/allocator/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMemory.h>
+#if MAJOR_VERSION >= 7
+#include <audio_policy_configuration_V7_0-enums.h>
+#include <audio_policy_configuration_V7_0.h>
+#endif
#include <common/all-versions/VersionUtils.h>
@@ -45,6 +51,12 @@
using ::android::hidl::memory::V1_0::IMemory;
using namespace ::android::hardware::audio::common::CPP_VERSION;
using namespace ::android::hardware::audio::effect::CPP_VERSION;
+#if MAJOR_VERSION >= 7
+// Make an alias for enumerations generated from the APM config XSD.
+namespace xsd {
+using namespace ::audio::policy::configuration::CPP_VERSION;
+}
+#endif
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
@@ -171,7 +183,7 @@
effectsFactory = IEffectsFactory::getService(std::get<PARAM_FACTORY_NAME>(GetParam()));
ASSERT_NE(nullptr, effectsFactory.get());
- findAndCreateEffect(getEffectType());
+ ASSERT_NO_FATAL_FAILURE(findAndCreateEffect(getEffectType()));
ASSERT_NE(nullptr, effect.get());
Return<Result> ret = effect->init();
@@ -201,7 +213,7 @@
void AudioEffectHidlTest::findAndCreateEffect(const Uuid& type) {
Uuid effectUuid;
- findEffectInstance(type, &effectUuid);
+ ASSERT_NO_FATAL_FAILURE(findEffectInstance(type, &effectUuid));
Return<void> ret = effectsFactory->createEffect(
effectUuid, 1 /*session*/, 1 /*ioHandle*/,
#if MAJOR_VERSION >= 6
@@ -244,10 +256,16 @@
});
ASSERT_TRUE(ret.isOk());
ASSERT_EQ(Result::OK, retval);
+#if MAJOR_VERSION <= 6
ASSERT_TRUE(audio_channel_mask_is_valid(
static_cast<audio_channel_mask_t>(currentConfig.outputCfg.channels)));
*channelCount = audio_channel_count_from_out_mask(
static_cast<audio_channel_mask_t>(currentConfig.outputCfg.channels));
+#else
+ *channelCount =
+ audio::policy::configuration::V7_0::getChannelCount(currentConfig.outputCfg.channels);
+ ASSERT_NE(*channelCount, 0);
+#endif
}
TEST_P(AudioEffectHidlTest, Close) {
@@ -391,7 +409,12 @@
TEST_P(AudioEffectHidlTest, SetDevice) {
description("Verify that SetDevice works for an output chain effect");
+#if MAJOR_VERSION <= 6
Return<Result> ret = effect->setDevice(mkEnumBitfield(AudioDevice::OUT_SPEAKER));
+#else
+ DeviceAddress device{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_SPEAKER)};
+ Return<Result> ret = effect->setDevice(device);
+#endif
EXPECT_TRUE(ret.isOk());
EXPECT_EQ(Result::OK, ret);
}
@@ -441,22 +464,28 @@
TEST_P(AudioEffectHidlTest, SetInputDevice) {
description("Verify that SetInputDevice does not crash");
+#if MAJOR_VERSION <= 6
Return<Result> ret = effect->setInputDevice(mkEnumBitfield(AudioDevice::IN_BUILTIN_MIC));
+#else
+ DeviceAddress device{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC)};
+ Return<Result> ret = effect->setInputDevice(device);
+#endif
EXPECT_TRUE(ret.isOk());
}
TEST_P(AudioEffectHidlTest, SetAudioSource) {
description("Verify that SetAudioSource does not crash");
+#if MAJOR_VERSION <= 6
Return<Result> ret = effect->setAudioSource(AudioSource::MIC);
+#else
+ Return<Result> ret = effect->setAudioSource(toString(xsd::AudioSource::AUDIO_SOURCE_MIC));
+#endif
EXPECT_TRUE(ret.isOk());
}
TEST_P(AudioEffectHidlTest, Offload) {
description("Verify that calling Offload method does not crash");
- EffectOffloadParameter offloadParam;
- offloadParam.isOffload = false;
- offloadParam.ioHandle = static_cast<int>(AudioHandleConsts::AUDIO_IO_HANDLE_NONE);
- Return<Result> ret = effect->offload(offloadParam);
+ Return<Result> ret = effect->offload(EffectOffloadParameter{});
EXPECT_TRUE(ret.isOk());
}
diff --git a/audio/policy/1.0/vts/functional/Android.bp b/audio/policy/1.0/vts/functional/Android.bp
index a5ddee5..7b7cf0d 100644
--- a/audio/policy/1.0/vts/functional/Android.bp
+++ b/audio/policy/1.0/vts/functional/Android.bp
@@ -1,6 +1,5 @@
cc_test {
name: "VtsHalAudioPolicyV1_0TargetTest",
- defaults: ["vts_target_tests_defaults"],
srcs: [
"ValidateEngineConfiguration.cpp",
],
diff --git a/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp b/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp
index 687c70c..c09b265 100644
--- a/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp
+++ b/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp
@@ -34,11 +34,19 @@
authsecret = IAuthSecret::getService(GetParam());
ASSERT_NE(authsecret, nullptr);
+ // Notify LSS to generate PIN code '1234' and corresponding secret.
+ (void)system("cmd lock_settings set-pin 1234");
+
// All tests must enroll the correct secret first as this cannot be changed
// without a factory reset and the order of tests could change.
authsecret->primaryUserCredential(CORRECT_SECRET);
}
+ static void TearDownTestSuite() {
+ // clean up PIN code after testing
+ (void)system("cmd lock_settings clear --old 1234");
+ }
+
sp<IAuthSecret> authsecret;
hidl_vec<uint8_t> CORRECT_SECRET{61, 93, 124, 240, 5, 0, 7, 201, 9, 129, 11, 12, 0, 14, 0, 16};
hidl_vec<uint8_t> WRONG_SECRET{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
diff --git a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
index 638ecd5..8de9304 100644
--- a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
+++ b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
@@ -72,6 +72,8 @@
using ::android::hardware::automotive::evs::V1_0::DisplayDesc;
using ::android::hardware::automotive::evs::V1_0::DisplayState;
using ::android::hardware::graphics::common::V1_0::PixelFormat;
+using ::android::frameworks::automotive::display::V1_0::HwDisplayConfig;
+using ::android::frameworks::automotive::display::V1_0::HwDisplayState;
using IEvsCamera_1_0 = ::android::hardware::automotive::evs::V1_0::IEvsCamera;
using IEvsCamera_1_1 = ::android::hardware::automotive::evs::V1_1::IEvsCamera;
using IEvsDisplay_1_0 = ::android::hardware::automotive::evs::V1_0::IEvsDisplay;
@@ -605,7 +607,10 @@
LOG(INFO) << "Display " << targetDisplayId << " is alreay in use.";
// Get the display descriptor
- pDisplay->getDisplayInfo_1_1([](const auto& config, const auto& state) {
+ pDisplay->getDisplayInfo_1_1([](const HwDisplayConfig& config, const HwDisplayState& state) {
+ ASSERT_GT(config.size(), 0);
+ ASSERT_GT(state.size(), 0);
+
android::DisplayConfig* pConfig = (android::DisplayConfig*)config.data();
const auto width = pConfig->resolution.getWidth();
const auto height = pConfig->resolution.getHeight();
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index 9a0d89d..590adc5 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -137,7 +137,6 @@
local_include_dirs: ["common/include/vhal_v2_0"],
export_include_dirs: ["impl"],
srcs: [
- "impl/vhal_v2_0/EmulatedUserHal.cpp",
"impl/vhal_v2_0/GeneratorHub.cpp",
"impl/vhal_v2_0/JsonFakeValueGenerator.cpp",
"impl/vhal_v2_0/LinearFakeValueGenerator.cpp",
diff --git a/automotive/vehicle/2.0/default/VehicleService.cpp b/automotive/vehicle/2.0/default/VehicleService.cpp
index 62a4f20..7e8deb6 100644
--- a/automotive/vehicle/2.0/default/VehicleService.cpp
+++ b/automotive/vehicle/2.0/default/VehicleService.cpp
@@ -31,7 +31,7 @@
int main(int /* argc */, char* /* argv */ []) {
auto store = std::make_unique<VehiclePropertyStore>();
- auto connector = impl::makeEmulatedPassthroughConnector();
+ auto connector = std::make_unique<impl::EmulatedVehicleConnector>();
auto userHal = connector->getEmulatedUserHal();
auto hal = std::make_unique<impl::EmulatedVehicleHal>(store.get(), connector.get(), userHal);
auto emulator = std::make_unique<impl::VehicleEmulator>(hal.get());
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 e3b559e..80a1831 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
@@ -1095,6 +1095,30 @@
{
.config =
{
+ .prop = toInt(VehicleProperty::POWER_POLICY_REQ),
+ .access = VehiclePropertyAccess::READ,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ },
+ },
+ {
+ .config =
+ {
+ .prop = toInt(VehicleProperty::POWER_POLICY_GROUP_REQ),
+ .access = VehiclePropertyAccess::READ,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ },
+ },
+ {
+ .config =
+ {
+ .prop = toInt(VehicleProperty::CURRENT_POWER_POLICY),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ },
+ },
+ {
+ .config =
+ {
.prop = toInt(VehicleProperty::WATCHDOG_ALIVE),
.access = VehiclePropertyAccess::WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp
index 7f9362f..ed3f4a2 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp
@@ -35,13 +35,33 @@
namespace impl {
-class EmulatedPassthroughConnector : public PassthroughConnector {
- public:
- bool onDump(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
-};
+EmulatedUserHal* EmulatedVehicleConnector::getEmulatedUserHal() {
+ return &mEmulatedUserHal;
+}
-bool EmulatedPassthroughConnector::onDump(const hidl_handle& handle,
- const hidl_vec<hidl_string>& options) {
+StatusCode EmulatedVehicleConnector::onSetProperty(const VehiclePropValue& value,
+ bool updateStatus) {
+ if (mEmulatedUserHal.isSupported(value.prop)) {
+ LOG(INFO) << "onSetProperty(): property " << value.prop << " will be handled by UserHal";
+
+ const auto& ret = mEmulatedUserHal.onSetProperty(value);
+ if (!ret.ok()) {
+ LOG(ERROR) << "onSetProperty(): HAL returned error: " << ret.error().message();
+ return StatusCode(ret.error().code());
+ }
+ auto updatedValue = ret.value().get();
+ if (updatedValue != nullptr) {
+ LOG(INFO) << "onSetProperty(): updating property returned by HAL: "
+ << toString(*updatedValue);
+ onPropertyValueFromCar(*updatedValue, updateStatus);
+ }
+ return StatusCode::OK;
+ }
+ return this->VehicleHalServer::onSetProperty(value, updateStatus);
+}
+
+bool EmulatedVehicleConnector::onDump(const hidl_handle& handle,
+ const hidl_vec<hidl_string>& options) {
int fd = handle->data[0];
if (options.size() > 0) {
@@ -68,10 +88,6 @@
return true;
}
-PassthroughConnectorPtr makeEmulatedPassthroughConnector() {
- return std::make_unique<EmulatedPassthroughConnector>();
-}
-
} // namespace impl
} // namespace V2_0
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h
index 57cbb8b..4c6c661 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h
@@ -19,6 +19,7 @@
#include <vhal_v2_0/VehicleConnector.h>
+#include "EmulatedUserHal.h"
#include "VehicleHalClient.h"
#include "VehicleHalServer.h"
@@ -30,10 +31,20 @@
namespace impl {
-using PassthroughConnector = IPassThroughConnector<VehicleHalClient, VehicleHalServer>;
-using PassthroughConnectorPtr = std::unique_ptr<PassthroughConnector>;
+class EmulatedVehicleConnector : public IPassThroughConnector<VehicleHalClient, VehicleHalServer> {
+ public:
+ EmulatedVehicleConnector() {}
-PassthroughConnectorPtr makeEmulatedPassthroughConnector();
+ EmulatedUserHal* getEmulatedUserHal();
+
+ // Methods from VehicleHalServer
+ StatusCode onSetProperty(const VehiclePropValue& value, bool updateStatus) override;
+
+ bool onDump(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
+
+ private:
+ EmulatedUserHal mEmulatedUserHal;
+};
} // namespace impl
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp
index 36f2534..0ee1835 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp
@@ -41,10 +41,6 @@
return mValuePool;
}
-EmulatedUserHal* VehicleHalServer::getEmulatedUserHal() {
- return &mEmulatedUserHal;
-}
-
void VehicleHalServer::setValuePool(VehiclePropValuePool* valuePool) {
if (!valuePool) {
LOG(WARNING) << __func__ << ": Setting value pool to nullptr!";
@@ -185,22 +181,6 @@
}
StatusCode VehicleHalServer::onSetProperty(const VehiclePropValue& value, bool updateStatus) {
- if (mEmulatedUserHal.isSupported(value.prop)) {
- LOG(INFO) << "onSetProperty(): property " << value.prop << " will be handled by UserHal";
-
- const auto& ret = mEmulatedUserHal.onSetProperty(value);
- if (!ret.ok()) {
- LOG(ERROR) << "onSetProperty(): HAL returned error: " << ret.error().message();
- return StatusCode(ret.error().code());
- }
- auto updatedValue = ret.value().get();
- if (updatedValue != nullptr) {
- LOG(INFO) << "onSetProperty(): updating property returned by HAL: "
- << toString(*updatedValue);
- onPropertyValueFromCar(*updatedValue, updateStatus);
- }
- return StatusCode::OK;
- }
LOG(DEBUG) << "onSetProperty(" << value.prop << ")";
// Some properties need to be treated non-trivially
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h
index fca78bc..117eadb 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h
@@ -19,7 +19,6 @@
#include <vhal_v2_0/VehicleObjectPool.h>
#include <vhal_v2_0/VehicleServer.h>
-#include "EmulatedUserHal.h"
#include "GeneratorHub.h"
namespace android::hardware::automotive::vehicle::V2_0::impl {
@@ -38,8 +37,6 @@
// Set the Property Value Pool used in this server
void setValuePool(VehiclePropValuePool* valuePool);
- EmulatedUserHal* getEmulatedUserHal();
-
private:
using VehiclePropValuePtr = recyclable_ptr<VehiclePropValue>;
@@ -56,11 +53,6 @@
VehiclePropValuePtr createHwInputKeyProp(VehicleHwKeyInputAction action, int32_t keyCode,
int32_t targetDisplay);
- // data members
-
- protected:
- EmulatedUserHal mEmulatedUserHal;
-
private:
GeneratorHub mGeneratorHub{
std::bind(&VehicleHalServer::onFakeValueGenerated, this, std::placeholders::_1)};
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index 11fe70e..931fee4 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -2921,6 +2921,65 @@
| VehicleArea:GLOBAL),
/**
+ * Defines a request to apply power policy.
+ *
+ * VHAL sets this property to change car power policy. Car power policy service subscribes to
+ * this property and actually changes the power policy.
+ * The request is made by setting the VehiclePropValue with the ID of a power policy which is
+ * defined at /vendor/etc/power_policy.xml. If the given ID is not defined, car power policy
+ * service ignores the request and the current power policy is maintained.
+ *
+ * string: "sample_policy_id" // power policy ID
+ *
+ * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+ * @access VehiclePropertyAccess:READ
+ */
+ POWER_POLICY_REQ = (
+ 0x0F21
+ | VehiclePropertyGroup:SYSTEM
+ | VehiclePropertyType:STRING
+ | VehicleArea:GLOBAL),
+
+ /**
+ * Defines a request to set the power polic group used to decide a default power policy per
+ * power status transition.
+ *
+ * VHAL sets this property with the ID of a power policy group in order to set the default power
+ * policy applied at power status transition. Power policy groups are defined at
+ * /vendor/etc/power_policy.xml. If the given ID is not defined, car power policy service
+ * ignores the request.
+ * Car power policy service subscribes to this property and sets the power policy group.
+ * The actual application of power policy takes place when the system power status changes and
+ * there is a valid mapped power policy for the new power status.
+ *
+ * string: "sample_policy_group_id" // power policy group ID
+ *
+ * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+ * @access VehiclePropertyAccess:READ
+ */
+ POWER_POLICY_GROUP_REQ = (
+ 0x0F22
+ | VehiclePropertyGroup:SYSTEM
+ | VehiclePropertyType:STRING
+ | VehicleArea:GLOBAL),
+
+ /**
+ * Notifies the current power policy to VHAL layer.
+ *
+ * Car power policy service sets this property when the current power policy is changed.
+ *
+ * string: "sample_policy_id" // power policy ID
+ *
+ * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+ * @access VehiclePropertyAccess:READ_WRITE
+ */
+ CURRENT_POWER_POLICY = (
+ 0x0F23
+ | VehiclePropertyGroup:SYSTEM
+ | VehiclePropertyType:STRING
+ | VehicleArea:GLOBAL),
+
+ /**
* Defines an event that car watchdog updates to tell it's alive.
*
* Car watchdog sets this property to system uptime in milliseconds at every 3 second.
@@ -2938,8 +2997,8 @@
/**
* Defines a process terminated by car watchdog and the reason of termination.
*
- * int32Values[0]: 1 // ProcessTerminationReason showing why a process is terminated.
- * string: "/system/bin/log" // Process execution command.
+ * int32Values[0]: 1 // ProcessTerminationReason showing why a process is terminated.
+ * string: "/system/bin/log" // Process execution command.
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
* @access VehiclePropertyAccess:WRITE
diff --git a/biometrics/face/aidl/Android.bp b/biometrics/face/aidl/Android.bp
new file mode 100644
index 0000000..a4fcbfe
--- /dev/null
+++ b/biometrics/face/aidl/Android.bp
@@ -0,0 +1,21 @@
+aidl_interface {
+ name: "android.hardware.biometrics.face",
+ vendor_available: true,
+ srcs: [
+ "android/hardware/biometrics/face/**/*.aidl",
+ ],
+ imports: [
+ "android.hardware.biometrics.common",
+ "android.hardware.common",
+ "android.hardware.keymaster",
+ ],
+ stability: "vintf",
+ backend: {
+ java: {
+ platform_apis: true,
+ },
+ cpp: {
+ enabled: false,
+ },
+ },
+}
diff --git a/biometrics/face/aidl/OWNERS b/biometrics/face/aidl/OWNERS
new file mode 100644
index 0000000..36d7261
--- /dev/null
+++ b/biometrics/face/aidl/OWNERS
@@ -0,0 +1,2 @@
+ilyamaty@google.com
+kchyn@google.com
diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/RailInfo.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl
similarity index 65%
rename from powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/RailInfo.aidl
rename to biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl
index 413ea0d..011b711 100644
--- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/RailInfo.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl
@@ -15,11 +15,30 @@
// 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.powerstats;
-@VintfStability
-parcelable RailInfo {
- int railIndex;
- String railName;
- String subsysName;
- int samplingRateHz;
+package android.hardware.biometrics.face;
+@Backing(type="byte") @VintfStability
+enum AcquiredInfo {
+ GOOD = 0,
+ INSUFFICIENT = 1,
+ TOO_BRIGHT = 2,
+ TOO_DARK = 3,
+ TOO_CLOSE = 4,
+ TOO_FAR = 5,
+ FACE_TOO_HIGH = 6,
+ FACE_TOO_LOW = 7,
+ FACE_TOO_RIGHT = 8,
+ FACE_TOO_LEFT = 9,
+ POOR_GAZE = 10,
+ NOT_DETECTED = 11,
+ TOO_MUCH_MOTION = 12,
+ RECALIBRATE = 13,
+ TOO_DIFFERENT = 14,
+ TOO_SIMILAR = 15,
+ PAN_TOO_EXTREME = 16,
+ TILT_TOO_EXTREME = 17,
+ ROLL_TOO_EXTREME = 18,
+ FACE_OBSCURED = 19,
+ START = 20,
+ SENSOR_DIRTY = 21,
+ VENDOR = 22,
}
diff --git a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/MQDescriptor.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl
similarity index 81%
copy from common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/MQDescriptor.aidl
copy to biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl
index c9fe1d7..15fcbf9 100644
--- a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/MQDescriptor.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl
@@ -15,11 +15,14 @@
// 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.common;
-@VintfStability
-parcelable MQDescriptor {
- android.hardware.common.GrantorDescriptor[] grantors;
- ParcelFileDescriptor fileDescriptor;
- int quantum;
- int flags;
+package android.hardware.biometrics.face;
+@Backing(type="byte") @VintfStability
+enum Error {
+ HW_UNAVAILABLE = 1,
+ UNABLE_TO_PROCESS = 2,
+ TIMEOUT = 3,
+ NO_SPACE = 4,
+ CANCELED = 5,
+ UNABLE_TO_REMOVE = 6,
+ VENDOR = 8,
}
diff --git a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/UnsynchronizedWrite.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl
similarity index 88%
copy from common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/UnsynchronizedWrite.aidl
copy to biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl
index e390d20..943129e 100644
--- a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/UnsynchronizedWrite.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl
@@ -15,8 +15,9 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.common;
-@VintfStability
-enum UnsynchronizedWrite {
- EMPTY = 0,
+package android.hardware.biometrics.face;
+@Backing(type="byte") @VintfStability
+enum FaceSensorType {
+ RGB = 0,
+ IR = 1,
}
diff --git a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/MQDescriptor.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl
similarity index 78%
copy from common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/MQDescriptor.aidl
copy to biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl
index c9fe1d7..518fb14 100644
--- a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/MQDescriptor.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl
@@ -15,11 +15,9 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.common;
+package android.hardware.biometrics.face;
@VintfStability
-parcelable MQDescriptor {
- android.hardware.common.GrantorDescriptor[] grantors;
- ParcelFileDescriptor fileDescriptor;
- int quantum;
- int flags;
+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/current/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
new file mode 100644
index 0000000..5d9a430
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
@@ -0,0 +1,31 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files 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;
+@VintfStability
+interface ISession {
+ void generateChallenge(in int cookie, in int timeoutSec);
+ void revokeChallenge(in int cookie, in long challenge);
+ android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.common.NativeHandle previewSurface);
+ android.hardware.biometrics.common.ICancellationSignal authenticate(in int cookie, in long operationId);
+ android.hardware.biometrics.common.ICancellationSignal detectInteraction(in int cookie);
+ void enumerateEnrollments(in int cookie);
+ void removeEnrollments(in int cookie, in int[] enrollmentIds);
+ void getAuthenticatorId(in int cookie);
+ void invalidateAuthenticatorId(in int cookie);
+ void resetLockout(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat);
+}
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
new file mode 100644
index 0000000..477ba5a
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl
@@ -0,0 +1,37 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files 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;
+@VintfStability
+interface ISessionCallback {
+ void onStateChanged(in int cookie, in android.hardware.biometrics.face.SessionState state);
+ void onChallengeGenerated(in int sensorId, in int userId, in long challenge);
+ void onChallengeRevoked(in int sensorId, in int userId, in long challenge);
+ void onAcquired(in android.hardware.biometrics.face.AcquiredInfo info, in int vendorCode);
+ 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 onEnrollmentsRemoved(in int[] enrollmentIds);
+ void onAuthenticatorIdRetrieved(in long authenticatorId);
+ void onAuthenticatorIdInvalidated();
+}
diff --git a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/MQDescriptor.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl
similarity index 82%
copy from common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/MQDescriptor.aidl
copy to biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl
index c9fe1d7..9f977f5 100644
--- a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/MQDescriptor.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl
@@ -15,11 +15,10 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.common;
+package android.hardware.biometrics.face;
@VintfStability
-parcelable MQDescriptor {
- android.hardware.common.GrantorDescriptor[] grantors;
- ParcelFileDescriptor fileDescriptor;
- int quantum;
- int flags;
+parcelable SensorProps {
+ android.hardware.biometrics.common.CommonProps commonProps;
+ android.hardware.biometrics.face.FaceSensorType sensorType;
+ boolean halControlsPreview;
}
diff --git a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/MQDescriptor.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl
similarity index 71%
copy from common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/MQDescriptor.aidl
copy to biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl
index c9fe1d7..8e5139b 100644
--- a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/MQDescriptor.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl
@@ -15,11 +15,19 @@
// 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.common;
-@VintfStability
-parcelable MQDescriptor {
- android.hardware.common.GrantorDescriptor[] grantors;
- ParcelFileDescriptor fileDescriptor;
- int quantum;
- int flags;
+package android.hardware.biometrics.face;
+@Backing(type="byte") @VintfStability
+enum SessionState {
+ IDLING = 0,
+ TERMINATED = 1,
+ GENERATING_CHALLENGE = 2,
+ REVOKING_CHALLENGE = 3,
+ ENROLLING = 4,
+ AUTHENTICATING = 5,
+ DETECTING_INTERACTION = 6,
+ ENUMERATING_ENROLLMENTS = 7,
+ REMOVING_ENROLLMENTS = 8,
+ GETTING_AUTHENTICATOR_ID = 9,
+ INVALIDATING_AUTHENTICATOR_ID = 10,
+ RESETTING_LOCKOUT = 11,
}
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl
new file mode 100644
index 0000000..fffb418
--- /dev/null
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics.face;
+
+@VintfStability
+@Backing(type="byte")
+enum AcquiredInfo {
+
+ /**
+ * The acquired face data was good, no further user interaction is necessary.
+ */
+ GOOD = 0,
+
+ /**
+ * The acquired face data was too noisy or did not have sufficient detail.
+ * This is a catch-all for all acquisition errors not captured by the other
+ * constants.
+ */
+ INSUFFICIENT = 1,
+
+ /**
+ * Because there was too much ambient light, the captured face data was too
+ * bright. It's reasonable to return this after multiple
+ * AcquiredInfo.INSUFFICIENT.
+ *
+ * The user is expected to take action to retry the operation in better
+ * lighting conditions when this is returned.
+ */
+ TOO_BRIGHT = 2,
+
+ /**
+ * Because there was not enough illumination, the captured face data was too
+ * dark. It's reasonable to return this after multiple
+ * AcquiredInfo.INSUFFICIENT.
+ *
+ * The user is expected to take action to retry the operation in better
+ * lighting conditions when this is returned.
+ */
+ TOO_DARK = 3,
+
+ /**
+ * The detected face is too close to the sensor, and the image cannot be
+ * processed.
+ *
+ * The user is expected to be informed to move further from the sensor when
+ * this is returned.
+ */
+ TOO_CLOSE = 4,
+
+ /**
+ * The detected face is too small, as the user might be too far away from
+ * the sensor.
+ *
+ * The user is expected to be informed to move closer to the sensor when
+ * this is returned.
+ */
+ TOO_FAR = 5,
+
+ /**
+ * Only the upper part of the face was detected. The sensor's field of view
+ * is too high.
+ *
+ * The user should be informed to move up with respect to the sensor when
+ * this is returned.
+ */
+ FACE_TOO_HIGH = 6,
+
+ /**
+ * Only the lower part of the face was detected. The sensor's field of view
+ * is too low.
+ *
+ * The user should be informed to move down with respect to the sensor when
+ * this is returned.
+ */
+ FACE_TOO_LOW = 7,
+
+ /**
+ * Only the right part of the face was detected. The sensor's field of view
+ * is too far right.
+ *
+ * The user should be informed to move to the right with respect to the
+ * sensor when this is returned.
+ */
+ FACE_TOO_RIGHT = 8,
+
+ /**
+ * Only the left part of the face was detected. The sensor's field of view
+ * is too far left.
+ *
+ * The user should be informed to move to the left with respect to the
+ * sensor when this is returned.
+ */
+ FACE_TOO_LEFT = 9,
+
+ /**
+ * The user's eyes have strayed away from the sensor. If this message is
+ * sent, the user should be informed to look at the device. If the user
+ * can't be found in the frame, one of the other acquisition messages
+ * must be sent, e.g. NOT_DETECTED.
+ */
+ POOR_GAZE = 10,
+
+ /**
+ * No face was detected within the sensor's field of view.
+ *
+ * The user should be informed to point the sensor to a face when this is
+ * returned.
+ */
+ NOT_DETECTED = 11,
+
+ /**
+ * Too much motion was detected.
+ *
+ * The user should be informed to keep their face steady relative to the
+ * sensor.
+ */
+ TOO_MUCH_MOTION = 12,
+
+ /**
+ * The sensor needs to be re-calibrated. This is an unexpected condition,
+ * and must only be sent if a serious, uncorrectable, and unrecoverable
+ * calibration issue is detected which requires user intervention, e.g.
+ * re-enrolling. The expected response to this message is to direct the
+ * user to re-enroll.
+ */
+ RECALIBRATE = 13,
+
+ /**
+ * The face is too different from a previous acquisition. This condition
+ * only applies to enrollment. This can happen if the user passes the
+ * device to someone else in the middle of enrollment.
+ */
+ TOO_DIFFERENT = 14,
+
+ /**
+ * The face is too similar to a previous acquisition. This condition only
+ * applies to enrollment. The user should change their pose.
+ */
+ TOO_SIMILAR = 15,
+
+ /**
+ * The magnitude of the pan angle of the user’s face with respect to the sensor’s
+ * capture plane is too high.
+ *
+ * The pan angle is defined as the angle swept out by the user’s face turning
+ * their neck left and right. The pan angle would be zero if the user faced the
+ * camera directly.
+ *
+ * The user should be informed to look more directly at the camera.
+ */
+ PAN_TOO_EXTREME = 16,
+
+ /**
+ * The magnitude of the tilt angle of the user’s face with respect to the sensor’s
+ * capture plane is too high.
+ *
+ * The tilt angle is defined as the angle swept out by the user’s face looking up
+ * and down. The tilt angle would be zero if the user faced the camera directly.
+ *
+ * The user should be informed to look more directly at the camera.
+ */
+ TILT_TOO_EXTREME = 17,
+
+ /**
+ * The magnitude of the roll angle of the user’s face with respect to the sensor’s
+ * capture plane is too high.
+ *
+ * The roll angle is defined as the angle swept out by the user’s face tilting their head
+ * towards their shoulders to the left and right. The roll angle would be zero if the user's
+ * head is vertically aligned with the camera.
+ *
+ * The user should be informed to look more directly at the camera.
+ */
+ ROLL_TOO_EXTREME = 18,
+
+ /**
+ * The user’s face has been obscured by some object.
+ *
+ * The user should be informed to remove any objects from the line of sight from
+ * the sensor to the user’s face.
+ */
+ FACE_OBSCURED = 19,
+
+ /**
+ * This message represents the earliest message sent at the beginning of the authentication
+ * pipeline. It is expected to be used to measure latency. For example, in a camera-based
+ * authentication system it's expected to be sent prior to camera initialization. Note this
+ * should be sent whenever authentication is restarted (see IBiometricsFace#userActivity).
+ * The framework will measure latency based on the time between the last START message and the
+ * onAuthenticated callback.
+ */
+ START = 20,
+
+ /**
+ * The sensor is dirty. The user should be informed to clean the sensor.
+ */
+ SENSOR_DIRTY = 21,
+
+ /**
+ * Vendor-specific acquisition message. See ISessionCallback#onAcquired vendorCode
+ * documentation.
+ */
+ VENDOR = 22
+}
+
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl
new file mode 100644
index 0000000..1d02456
--- /dev/null
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics.face;
+
+@VintfStability
+@Backing(type="byte")
+enum Error {
+ /**
+ * Reserved for testing and to keep subsequent numbering consistent with
+ * older interfaces.
+ *
+ * NO_ERROR = 0,
+ */
+
+ /**
+ * A hardware error has occurred that cannot be resolved. Try again later.
+ */
+ HW_UNAVAILABLE = 1,
+
+ /**
+ * The current enroll or authenticate operation could not be completed,
+ * e.g. the sensor was unable to process the current image or the HAT was
+ * invalid.
+ */
+ UNABLE_TO_PROCESS = 2,
+
+ /**
+ * The current operation took too long to complete. This is intended to
+ * prevent programs from blocking the face HAL indefinitely. The timeout is
+ * framework and sensor-specific, but is generally on the order of 30
+ * seconds.
+ *
+ * The timeout is a device-specific time meant to optimize power. For
+ * example after 30 seconds of searching for a face it can be use to
+ * indicate that the implementation is no longer looking and the framework
+ * should restart the operation on the next user interaction.
+ */
+ TIMEOUT = 3,
+
+ /**
+ * The current operation could not be completed because there is not enough
+ * storage space remaining to do so.
+ */
+ NO_SPACE = 4,
+
+ /**
+ * The current operation has been cancelled. This may happen if a new
+ * request (authenticate, remove, enumerate, enroll) is initiated while
+ * an on-going operation is in progress, or if cancel() was called.
+ */
+ CANCELED = 5,
+
+ /**
+ * The current remove operation could not be completed; the face template
+ * provided could not be removed.
+ */
+ UNABLE_TO_REMOVE = 6,
+
+ /**
+ * Reserved to maintain backwards compatibility. See
+ * ISessionCallback#onLockoutTimed instead.
+ *
+ * LOCKOUT = 7,
+ */
+
+ /**
+ * Used to enable a vendor-specific error message.
+ */
+ VENDOR = 8,
+
+ /**
+ * Reserved to maintain backwards compatibility. See
+ * ISessionCallback#onLockoutPermanent instead.
+ *
+ * LOCKOUT_PERMANENT = 9
+ */
+}
+
diff --git a/tests/safeunion/1.0/IOtherInterface.hal b/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl
similarity index 73%
copy from tests/safeunion/1.0/IOtherInterface.hal
copy to biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl
index cdaf847..766f732 100644
--- a/tests/safeunion/1.0/IOtherInterface.hal
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,8 +14,11 @@
* limitations under the License.
*/
-package android.hardware.tests.safeunion@1.0;
+package android.hardware.biometrics.face;
-interface IOtherInterface {
- concatTwoStrings(string a, string b) generates (string result);
-};
+@VintfStability
+@Backing(type="byte")
+enum FaceSensorType {
+ RGB,
+ IR
+}
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl
new file mode 100644
index 0000000..e9a66e2
--- /dev/null
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics.face;
+
+import android.hardware.biometrics.face.ISession;
+import android.hardware.biometrics.face.ISessionCallback;
+import android.hardware.biometrics.face.SensorProps;
+
+@VintfStability
+interface IFace {
+ /**
+ * getSensorProps:
+ *
+ * @return A list of properties for all face sensors available to the HAL.
+ */
+ SensorProps[] getSensorProps();
+
+ /**
+ * createSession:
+ *
+ * Creates a session that can be used by the framework to perform operations such as
+ * enroll, authenticate, etc. for the given sensorId and userId.
+ *
+ * Implementations must store user-specific state or metadata in /data/vendor_de/<user>/facedata
+ * as specified by the SELinux policy. The directory /data/vendor_de is managed by vold (see
+ * vold_prepare_subdirs.cpp). Implementations may store additional user-specific data, such as
+ * embeddings or templates in StrongBox.
+ *
+ * @param sensorId The sensorId with which this session is being created.
+ * @param userId The userId with which this session is being created.
+ * @param cb A callback to notify the framework about the session's results and events.
+ * @return A new session.
+ */
+ ISession createSession(in int sensorId, in int userId, in ISessionCallback cb);
+
+}
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
new file mode 100644
index 0000000..c7beae0
--- /dev/null
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics.face;
+
+import android.hardware.biometrics.common.ICancellationSignal;
+import android.hardware.keymaster.HardwareAuthToken;
+import android.hardware.common.NativeHandle;
+
+/**
+ * A session is a collection of immutable state (sensorId, userId), mutable state (SessionState),
+ * methods available for the framework to call, and a callback (ISessionCallback) to notify the
+ * framework about the events and results. A session is used to establish communication between
+ * the framework and the HAL.
+ */
+@VintfStability
+interface ISession {
+ /**
+ * generateChallenge:
+ *
+ * Begins a secure transaction request. Note that the challenge by itself is not useful. It only
+ * becomes useful when wrapped in a verifiable message such as a HardwareAuthToken.
+ *
+ * Canonical example:
+ * 1) User requests an operation, such as face enrollment.
+ * 2) Face enrollment cannot happen until the user confirms their lockscreen credential
+ * (PIN/Pattern/Password).
+ * 3) However, the biometric subsystem does not want just "any" proof of credential
+ * confirmation. It needs proof that the user explicitly authenticated credential in order
+ * to allow addition of biometric enrollments.
+ * To secure this path, the following path is taken:
+ * 1) Upon user requesting face enroll, the framework requests
+ * IFace#generateChallenge
+ * 2) Framework sends the challenge to the credential subsystem, and upon credential
+ * confirmation, a HAT is created, containing the challenge in the "challenge" field.
+ * 3) Framework sends the HAT to the HAL, e.g. ISession#enroll.
+ * 4) Implementation verifies the authenticity and integrity of the HAT.
+ * 5) Implementation now has confidence that the user entered their credential to allow
+ * biometric enrollment.
+ *
+ * Note that the interface allows multiple in-flight challenges. For example, invoking
+ * generateChallenge(0, 0, timeoutSec) twice does not invalidate the first challenge. The
+ * challenge is invalidated only when:
+ * 1) The provided timeout expires, or
+ * 2) IFace#revokeChallenge is invoked
+ *
+ * For example, the following is a possible table of valid challenges:
+ * ----------------------------------------------
+ * | SensorId | UserId | ValidUntil | Challenge |
+ * |----------|--------|------------|-----------|
+ * | 0 | 0 | <Time1> | <Random1> |
+ * | 0 | 0 | <Time2> | <Random2> |
+ * | 1 | 0 | <Time3> | <Random3> |
+ * | 0 | 10 | <Time4> | <Random4> |
+ * ----------------------------------------------
+ *
+ * @param cookie A unique number identifying this operation
+ * @param timeoutSec Duration for which the challenge is valid for
+ */
+ void generateChallenge(in int cookie, in int timeoutSec);
+
+ /**
+ * revokeChallenge:
+ *
+ * Revokes a challenge that was previously generated. Note that if an invalid combination of
+ * parameters is requested, the implementation must still notify the framework using the
+ * provided callback.
+ *
+ * @param cookie A unique number identifying this operation
+ * @param challenge Challenge that should be revoked.
+ */
+ void revokeChallenge(in int cookie, in long challenge);
+
+ /**
+ * enroll:
+ *
+ * A request to add a face enrollment.
+ *
+ * Once the HAL is able to start processing the enrollment request, it must notify the framework
+ * via ISessionCallback#onStateChanged with SessionState::ENROLLING.
+ *
+ * At any point during enrollment, if a non-recoverable error occurs, the HAL must notify the
+ * framework via ISessionCallback#onError with the applicable enrollment-specific error, and
+ * then send ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no subsequent
+ * operation is in the queue.
+ *
+ * Before capturing face data, the implementation must first verify the authenticity and
+ * integrity of the provided HardwareAuthToken. In addition, it must check that the challenge
+ * within the provided HardwareAuthToken is valid. See IFace#generateChallenge. If any of
+ * the above checks fail, the framework must be notified via ISessionCallback#onError and the
+ * HAL must notify the framework when it returns to the idle state. See
+ * Error::UNABLE_TO_PROCESS.
+ *
+ * During enrollment, the implementation may notify the framework via
+ * ISessionCallback#onAcquired with messages that may be used to guide the user. This callback
+ * can be invoked multiple times if necessary. Similarly, the framework may be notified of
+ * enrollment progress changes via ISessionCallback#onEnrollmentProgress. Once the framework is
+ * notified that there are 0 "remaining" steps, the framework may cache the "enrollmentId". See
+ * ISessionCallback#onEnrollmentProgress for more info. The HAL must notify the framework once
+ * it returns to the idle state.
+ *
+ * When a finger is successfully added and before the framework is notified of remaining=0, the
+ * implementation MUST update and associate this (sensorId, userId) pair with a new new
+ * entropy-encoded random identifier. See ISession#getAuthenticatorId for more information.
+ *
+ * @param cookie An identifier used to track subsystem operations related to this call path. The
+ * client must guarantee that it is unique per ISession.
+ * @param previewSurface A surface provided by the framework if SensorProps#halControlsPreview is
+ * set to true. The HAL must send the preview frames to previewSurface if
+ * it's not null.
+ * @param hat See above documentation.
+ * @return ICancellationSignal An object that can be used by the framework to cancel this
+ * operation.
+ */
+ ICancellationSignal enroll(in int cookie, in HardwareAuthToken hat, in NativeHandle previewSurface);
+
+ /**
+ * authenticate:
+ *
+ * A request to start looking for faces to authenticate.
+ *
+ * Once the HAL is able to start processing the authentication request, it must notify framework
+ * via ISessionCallback#onStateChanged with SessionState::AUTHENTICATING.
+ *
+ * At any point during authentication, if a non-recoverable error occurs, the HAL must notify
+ * the framework via ISessionCallback#onError with the applicable authentication-specific error,
+ * and then send ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no
+ * subsequent operation is in the queue.
+ *
+ * During authentication, the implementation may notify the framework via
+ * ISessionCallback#onAcquired with messages that may be used to guide the user. This callback
+ * can be invoked multiple times if necessary.
+ *
+ * The HAL must notify the framework of accepts/rejects via ISessionCallback#onAuthentication*.
+ *
+ * The authentication lifecycle ends when either
+ * 1) A face is accepted, and ISessionCallback#onAuthenticationSucceeded is invoked, or
+ * 2) Any non-recoverable error occurs (such as lockout). See the full list of
+ * authentication-specific errors in the Error enum.
+ *
+ * Note that upon successful authentication, the lockout counter for this (sensorId, userId)
+ * pair must be cleared.
+ *
+ * Note that upon successful authentication, ONLY sensors configured as SensorStrength::STRONG
+ * are allowed to create and send a HardwareAuthToken to the framework. See the Android CDD for
+ * more details. For SensorStrength::STRONG sensors, the HardwareAuthToken's "challenge" field
+ * must be set with the operationId passed in during #authenticate. If the sensor is NOT
+ * SensorStrength::STRONG, the HardwareAuthToken MUST be null.
+ *
+ * @param cookie An identifier used to track subsystem operations related to this call path. The
+ * client must guarantee that it is unique per ISession.
+ * @param operationId For sensors configured as SensorStrength::STRONG, this must be used ONLY
+ * upon successful authentication and wrapped in the HardwareAuthToken's
+ * "challenge" field and sent to the framework via
+ * ISessionCallback#onAuthenticated. The operationId is an opaque identifier
+ * created from a separate secure subsystem such as, but not limited to
+ * KeyStore/KeyMaster. The HardwareAuthToken can then be used as an
+ * attestation for the provided operation. For example, this is used
+ * to unlock biometric-bound auth-per-use keys (see
+ * setUserAuthenticationParameters in KeyGenParameterSpec.Builder and
+ * KeyProtection.Builder.
+ * @return ICancellationSignal An object that can be used by the framework to cancel this
+ * operation.
+ */
+ ICancellationSignal authenticate(in int cookie, in long operationId);
+
+ /**
+ * detectInteraction:
+ *
+ * A request to start looking for faces without performing matching.
+ *
+ * Once the HAL is able to start processing this request, it must notify the framework via
+ * ISessionCallback#onStateChanged with SessionState::DETECTING_INTERACTION.
+ *
+ * The framework will use this method in cases where determing user presence is required, but
+ * identifying/authentication is not. For example, when the device is encrypted (first boot) or
+ * in lockdown mode.
+ *
+ * At any point during detectInteraction, if a non-recoverable error occurs, the HAL must notify
+ * the framework via ISessionCallback#onError with the applicable error, and then send
+ * ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no subsequent operation is
+ * in the queue.
+ *
+ * The implementation must only check for a face-like image was detected (e.g. to
+ * minimize interactions due to non-face objects), and the lockout counter must not
+ * be modified.
+ *
+ * Upon detecting any face, the implementation must invoke
+ * ISessionCallback#onInteractionDetected.
+ *
+ * The lifecycle of this operation ends when either
+ * 1) Any face is detected and the framework is notified via
+ * ISessionCallback#onInteractiondetected
+ * 2) The operation was cancelled by the framework (see ICancellationSignal)
+ * 3) The HAL ends the operation, for example when a subsequent operation pre-empts this one.
+ *
+ * Note that if the operation is canceled, the implementation must notify the framework via
+ * ISessionCallback#onError with Error::CANCELED.
+ *
+ * @param cookie An identifier used to track subsystem operations related to this call path.
+ * The framework will guarantee that it is unique per ISession.
+ * @return ICancellationSignal An object that can be used by the framework to cancel this
+ * operation.
+ */
+ ICancellationSignal detectInteraction(in int cookie);
+
+ /*
+ * enumerateEnrollments:
+ *
+ * A request to enumerate (list) the enrollments for this (sensorId, userId) pair. The
+ * framework typically uses this to ensure that its cache is in sync with the HAL.
+ *
+ * Once the HAL is able to start processing this request, it must notify the framework via
+ * ISessionCallback#onStateChanged with SessionState::ENUMERATING_ENROLLMENTS.
+ *
+ * The implementation must then notify the framework with a list of enrollments applicable
+ * for the current session via ISessionCallback#onEnrollmentsEnumerated.
+ *
+ * @param cookie An identifier used to track subsystem operations related to this call path.
+ * The framework will guarantee that it is unique per ISession.
+ */
+ void enumerateEnrollments(in int cookie);
+
+ /**
+ * removeEnrollments:
+ *
+ * A request to remove the enrollments for this (sensorId, userId) pair.
+ *
+ * Once the HAL is able to start processing this request, it must notify the framework via
+ * ISessionCallback#onStateChanged with SessionState::REMOVING_ENROLLMENTS.
+ *
+ * After removing the enrollmentIds from everywhere necessary (filesystem, secure subsystems,
+ * etc), the implementation must notify the framework via ISessionCallback#onEnrollmentsRemoved.
+ *
+ * @param cookie An identifier used to track subsystem operations related to this call path.
+ * The framework will guarantee that it is unique per ISession.
+ */
+ void removeEnrollments(in int cookie, in int[] enrollmentIds);
+
+ /**
+ * getAuthenticatorId:
+ *
+ * MUST return 0 via ISessionCallback#onAuthenticatorIdRetrieved for sensors that are configured
+ * as SensorStrength::WEAK or SensorStrength::CONVENIENCE.
+ *
+ * The following only applies to sensors that are configured as SensorStrength::STRONG.
+ *
+ * The authenticatorId is a (sensorId, user)-specific identifier which can be used during key
+ * generation and key import to to associate a key (in KeyStore / KeyMaster) with the current
+ * set of enrolled faces. For example, the following public Android APIs allow for keys
+ * to be invalidated when the user adds a new enrollment after the key was created:
+ * KeyGenParameterSpec.Builder.setInvalidatedByBiometricEnrollment and
+ * KeyProtection.Builder.setInvalidatedByBiometricEnrollment.
+ *
+ * In addition, upon successful face authentication, the signed HAT that is returned to
+ * the framework via ISessionCallback#onAuthenticated must contain this identifier in the
+ * authenticatorId field.
+ *
+ * Returns an entropy-encoded random identifier associated with the current set of enrollments
+ * via ISessionCallback#onAuthenticatorIdRetrieved. The authenticatorId
+ * 1) MUST change whenever a new face is enrolled
+ * 2) MUST return 0 if no faces are enrolled
+ * 3) MUST not change if a face is deleted.
+ * 4) MUST be an entropy-encoded random number
+ *
+ * @param cookie An identifier used to track subsystem operations related to this call path. The
+ * client must guarantee that it is unique per ISession.
+ */
+ void getAuthenticatorId(in int cookie);
+
+ /**
+ * invalidateAuthenticatorId:
+ *
+ * This method only applies to sensors that are configured as SensorStrength::STRONG. If invoked
+ * by the framework for sensor of other strengths, the HAL should immediately invoke
+ * ISessionCallback#onAuthenticatorIdInvalidated.
+ *
+ * The following only applies to sensors that are configured as SensorStrength::STRONG.
+ *
+ * When invoked by the framework, the implementation must perform the following sequence of
+ * events:
+ * 1) Verify the authenticity and integrity of the provided HAT. If this check fails, the HAL
+ * must invoke ISessionCallback#onError with Error::UNABLE_TO_PROCESS and return to
+ * SessionState::IDLING if no subsequent work is in the queue.
+ * 2) Verify that the timestamp provided within the HAT is relatively recent (e.g. on the
+ * order of minutes, not hours). If this check fails, the HAL must invoke
+ * ISessionCallback#onError with Error::UNABLE_TO_PROCESS and return to
+ * SessionState::IDLING if no subsequent work is in the queue.
+ * 3) Update the authenticatorId with a new entropy-encoded random number
+ * 4) Persist the new authenticatorId to non-ephemeral storage
+ * 5) Notify the framework that the above is completed, via
+ * ISessionCallback#onAuthenticatorInvalidated
+ *
+ * A practical use case of invalidation would be when the user adds a new enrollment to a sensor
+ * managed by a different HAL instance. The public android.security.keystore APIs bind keys to
+ * "all biometrics" rather than "face-only" or "face-only" (see #getAuthenticatorId
+ * for more details). As such, the framework would coordinate invalidation across multiple
+ * biometric HALs as necessary.
+ *
+ * @param cookie An identifier used to track subsystem operations related to this call path. The
+ * client must guarantee that it is unique per ISession.
+ */
+ void invalidateAuthenticatorId(in int cookie);
+
+ /**
+ * resetLockout:
+ *
+ * Requests the implementation to clear the lockout counter. Upon receiving this request, the
+ * implementation must perform the following:
+ * 1) Verify the authenticity and integrity of the provided HAT
+ * 2) Verify that the timestamp provided within the HAT is relatively recent (e.g. on the
+ * order of minutes, not hours).
+ * If either of the checks fail, the HAL must invoke ISessionCallback#onError with
+ * Error::UNABLE_TO_PROCESS and return to SessionState::IDLING if no subsequent work is in the
+ * queue.
+ *
+ * Upon successful verification, the HAL must clear the lockout counter and notify the framework
+ * via ISessionCallback#onLockoutCleared.
+ *
+ * Note that lockout is user AND sensor specific. In other words, there is a separate lockout
+ * state for each (user, sensor) pair. For example, the following is a valid state on a
+ * multi-sensor device:
+ * ------------------------------------------------------------------
+ * | SensorId | UserId | FailedAttempts | LockedOut | LockedUntil |
+ * |----------|--------|----------------|-----------|---------------|
+ * | 0 | 0 | 1 | false | x |
+ * | 1 | 0 | 5 | true | <future_time> |
+ * | 0 | 10 | 0 | false | x |
+ * | 1 | 10 | 0 | false | x |
+ * ------------------------------------------------------------------
+ *
+ * Lockout may be cleared in the following ways:
+ * 1) ISession#resetLockout
+ * 2) After a period of time, according to a rate-limiter.
+ *
+ * Note that the "FailedAttempts" counter must be cleared upon successful face
+ * authentication. For example, if SensorId=0 UserId=0 FailedAttempts=1, and a successful
+ * face authentication occurs, the counter for that (SensorId, UserId) pair must be reset
+ * to 0.
+ *
+ * In addition, lockout states MUST persist after device reboots, HAL crashes, etc.
+ *
+ * See the Android CDD section 7.3.10 for the full set of lockout and rate-limiting
+ * requirements.
+ *
+ * @param cookie An identifier used to track subsystem operations related to this call path. The
+ * client must guarantee that it is unique per ISession.
+ * @param hat HardwareAuthToken See above documentation.
+ */
+ void resetLockout(in int cookie, in HardwareAuthToken hat);
+}
+
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl
new file mode 100644
index 0000000..2608d5f
--- /dev/null
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics.face;
+
+import android.hardware.biometrics.face.AcquiredInfo;
+import android.hardware.biometrics.face.Error;
+import android.hardware.biometrics.face.SessionState;
+import android.hardware.keymaster.HardwareAuthToken;
+
+@VintfStability
+interface ISessionCallback {
+ /**
+ * Used to notify the framework of session state changes. See ISession for more information.
+ */
+ void onStateChanged(in int cookie, in SessionState state);
+
+ /**
+ * Notifies the framework when a challenge is successfully generated.
+ */
+ void onChallengeGenerated(in int sensorId, in int userId, in long challenge);
+
+ /**
+ * Notifies the framework when a challenge has been revoked.
+ */
+ void onChallengeRevoked(in int sensorId, in int userId, in long challenge);
+
+ /**
+ * This method must only be used to notify the framework during the following states:
+ * 1) SessionState::ENROLLING
+ * 2) SessionState::AUTHENTICATING
+ * 3) SessionState::DETECTING_INTERACTION
+ *
+ * These messages may be used to provide user guidance multiple times if necessary per
+ * operation.
+ *
+ * @param info See the AcquiredInfo enum.
+ * @param vendorCode Only valid if info == AcquiredInfo::VENDOR. The vendorCode must be used to
+ * index into the configuration
+ * com.android.internal.R.array.face_acquired_vendor that's installed
+ * on the vendor partition.
+ */
+ void onAcquired(in AcquiredInfo info, in int vendorCode);
+
+ /**
+ * This method must only be used to notify the framework during the following states:
+ * 1) SessionState::ENROLLING
+ * 2) SessionState::AUTHENTICATING
+ * 3) SessionState::DETECTING_INTERACTION
+ * 4) SessionState::INVALIDATING_AUTHENTICATOR_ID
+ * 5) SessionState::RESETTING_LOCKOUT
+ *
+ * These messages may be used to notify the framework or user that a non-recoverable error
+ * has occurred. The operation is finished, and the HAL must proceed with the next operation
+ * or return to SessionState::IDLING if the queue is empty.
+ *
+ * Note that cancellation (see common::ICancellationSignal) and preemption most be followed with
+ * an Error::CANCELED message.
+ *
+ * @param error See the Error enum.
+ * @param vendorCode Only valid if error == Error::VENDOR. The vendorCode must be used to index
+ * into the configuration
+ * com.android.internal.R.face_error_vendor that's installed on the
+ * vendor partition.
+ */
+ void onError(in Error error, in int vendorCode);
+
+ /**
+ * This method must only be used to notify the framework during the following state:
+ * 1) SessionState::ENROLLING
+ *
+ * @param enrollmentId Unique stable identifier for the enrollment that's being added by this
+ * ISession#enroll invocation.
+ * @param remaining Remaining number of steps before enrollment is complete.
+ */
+ void onEnrollmentProgress(in int enrollmentId, int remaining);
+
+ /**
+ * This method must only be used to notify the framework during SessionState::AUTHENTICATING.
+ *
+ * Used to notify the framework upon successful authentication. Note that the authentication
+ * lifecycle ends when either 1) a face is accepted, or 2) an error occurred. The
+ * authentication lifecycle does NOT end when a face is rejected.
+ *
+ * @param enrollmentId Face that was accepted.
+ * @param hat If the sensor is configured as SensorStrength::STRONG, a non-null attestation that
+ * a face was accepted. The HardwareAuthToken's "challenge" field must be set
+ * with the operationId passed in during ISession#authenticate. If the sensor is NOT
+ * SensorStrength::STRONG, the HardwareAuthToken MUST be null.
+ */
+ void onAuthenticationSucceeded(in int enrollmentId, in HardwareAuthToken hat);
+
+ /**
+ * This method must only be used to notify the framework during SessionState::AUTHENTICATING.
+ *
+ * Used to notify the framework upon rejected attempts. Note that the authentication
+ * lifecycle ends when either 1) a face is accepted, or 2) an occurred. The
+ * authentication lifecycle does NOT end when a face is rejected.
+ */
+ void onAuthenticationFailed();
+
+ /**
+ * This method must only be used to notify the framework during SessionState::AUTHENTICATING.
+ *
+ * Authentication is locked out due to too many unsuccessful attempts. This is a rate-limiting
+ * lockout, and authentication can be restarted after a period of time. See
+ * ISession#resetLockout.
+ *
+ * @param sensorId Sensor for which the user is locked out.
+ * @param userId User for which the sensor is locked out.
+ * @param durationMillis Remaining duration of the lockout.
+ */
+ void onLockoutTimed(in long durationMillis);
+
+ /**
+ * This method must only be used to notify the framework during SessionState::AUTHENTICATING.
+ *
+ * Authentication is disabled until the user unlocks with their device credential
+ * (PIN/Pattern/Password). See ISession#resetLockout.
+ *
+ * @param sensorId Sensor for which the user is locked out.
+ * @param userId User for which the sensor is locked out.
+ */
+ void onLockoutPermanent();
+
+ /**
+ * Notifies the framework that lockout has been cleared for this (sensorId, userId) pair.
+ *
+ * Note that this method can be used to notify the framework during any state.
+ *
+ * Lockout can be cleared in the following scenarios:
+ * 1) A timed lockout has ended (e.g. durationMillis specified in previous #onLockoutTimed
+ * has expired.
+ * 2) See ISession#resetLockout.
+ *
+ * @param sensorId Sensor for which the user's lockout is cleared.
+ * @param userId User for the sensor's lockout is cleared.
+ */
+ void onLockoutCleared();
+
+ /**
+ * This method must only be used to notify the framework during
+ * SessionState::DETECTING_INTERACTION
+ *
+ * Notifies the framework that user interaction occurred. See ISession#detectInteraction.
+ */
+ void onInteractionDetected();
+
+ /**
+ * This method must only be used to notify the framework during
+ * SessionState::ENUMERATING_ENROLLMENTS.
+ *
+ * Notifies the framework of the current enrollments. See ISession#enumerateEnrollments.
+ *
+ * @param enrollmentIds A list of enrollments for the session's (userId, sensorId) pair.
+ */
+ void onEnrollmentsEnumerated(in int[] enrollmentIds);
+
+ /**
+ * This method must only be used to notify the framework during
+ * SessionState::REMOVING_ENROLLMENTS.
+ *
+ * Notifies the framework that the specified enrollments are removed.
+ *
+ * @param enrollmentIds The enrollments that were removed.
+ */
+ void onEnrollmentsRemoved(in int[] enrollmentIds);
+
+ /**
+ * This method must only be used to notify the framework during
+ * SessionState::GETTING_AUTHENTICATOR_ID.
+ *
+ * Notifies the framework with the authenticatorId corresponding to this session's
+ * (userId, sensorId) pair.
+ *
+ * @param authenticatorId See the above documentation.
+ */
+ void onAuthenticatorIdRetrieved(in long authenticatorId);
+
+ /**
+ * This method must only be used to notify the framework during
+ * SessionState::INVALIDATING_AUTHENTICATOR_ID.
+ *
+ * See ISession#invalidateAuthenticatorId for more information.
+ */
+ void onAuthenticatorIdInvalidated();
+}
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl
new file mode 100644
index 0000000..53cc44e
--- /dev/null
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics.face;
+
+import android.hardware.biometrics.common.CommonProps;
+import android.hardware.biometrics.face.FaceSensorType;
+
+@VintfStability
+parcelable SensorProps {
+ /**
+ * Statically configured properties that apply to this face sensor.
+ */
+ CommonProps commonProps;
+
+ /**
+ * A statically configured sensor type representing this face sensor.
+ */
+ FaceSensorType sensorType;
+
+ /**
+ * Whether or not the HAL is responsible for showing the face enrollment preview to the user.
+ * Devices with multiple front camera sensors can set this to false and rely on the framework to
+ * show the preview with one of the unused cameras. Devices with a single front sensor must set
+ * this to true and configure their send their camera stream to the preview surface provided by
+ * the framework.
+ */
+ boolean halControlsPreview;
+}
+
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl
new file mode 100644
index 0000000..1878f7c
--- /dev/null
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics.face;
+
+@VintfStability
+@Backing(type="byte")
+enum SessionState {
+ /**
+ * The HAL is not processing any session requests.
+ */
+ IDLING,
+
+ /**
+ * The session has been terminated by the HAL.
+ */
+ TERMINATED,
+
+ /**
+ * The HAL is processing the ISession#generateChallenge request.
+ */
+ GENERATING_CHALLENGE,
+
+ /**
+ * The HAL is processing the ISession#revokeChallenge request.
+ */
+ REVOKING_CHALLENGE,
+
+ /**
+ * The HAL is processing the ISession#enroll request.
+ */
+ ENROLLING,
+
+ /**
+ * The HAL is processing the ISession#authenticate request.
+ */
+ AUTHENTICATING,
+
+ /**
+ * The HAL is processing the ISession#detectInteraction request.
+ */
+ DETECTING_INTERACTION,
+
+ /**
+ * The HAL is processing the ISession#enumerateEnrollments request.
+ */
+ ENUMERATING_ENROLLMENTS,
+
+ /**
+ * The HAL is processing the ISession#removeEnrollments request.
+ */
+ REMOVING_ENROLLMENTS,
+
+ /**
+ * The HAL is processing the ISession#getAuthenticatorId request.
+ */
+ GETTING_AUTHENTICATOR_ID,
+
+ /**
+ * The HAL is processing the ISession#invalidateAuthenticatorId request.
+ */
+ INVALIDATING_AUTHENTICATOR_ID,
+
+ /**
+ * The HAL is processing the ISession#resetLockout request.
+ */
+ RESETTING_LOCKOUT
+}
+
diff --git a/biometrics/face/aidl/default/Android.bp b/biometrics/face/aidl/default/Android.bp
new file mode 100644
index 0000000..51a8ef4
--- /dev/null
+++ b/biometrics/face/aidl/default/Android.bp
@@ -0,0 +1,18 @@
+cc_binary {
+ name: "android.hardware.biometrics.face-service.example",
+ relative_install_path: "hw",
+ init_rc: ["face-default.rc"],
+ vintf_fragments: ["face-default.xml"],
+ vendor: true,
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "android.hardware.biometrics.face-ndk_platform",
+ "android.hardware.biometrics.common-unstable-ndk_platform",
+ ],
+ srcs: [
+ "main.cpp",
+ "Face.cpp",
+ "Session.cpp",
+ ],
+}
diff --git a/biometrics/face/aidl/default/Face.cpp b/biometrics/face/aidl/default/Face.cpp
new file mode 100644
index 0000000..1526245
--- /dev/null
+++ b/biometrics/face/aidl/default/Face.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Face.h"
+#include "Session.h"
+
+namespace aidl::android::hardware::biometrics::face {
+
+const int kSensorId = 0;
+const common::SensorStrength kSensorStrength = common::SensorStrength::WEAK;
+const int kMaxEnrollmentsPerUser = 5;
+const FaceSensorType kSensorType = FaceSensorType::RGB;
+const bool kHalControlsPreview = true;
+const std::string kHwDeviceName = "faceSensor";
+const std::string kHardwareVersion = "vendor/model/revision";
+const std::string kFirmwareVersion = "1.01";
+const std::string kSerialNumber = "00000001";
+
+ndk::ScopedAStatus Face::getSensorProps(std::vector<SensorProps>* return_val) {
+ common::HardwareInfo hardware_info;
+ hardware_info.deviceName = kHwDeviceName;
+ hardware_info.hardwareVersion = kHardwareVersion;
+ hardware_info.firmwareVersion = kFirmwareVersion;
+ hardware_info.serialNumber = kSerialNumber;
+
+ common::CommonProps commonProps;
+ commonProps.sensorId = kSensorId;
+ commonProps.sensorStrength = kSensorStrength;
+ commonProps.maxEnrollmentsPerUser = kMaxEnrollmentsPerUser;
+ commonProps.hardwareInfo = {std::move(hardware_info)};
+
+ SensorProps props;
+ props.commonProps = std::move(commonProps);
+ props.sensorType = kSensorType;
+ props.halControlsPreview = kHalControlsPreview;
+
+ *return_val = {std::move(props)};
+ return ndk::ScopedAStatus::ok();
+}
+
+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>(cb);
+ return ndk::ScopedAStatus::ok();
+}
+
+} // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/face/aidl/default/Face.h b/biometrics/face/aidl/default/Face.h
new file mode 100644
index 0000000..786b4f8
--- /dev/null
+++ b/biometrics/face/aidl/default/Face.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/biometrics/face/BnFace.h>
+
+namespace aidl::android::hardware::biometrics::face {
+
+class Face : public BnFace {
+ public:
+ 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;
+};
+
+} // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp
new file mode 100644
index 0000000..2b1d4a7
--- /dev/null
+++ b/biometrics/face/aidl/default/Session.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/biometrics/common/BnCancellationSignal.h>
+
+#include "Session.h"
+
+namespace aidl::android::hardware::biometrics::face {
+
+class CancellationSignal : public common::BnCancellationSignal {
+ public:
+ ndk::ScopedAStatus cancel() override { return ndk::ScopedAStatus::ok(); }
+};
+
+Session::Session(std::shared_ptr<ISessionCallback> cb) : cb_(std::move(cb)) {}
+
+ndk::ScopedAStatus Session::generateChallenge(int32_t /*cookie*/, int32_t /*timeoutSec*/) {
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Session::revokeChallenge(int32_t /*cookie*/, int64_t /*challenge*/) {
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Session::enroll(int32_t /*cookie*/, const keymaster::HardwareAuthToken& /*hat*/,
+ const NativeHandle& /*previewSurface*/,
+ std::shared_ptr<biometrics::common::ICancellationSignal>*
+ /*returnVal*/) {
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Session::authenticate(int32_t /*cookie*/, int64_t /*keystoreOperationId*/,
+ std::shared_ptr<common::ICancellationSignal>* return_val) {
+ if (cb_) {
+ cb_->onStateChanged(0, SessionState::AUTHENTICATING);
+ }
+ *return_val = SharedRefBase::make<CancellationSignal>();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Session::detectInteraction(
+ int32_t /*cookie*/, std::shared_ptr<common::ICancellationSignal>* /*return_val*/) {
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Session::enumerateEnrollments(int32_t /*cookie*/) {
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Session::removeEnrollments(int32_t /*cookie*/,
+ const std::vector<int32_t>& /*enrollmentIds*/) {
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Session::getAuthenticatorId(int32_t /*cookie*/) {
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Session::invalidateAuthenticatorId(int32_t /*cookie*/) {
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Session::resetLockout(int32_t /*cookie*/,
+ const keymaster::HardwareAuthToken& /*hat*/) {
+ return ndk::ScopedAStatus::ok();
+}
+} // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h
new file mode 100644
index 0000000..2bb5c42
--- /dev/null
+++ b/biometrics/face/aidl/default/Session.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/biometrics/face/BnSession.h>
+#include <aidl/android/hardware/biometrics/face/ISessionCallback.h>
+
+namespace aidl::android::hardware::biometrics::face {
+
+namespace common = aidl::android::hardware::biometrics::common;
+namespace keymaster = aidl::android::hardware::keymaster;
+
+using aidl::android::hardware::common::NativeHandle;
+
+class Session : public BnSession {
+ public:
+ explicit Session(std::shared_ptr<ISessionCallback> cb);
+
+ ndk::ScopedAStatus generateChallenge(int32_t cookie, int32_t timeoutSec) override;
+
+ ndk::ScopedAStatus revokeChallenge(int32_t cookie, int64_t challenge) override;
+
+ ndk::ScopedAStatus enroll(
+ int32_t cookie, const keymaster::HardwareAuthToken& hat,
+ const NativeHandle& previewSurface,
+ std::shared_ptr<biometrics::common::ICancellationSignal>* returnVal) override;
+
+ ndk::ScopedAStatus authenticate(
+ int32_t cookie, int64_t keystoreOperationId,
+ std::shared_ptr<common::ICancellationSignal>* returnVal) override;
+
+ ndk::ScopedAStatus detectInteraction(
+ int32_t cookie, std::shared_ptr<common::ICancellationSignal>* returnVal) override;
+
+ ndk::ScopedAStatus enumerateEnrollments(int32_t cookie) override;
+
+ ndk::ScopedAStatus removeEnrollments(int32_t cookie,
+ const std::vector<int32_t>& enrollmentIds) override;
+
+ ndk::ScopedAStatus getAuthenticatorId(int32_t cookie) override;
+
+ ndk::ScopedAStatus invalidateAuthenticatorId(int32_t cookie) override;
+
+ ndk::ScopedAStatus resetLockout(int32_t cookie,
+ const keymaster::HardwareAuthToken& hat) override;
+
+ private:
+ std::shared_ptr<ISessionCallback> cb_;
+};
+
+} // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/face/aidl/default/face-default.rc b/biometrics/face/aidl/default/face-default.rc
new file mode 100644
index 0000000..f6499f0
--- /dev/null
+++ b/biometrics/face/aidl/default/face-default.rc
@@ -0,0 +1,5 @@
+service vendor.face-default /vendor/bin/hw/android.hardware.biometrics.face-service.example
+ class hal
+ user nobody
+ group nobody
+
diff --git a/biometrics/face/aidl/default/face-default.xml b/biometrics/face/aidl/default/face-default.xml
new file mode 100644
index 0000000..6915ad0
--- /dev/null
+++ b/biometrics/face/aidl/default/face-default.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.biometrics.face</name>
+ <fqname>IFace/default</fqname>
+ </hal>
+</manifest>
diff --git a/powerstats/aidl/default/main.cpp b/biometrics/face/aidl/default/main.cpp
similarity index 72%
copy from powerstats/aidl/default/main.cpp
copy to biometrics/face/aidl/default/main.cpp
index 1496805..80b153e 100644
--- a/powerstats/aidl/default/main.cpp
+++ b/biometrics/face/aidl/default/main.cpp
@@ -14,20 +14,21 @@
* limitations under the License.
*/
-#include "PowerStats.h"
+#include "Face.h"
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
-using aidl::android::hardware::powerstats::PowerStats;
+using aidl::android::hardware::biometrics::face::Face;
int main() {
+ LOG(INFO) << "Face HAL started";
ABinderProcess_setThreadPoolMaxThreadCount(0);
- std::shared_ptr<PowerStats> p = ndk::SharedRefBase::make<PowerStats>();
+ std::shared_ptr<Face> hal = ndk::SharedRefBase::make<Face>();
- const std::string instance = std::string() + PowerStats::descriptor + "/default";
- binder_status_t status = AServiceManager_addService(p->asBinder().get(), instance.c_str());
+ const std::string instance = std::string(Face::descriptor) + "/default";
+ binder_status_t status = AServiceManager_addService(hal->asBinder().get(), instance.c_str());
CHECK(status == STATUS_OK);
ABinderProcess_joinThreadPool();
diff --git a/biometrics/face/aidl/vts/Android.bp b/biometrics/face/aidl/vts/Android.bp
new file mode 100644
index 0000000..427b878
--- /dev/null
+++ b/biometrics/face/aidl/vts/Android.bp
@@ -0,0 +1,16 @@
+cc_test {
+ name: "VtsHalBiometricsFaceTargetTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: ["VtsHalBiometricsFaceTargetTest.cpp"],
+ shared_libs: [
+ "libbinder_ndk",
+ "android.hardware.biometrics.face-ndk_platform",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
diff --git a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp
new file mode 100644
index 0000000..c1ba66b
--- /dev/null
+++ b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/biometrics/face/BnFace.h>
+#include <aidl/android/hardware/biometrics/face/BnSessionCallback.h>
+
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include <future>
+
+namespace aidl::android::hardware::biometrics::face {
+namespace {
+
+constexpr int kSensorId = 0;
+constexpr int kUserId = 0;
+constexpr auto kCallbackTimeout = std::chrono::seconds(1);
+
+enum class SessionCallbackMethodName {
+ kOnStateChanged,
+};
+
+struct SessionCallbackInvocation {
+ SessionCallbackMethodName method_name;
+ SessionState state;
+};
+
+class SessionCallback : public BnSessionCallback {
+ public:
+ explicit SessionCallback(std::promise<SessionCallbackInvocation> invocation_promise)
+ : invocation_promise_(std::move(invocation_promise)) {}
+ ndk::ScopedAStatus onStateChanged(int32_t /*cookie*/, SessionState state) override {
+ SessionCallbackInvocation invocation = {};
+ invocation.method_name = SessionCallbackMethodName::kOnStateChanged;
+ invocation.state = state;
+ invocation_promise_.set_value(invocation);
+ return ndk::ScopedAStatus::ok();
+ }
+
+ ndk::ScopedAStatus onChallengeGenerated(int32_t /*sensorId*/, int32_t /*userId*/,
+ int64_t /*challenge*/) override {
+ return ndk::ScopedAStatus::ok();
+ }
+
+ ndk::ScopedAStatus onChallengeRevoked(int32_t /*sensorId*/, int32_t /*userId*/,
+ int64_t /*challenge*/) override {
+ return ndk::ScopedAStatus::ok();
+ }
+
+ ndk::ScopedAStatus onAcquired(AcquiredInfo /*info*/, int32_t /*vendorCode*/) override {
+ return ndk::ScopedAStatus::ok();
+ }
+
+ ndk::ScopedAStatus onError(Error /*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& /*hat*/) override {
+ return ndk::ScopedAStatus::ok();
+ }
+
+ ndk::ScopedAStatus onAuthenticationFailed() override { return ndk::ScopedAStatus::ok(); }
+
+ ndk::ScopedAStatus onLockoutTimed(int64_t /*durationMillis*/) override {
+ return ndk::ScopedAStatus::ok();
+ }
+
+ ndk::ScopedAStatus onLockoutPermanent() override { return ndk::ScopedAStatus::ok(); }
+
+ ndk::ScopedAStatus onLockoutCleared() override { return ndk::ScopedAStatus::ok(); }
+
+ ndk::ScopedAStatus onInteractionDetected() override { return ndk::ScopedAStatus::ok(); }
+
+ ndk::ScopedAStatus onEnrollmentsEnumerated(
+ const std::vector<int32_t>& /*enrollmentIds*/) 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() override { return ndk::ScopedAStatus::ok(); }
+
+ private:
+ std::promise<SessionCallbackInvocation> invocation_promise_;
+};
+
+class Face : public testing::TestWithParam<std::string> {
+ protected:
+ void SetUp() override {
+ AIBinder* binder = AServiceManager_waitForService(GetParam().c_str());
+ ASSERT_NE(binder, nullptr);
+ hal_ = IFace::fromBinder(ndk::SpAIBinder(binder));
+ }
+
+ std::shared_ptr<IFace> hal_;
+};
+
+TEST_P(Face, AuthenticateTest) {
+ std::promise<SessionCallbackInvocation> invocation_promise;
+ std::future<SessionCallbackInvocation> invocation_future = invocation_promise.get_future();
+ std::shared_ptr<SessionCallback> session_cb =
+ ndk::SharedRefBase::make<SessionCallback>(std::move(invocation_promise));
+
+ std::shared_ptr<ISession> session;
+ ASSERT_TRUE(hal_->createSession(kSensorId, kUserId, session_cb, &session).isOk());
+
+ std::shared_ptr<common::ICancellationSignal> cancel_cb;
+ ASSERT_TRUE(session->authenticate(0, 0, &cancel_cb).isOk());
+ ASSERT_EQ(invocation_future.wait_for(kCallbackTimeout), std::future_status::ready);
+
+ SessionCallbackInvocation invocation = invocation_future.get();
+ EXPECT_EQ(invocation.method_name, SessionCallbackMethodName::kOnStateChanged);
+ EXPECT_EQ(invocation.state, SessionState::AUTHENTICATING);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Face);
+INSTANTIATE_TEST_SUITE_P(IFace, Face,
+ testing::ValuesIn(::android::getAidlHalInstanceNames(IFace::descriptor)),
+ ::android::PrintInstanceNameToString);
+
+} // namespace
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
+ return RUN_ALL_TESTS();
+}
+
+} // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/fingerprint/aidl/OWNERS b/biometrics/fingerprint/aidl/OWNERS
new file mode 100644
index 0000000..36d7261
--- /dev/null
+++ b/biometrics/fingerprint/aidl/OWNERS
@@ -0,0 +1,2 @@
+ilyamaty@google.com
+kchyn@google.com
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
index 6ca6d16..c5c6786 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
@@ -20,6 +20,4 @@
interface IFingerprint {
android.hardware.biometrics.fingerprint.SensorProps[] getSensorProps();
android.hardware.biometrics.fingerprint.ISession createSession(in int sensorId, in int userId, in android.hardware.biometrics.fingerprint.ISessionCallback cb);
- void generateChallenge(in int sensorId, in int userId, in int timeoutSec, in android.hardware.biometrics.fingerprint.IGenerateChallengeCallback cb);
- void revokeChallenge(in int sensorId, in int userId, in long challenge, in android.hardware.biometrics.fingerprint.IRevokeChallengeCallback cb);
}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl
deleted file mode 100644
index 063be60..0000000
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl
+++ /dev/null
@@ -1,22 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files 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.fingerprint;
-@VintfStability
-interface IGenerateChallengeCallback {
- oneway void onChallengeGenerated(in int sensorId, in int userId, in long challenge);
-}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl
deleted file mode 100644
index 23fc10f..0000000
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl
+++ /dev/null
@@ -1,22 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files 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.fingerprint;
-@VintfStability
-interface IRevokeChallengeCallback {
- oneway void onChallengeRevoked(in int sensorId, in int userId, in long challenge);
-}
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 c1f66e3..00a08ba 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
@@ -18,6 +18,8 @@
package android.hardware.biometrics.fingerprint;
@VintfStability
interface ISession {
+ void generateChallenge(in int cookie, in int timeoutSec);
+ void revokeChallenge(in int cookie, in long challenge);
android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat);
android.hardware.biometrics.common.ICancellationSignal authenticate(in int cookie, in long operationId);
android.hardware.biometrics.common.ICancellationSignal detectInteraction(in int cookie);
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
index 74ec077..b7a48a5 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
@@ -19,6 +19,8 @@
@VintfStability
interface ISessionCallback {
void onStateChanged(in int cookie, in android.hardware.biometrics.fingerprint.SessionState state);
+ void onChallengeGenerated(in long challenge);
+ void onChallengeRevoked(in long challenge);
void onAcquired(in android.hardware.biometrics.fingerprint.AcquiredInfo info, in int vendorCode);
void onError(in android.hardware.biometrics.fingerprint.Error error, in int vendorCode);
void onEnrollmentProgress(in int enrollmentId, int remaining);
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl
index 97f1a1e..e9daef1 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl
@@ -19,12 +19,14 @@
@Backing(type="byte") @VintfStability
enum SessionState {
IDLING = 0,
- ENROLLING = 1,
- AUTHENTICATING = 2,
- DETECTING_INTERACTION = 3,
- ENUMERATING_ENROLLMENTS = 4,
- REMOVING_ENROLLMENTS = 5,
- GETTING_AUTHENTICATOR_ID = 6,
- INVALIDATING_AUTHENTICATOR_ID = 7,
- RESETTING_LOCKOUT = 8,
+ GENERATING_CHALLENGE = 1,
+ REVOKING_CHALLENGE = 2,
+ ENROLLING = 3,
+ AUTHENTICATING = 4,
+ DETECTING_INTERACTION = 5,
+ ENUMERATING_ENROLLMENTS = 6,
+ REMOVING_ENROLLMENTS = 7,
+ GETTING_AUTHENTICATOR_ID = 8,
+ INVALIDATING_AUTHENTICATOR_ID = 9,
+ RESETTING_LOCKOUT = 10,
}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
index 4b907b4..3675aa4 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
@@ -16,8 +16,6 @@
package android.hardware.biometrics.fingerprint;
-import android.hardware.biometrics.fingerprint.IGenerateChallengeCallback;
-import android.hardware.biometrics.fingerprint.IRevokeChallengeCallback;
import android.hardware.biometrics.fingerprint.ISession;
import android.hardware.biometrics.fingerprint.ISessionCallback;
import android.hardware.biometrics.fingerprint.SensorProps;
@@ -63,64 +61,4 @@
* @return A new session
*/
ISession createSession(in int sensorId, in int userId, in ISessionCallback cb);
-
- /**
- * generateChallenge:
- *
- * Begins a secure transaction request. Note that the challenge by itself is not useful. It only
- * becomes useful when wrapped in a verifiable message such as a HardwareAuthToken.
- *
- * Canonical example:
- * 1) User requests an operation, such as fingerprint enrollment.
- * 2) Fingerprint enrollment cannot happen until the user confirms their lockscreen credential
- * (PIN/Pattern/Password).
- * 3) However, the biometric subsystem does not want just "any" proof of credential
- * confirmation. It needs proof that the user explicitly authenticated credential in order
- * to allow addition of biometric enrollments.
- * To secure this path, the following path is taken:
- * 1) Upon user requesting fingerprint enroll, the framework requests
- * IFingerprint#generateChallenge
- * 2) Framework sends the challenge to the credential subsystem, and upon credential
- * confirmation, a HAT is created, containing the challenge in the "challenge" field.
- * 3) Framework sends the HAT to the HAL, e.g. ISession#enroll.
- * 4) Implementation verifies the authenticity and integrity of the HAT.
- * 5) Implementation now has confidence that the user entered their credential to allow
- * biometric enrollment.
- *
- * Note that the interface allows multiple in-flight challenges. For example, invoking
- * generateChallenge(0, 0, timeoutSec, cb) twice does not invalidate the first challenge. The
- * challenge is invalidated only when:
- * 1) The provided timeout expires, or
- * 2) IFingerprint#revokeChallenge is invoked
- *
- * For example, the following is a possible table of valid challenges:
- * ----------------------------------------------
- * | SensorId | UserId | ValidUntil | Challenge |
- * |----------|--------|------------|-----------|
- * | 0 | 0 | <Time1> | <Random1> |
- * | 0 | 0 | <Time2> | <Random2> |
- * | 1 | 0 | <Time3> | <Random3> |
- * | 0 | 10 | <Time4> | <Random4> |
- * ----------------------------------------------
- *
- * @param sensorId Sensor to associate the challenge with
- * @param userId User to associate the challenge with
- * @param timeoutSec Duration for which the challenge is valid for
- * @param cb Callback to notify the framework
- */
- void generateChallenge(in int sensorId, in int userId, in int timeoutSec, in IGenerateChallengeCallback cb);
-
- /**
- * revokeChallenge:
- *
- * Revokes a challenge that was previously generated. Note that if an invalid combination of
- * parameters is requested, the implementation must still notify the framework using the
- * provided callback.
- *
- * @param sensorId Sensor that the revocation should apply to.
- * @param userId User that the revocation should apply to.
- * @param challenge Challenge that should be revoked.
- * @param cb Used to notify the framework.
- */
- void revokeChallenge(in int sensorId, in int userId, in long challenge, in IRevokeChallengeCallback cb);
}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
index 644e214..da767be 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -47,6 +47,62 @@
*/
/**
+ * generateChallenge:
+ *
+ * Begins a secure transaction request. Note that the challenge by itself is not useful. It only
+ * becomes useful when wrapped in a verifiable message such as a HardwareAuthToken.
+ *
+ * Canonical example:
+ * 1) User requests an operation, such as fingerprint enrollment.
+ * 2) Fingerprint enrollment cannot happen until the user confirms their lockscreen credential
+ * (PIN/Pattern/Password).
+ * 3) However, the biometric subsystem does not want just "any" proof of credential
+ * confirmation. It needs proof that the user explicitly authenticated credential in order
+ * to allow addition of biometric enrollments.
+ * To secure this path, the following path is taken:
+ * 1) Upon user requesting fingerprint enroll, the framework requests
+ * IFingerprint#generateChallenge
+ * 2) Framework sends the challenge to the credential subsystem, and upon credential
+ * confirmation, a HAT is created, containing the challenge in the "challenge" field.
+ * 3) Framework sends the HAT to the HAL, e.g. ISession#enroll.
+ * 4) Implementation verifies the authenticity and integrity of the HAT.
+ * 5) Implementation now has confidence that the user entered their credential to allow
+ * biometric enrollment.
+ *
+ * Note that the interface allows multiple in-flight challenges. For example, invoking
+ * generateChallenge(0, 0, timeoutSec, cb) twice does not invalidate the first challenge. The
+ * challenge is invalidated only when:
+ * 1) The provided timeout expires, or
+ * 2) IFingerprint#revokeChallenge is invoked
+ *
+ * For example, the following is a possible table of valid challenges:
+ * ----------------------------------------------
+ * | SensorId | UserId | ValidUntil | Challenge |
+ * |----------|--------|------------|-----------|
+ * | 0 | 0 | <Time1> | <Random1> |
+ * | 0 | 0 | <Time2> | <Random2> |
+ * | 1 | 0 | <Time3> | <Random3> |
+ * | 0 | 10 | <Time4> | <Random4> |
+ * ----------------------------------------------
+ *
+ * @param cookie A unique number identifying this operation
+ * @param timeoutSec Duration for which the challenge is valid for
+ */
+ void generateChallenge(in int cookie, in int timeoutSec);
+
+ /**
+ * revokeChallenge:
+ *
+ * Revokes a challenge that was previously generated. Note that if an invalid combination of
+ * parameters is requested, the implementation must still notify the framework using the
+ * provided callback.
+ *
+ * @param cookie A unique number identifying this operation
+ * @param challenge Challenge that should be revoked.
+ */
+ void revokeChallenge(in int cookie, in long challenge);
+
+ /**
* enroll:
*
* A request to add a fingerprint enrollment.
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
index 74792d8..4387f98 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
@@ -29,6 +29,16 @@
void onStateChanged(in int cookie, in SessionState state);
/**
+ * Notifies the framework when a challenge is successfully generated.
+ */
+ void onChallengeGenerated(in long challenge);
+
+ /**
+ * Notifies the framework when a challenge has been revoked.
+ */
+ void onChallengeRevoked(in long challenge);
+
+ /**
* This method must only be used to notify the framework during the following states:
* 1) SessionState::ENROLLING
* 2) SessionState::AUTHENTICATING
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl
index 405b011..1de01ad 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl
@@ -25,6 +25,16 @@
IDLING,
/**
+ * The HAL is processing the ISession#generateChallenge request.
+ */
+ GENERATING_CHALLENGE,
+
+ /**
+ * The HAL is processing the ISession#revokeChallenge request.
+ */
+ REVOKING_CHALLENGE,
+
+ /**
* The HAL is processing the ISession#enroll request.
*/
ENROLLING,
diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
index b907bf1..18ce0c8 100644
--- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp
+++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
@@ -60,17 +60,4 @@
*return_val = SharedRefBase::make<Session>(cb);
return ndk::ScopedAStatus::ok();
}
-
-ndk::ScopedAStatus Fingerprint::generateChallenge(
- int32_t /*sensorId*/, int32_t /*userId*/, int32_t /*timeoutSec*/,
- const std::shared_ptr<IGenerateChallengeCallback>& /*cb*/) {
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus Fingerprint::revokeChallenge(
- int32_t /*sensorId*/, int32_t /*userId*/, int64_t /*challenge*/,
- const std::shared_ptr<IRevokeChallengeCallback>& /*cb*/) {
- return ndk::ScopedAStatus::ok();
-}
-
} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.h b/biometrics/fingerprint/aidl/default/Fingerprint.h
index 59cdd44..4e952ba 100644
--- a/biometrics/fingerprint/aidl/default/Fingerprint.h
+++ b/biometrics/fingerprint/aidl/default/Fingerprint.h
@@ -27,14 +27,6 @@
ndk::ScopedAStatus createSession(int32_t sensorId, int32_t userId,
const std::shared_ptr<ISessionCallback>& cb,
std::shared_ptr<ISession>* _aidl_return) override;
-
- ndk::ScopedAStatus generateChallenge(
- int32_t sensorId, int32_t userId, int32_t timeoutSec,
- const std::shared_ptr<IGenerateChallengeCallback>& cb) override;
-
- ndk::ScopedAStatus revokeChallenge(
- int32_t sensorId, int32_t userId, int64_t challenge,
- const std::shared_ptr<IRevokeChallengeCallback>& cb) override;
};
} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp
index c2934a8..96f1e56 100644
--- a/biometrics/fingerprint/aidl/default/Session.cpp
+++ b/biometrics/fingerprint/aidl/default/Session.cpp
@@ -27,6 +27,14 @@
Session::Session(std::shared_ptr<ISessionCallback> cb) : cb_(std::move(cb)) {}
+ndk::ScopedAStatus Session::generateChallenge(int32_t /*cookie*/, int32_t /*timeoutSec*/) {
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Session::revokeChallenge(int32_t /*cookie*/, int64_t /*challenge*/) {
+ return ndk::ScopedAStatus::ok();
+}
+
ndk::ScopedAStatus Session::enroll(int32_t /*cookie*/, const keymaster::HardwareAuthToken& /*hat*/,
std::shared_ptr<common::ICancellationSignal>* /*return_val*/) {
return ndk::ScopedAStatus::ok();
@@ -47,20 +55,32 @@
}
ndk::ScopedAStatus Session::enumerateEnrollments(int32_t /*cookie*/) {
+ if (cb_) {
+ cb_->onStateChanged(0, SessionState::ENUMERATING_ENROLLMENTS);
+ cb_->onEnrollmentsEnumerated(std::vector<int32_t>());
+ }
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::removeEnrollments(int32_t /*cookie*/,
const std::vector<int32_t>& /*enrollmentIds*/) {
+ if (cb_) {
+ cb_->onStateChanged(0, SessionState::REMOVING_ENROLLMENTS);
+ cb_->onEnrollmentsRemoved(std::vector<int32_t>());
+ }
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::getAuthenticatorId(int32_t /*cookie*/) {
+ if (cb_) {
+ cb_->onStateChanged(0, SessionState::GETTING_AUTHENTICATOR_ID);
+ cb_->onAuthenticatorIdRetrieved(0 /* authenticatorId */);
+ }
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::invalidateAuthenticatorId(int32_t /*cookie*/,
- const keymaster::HardwareAuthToken& /*hat*/) {
+ const keymaster::HardwareAuthToken& /*hat*/) {
return ndk::ScopedAStatus::ok();
}
@@ -81,5 +101,4 @@
ndk::ScopedAStatus Session::onUiReady() {
return ndk::ScopedAStatus::ok();
}
-
} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/Session.h b/biometrics/fingerprint/aidl/default/Session.h
index f7cba1b..05c570c 100644
--- a/biometrics/fingerprint/aidl/default/Session.h
+++ b/biometrics/fingerprint/aidl/default/Session.h
@@ -28,14 +28,19 @@
public:
explicit Session(std::shared_ptr<ISessionCallback> cb);
+ ndk::ScopedAStatus generateChallenge(int32_t cookie, int32_t timeoutSec) override;
+
+ ndk::ScopedAStatus revokeChallenge(int32_t cookie, int64_t challenge) override;
+
ndk::ScopedAStatus enroll(int32_t cookie, const keymaster::HardwareAuthToken& hat,
std::shared_ptr<common::ICancellationSignal>* return_val) override;
- ndk::ScopedAStatus authenticate(int32_t cookie, int64_t keystoreOperationId,
- std::shared_ptr<common::ICancellationSignal>* return_val) override;
+ ndk::ScopedAStatus authenticate(
+ int32_t cookie, int64_t keystoreOperationId,
+ std::shared_ptr<common::ICancellationSignal>* return_val) override;
- ndk::ScopedAStatus detectInteraction(int32_t cookie,
- std::shared_ptr<common::ICancellationSignal>* return_val) override;
+ ndk::ScopedAStatus detectInteraction(
+ int32_t cookie, std::shared_ptr<common::ICancellationSignal>* return_val) override;
ndk::ScopedAStatus enumerateEnrollments(int32_t cookie) override;
@@ -45,7 +50,7 @@
ndk::ScopedAStatus getAuthenticatorId(int32_t cookie) override;
ndk::ScopedAStatus invalidateAuthenticatorId(int32_t cookie,
- const keymaster::HardwareAuthToken& hat) override;
+ const keymaster::HardwareAuthToken& hat) override;
ndk::ScopedAStatus resetLockout(int32_t cookie,
const keymaster::HardwareAuthToken& hat) override;
diff --git a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp
index 496badc..adb98ac 100644
--- a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp
+++ b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp
@@ -52,6 +52,14 @@
return ndk::ScopedAStatus::ok();
}
+ ndk::ScopedAStatus onChallengeGenerated(int64_t /*challenge*/) override {
+ return ndk::ScopedAStatus::ok();
+ }
+
+ ndk::ScopedAStatus onChallengeRevoked(int64_t /*challenge*/) override {
+ return ndk::ScopedAStatus::ok();
+ }
+
ndk::ScopedAStatus onAcquired(AcquiredInfo /*info*/, int32_t /*vendorCode*/) override {
return ndk::ScopedAStatus::ok();
}
diff --git a/bluetooth/audio/2.1/Android.bp b/bluetooth/audio/2.1/Android.bp
new file mode 100644
index 0000000..9af8add
--- /dev/null
+++ b/bluetooth/audio/2.1/Android.bp
@@ -0,0 +1,22 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.bluetooth.audio@2.1",
+ root: "android.hardware",
+ srcs: [
+ "types.hal",
+ "IBluetoothAudioProvider.hal",
+ "IBluetoothAudioProvidersFactory.hal",
+ ],
+ interfaces: [
+ "android.hardware.audio.common@5.0",
+ "android.hardware.bluetooth.audio@2.0",
+ "android.hidl.base@1.0",
+ "android.hidl.safe_union@1.0",
+ ],
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.bluetooth.updatable",
+ ],
+ gen_java: false,
+}
diff --git a/bluetooth/audio/2.1/IBluetoothAudioProvider.hal b/bluetooth/audio/2.1/IBluetoothAudioProvider.hal
new file mode 100644
index 0000000..c462b9e
--- /dev/null
+++ b/bluetooth/audio/2.1/IBluetoothAudioProvider.hal
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio@2.1;
+
+import @2.0::IBluetoothAudioProvider;
+import @2.0::IBluetoothAudioPort;
+import @2.0::Status;
+
+/**
+ * HAL interface from the Bluetooth stack to the Audio HAL
+ *
+ * The Bluetooth stack calls methods in this interface to start and end audio
+ * sessions and sends callback events to the Audio HAL.
+ *
+ * Note: For HIDL APIs with a "generates" statement, the callback parameter used
+ * for return value must be invoked synchronously before the API call returns.
+ */
+interface IBluetoothAudioProvider extends @2.0::IBluetoothAudioProvider {
+
+ /**
+ * This method indicates that the Bluetooth stack is ready to stream audio.
+ * It registers an instance of IBluetoothAudioPort with and provides the
+ * current negotiated codec to the Audio HAL. After this method is called,
+ * the Audio HAL can invoke IBluetoothAudioPort.startStream().
+ *
+ * Note: endSession() must be called to unregister this IBluetoothAudioPort
+ *
+ * @param hostIf An instance of IBluetoothAudioPort for stream control
+ * @param audioConfig The audio configuration negotiated with the remote
+ * device. The PCM parameters are set if software based encoding,
+ * otherwise the correct codec configuration is used for hardware
+ * encoding.
+ *
+ * @return status One of the following
+ * SUCCESS if this IBluetoothAudioPort was successfully registered with
+ * the Audio HAL
+ * UNSUPPORTED_CODEC_CONFIGURATION if the Audio HAL cannot register this
+ * IBluetoothAudioPort with the given codec configuration
+ * FAILURE if the Audio HAL cannot register this IBluetoothAudioPort for
+ * any other reason
+ * @return dataMQ The fast message queue for audio data from/to this
+ * provider. Audio data will be in PCM format as specified by the
+ * audioConfig.pcmConfig parameter. Invalid if streaming is offloaded
+ * from/to hardware or on failure.
+ */
+ startSession_2_1(IBluetoothAudioPort hostIf, AudioConfiguration audioConfig)
+ generates (Status status, fmq_sync<uint8_t> dataMQ);
+};
diff --git a/bluetooth/audio/2.1/IBluetoothAudioProvidersFactory.hal b/bluetooth/audio/2.1/IBluetoothAudioProvidersFactory.hal
new file mode 100644
index 0000000..5593c7c
--- /dev/null
+++ b/bluetooth/audio/2.1/IBluetoothAudioProvidersFactory.hal
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio@2.1;
+
+import IBluetoothAudioProvider;
+import @2.0::IBluetoothAudioProvidersFactory;
+import @2.0::Status;
+
+/**
+ * This factory allows a HAL implementation to be split into multiple
+ * independent providers.
+ *
+ * When the Bluetooth stack is ready to create an audio session, it must first
+ * obtain the IBluetoothAudioProvider for that session type by calling
+ * openProvider().
+ *
+ * Note: For HIDL APIs with a "generates" statement, the callback parameter used
+ * for return value must be invoked synchronously before the API call returns.
+ */
+interface IBluetoothAudioProvidersFactory extends @2.0::IBluetoothAudioProvidersFactory {
+
+ /**
+ * Opens an audio provider for a session type. To close the provider, it is
+ * necessary to release references to the returned provider object.
+ *
+ * @param sessionType The session type (e.g.
+ * LE_AUDIO_SOFTWARE_ENCODING_DATAPATH).
+ *
+ * @return status One of the following
+ * SUCCESS if the Audio HAL successfully opens the provider with the
+ * given session type
+ * FAILURE if the Audio HAL cannot open the provider
+ * @return provider The provider of the specified session type
+ */
+ openProvider_2_1(SessionType sessionType)
+ generates (Status status, IBluetoothAudioProvider provider);
+
+ /**
+ * Gets a list of audio capabilities for a session type.
+ *
+ * For software encoding, the PCM capabilities are returned.
+ * For hardware encoding, the supported codecs and their capabilities are
+ * returned.
+ *
+ * @param sessionType The session type (e.g.
+ * A2DP_SOFTWARE_ENCODING_DATAPATH).
+ * @return audioCapabilities A list containing all the capabilities
+ * supported by the sesson type. The capabilities is a list of
+ * available options when configuring the codec for the session.
+ * For software encoding it is the PCM data rate.
+ * For hardware encoding it is the list of supported codecs and their
+ * capabilities.
+ * If a provider isn't supported, an empty list should be returned.
+ * Note: Only one entry should exist per codec when using hardware
+ * encoding.
+ */
+ getProviderCapabilities_2_1(SessionType sessionType)
+ generates (vec<AudioCapabilities> audioCapabilities);
+};
diff --git a/bluetooth/audio/2.1/default/A2dpOffloadAudioProvider.cpp b/bluetooth/audio/2.1/default/A2dpOffloadAudioProvider.cpp
new file mode 100644
index 0000000..b4a61b6
--- /dev/null
+++ b/bluetooth/audio/2.1/default/A2dpOffloadAudioProvider.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BTAudioProviderA2dpOffload"
+
+#include "A2dpOffloadAudioProvider.h"
+
+#include <android-base/logging.h>
+#include <fmq/MessageQueue.h>
+#include <hidl/MQDescriptor.h>
+
+#include "BluetoothAudioSessionReport.h"
+#include "BluetoothAudioSupportedCodecsDB.h"
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::bluetooth::audio::BluetoothAudioSessionReport;
+using ::android::hardware::kSynchronizedReadWrite;
+using ::android::hardware::MessageQueue;
+using ::android::hardware::Void;
+using ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
+
+using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+
+A2dpOffloadAudioProvider::A2dpOffloadAudioProvider()
+ : BluetoothAudioProvider() {
+ session_type_ = SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH;
+}
+
+bool A2dpOffloadAudioProvider::isValid(const V2_0::SessionType& sessionType) {
+ return isValid(static_cast<SessionType>(sessionType));
+}
+
+bool A2dpOffloadAudioProvider::isValid(const SessionType& sessionType) {
+ return (sessionType == session_type_);
+}
+
+Return<void> A2dpOffloadAudioProvider::startSession(
+ const sp<IBluetoothAudioPort>& hostIf,
+ const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
+ /**
+ * Initialize the audio platform if audioConfiguration is supported.
+ * Save the IBluetoothAudioPort interface, so that it can be used
+ * later to send stream control commands to the HAL client, based on
+ * interaction with Audio framework.
+ */
+ if (audioConfig.getDiscriminator() !=
+ AudioConfiguration::hidl_discriminator::codecConfig) {
+ LOG(WARNING) << __func__
+ << " - Invalid Audio Configuration=" << toString(audioConfig);
+ _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
+ DataMQ::Descriptor());
+ return Void();
+ } else if (!android::bluetooth::audio::IsOffloadCodecConfigurationValid(
+ session_type_, audioConfig.codecConfig())) {
+ _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
+ DataMQ::Descriptor());
+ return Void();
+ }
+
+ return BluetoothAudioProvider::startSession(hostIf, audioConfig, _hidl_cb);
+}
+
+Return<void> A2dpOffloadAudioProvider::onSessionReady(
+ startSession_cb _hidl_cb) {
+ BluetoothAudioSessionReport::OnSessionStarted(session_type_, stack_iface_,
+ nullptr, audio_config_);
+ _hidl_cb(BluetoothAudioStatus::SUCCESS, DataMQ::Descriptor());
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/bluetooth/audio/2.1/default/A2dpOffloadAudioProvider.h b/bluetooth/audio/2.1/default/A2dpOffloadAudioProvider.h
new file mode 100644
index 0000000..13e0b9a
--- /dev/null
+++ b/bluetooth/audio/2.1/default/A2dpOffloadAudioProvider.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "BluetoothAudioProvider.h"
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+namespace V2_1 {
+namespace implementation {
+
+class A2dpOffloadAudioProvider : public BluetoothAudioProvider {
+ public:
+ A2dpOffloadAudioProvider();
+
+ bool isValid(const SessionType& sessionType) override;
+ bool isValid(const V2_0::SessionType& sessionType) override;
+
+ Return<void> startSession(const sp<V2_0::IBluetoothAudioPort>& hostIf,
+ const V2_0::AudioConfiguration& audioConfig,
+ startSession_cb _hidl_cb) override;
+
+ private:
+ Return<void> onSessionReady(startSession_cb _hidl_cb) override;
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/bluetooth/audio/2.1/default/A2dpSoftwareAudioProvider.cpp b/bluetooth/audio/2.1/default/A2dpSoftwareAudioProvider.cpp
new file mode 100644
index 0000000..a67c341
--- /dev/null
+++ b/bluetooth/audio/2.1/default/A2dpSoftwareAudioProvider.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BTAudioProviderA2dpSoftware"
+
+#include "A2dpSoftwareAudioProvider.h"
+
+#include <android-base/logging.h>
+
+#include "BluetoothAudioSessionReport.h"
+#include "BluetoothAudioSupportedCodecsDB.h"
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::bluetooth::audio::BluetoothAudioSessionReport;
+using ::android::hardware::Void;
+using ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
+
+static constexpr uint32_t kPcmFrameSize = 4; // 16 bits per sample / stereo
+static constexpr uint32_t kPcmFrameCount = 128;
+static constexpr uint32_t kRtpFrameSize = kPcmFrameSize * kPcmFrameCount;
+static constexpr uint32_t kRtpFrameCount = 7; // max counts by 1 tick (20ms)
+static constexpr uint32_t kBufferSize = kRtpFrameSize * kRtpFrameCount;
+static constexpr uint32_t kBufferCount = 2; // double buffer
+static constexpr uint32_t kDataMqSize = kBufferSize * kBufferCount;
+
+A2dpSoftwareAudioProvider::A2dpSoftwareAudioProvider()
+ : BluetoothAudioProvider(), mDataMQ(nullptr) {
+ LOG(INFO) << __func__ << " - size of audio buffer " << kDataMqSize
+ << " byte(s)";
+ std::unique_ptr<DataMQ> tempDataMQ(
+ new DataMQ(kDataMqSize, /* EventFlag */ true));
+ if (tempDataMQ && tempDataMQ->isValid()) {
+ mDataMQ = std::move(tempDataMQ);
+ session_type_ = SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH;
+ } else {
+ ALOGE_IF(!tempDataMQ, "failed to allocate data MQ");
+ ALOGE_IF(tempDataMQ && !tempDataMQ->isValid(), "data MQ is invalid");
+ }
+}
+
+bool A2dpSoftwareAudioProvider::isValid(const V2_0::SessionType& sessionType) {
+ return isValid(static_cast<SessionType>(sessionType));
+}
+
+bool A2dpSoftwareAudioProvider::isValid(const SessionType& sessionType) {
+ return (sessionType == session_type_ && mDataMQ && mDataMQ->isValid());
+}
+
+Return<void> A2dpSoftwareAudioProvider::startSession(
+ const sp<IBluetoothAudioPort>& hostIf,
+ const V2_0::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
+ /**
+ * Initialize the audio platform if audioConfiguration is supported.
+ * Save the IBluetoothAudioPort interface, so that it can be used
+ * later to send stream control commands to the HAL client, based on
+ * interaction with Audio framework.
+ */
+ if (audioConfig.getDiscriminator() !=
+ AudioConfiguration::hidl_discriminator::pcmConfig) {
+ LOG(WARNING) << __func__
+ << " - Invalid Audio Configuration=" << toString(audioConfig);
+ _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
+ DataMQ::Descriptor());
+ return Void();
+ } else if (!android::bluetooth::audio::IsSoftwarePcmConfigurationValid(
+ audioConfig.pcmConfig())) {
+ LOG(WARNING) << __func__ << " - Unsupported PCM Configuration="
+ << toString(audioConfig.pcmConfig());
+ _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
+ DataMQ::Descriptor());
+ return Void();
+ }
+
+ return BluetoothAudioProvider::startSession(hostIf, audioConfig, _hidl_cb);
+}
+
+Return<void> A2dpSoftwareAudioProvider::onSessionReady(
+ startSession_cb _hidl_cb) {
+ if (mDataMQ && mDataMQ->isValid()) {
+ BluetoothAudioSessionReport::OnSessionStarted(
+ session_type_, stack_iface_, mDataMQ->getDesc(), audio_config_);
+ _hidl_cb(BluetoothAudioStatus::SUCCESS, *mDataMQ->getDesc());
+ } else {
+ _hidl_cb(BluetoothAudioStatus::FAILURE, DataMQ::Descriptor());
+ }
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/bluetooth/audio/2.1/default/A2dpSoftwareAudioProvider.h b/bluetooth/audio/2.1/default/A2dpSoftwareAudioProvider.h
new file mode 100644
index 0000000..20566d1
--- /dev/null
+++ b/bluetooth/audio/2.1/default/A2dpSoftwareAudioProvider.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <fmq/MessageQueue.h>
+#include <hidl/MQDescriptor.h>
+
+#include "BluetoothAudioProvider.h"
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::hardware::kSynchronizedReadWrite;
+using ::android::hardware::MessageQueue;
+
+using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+
+class A2dpSoftwareAudioProvider : public BluetoothAudioProvider {
+ public:
+ A2dpSoftwareAudioProvider();
+
+ bool isValid(const SessionType& sessionType) override;
+ bool isValid(const V2_0::SessionType& sessionType) override;
+
+ Return<void> startSession(const sp<IBluetoothAudioPort>& hostIf,
+ const V2_0::AudioConfiguration& audioConfig,
+ startSession_cb _hidl_cb) override;
+
+ private:
+ // audio data queue for software encoding
+ std::unique_ptr<DataMQ> mDataMQ;
+
+ Return<void> onSessionReady(startSession_cb _hidl_cb) override;
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/bluetooth/audio/2.1/default/Android.bp b/bluetooth/audio/2.1/default/Android.bp
new file mode 100644
index 0000000..5381fec
--- /dev/null
+++ b/bluetooth/audio/2.1/default/Android.bp
@@ -0,0 +1,48 @@
+cc_library_shared {
+ name: "android.hardware.bluetooth.audio@2.1-impl",
+ defaults: ["hidl_defaults"],
+ vendor: true,
+ relative_install_path: "hw",
+ srcs: [
+ "BluetoothAudioProvidersFactory.cpp",
+ "BluetoothAudioProvider.cpp",
+ "A2dpOffloadAudioProvider.cpp",
+ "A2dpSoftwareAudioProvider.cpp",
+ "HearingAidAudioProvider.cpp",
+ "LeAudioAudioProvider.cpp",
+ ],
+ header_libs: ["libhardware_headers"],
+ shared_libs: [
+ "android.hardware.bluetooth.audio@2.0",
+ "android.hardware.bluetooth.audio@2.1",
+ "libbase",
+ "libbluetooth_audio_session_2_1",
+ "libcutils",
+ "libfmq",
+ "libhidlbase",
+ "liblog",
+ "libutils",
+ ],
+}
+
+cc_library_shared {
+ name: "libbluetooth_audio_session_2_1",
+ defaults: ["hidl_defaults"],
+ vendor: true,
+ srcs: [
+ "session/BluetoothAudioSession.cpp",
+ "session/BluetoothAudioSupportedCodecsDB.cpp",
+ ],
+ export_include_dirs: ["session/"],
+ header_libs: ["libhardware_headers"],
+ shared_libs: [
+ "android.hardware.bluetooth.audio@2.0",
+ "android.hardware.bluetooth.audio@2.1",
+ "libbase",
+ "libcutils",
+ "libfmq",
+ "libhidlbase",
+ "liblog",
+ "libutils",
+ ],
+}
diff --git a/bluetooth/audio/2.1/default/BluetoothAudioProvider.cpp b/bluetooth/audio/2.1/default/BluetoothAudioProvider.cpp
new file mode 100644
index 0000000..0f349a4
--- /dev/null
+++ b/bluetooth/audio/2.1/default/BluetoothAudioProvider.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BTAudioProviderStub"
+
+#include "BluetoothAudioProvider.h"
+
+#include <android-base/logging.h>
+
+#include "BluetoothAudioSessionReport.h"
+#include "BluetoothAudioSupportedCodecsDB.h"
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::bluetooth::audio::BluetoothAudioSessionReport;
+using ::android::hardware::kSynchronizedReadWrite;
+using ::android::hardware::MessageQueue;
+using ::android::hardware::Void;
+
+using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+
+void BluetoothAudioDeathRecipient::serviceDied(
+ uint64_t cookie __unused,
+ const wp<::android::hidl::base::V1_0::IBase>& who __unused) {
+ LOG(ERROR) << "BluetoothAudioDeathRecipient::" << __func__
+ << " - BluetoothAudio Service died";
+ provider_->endSession();
+}
+
+BluetoothAudioProvider::BluetoothAudioProvider()
+ : death_recipient_(new BluetoothAudioDeathRecipient(this)),
+ session_type_(SessionType::UNKNOWN),
+ audio_config_({}) {}
+
+Return<void> BluetoothAudioProvider::startSession(
+ const sp<IBluetoothAudioPort>& hostIf,
+ const V2_0::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
+ AudioConfiguration audioConfig_2_1;
+
+ audioConfig_2_1.codecConfig() = audioConfig.codecConfig();
+ audioConfig_2_1.pcmConfig() = {
+ .sampleRate = static_cast<SampleRate>(audioConfig.pcmConfig().sampleRate),
+ .channelMode = audioConfig.pcmConfig().channelMode,
+ .bitsPerSample = audioConfig.pcmConfig().bitsPerSample,
+ .dataIntervalUs = 0};
+
+ return startSession_2_1(hostIf, audioConfig_2_1, _hidl_cb);
+}
+
+Return<void> BluetoothAudioProvider::startSession_2_1(
+ const sp<IBluetoothAudioPort>& hostIf,
+ const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
+ if (hostIf == nullptr) {
+ _hidl_cb(BluetoothAudioStatus::FAILURE, DataMQ::Descriptor());
+ return Void();
+ }
+
+ /**
+ * Initialize the audio platform if audioConfiguration is supported.
+ * Save the IBluetoothAudioPort interface, so that it can be used
+ * later to send stream control commands to the HAL client, based on
+ * interaction with Audio framework.
+ */
+ audio_config_ = audioConfig;
+ stack_iface_ = hostIf;
+ stack_iface_->linkToDeath(death_recipient_, 0);
+
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+ << ", AudioConfiguration=[" << toString(audio_config_) << "]";
+
+ onSessionReady(_hidl_cb);
+ return Void();
+}
+
+Return<void> BluetoothAudioProvider::streamStarted(
+ BluetoothAudioStatus status) {
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+ << ", status=" << toString(status);
+
+ /**
+ * Streaming on control path has started,
+ * HAL server should start the streaming on data path.
+ */
+ if (stack_iface_) {
+ BluetoothAudioSessionReport::ReportControlStatus(session_type_, true,
+ status);
+ } else {
+ LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
+ << ", status=" << toString(status) << " has NO session";
+ }
+
+ return Void();
+}
+
+Return<void> BluetoothAudioProvider::streamSuspended(
+ BluetoothAudioStatus status) {
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+ << ", status=" << toString(status);
+
+ /**
+ * Streaming on control path has suspend,
+ * HAL server should suspend the streaming on data path.
+ */
+ if (stack_iface_) {
+ BluetoothAudioSessionReport::ReportControlStatus(session_type_, false,
+ status);
+ } else {
+ LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
+ << ", status=" << toString(status) << " has NO session";
+ }
+
+ return Void();
+}
+
+Return<void> BluetoothAudioProvider::endSession() {
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
+
+ if (stack_iface_) {
+ BluetoothAudioSessionReport::OnSessionEnded(session_type_);
+ stack_iface_->unlinkToDeath(death_recipient_);
+ } else {
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+ << " has NO session";
+ }
+
+ /**
+ * Clean up the audio platform as remote audio device is no
+ * longer active
+ */
+ stack_iface_ = nullptr;
+ audio_config_ = {};
+
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/bluetooth/audio/2.1/default/BluetoothAudioProvider.h b/bluetooth/audio/2.1/default/BluetoothAudioProvider.h
new file mode 100644
index 0000000..a2e611f
--- /dev/null
+++ b/bluetooth/audio/2.1/default/BluetoothAudioProvider.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/bluetooth/audio/2.1/IBluetoothAudioProvider.h>
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioPort;
+
+using BluetoothAudioStatus =
+ ::android::hardware::bluetooth::audio::V2_0::Status;
+
+class BluetoothAudioDeathRecipient;
+
+class BluetoothAudioProvider : public IBluetoothAudioProvider {
+ public:
+ BluetoothAudioProvider();
+ ~BluetoothAudioProvider() = default;
+
+ virtual bool isValid(const SessionType& sessionType) = 0;
+ virtual bool isValid(const V2_0::SessionType& sessionType) = 0;
+
+ Return<void> startSession(const sp<IBluetoothAudioPort>& hostIf,
+ const V2_0::AudioConfiguration& audioConfig,
+ startSession_cb _hidl_cb) override;
+ Return<void> startSession_2_1(const sp<IBluetoothAudioPort>& hostIf,
+ const AudioConfiguration& audioConfig,
+ startSession_cb _hidl_cb) override;
+ Return<void> streamStarted(BluetoothAudioStatus status) override;
+ Return<void> streamSuspended(BluetoothAudioStatus status) override;
+ Return<void> endSession() override;
+
+ protected:
+ sp<BluetoothAudioDeathRecipient> death_recipient_;
+
+ SessionType session_type_;
+ AudioConfiguration audio_config_;
+ sp<V2_0::IBluetoothAudioPort> stack_iface_;
+
+ virtual Return<void> onSessionReady(startSession_cb _hidl_cb) = 0;
+};
+
+class BluetoothAudioDeathRecipient : public hidl_death_recipient {
+ public:
+ BluetoothAudioDeathRecipient(const sp<BluetoothAudioProvider> provider)
+ : provider_(provider) {}
+
+ virtual void serviceDied(
+ uint64_t cookie,
+ const wp<::android::hidl::base::V1_0::IBase>& who) override;
+
+ private:
+ sp<BluetoothAudioProvider> provider_;
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp
new file mode 100644
index 0000000..adf2717
--- /dev/null
+++ b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BTAudioProvidersFactory"
+
+#include "BluetoothAudioProvidersFactory.h"
+
+#include <android-base/logging.h>
+
+#include "BluetoothAudioSupportedCodecsDB.h"
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Void;
+using ::android::hardware::bluetooth::audio::V2_0::CodecCapabilities;
+
+A2dpSoftwareAudioProvider
+ BluetoothAudioProvidersFactory::a2dp_software_provider_instance_;
+A2dpOffloadAudioProvider
+ BluetoothAudioProvidersFactory::a2dp_offload_provider_instance_;
+HearingAidAudioProvider
+ BluetoothAudioProvidersFactory::hearing_aid_provider_instance_;
+LeAudioOutputAudioProvider
+ BluetoothAudioProvidersFactory::leaudio_output_provider_instance_;
+LeAudioInputAudioProvider
+ BluetoothAudioProvidersFactory::leaudio_input_provider_instance_;
+
+Return<void> BluetoothAudioProvidersFactory::openProvider(
+ const V2_0::SessionType sessionType, openProvider_cb _hidl_cb) {
+ LOG(INFO) << __func__ << " - SessionType=" << toString(sessionType);
+ BluetoothAudioStatus status = BluetoothAudioStatus::SUCCESS;
+ BluetoothAudioProvider* provider = nullptr;
+ switch (sessionType) {
+ case V2_0::SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
+ provider = &a2dp_software_provider_instance_;
+ break;
+ case V2_0::SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH:
+ provider = &a2dp_offload_provider_instance_;
+ break;
+ case V2_0::SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
+ provider = &hearing_aid_provider_instance_;
+ break;
+ default:
+ status = BluetoothAudioStatus::FAILURE;
+ }
+ if (provider == nullptr || !provider->isValid(sessionType)) {
+ provider = nullptr;
+ status = BluetoothAudioStatus::FAILURE;
+ LOG(ERROR) << __func__ << " - SessionType=" << toString(sessionType)
+ << ", status=" << toString(status);
+ }
+ _hidl_cb(status, provider);
+ return Void();
+}
+
+Return<void> BluetoothAudioProvidersFactory::openProvider_2_1(
+ const SessionType sessionType, openProvider_2_1_cb _hidl_cb) {
+ LOG(INFO) << __func__ << " - SessionType=" << toString(sessionType);
+ BluetoothAudioStatus status = BluetoothAudioStatus::SUCCESS;
+ BluetoothAudioProvider* provider = nullptr;
+ switch (sessionType) {
+ case SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
+ provider = &a2dp_software_provider_instance_;
+ break;
+ case SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH:
+ provider = &a2dp_offload_provider_instance_;
+ break;
+ case SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
+ provider = &hearing_aid_provider_instance_;
+ break;
+ case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
+ provider = &leaudio_output_provider_instance_;
+ break;
+ case SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH:
+ provider = &leaudio_input_provider_instance_;
+ break;
+ default:
+ status = BluetoothAudioStatus::FAILURE;
+ }
+ if (provider == nullptr || !provider->isValid(sessionType)) {
+ provider = nullptr;
+ status = BluetoothAudioStatus::FAILURE;
+ LOG(ERROR) << __func__ << " - SessionType=" << toString(sessionType)
+ << ", status=" << toString(status);
+ }
+ _hidl_cb(status, provider);
+ return Void();
+}
+
+Return<void> BluetoothAudioProvidersFactory::getProviderCapabilities(
+ const V2_0::SessionType sessionType, getProviderCapabilities_cb _hidl_cb) {
+ hidl_vec<V2_0::AudioCapabilities> audio_capabilities =
+ hidl_vec<V2_0::AudioCapabilities>(0);
+ if (sessionType == V2_0::SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
+ std::vector<CodecCapabilities> db_codec_capabilities =
+ android::bluetooth::audio::GetOffloadCodecCapabilities(sessionType);
+ if (db_codec_capabilities.size()) {
+ audio_capabilities.resize(db_codec_capabilities.size());
+ for (int i = 0; i < db_codec_capabilities.size(); ++i) {
+ audio_capabilities[i].codecCapabilities(db_codec_capabilities[i]);
+ }
+ }
+ } else if (sessionType != V2_0::SessionType::UNKNOWN) {
+ std::vector<::android::hardware::bluetooth::audio::V2_0::PcmParameters>
+ db_pcm_capabilities =
+ android::bluetooth::audio::GetSoftwarePcmCapabilities();
+ if (db_pcm_capabilities.size() == 1) {
+ audio_capabilities.resize(1);
+ audio_capabilities[0].pcmCapabilities(db_pcm_capabilities[0]);
+ }
+ }
+ LOG(INFO) << __func__ << " - SessionType=" << toString(sessionType)
+ << " supports " << audio_capabilities.size() << " codecs";
+ _hidl_cb(audio_capabilities);
+ return Void();
+}
+
+Return<void> BluetoothAudioProvidersFactory::getProviderCapabilities_2_1(
+ const SessionType sessionType, getProviderCapabilities_2_1_cb _hidl_cb) {
+ hidl_vec<AudioCapabilities> audio_capabilities =
+ hidl_vec<AudioCapabilities>(0);
+ if (sessionType == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
+ std::vector<CodecCapabilities> db_codec_capabilities =
+ android::bluetooth::audio::GetOffloadCodecCapabilities(sessionType);
+ if (db_codec_capabilities.size()) {
+ audio_capabilities.resize(db_codec_capabilities.size());
+ for (int i = 0; i < db_codec_capabilities.size(); ++i) {
+ audio_capabilities[i].codecCapabilities(db_codec_capabilities[i]);
+ }
+ }
+ } else if (sessionType != SessionType::UNKNOWN) {
+ std::vector<PcmParameters> db_pcm_capabilities =
+ android::bluetooth::audio::GetSoftwarePcmCapabilities_2_1();
+ if (db_pcm_capabilities.size() == 1) {
+ audio_capabilities.resize(1);
+ audio_capabilities[0].pcmCapabilities(db_pcm_capabilities[0]);
+ }
+ }
+ LOG(INFO) << __func__ << " - SessionType=" << toString(sessionType)
+ << " supports " << audio_capabilities.size() << " codecs";
+ _hidl_cb(audio_capabilities);
+ return Void();
+}
+
+IBluetoothAudioProvidersFactory* HIDL_FETCH_IBluetoothAudioProvidersFactory(
+ const char* /* name */) {
+ return new BluetoothAudioProvidersFactory();
+}
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.h b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.h
new file mode 100644
index 0000000..fd83694
--- /dev/null
+++ b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/bluetooth/audio/2.1/IBluetoothAudioProvidersFactory.h>
+
+#include "A2dpOffloadAudioProvider.h"
+#include "A2dpSoftwareAudioProvider.h"
+#include "BluetoothAudioProvider.h"
+#include "HearingAidAudioProvider.h"
+#include "LeAudioAudioProvider.h"
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+namespace V2_1 {
+namespace implementation {
+
+class BluetoothAudioProvidersFactory : public IBluetoothAudioProvidersFactory {
+ public:
+ BluetoothAudioProvidersFactory() {}
+
+ Return<void> openProvider(const V2_0::SessionType sessionType,
+ openProvider_cb _hidl_cb) override;
+
+ Return<void> getProviderCapabilities(
+ const V2_0::SessionType sessionType,
+ getProviderCapabilities_cb _hidl_cb) override;
+
+ Return<void> openProvider_2_1(const SessionType sessionType,
+ openProvider_2_1_cb _hidl_cb) override;
+
+ Return<void> getProviderCapabilities_2_1(
+ const SessionType sessionType,
+ getProviderCapabilities_2_1_cb _hidl_cb) override;
+
+ private:
+ static A2dpSoftwareAudioProvider a2dp_software_provider_instance_;
+ static A2dpOffloadAudioProvider a2dp_offload_provider_instance_;
+ static HearingAidAudioProvider hearing_aid_provider_instance_;
+ static LeAudioOutputAudioProvider leaudio_output_provider_instance_;
+ static LeAudioInputAudioProvider leaudio_input_provider_instance_;
+};
+
+extern "C" IBluetoothAudioProvidersFactory*
+HIDL_FETCH_IBluetoothAudioProvidersFactory(const char* name);
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/bluetooth/audio/2.1/default/HearingAidAudioProvider.cpp b/bluetooth/audio/2.1/default/HearingAidAudioProvider.cpp
new file mode 100644
index 0000000..aded7e1
--- /dev/null
+++ b/bluetooth/audio/2.1/default/HearingAidAudioProvider.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BTAudioProviderHearingAid"
+
+#include "HearingAidAudioProvider.h"
+
+#include <android-base/logging.h>
+
+#include "BluetoothAudioSessionReport.h"
+#include "BluetoothAudioSupportedCodecsDB.h"
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::bluetooth::audio::BluetoothAudioSessionReport;
+using ::android::hardware::Void;
+using ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
+
+static constexpr uint32_t kPcmFrameSize = 4; // 16 bits per sample / stereo
+static constexpr uint32_t kPcmFrameCount = 128;
+static constexpr uint32_t kRtpFrameSize = kPcmFrameSize * kPcmFrameCount;
+static constexpr uint32_t kRtpFrameCount = 7; // max counts by 1 tick (20ms)
+static constexpr uint32_t kBufferSize = kRtpFrameSize * kRtpFrameCount;
+static constexpr uint32_t kBufferCount = 1; // single buffer
+static constexpr uint32_t kDataMqSize = kBufferSize * kBufferCount;
+
+HearingAidAudioProvider::HearingAidAudioProvider()
+ : BluetoothAudioProvider(), mDataMQ(nullptr) {
+ LOG(INFO) << __func__ << " - size of audio buffer " << kDataMqSize
+ << " byte(s)";
+ std::unique_ptr<DataMQ> tempDataMQ(
+ new DataMQ(kDataMqSize, /* EventFlag */ true));
+ if (tempDataMQ && tempDataMQ->isValid()) {
+ mDataMQ = std::move(tempDataMQ);
+ session_type_ = SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH;
+ } else {
+ ALOGE_IF(!tempDataMQ, "failed to allocate data MQ");
+ ALOGE_IF(tempDataMQ && !tempDataMQ->isValid(), "data MQ is invalid");
+ }
+}
+
+bool HearingAidAudioProvider::isValid(const V2_0::SessionType& sessionType) {
+ return isValid(static_cast<SessionType>(sessionType));
+}
+
+bool HearingAidAudioProvider::isValid(const SessionType& sessionType) {
+ return (sessionType == session_type_ && mDataMQ && mDataMQ->isValid());
+}
+
+Return<void> HearingAidAudioProvider::startSession(
+ const sp<IBluetoothAudioPort>& hostIf,
+ const V2_0::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
+ /**
+ * Initialize the audio platform if audioConfiguration is supported.
+ * Save the IBluetoothAudioPort interface, so that it can be used
+ * later to send stream control commands to the HAL client, based on
+ * interaction with Audio framework.
+ */
+ if (audioConfig.getDiscriminator() !=
+ AudioConfiguration::hidl_discriminator::pcmConfig) {
+ LOG(WARNING) << __func__
+ << " - Invalid Audio Configuration=" << toString(audioConfig);
+ _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
+ DataMQ::Descriptor());
+ return Void();
+ } else if (!android::bluetooth::audio::IsSoftwarePcmConfigurationValid(
+ audioConfig.pcmConfig())) {
+ LOG(WARNING) << __func__ << " - Unsupported PCM Configuration="
+ << toString(audioConfig.pcmConfig());
+ _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
+ DataMQ::Descriptor());
+ return Void();
+ }
+
+ return BluetoothAudioProvider::startSession(hostIf, audioConfig, _hidl_cb);
+}
+
+Return<void> HearingAidAudioProvider::onSessionReady(startSession_cb _hidl_cb) {
+ if (mDataMQ && mDataMQ->isValid()) {
+ BluetoothAudioSessionReport::OnSessionStarted(
+ session_type_, stack_iface_, mDataMQ->getDesc(), audio_config_);
+ _hidl_cb(BluetoothAudioStatus::SUCCESS, *mDataMQ->getDesc());
+ } else {
+ _hidl_cb(BluetoothAudioStatus::FAILURE, DataMQ::Descriptor());
+ }
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/bluetooth/audio/2.1/default/HearingAidAudioProvider.h b/bluetooth/audio/2.1/default/HearingAidAudioProvider.h
new file mode 100644
index 0000000..c949257
--- /dev/null
+++ b/bluetooth/audio/2.1/default/HearingAidAudioProvider.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <fmq/MessageQueue.h>
+#include <hidl/MQDescriptor.h>
+
+#include "BluetoothAudioProvider.h"
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::hardware::kSynchronizedReadWrite;
+using ::android::hardware::MessageQueue;
+
+using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+
+class HearingAidAudioProvider : public BluetoothAudioProvider {
+ public:
+ HearingAidAudioProvider();
+
+ bool isValid(const SessionType& sessionType) override;
+ bool isValid(const V2_0::SessionType& sessionType) override;
+
+ Return<void> startSession(const sp<IBluetoothAudioPort>& hostIf,
+ const V2_0::AudioConfiguration& audioConfig,
+ startSession_cb _hidl_cb) override;
+
+ private:
+ // audio data queue for software encoding
+ std::unique_ptr<DataMQ> mDataMQ;
+
+ Return<void> onSessionReady(startSession_cb _hidl_cb) override;
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/bluetooth/audio/2.1/default/LeAudioAudioProvider.cpp b/bluetooth/audio/2.1/default/LeAudioAudioProvider.cpp
new file mode 100644
index 0000000..1fa2dce
--- /dev/null
+++ b/bluetooth/audio/2.1/default/LeAudioAudioProvider.cpp
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2020 HIMSA II K/S - www.himsa.com. Represented by EHIMA -
+ * www.ehima.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "BTAudioProviderLeAudio"
+
+#include "LeAudioAudioProvider.h"
+
+#include <android-base/logging.h>
+
+#include "BluetoothAudioSessionReport.h"
+#include "BluetoothAudioSupportedCodecsDB.h"
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::bluetooth::audio::BluetoothAudioSessionReport;
+using ::android::hardware::Void;
+using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
+using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
+using ::android::hardware::bluetooth::audio::V2_1::SampleRate;
+
+static constexpr uint32_t kBufferOutCount = 2; // two frame buffer
+static constexpr uint32_t kBufferInCount = 2; // two frame buffer
+
+LeAudioOutputAudioProvider::LeAudioOutputAudioProvider()
+ : LeAudioAudioProvider() {
+ session_type_ = SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH;
+}
+
+LeAudioInputAudioProvider::LeAudioInputAudioProvider()
+ : LeAudioAudioProvider() {
+ session_type_ = SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH;
+}
+
+LeAudioAudioProvider::LeAudioAudioProvider()
+ : BluetoothAudioProvider(), mDataMQ(nullptr) {}
+
+bool LeAudioAudioProvider::isValid(const V2_0::SessionType& sessionType) {
+ LOG(ERROR) << __func__ << ", invalid session type for Le Audio provider: "
+ << toString(sessionType);
+
+ return false;
+}
+
+bool LeAudioAudioProvider::isValid(const SessionType& sessionType) {
+ return (sessionType == session_type_);
+}
+
+Return<void> LeAudioAudioProvider::startSession_2_1(
+ const sp<V2_0::IBluetoothAudioPort>& hostIf,
+ const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
+ /**
+ * Initialize the audio platform if audioConfiguration is supported.
+ * Save the IBluetoothAudioPort interface, so that it can be used
+ * later to send stream control commands to the HAL client, based on
+ * interaction with Audio framework.
+ */
+ if (audioConfig.getDiscriminator() !=
+ AudioConfiguration::hidl_discriminator::pcmConfig) {
+ LOG(WARNING) << __func__
+ << " - Invalid Audio Configuration=" << toString(audioConfig);
+ _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
+ DataMQ::Descriptor());
+ return Void();
+ } else if (!android::bluetooth::audio::IsSoftwarePcmConfigurationValid_2_1(
+ audioConfig.pcmConfig())) {
+ LOG(WARNING) << __func__ << " - Unsupported PCM Configuration="
+ << toString(audioConfig.pcmConfig());
+ _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
+ DataMQ::Descriptor());
+ return Void();
+ }
+
+ uint32_t kDataMqSize = 0;
+ switch (audioConfig.pcmConfig().sampleRate) {
+ case SampleRate::RATE_16000:
+ kDataMqSize = 16000;
+ break;
+ case SampleRate::RATE_24000:
+ kDataMqSize = 24000;
+ break;
+ case SampleRate::RATE_44100:
+ kDataMqSize = 44100;
+ break;
+ case SampleRate::RATE_48000:
+ kDataMqSize = 48000;
+ break;
+ case SampleRate::RATE_88200:
+ kDataMqSize = 88200;
+ break;
+ case SampleRate::RATE_96000:
+ kDataMqSize = 96000;
+ break;
+ case SampleRate::RATE_176400:
+ kDataMqSize = 176400;
+ break;
+ case SampleRate::RATE_192000:
+ kDataMqSize = 192000;
+ break;
+ default:
+ /* This should never happen it would be caught while validating
+ * parameters.
+ */
+ break;
+ }
+
+ /* Number of samples per millisecond */
+ kDataMqSize = ceil(kDataMqSize / 1000);
+
+ switch (audioConfig.pcmConfig().channelMode) {
+ case ChannelMode::MONO:
+ break;
+ case ChannelMode::STEREO:
+ kDataMqSize *= 2;
+ break;
+ default:
+ /* This should never happen it would be caught while validating
+ * parameters.
+ */
+ break;
+ }
+
+ switch (audioConfig.pcmConfig().bitsPerSample) {
+ case BitsPerSample::BITS_16:
+ kDataMqSize *= 2;
+ break;
+ case BitsPerSample::BITS_24:
+ kDataMqSize *= 3;
+ break;
+ case BitsPerSample::BITS_32:
+ kDataMqSize *= 4;
+ break;
+ default:
+ /* This should never happen it would be caught while validating
+ * parameters.
+ */
+ break;
+ }
+
+ if (session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH)
+ kDataMqSize *= kBufferOutCount;
+ else if (session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH)
+ kDataMqSize *= kBufferInCount;
+ else
+ LOG(WARNING) << __func__ << ", default single buffer used";
+
+ kDataMqSize *= audioConfig.pcmConfig().dataIntervalUs / 1000;
+
+ LOG(INFO) << __func__ << " - size of audio buffer " << kDataMqSize
+ << " byte(s)";
+
+ std::unique_ptr<DataMQ> tempDataMQ(
+ new DataMQ(kDataMqSize, /* EventFlag */ true));
+ if (tempDataMQ && tempDataMQ->isValid()) {
+ mDataMQ = std::move(tempDataMQ);
+ } else {
+ ALOGE_IF(!tempDataMQ, "failed to allocate data MQ");
+ ALOGE_IF(tempDataMQ && !tempDataMQ->isValid(), "data MQ is invalid");
+ _hidl_cb(BluetoothAudioStatus::FAILURE, DataMQ::Descriptor());
+ return Void();
+ }
+
+ return BluetoothAudioProvider::startSession_2_1(hostIf, audioConfig,
+ _hidl_cb);
+}
+
+Return<void> LeAudioAudioProvider::onSessionReady(startSession_cb _hidl_cb) {
+ if (mDataMQ && mDataMQ->isValid()) {
+ BluetoothAudioSessionReport::OnSessionStarted(
+ session_type_, stack_iface_, mDataMQ->getDesc(), audio_config_);
+ _hidl_cb(BluetoothAudioStatus::SUCCESS, *mDataMQ->getDesc());
+ } else {
+ _hidl_cb(BluetoothAudioStatus::FAILURE, DataMQ::Descriptor());
+ }
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/bluetooth/audio/2.1/default/LeAudioAudioProvider.h b/bluetooth/audio/2.1/default/LeAudioAudioProvider.h
new file mode 100644
index 0000000..09b2b54
--- /dev/null
+++ b/bluetooth/audio/2.1/default/LeAudioAudioProvider.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2020 HIMSA II K/S - www.himsa.com. Represented by EHIMA -
+ * www.ehima.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <android/hardware/bluetooth/audio/2.1/types.h>
+#include <fmq/MessageQueue.h>
+#include <hidl/MQDescriptor.h>
+
+#include "BluetoothAudioProvider.h"
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::hardware::kSynchronizedReadWrite;
+using ::android::hardware::MessageQueue;
+
+using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+
+class LeAudioAudioProvider : public BluetoothAudioProvider {
+ public:
+ LeAudioAudioProvider();
+
+ bool isValid(const SessionType& sessionType) override;
+ bool isValid(const V2_0::SessionType& sessionType) override;
+
+ Return<void> startSession_2_1(const sp<V2_0::IBluetoothAudioPort>& hostIf,
+ const AudioConfiguration& audioConfig,
+ startSession_cb _hidl_cb) override;
+
+ private:
+ /** queue for software encodec/decoded audio data */
+ std::unique_ptr<DataMQ> mDataMQ;
+
+ Return<void> onSessionReady(startSession_cb _hidl_cb) override;
+};
+
+class LeAudioOutputAudioProvider : public LeAudioAudioProvider {
+ public:
+ LeAudioOutputAudioProvider();
+};
+
+class LeAudioInputAudioProvider : public LeAudioAudioProvider {
+ public:
+ LeAudioInputAudioProvider();
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/bluetooth/audio/2.1/default/session/BluetoothAudioSession.cpp b/bluetooth/audio/2.1/default/session/BluetoothAudioSession.cpp
new file mode 100644
index 0000000..ea2c54a
--- /dev/null
+++ b/bluetooth/audio/2.1/default/session/BluetoothAudioSession.cpp
@@ -0,0 +1,467 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BTAudioProviderSession"
+
+#include "BluetoothAudioSession.h"
+
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+
+namespace android {
+namespace bluetooth {
+namespace audio {
+
+using ::android::hardware::audio::common::V5_0::AudioContentType;
+using ::android::hardware::audio::common::V5_0::AudioUsage;
+using ::android::hardware::audio::common::V5_0::PlaybackTrackMetadata;
+using ::android::hardware::audio::common::V5_0::SourceMetadata;
+using ::android::hardware::bluetooth::audio::V2_0::CodecType;
+using ::android::hardware::bluetooth::audio::V2_0::TimeSpec;
+
+const CodecConfiguration BluetoothAudioSession::kInvalidCodecConfiguration = {
+ .codecType = CodecType::UNKNOWN,
+ .encodedAudioBitrate = 0x00000000,
+ .peerMtu = 0xffff,
+ .isScmstEnabled = false,
+ .config = {}};
+AudioConfiguration BluetoothAudioSession::invalidSoftwareAudioConfiguration =
+ {};
+AudioConfiguration BluetoothAudioSession::invalidOffloadAudioConfiguration = {};
+
+static constexpr int kFmqSendTimeoutMs = 1000; // 1000 ms timeout for sending
+static constexpr int kFmqReceiveTimeoutMs =
+ 1000; // 1000 ms timeout for receiving
+static constexpr int kWritePollMs = 1; // polled non-blocking interval
+static constexpr int kReadPollMs = 1; // polled non-blocking interval
+
+static inline timespec timespec_convert_from_hal(const TimeSpec& TS) {
+ return {.tv_sec = static_cast<long>(TS.tvSec),
+ .tv_nsec = static_cast<long>(TS.tvNSec)};
+}
+
+BluetoothAudioSession::BluetoothAudioSession(const SessionType& session_type)
+ : session_type_(session_type), stack_iface_(nullptr), mDataMQ(nullptr) {
+ invalidSoftwareAudioConfiguration.pcmConfig(kInvalidPcmParameters);
+ invalidOffloadAudioConfiguration.codecConfig(kInvalidCodecConfiguration);
+}
+
+// The report function is used to report that the Bluetooth stack has started
+// this session without any failure, and will invoke session_changed_cb_ to
+// notify those registered bluetooth_audio outputs
+void BluetoothAudioSession::OnSessionStarted(
+ const sp<IBluetoothAudioPort> stack_iface, const DataMQ::Descriptor* dataMQ,
+ const AudioConfiguration& audio_config) {
+ std::lock_guard<std::recursive_mutex> guard(mutex_);
+ if (stack_iface == nullptr) {
+ LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
+ << ", IBluetoothAudioPort Invalid";
+ } else if (!UpdateAudioConfig(audio_config)) {
+ LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
+ << ", AudioConfiguration=" << toString(audio_config)
+ << " Invalid";
+ } else if (!UpdateDataPath(dataMQ)) {
+ LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
+ << " DataMQ Invalid";
+ audio_config_ =
+ (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH
+ ? kInvalidOffloadAudioConfiguration
+ : kInvalidSoftwareAudioConfiguration);
+ } else {
+ stack_iface_ = stack_iface;
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+ << ", AudioConfiguration=" << toString(audio_config);
+ ReportSessionStatus();
+ }
+}
+
+// The report function is used to report that the Bluetooth stack has ended the
+// session, and will invoke session_changed_cb_ to notify registered
+// bluetooth_audio outputs
+void BluetoothAudioSession::OnSessionEnded() {
+ std::lock_guard<std::recursive_mutex> guard(mutex_);
+ bool toggled = IsSessionReady();
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
+ audio_config_ = (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH
+ ? kInvalidOffloadAudioConfiguration
+ : kInvalidSoftwareAudioConfiguration);
+ stack_iface_ = nullptr;
+ UpdateDataPath(nullptr);
+ if (toggled) {
+ ReportSessionStatus();
+ }
+}
+
+// invoking the registered session_changed_cb_
+void BluetoothAudioSession::ReportSessionStatus() {
+ // This is locked already by OnSessionStarted / OnSessionEnded
+ if (observers_.empty()) {
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+ << " has NO port state observer";
+ return;
+ }
+ for (auto& observer : observers_) {
+ uint16_t cookie = observer.first;
+ std::shared_ptr<struct PortStatusCallbacks> cb = observer.second;
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+ << " notify to bluetooth_audio=0x"
+ << android::base::StringPrintf("%04x", cookie);
+ cb->session_changed_cb_(cookie);
+ }
+}
+
+// The report function is used to report that the Bluetooth stack has notified
+// the result of startStream or suspendStream, and will invoke
+// control_result_cb_ to notify registered bluetooth_audio outputs
+void BluetoothAudioSession::ReportControlStatus(
+ bool start_resp, const BluetoothAudioStatus& status) {
+ std::lock_guard<std::recursive_mutex> guard(mutex_);
+ if (observers_.empty()) {
+ LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
+ << " has NO port state observer";
+ return;
+ }
+ for (auto& observer : observers_) {
+ uint16_t cookie = observer.first;
+ std::shared_ptr<struct PortStatusCallbacks> cb = observer.second;
+ LOG(INFO) << __func__ << " - status=" << toString(status)
+ << " for SessionType=" << toString(session_type_)
+ << ", bluetooth_audio=0x"
+ << android::base::StringPrintf("%04x", cookie)
+ << (start_resp ? " started" : " suspended");
+ cb->control_result_cb_(cookie, start_resp, status);
+ }
+}
+
+// The function helps to check if this session is ready or not
+// @return: true if the Bluetooth stack has started the specified session
+bool BluetoothAudioSession::IsSessionReady() {
+ std::lock_guard<std::recursive_mutex> guard(mutex_);
+ bool dataMQ_valid =
+ (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH ||
+ (mDataMQ != nullptr && mDataMQ->isValid()));
+ return stack_iface_ != nullptr && dataMQ_valid;
+}
+
+bool BluetoothAudioSession::UpdateDataPath(const DataMQ::Descriptor* dataMQ) {
+ if (dataMQ == nullptr) {
+ // usecase of reset by nullptr
+ mDataMQ = nullptr;
+ return true;
+ }
+ std::unique_ptr<DataMQ> tempDataMQ;
+ tempDataMQ.reset(new DataMQ(*dataMQ));
+ if (!tempDataMQ || !tempDataMQ->isValid()) {
+ mDataMQ = nullptr;
+ return false;
+ }
+ mDataMQ = std::move(tempDataMQ);
+ return true;
+}
+
+bool BluetoothAudioSession::UpdateAudioConfig(
+ const AudioConfiguration& audio_config) {
+ bool is_software_session =
+ (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
+ session_type_ == SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH ||
+ session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
+ session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH);
+ bool is_offload_session =
+ (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
+ auto audio_config_discriminator = audio_config.getDiscriminator();
+ bool is_software_audio_config =
+ (is_software_session &&
+ audio_config_discriminator ==
+ AudioConfiguration::hidl_discriminator::pcmConfig);
+ bool is_offload_audio_config =
+ (is_offload_session &&
+ audio_config_discriminator ==
+ AudioConfiguration::hidl_discriminator::codecConfig);
+ if (!is_software_audio_config && !is_offload_audio_config) {
+ return false;
+ }
+ audio_config_ = audio_config;
+ return true;
+}
+
+// The control function helps the bluetooth_audio module to register
+// PortStatusCallbacks
+// @return: cookie - the assigned number to this bluetooth_audio output
+uint16_t BluetoothAudioSession::RegisterStatusCback(
+ const PortStatusCallbacks& cbacks) {
+ std::lock_guard<std::recursive_mutex> guard(mutex_);
+ uint16_t cookie = ObserversCookieGetInitValue(session_type_);
+ uint16_t cookie_upper_bound = ObserversCookieGetUpperBound(session_type_);
+
+ while (cookie < cookie_upper_bound) {
+ if (observers_.find(cookie) == observers_.end()) {
+ break;
+ }
+ ++cookie;
+ }
+ if (cookie >= cookie_upper_bound) {
+ LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
+ << " has " << observers_.size()
+ << " observers already (No Resource)";
+ return kObserversCookieUndefined;
+ }
+ std::shared_ptr<struct PortStatusCallbacks> cb =
+ std::make_shared<struct PortStatusCallbacks>();
+ *cb = cbacks;
+ observers_[cookie] = cb;
+ return cookie;
+}
+
+// The control function helps the bluetooth_audio module to unregister
+// PortStatusCallbacks
+// @param: cookie - indicates which bluetooth_audio output is
+void BluetoothAudioSession::UnregisterStatusCback(uint16_t cookie) {
+ std::lock_guard<std::recursive_mutex> guard(mutex_);
+ if (observers_.erase(cookie) != 1) {
+ LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
+ << " no such provider=0x"
+ << android::base::StringPrintf("%04x", cookie);
+ }
+}
+
+// The control function is for the bluetooth_audio module to get the current
+// AudioConfiguration
+const AudioConfiguration& BluetoothAudioSession::GetAudioConfig() {
+ std::lock_guard<std::recursive_mutex> guard(mutex_);
+ if (IsSessionReady()) {
+ return audio_config_;
+ } else if (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
+ return kInvalidOffloadAudioConfiguration;
+ } else {
+ return kInvalidSoftwareAudioConfiguration;
+ }
+}
+
+// Those control functions are for the bluetooth_audio module to start, suspend,
+// stop stream, to check position, and to update metadata.
+bool BluetoothAudioSession::StartStream() {
+ std::lock_guard<std::recursive_mutex> guard(mutex_);
+ if (!IsSessionReady()) {
+ LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
+ << " has NO session";
+ return false;
+ }
+ auto hal_retval = stack_iface_->startStream();
+ if (!hal_retval.isOk()) {
+ LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
+ << toString(session_type_) << " failed";
+ return false;
+ }
+ return true;
+}
+
+bool BluetoothAudioSession::SuspendStream() {
+ std::lock_guard<std::recursive_mutex> guard(mutex_);
+ if (!IsSessionReady()) {
+ LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
+ << " has NO session";
+ return false;
+ }
+ auto hal_retval = stack_iface_->suspendStream();
+ if (!hal_retval.isOk()) {
+ LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
+ << toString(session_type_) << " failed";
+ return false;
+ }
+ return true;
+}
+
+void BluetoothAudioSession::StopStream() {
+ std::lock_guard<std::recursive_mutex> guard(mutex_);
+ if (!IsSessionReady()) {
+ return;
+ }
+ auto hal_retval = stack_iface_->stopStream();
+ if (!hal_retval.isOk()) {
+ LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
+ << toString(session_type_) << " failed";
+ }
+}
+
+bool BluetoothAudioSession::GetPresentationPosition(
+ uint64_t* remote_delay_report_ns, uint64_t* total_bytes_readed,
+ timespec* data_position) {
+ std::lock_guard<std::recursive_mutex> guard(mutex_);
+ if (!IsSessionReady()) {
+ LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
+ << " has NO session";
+ return false;
+ }
+ bool retval = false;
+ auto hal_retval = stack_iface_->getPresentationPosition(
+ [&retval, &remote_delay_report_ns, &total_bytes_readed, &data_position](
+ BluetoothAudioStatus status,
+ const uint64_t& remoteDeviceAudioDelayNanos,
+ uint64_t transmittedOctets,
+ const TimeSpec& transmittedOctetsTimeStamp) {
+ if (status == BluetoothAudioStatus::SUCCESS) {
+ if (remote_delay_report_ns)
+ *remote_delay_report_ns = remoteDeviceAudioDelayNanos;
+ if (total_bytes_readed) *total_bytes_readed = transmittedOctets;
+ if (data_position)
+ *data_position =
+ timespec_convert_from_hal(transmittedOctetsTimeStamp);
+ retval = true;
+ }
+ });
+ if (!hal_retval.isOk()) {
+ LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
+ << toString(session_type_) << " failed";
+ return false;
+ }
+ return retval;
+}
+
+void BluetoothAudioSession::UpdateTracksMetadata(
+ const struct source_metadata* source_metadata) {
+ std::lock_guard<std::recursive_mutex> guard(mutex_);
+ if (!IsSessionReady()) {
+ LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
+ << " has NO session";
+ return;
+ }
+
+ ssize_t track_count = source_metadata->track_count;
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << ", "
+ << track_count << " track(s)";
+ if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
+ session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
+ return;
+ }
+
+ struct playback_track_metadata* track = source_metadata->tracks;
+ SourceMetadata sourceMetadata;
+ PlaybackTrackMetadata* halMetadata;
+
+ sourceMetadata.tracks.resize(track_count);
+ halMetadata = sourceMetadata.tracks.data();
+ while (track_count && track) {
+ halMetadata->usage = static_cast<AudioUsage>(track->usage);
+ halMetadata->contentType =
+ static_cast<AudioContentType>(track->content_type);
+ halMetadata->gain = track->gain;
+ LOG(VERBOSE) << __func__ << " - SessionType=" << toString(session_type_)
+ << ", usage=" << toString(halMetadata->usage)
+ << ", content=" << toString(halMetadata->contentType)
+ << ", gain=" << halMetadata->gain;
+ --track_count;
+ ++track;
+ ++halMetadata;
+ }
+ auto hal_retval = stack_iface_->updateMetadata(sourceMetadata);
+ if (!hal_retval.isOk()) {
+ LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
+ << toString(session_type_) << " failed";
+ }
+}
+
+// The control function writes stream to FMQ
+size_t BluetoothAudioSession::OutWritePcmData(const void* buffer,
+ size_t bytes) {
+ if (buffer == nullptr || !bytes) return 0;
+ size_t totalWritten = 0;
+ int ms_timeout = kFmqSendTimeoutMs;
+ do {
+ std::unique_lock<std::recursive_mutex> lock(mutex_);
+ if (!IsSessionReady()) break;
+ size_t availableToWrite = mDataMQ->availableToWrite();
+ if (availableToWrite) {
+ if (availableToWrite > (bytes - totalWritten)) {
+ availableToWrite = bytes - totalWritten;
+ }
+
+ if (!mDataMQ->write(static_cast<const uint8_t*>(buffer) + totalWritten,
+ availableToWrite)) {
+ ALOGE("FMQ datapath writing %zu/%zu failed", totalWritten, bytes);
+ return totalWritten;
+ }
+ totalWritten += availableToWrite;
+ } else if (ms_timeout >= kWritePollMs) {
+ lock.unlock();
+ usleep(kWritePollMs * 1000);
+ ms_timeout -= kWritePollMs;
+ } else {
+ ALOGD("out data %zu/%zu overflow %d ms", totalWritten, bytes,
+ (kFmqSendTimeoutMs - ms_timeout));
+ return totalWritten;
+ }
+ } while (totalWritten < bytes);
+ return totalWritten;
+}
+
+// The control function reads stream from FMQ
+size_t BluetoothAudioSession::InReadPcmData(void* buffer, size_t bytes) {
+ if (buffer == nullptr || !bytes) return 0;
+ size_t totalRead = 0;
+ int ms_timeout = kFmqReceiveTimeoutMs;
+ do {
+ std::unique_lock<std::recursive_mutex> lock(mutex_);
+ if (!IsSessionReady()) break;
+ size_t availableToRead = mDataMQ->availableToRead();
+ if (availableToRead) {
+ if (availableToRead > (bytes - totalRead)) {
+ availableToRead = bytes - totalRead;
+ }
+ if (!mDataMQ->read(static_cast<uint8_t*>(buffer) + totalRead,
+ availableToRead)) {
+ ALOGE("FMQ datapath reading %zu/%zu failed", totalRead, bytes);
+ return totalRead;
+ }
+ totalRead += availableToRead;
+ } else if (ms_timeout >= kReadPollMs) {
+ lock.unlock();
+ usleep(kReadPollMs * 1000);
+ ms_timeout -= kReadPollMs;
+ continue;
+ } else {
+ ALOGD("in data %zu/%zu overflow %d ms", totalRead, bytes,
+ (kFmqReceiveTimeoutMs - ms_timeout));
+ return totalRead;
+ }
+ } while (totalRead < bytes);
+ return totalRead;
+}
+
+std::unique_ptr<BluetoothAudioSessionInstance>
+ BluetoothAudioSessionInstance::instance_ptr =
+ std::unique_ptr<BluetoothAudioSessionInstance>(
+ new BluetoothAudioSessionInstance());
+
+// API to fetch the session
+std::shared_ptr<BluetoothAudioSession>
+BluetoothAudioSessionInstance::GetSessionInstance(
+ const SessionType& session_type) {
+ std::lock_guard<std::mutex> guard(instance_ptr->mutex_);
+ if (!instance_ptr->sessions_map_.empty()) {
+ auto entry = instance_ptr->sessions_map_.find(session_type);
+ if (entry != instance_ptr->sessions_map_.end()) {
+ return entry->second;
+ }
+ }
+ std::shared_ptr<BluetoothAudioSession> session_ptr =
+ std::make_shared<BluetoothAudioSession>(session_type);
+ instance_ptr->sessions_map_[session_type] = session_ptr;
+ return session_ptr;
+}
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace android
diff --git a/bluetooth/audio/2.1/default/session/BluetoothAudioSession.h b/bluetooth/audio/2.1/default/session/BluetoothAudioSession.h
new file mode 100644
index 0000000..7bc12e6
--- /dev/null
+++ b/bluetooth/audio/2.1/default/session/BluetoothAudioSession.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <mutex>
+#include <unordered_map>
+
+#include <android/hardware/bluetooth/audio/2.0/IBluetoothAudioPort.h>
+#include <android/hardware/bluetooth/audio/2.1/types.h>
+#include <fmq/MessageQueue.h>
+#include <hardware/audio.h>
+#include <hidl/MQDescriptor.h>
+
+namespace android {
+namespace bluetooth {
+namespace audio {
+
+using ::android::sp;
+using ::android::hardware::kSynchronizedReadWrite;
+using ::android::hardware::MessageQueue;
+using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
+using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
+using ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration;
+using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioPort;
+using ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration;
+using ::android::hardware::bluetooth::audio::V2_1::PcmParameters;
+using ::android::hardware::bluetooth::audio::V2_1::SampleRate;
+using ::android::hardware::bluetooth::audio::V2_1::SessionType;
+
+using BluetoothAudioStatus =
+ ::android::hardware::bluetooth::audio::V2_0::Status;
+
+using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+
+static constexpr uint16_t kObserversCookieSize = 0x0010; // 0x0000 ~ 0x000f
+constexpr uint16_t kObserversCookieUndefined =
+ (static_cast<uint16_t>(SessionType::UNKNOWN) << 8 & 0xff00);
+inline SessionType ObserversCookieGetSessionType(uint16_t cookie) {
+ return static_cast<SessionType>(cookie >> 8 & 0x00ff);
+}
+inline uint16_t ObserversCookieGetInitValue(SessionType session_type) {
+ return (static_cast<uint16_t>(session_type) << 8 & 0xff00);
+}
+inline uint16_t ObserversCookieGetUpperBound(SessionType session_type) {
+ return (static_cast<uint16_t>(session_type) << 8 & 0xff00) +
+ kObserversCookieSize;
+}
+
+// This presents the callbacks of started / suspended and session changed,
+// and the bluetooth_audio module uses to receive the status notification
+struct PortStatusCallbacks {
+ // control_result_cb_ - when the Bluetooth stack reports results of
+ // streamStarted or streamSuspended, the BluetoothAudioProvider will invoke
+ // this callback to report to the bluetooth_audio module.
+ // @param: cookie - indicates which bluetooth_audio output should handle
+ // @param: start_resp - this report is for startStream or not
+ // @param: status - the result of startStream
+ std::function<void(uint16_t cookie, bool start_resp,
+ const BluetoothAudioStatus& status)>
+ control_result_cb_;
+ // session_changed_cb_ - when the Bluetooth stack start / end session, the
+ // BluetoothAudioProvider will invoke this callback to notify to the
+ // bluetooth_audio module.
+ // @param: cookie - indicates which bluetooth_audio output should handle
+ std::function<void(uint16_t cookie)> session_changed_cb_;
+};
+
+class BluetoothAudioSession {
+ private:
+ // using recursive_mutex to allow hwbinder to re-enter again.
+ std::recursive_mutex mutex_;
+ SessionType session_type_;
+
+ // audio control path to use for both software and offloading
+ sp<IBluetoothAudioPort> stack_iface_;
+ // Audio path (FMQ) for software encoding/decoded data
+ std::unique_ptr<DataMQ> mDataMQ;
+ // audio data configuration for both software and offloading
+ AudioConfiguration audio_config_;
+
+ static AudioConfiguration invalidSoftwareAudioConfiguration;
+ static AudioConfiguration invalidOffloadAudioConfiguration;
+
+ // saving those registered bluetooth_audio's callbacks
+ std::unordered_map<uint16_t, std::shared_ptr<struct PortStatusCallbacks>>
+ observers_;
+
+ bool UpdateDataPath(const DataMQ::Descriptor* dataMQ);
+ bool UpdateAudioConfig(const AudioConfiguration& audio_config);
+ // invoking the registered session_changed_cb_
+ void ReportSessionStatus();
+
+ public:
+ BluetoothAudioSession(const SessionType& session_type);
+
+ // The function helps to check if this session is ready or not
+ // @return: true if the Bluetooth stack has started the specified session
+ bool IsSessionReady();
+
+ // The report function is used to report that the Bluetooth stack has started
+ // this session without any failure, and will invoke session_changed_cb_ to
+ // notify those registered bluetooth_audio outputs
+ void OnSessionStarted(const sp<IBluetoothAudioPort> stack_iface,
+ const DataMQ::Descriptor* dataMQ,
+ const AudioConfiguration& audio_config);
+
+ // The report function is used to report that the Bluetooth stack has ended
+ // the session, and will invoke session_changed_cb_ to notify registered
+ // bluetooth_audio outputs
+ void OnSessionEnded();
+
+ // The report function is used to report that the Bluetooth stack has notified
+ // the result of startStream or suspendStream, and will invoke
+ // control_result_cb_ to notify registered bluetooth_audio outputs
+ void ReportControlStatus(bool start_resp, const BluetoothAudioStatus& status);
+
+ // The control function helps the bluetooth_audio module to register
+ // PortStatusCallbacks
+ // @return: cookie - the assigned number to this bluetooth_audio output
+ uint16_t RegisterStatusCback(const PortStatusCallbacks& cbacks);
+
+ // The control function helps the bluetooth_audio module to unregister
+ // PortStatusCallbacks
+ // @param: cookie - indicates which bluetooth_audio output is
+ void UnregisterStatusCback(uint16_t cookie);
+
+ // The control function is for the bluetooth_audio module to get the current
+ // AudioConfiguration
+ const AudioConfiguration& GetAudioConfig();
+
+ // Those control functions are for the bluetooth_audio module to start,
+ // suspend, stop stream, to check position, and to update metadata.
+ bool StartStream();
+ bool SuspendStream();
+ void StopStream();
+ bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
+ uint64_t* total_bytes_readed,
+ timespec* data_position);
+ void UpdateTracksMetadata(const struct source_metadata* source_metadata);
+
+ // The control function writes stream to FMQ
+ size_t OutWritePcmData(const void* buffer, size_t bytes);
+ // The control function read stream from FMQ
+ size_t InReadPcmData(void* buffer, size_t bytes);
+
+ static constexpr PcmParameters kInvalidPcmParameters = {
+ .sampleRate = SampleRate::RATE_UNKNOWN,
+ .channelMode = ChannelMode::UNKNOWN,
+ .bitsPerSample = BitsPerSample::BITS_UNKNOWN,
+ .dataIntervalUs = 0,
+ };
+ // can't be constexpr because of non-literal type
+ static const CodecConfiguration kInvalidCodecConfiguration;
+
+ static constexpr AudioConfiguration& kInvalidSoftwareAudioConfiguration =
+ invalidSoftwareAudioConfiguration;
+ static constexpr AudioConfiguration& kInvalidOffloadAudioConfiguration =
+ invalidOffloadAudioConfiguration;
+};
+
+class BluetoothAudioSessionInstance {
+ public:
+ // The API is to fetch the specified session
+ static std::shared_ptr<BluetoothAudioSession> GetSessionInstance(
+ const SessionType& session_type);
+
+ private:
+ static std::unique_ptr<BluetoothAudioSessionInstance> instance_ptr;
+ std::mutex mutex_;
+ std::unordered_map<SessionType, std::shared_ptr<BluetoothAudioSession>>
+ sessions_map_;
+};
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace android
diff --git a/bluetooth/audio/2.1/default/session/BluetoothAudioSessionControl.h b/bluetooth/audio/2.1/default/session/BluetoothAudioSessionControl.h
new file mode 100644
index 0000000..017a611
--- /dev/null
+++ b/bluetooth/audio/2.1/default/session/BluetoothAudioSessionControl.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "BluetoothAudioSession.h"
+
+namespace android {
+namespace bluetooth {
+namespace audio {
+
+class BluetoothAudioSessionControl {
+ public:
+ // The control API helps to check if session is ready or not
+ // @return: true if the Bluetooth stack has started th specified session
+ static bool IsSessionReady(const SessionType& session_type) {
+ std::shared_ptr<BluetoothAudioSession> session_ptr =
+ BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ return session_ptr->IsSessionReady();
+ }
+ return false;
+ }
+
+ // The control API helps the bluetooth_audio module to register
+ // PortStatusCallbacks
+ // @return: cookie - the assigned number to this bluetooth_audio output
+ static uint16_t RegisterControlResultCback(
+ const SessionType& session_type, const PortStatusCallbacks& cbacks) {
+ std::shared_ptr<BluetoothAudioSession> session_ptr =
+ BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ return session_ptr->RegisterStatusCback(cbacks);
+ }
+ return kObserversCookieUndefined;
+ }
+
+ // The control API helps the bluetooth_audio module to unregister
+ // PortStatusCallbacks
+ // @param: cookie - indicates which bluetooth_audio output is
+ static void UnregisterControlResultCback(const SessionType& session_type,
+ uint16_t cookie) {
+ std::shared_ptr<BluetoothAudioSession> session_ptr =
+ BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ session_ptr->UnregisterStatusCback(cookie);
+ }
+ }
+
+ // The control API for the bluetooth_audio module to get current
+ // AudioConfiguration
+ static const AudioConfiguration& GetAudioConfig(
+ const SessionType& session_type) {
+ std::shared_ptr<BluetoothAudioSession> session_ptr =
+ BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ return session_ptr->GetAudioConfig();
+ } else if (session_type == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
+ return BluetoothAudioSession::kInvalidOffloadAudioConfiguration;
+ } else {
+ return BluetoothAudioSession::kInvalidSoftwareAudioConfiguration;
+ }
+ }
+
+ // Those control APIs for the bluetooth_audio module to start / suspend / stop
+ // stream, to check position, and to update metadata.
+ static bool StartStream(const SessionType& session_type) {
+ std::shared_ptr<BluetoothAudioSession> session_ptr =
+ BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ return session_ptr->StartStream();
+ }
+ return false;
+ }
+
+ static bool SuspendStream(const SessionType& session_type) {
+ std::shared_ptr<BluetoothAudioSession> session_ptr =
+ BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ return session_ptr->SuspendStream();
+ }
+ return false;
+ }
+
+ static void StopStream(const SessionType& session_type) {
+ std::shared_ptr<BluetoothAudioSession> session_ptr =
+ BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ session_ptr->StopStream();
+ }
+ }
+
+ static bool GetPresentationPosition(const SessionType& session_type,
+ uint64_t* remote_delay_report_ns,
+ uint64_t* total_bytes_readed,
+ timespec* data_position) {
+ std::shared_ptr<BluetoothAudioSession> session_ptr =
+ BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ return session_ptr->GetPresentationPosition(
+ remote_delay_report_ns, total_bytes_readed, data_position);
+ }
+ return false;
+ }
+
+ static void UpdateTracksMetadata(
+ const SessionType& session_type,
+ const struct source_metadata* source_metadata) {
+ std::shared_ptr<BluetoothAudioSession> session_ptr =
+ BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ session_ptr->UpdateTracksMetadata(source_metadata);
+ }
+ }
+
+ // The control API writes stream to FMQ
+ static size_t OutWritePcmData(const SessionType& session_type,
+ const void* buffer, size_t bytes) {
+ std::shared_ptr<BluetoothAudioSession> session_ptr =
+ BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ return session_ptr->OutWritePcmData(buffer, bytes);
+ }
+ return 0;
+ }
+
+ // The control API reads stream from FMQ
+ static size_t InReadPcmData(const SessionType& session_type, void* buffer,
+ size_t bytes) {
+ std::shared_ptr<BluetoothAudioSession> session_ptr =
+ BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ return session_ptr->InReadPcmData(buffer, bytes);
+ }
+ return 0;
+ }
+};
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace android
diff --git a/bluetooth/audio/2.1/default/session/BluetoothAudioSessionReport.h b/bluetooth/audio/2.1/default/session/BluetoothAudioSessionReport.h
new file mode 100644
index 0000000..267bf8f
--- /dev/null
+++ b/bluetooth/audio/2.1/default/session/BluetoothAudioSessionReport.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "BluetoothAudioSession.h"
+
+namespace android {
+namespace bluetooth {
+namespace audio {
+
+class BluetoothAudioSessionReport {
+ public:
+ // The API reports the Bluetooth stack has started the session, and will
+ // inform registered bluetooth_audio session
+ static void OnSessionStarted(const SessionType& session_type,
+ const sp<IBluetoothAudioPort> host_iface,
+ const DataMQ::Descriptor* dataMQ,
+ const AudioConfiguration& audio_config) {
+ std::shared_ptr<BluetoothAudioSession> session_ptr =
+ BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ session_ptr->OnSessionStarted(host_iface, dataMQ, audio_config);
+ }
+ }
+ // The API reports the Bluetooth stack has ended the session, and will
+ // inform registered bluetooth_audio outputs
+ static void OnSessionEnded(const SessionType& session_type) {
+ std::shared_ptr<BluetoothAudioSession> session_ptr =
+ BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ session_ptr->OnSessionEnded();
+ }
+ }
+ // The API reports the Bluetooth stack has replied the result of startStream
+ // or suspendStream, and will inform registered bluetooth_audio outputs
+ static void ReportControlStatus(const SessionType& session_type,
+ const bool& start_resp,
+ const BluetoothAudioStatus& status) {
+ std::shared_ptr<BluetoothAudioSession> session_ptr =
+ BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ session_ptr->ReportControlStatus(start_resp, status);
+ }
+ }
+};
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace android
diff --git a/bluetooth/audio/2.1/default/session/BluetoothAudioSupportedCodecsDB.cpp b/bluetooth/audio/2.1/default/session/BluetoothAudioSupportedCodecsDB.cpp
new file mode 100644
index 0000000..d15db49
--- /dev/null
+++ b/bluetooth/audio/2.1/default/session/BluetoothAudioSupportedCodecsDB.cpp
@@ -0,0 +1,487 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BTAudioProviderSessionCodecsDB"
+
+#include "BluetoothAudioSupportedCodecsDB.h"
+
+#include <android-base/logging.h>
+
+namespace android {
+namespace bluetooth {
+namespace audio {
+
+using ::android::hardware::bluetooth::audio::V2_0::AacObjectType;
+using ::android::hardware::bluetooth::audio::V2_0::AacParameters;
+using ::android::hardware::bluetooth::audio::V2_0::AacVariableBitRate;
+using ::android::hardware::bluetooth::audio::V2_0::AptxParameters;
+using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
+using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
+using ::android::hardware::bluetooth::audio::V2_0::CodecType;
+using ::android::hardware::bluetooth::audio::V2_0::LdacChannelMode;
+using ::android::hardware::bluetooth::audio::V2_0::LdacParameters;
+using ::android::hardware::bluetooth::audio::V2_0::LdacQualityIndex;
+using ::android::hardware::bluetooth::audio::V2_0::SbcAllocMethod;
+using ::android::hardware::bluetooth::audio::V2_0::SbcBlockLength;
+using ::android::hardware::bluetooth::audio::V2_0::SbcChannelMode;
+using ::android::hardware::bluetooth::audio::V2_0::SbcNumSubbands;
+using ::android::hardware::bluetooth::audio::V2_0::SbcParameters;
+using ::android::hardware::bluetooth::audio::V2_1::SampleRate;
+
+// Default Supported PCM Parameters
+static const ::android::hardware::bluetooth::audio::V2_0::PcmParameters
+ kDefaultSoftwarePcmCapabilities = {
+ .sampleRate = static_cast<
+ android::hardware::bluetooth::audio::V2_0::SampleRate>(
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_44100 |
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_48000 |
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_88200 |
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_96000 |
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_16000),
+ .channelMode =
+ static_cast<ChannelMode>(ChannelMode::MONO | ChannelMode::STEREO),
+ .bitsPerSample = static_cast<BitsPerSample>(BitsPerSample::BITS_16 |
+ BitsPerSample::BITS_24 |
+ BitsPerSample::BITS_32)};
+
+static const PcmParameters kDefaultSoftwarePcmCapabilities_2_1 = {
+ .sampleRate = static_cast<SampleRate>(
+ SampleRate::RATE_48000 | SampleRate::RATE_44100 |
+ SampleRate::RATE_32000 | SampleRate::RATE_24000 |
+ SampleRate::RATE_16000 | SampleRate::RATE_8000),
+ .channelMode =
+ static_cast<ChannelMode>(ChannelMode::MONO | ChannelMode::STEREO),
+ .bitsPerSample = static_cast<BitsPerSample>(BitsPerSample::BITS_16)};
+
+// Default Supported Codecs
+// SBC: mSampleRate:(44100), mBitsPerSample:(16), mChannelMode:(MONO|STEREO)
+// all blocks | subbands 8 | Loudness
+static const SbcParameters kDefaultOffloadSbcCapability = {
+ .sampleRate =
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_44100,
+ .channelMode = static_cast<SbcChannelMode>(SbcChannelMode::MONO |
+ SbcChannelMode::JOINT_STEREO),
+ .blockLength = static_cast<SbcBlockLength>(
+ SbcBlockLength::BLOCKS_4 | SbcBlockLength::BLOCKS_8 |
+ SbcBlockLength::BLOCKS_12 | SbcBlockLength::BLOCKS_16),
+ .numSubbands = SbcNumSubbands::SUBBAND_8,
+ .allocMethod = SbcAllocMethod::ALLOC_MD_L,
+ .bitsPerSample = BitsPerSample::BITS_16,
+ .minBitpool = 2,
+ .maxBitpool = 53};
+
+// AAC: mSampleRate:(44100), mBitsPerSample:(16), mChannelMode:(STEREO)
+static const AacParameters kDefaultOffloadAacCapability = {
+ .objectType = AacObjectType::MPEG2_LC,
+ .sampleRate =
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_44100,
+ .channelMode = ChannelMode::STEREO,
+ .variableBitRateEnabled = AacVariableBitRate::ENABLED,
+ .bitsPerSample = BitsPerSample::BITS_16};
+
+// LDAC: mSampleRate:(44100|48000|88200|96000), mBitsPerSample:(16|24|32),
+// mChannelMode:(DUAL|STEREO)
+static const LdacParameters kDefaultOffloadLdacCapability = {
+ .sampleRate =
+ static_cast<android::hardware::bluetooth::audio::V2_0::SampleRate>(
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_44100 |
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_48000 |
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_88200 |
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_96000),
+ .channelMode = static_cast<LdacChannelMode>(LdacChannelMode::DUAL |
+ LdacChannelMode::STEREO),
+ .qualityIndex = LdacQualityIndex::QUALITY_HIGH,
+ .bitsPerSample = static_cast<BitsPerSample>(BitsPerSample::BITS_16 |
+ BitsPerSample::BITS_24 |
+ BitsPerSample::BITS_32)};
+
+// aptX: mSampleRate:(44100|48000), mBitsPerSample:(16), mChannelMode:(STEREO)
+static const AptxParameters kDefaultOffloadAptxCapability = {
+ .sampleRate =
+ static_cast<android::hardware::bluetooth::audio::V2_0::SampleRate>(
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_44100 |
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_48000),
+ .channelMode = ChannelMode::STEREO,
+ .bitsPerSample = BitsPerSample::BITS_16,
+};
+
+// aptX HD: mSampleRate:(44100|48000), mBitsPerSample:(24),
+// mChannelMode:(STEREO)
+static const AptxParameters kDefaultOffloadAptxHdCapability = {
+ .sampleRate =
+ static_cast<android::hardware::bluetooth::audio::V2_0::SampleRate>(
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_44100 |
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_48000),
+ .channelMode = ChannelMode::STEREO,
+ .bitsPerSample = BitsPerSample::BITS_24,
+};
+
+const std::vector<CodecCapabilities> kDefaultOffloadA2dpCodecCapabilities = {
+ {.codecType = CodecType::SBC, .capabilities = {}},
+ {.codecType = CodecType::AAC, .capabilities = {}},
+ {.codecType = CodecType::LDAC, .capabilities = {}},
+ {.codecType = CodecType::APTX, .capabilities = {}},
+ {.codecType = CodecType::APTX_HD, .capabilities = {}}};
+
+static bool IsSingleBit(uint32_t bitmasks, uint32_t bitfield) {
+ bool single = false;
+ uint32_t test_bit = 0x00000001;
+ while (test_bit <= bitmasks && test_bit <= bitfield) {
+ if (bitfield & test_bit && bitmasks & test_bit) {
+ if (single) return false;
+ single = true;
+ }
+ if (test_bit == 0x80000000) break;
+ test_bit <<= 1;
+ }
+ return single;
+}
+
+static bool IsOffloadSbcConfigurationValid(
+ const CodecConfiguration::CodecSpecific& codec_specific);
+static bool IsOffloadAacConfigurationValid(
+ const CodecConfiguration::CodecSpecific& codec_specific);
+static bool IsOffloadLdacConfigurationValid(
+ const CodecConfiguration::CodecSpecific& codec_specific);
+static bool IsOffloadAptxConfigurationValid(
+ const CodecConfiguration::CodecSpecific& codec_specific);
+static bool IsOffloadAptxHdConfigurationValid(
+ const CodecConfiguration::CodecSpecific& codec_specific);
+
+static bool IsOffloadSbcConfigurationValid(
+ const CodecConfiguration::CodecSpecific& codec_specific) {
+ if (codec_specific.getDiscriminator() !=
+ CodecConfiguration::CodecSpecific::hidl_discriminator::sbcConfig) {
+ LOG(WARNING) << __func__
+ << ": Invalid CodecSpecific=" << toString(codec_specific);
+ return false;
+ }
+ const SbcParameters sbc_data = codec_specific.sbcConfig();
+ if (!IsSingleBit(static_cast<uint32_t>(sbc_data.sampleRate), 0xff) ||
+ !IsSingleBit(static_cast<uint32_t>(sbc_data.channelMode), 0x0f) ||
+ !IsSingleBit(static_cast<uint32_t>(sbc_data.blockLength), 0xf0) ||
+ !IsSingleBit(static_cast<uint32_t>(sbc_data.numSubbands), 0x0c) ||
+ !IsSingleBit(static_cast<uint32_t>(sbc_data.allocMethod), 0x03) ||
+ !IsSingleBit(static_cast<uint32_t>(sbc_data.bitsPerSample), 0x07) ||
+ sbc_data.minBitpool > sbc_data.maxBitpool) {
+ LOG(WARNING) << __func__
+ << ": Invalid CodecSpecific=" << toString(codec_specific);
+ return false;
+ } else if ((sbc_data.sampleRate & kDefaultOffloadSbcCapability.sampleRate) &&
+ (sbc_data.channelMode &
+ kDefaultOffloadSbcCapability.channelMode) &&
+ (sbc_data.blockLength &
+ kDefaultOffloadSbcCapability.blockLength) &&
+ (sbc_data.numSubbands &
+ kDefaultOffloadSbcCapability.numSubbands) &&
+ (sbc_data.allocMethod &
+ kDefaultOffloadSbcCapability.allocMethod) &&
+ (sbc_data.bitsPerSample &
+ kDefaultOffloadSbcCapability.bitsPerSample) &&
+ (kDefaultOffloadSbcCapability.minBitpool <= sbc_data.minBitpool &&
+ sbc_data.maxBitpool <= kDefaultOffloadSbcCapability.maxBitpool)) {
+ return true;
+ }
+ LOG(WARNING) << __func__
+ << ": Unsupported CodecSpecific=" << toString(codec_specific);
+ return false;
+}
+
+static bool IsOffloadAacConfigurationValid(
+ const CodecConfiguration::CodecSpecific& codec_specific) {
+ if (codec_specific.getDiscriminator() !=
+ CodecConfiguration::CodecSpecific::hidl_discriminator::aacConfig) {
+ LOG(WARNING) << __func__
+ << ": Invalid CodecSpecific=" << toString(codec_specific);
+ return false;
+ }
+ const AacParameters aac_data = codec_specific.aacConfig();
+ if (!IsSingleBit(static_cast<uint32_t>(aac_data.objectType), 0xf0) ||
+ !IsSingleBit(static_cast<uint32_t>(aac_data.sampleRate), 0xff) ||
+ !IsSingleBit(static_cast<uint32_t>(aac_data.channelMode), 0x03) ||
+ !IsSingleBit(static_cast<uint32_t>(aac_data.bitsPerSample), 0x07)) {
+ LOG(WARNING) << __func__
+ << ": Invalid CodecSpecific=" << toString(codec_specific);
+ return false;
+ } else if ((aac_data.objectType & kDefaultOffloadAacCapability.objectType) &&
+ (aac_data.sampleRate & kDefaultOffloadAacCapability.sampleRate) &&
+ (aac_data.channelMode &
+ kDefaultOffloadAacCapability.channelMode) &&
+ (aac_data.variableBitRateEnabled == AacVariableBitRate::DISABLED ||
+ kDefaultOffloadAacCapability.variableBitRateEnabled ==
+ AacVariableBitRate::ENABLED) &&
+ (aac_data.bitsPerSample &
+ kDefaultOffloadAacCapability.bitsPerSample)) {
+ return true;
+ }
+ LOG(WARNING) << __func__
+ << ": Unsupported CodecSpecific=" << toString(codec_specific);
+ return false;
+}
+
+static bool IsOffloadLdacConfigurationValid(
+ const CodecConfiguration::CodecSpecific& codec_specific) {
+ if (codec_specific.getDiscriminator() !=
+ CodecConfiguration::CodecSpecific::hidl_discriminator::ldacConfig) {
+ LOG(WARNING) << __func__
+ << ": Invalid CodecSpecific=" << toString(codec_specific);
+ return false;
+ }
+ const LdacParameters ldac_data = codec_specific.ldacConfig();
+ if (!IsSingleBit(static_cast<uint32_t>(ldac_data.sampleRate), 0xff) ||
+ !IsSingleBit(static_cast<uint32_t>(ldac_data.channelMode), 0x07) ||
+ (ldac_data.qualityIndex > LdacQualityIndex::QUALITY_LOW &&
+ ldac_data.qualityIndex != LdacQualityIndex::QUALITY_ABR) ||
+ !IsSingleBit(static_cast<uint32_t>(ldac_data.bitsPerSample), 0x07)) {
+ LOG(WARNING) << __func__
+ << ": Invalid CodecSpecific=" << toString(codec_specific);
+ return false;
+ } else if ((ldac_data.sampleRate &
+ kDefaultOffloadLdacCapability.sampleRate) &&
+ (ldac_data.channelMode &
+ kDefaultOffloadLdacCapability.channelMode) &&
+ (ldac_data.bitsPerSample &
+ kDefaultOffloadLdacCapability.bitsPerSample)) {
+ return true;
+ }
+ LOG(WARNING) << __func__
+ << ": Unsupported CodecSpecific=" << toString(codec_specific);
+ return false;
+}
+
+static bool IsOffloadAptxConfigurationValid(
+ const CodecConfiguration::CodecSpecific& codec_specific) {
+ if (codec_specific.getDiscriminator() !=
+ CodecConfiguration::CodecSpecific::hidl_discriminator::aptxConfig) {
+ LOG(WARNING) << __func__
+ << ": Invalid CodecSpecific=" << toString(codec_specific);
+ return false;
+ }
+ const AptxParameters aptx_data = codec_specific.aptxConfig();
+ if (!IsSingleBit(static_cast<uint32_t>(aptx_data.sampleRate), 0xff) ||
+ !IsSingleBit(static_cast<uint32_t>(aptx_data.channelMode), 0x03) ||
+ !IsSingleBit(static_cast<uint32_t>(aptx_data.bitsPerSample), 0x07)) {
+ LOG(WARNING) << __func__
+ << ": Invalid CodecSpecific=" << toString(codec_specific);
+ return false;
+ } else if ((aptx_data.sampleRate &
+ kDefaultOffloadAptxCapability.sampleRate) &&
+ (aptx_data.channelMode &
+ kDefaultOffloadAptxCapability.channelMode) &&
+ (aptx_data.bitsPerSample &
+ kDefaultOffloadAptxCapability.bitsPerSample)) {
+ return true;
+ }
+ LOG(WARNING) << __func__
+ << ": Unsupported CodecSpecific=" << toString(codec_specific);
+ return false;
+}
+
+static bool IsOffloadAptxHdConfigurationValid(
+ const CodecConfiguration::CodecSpecific& codec_specific) {
+ if (codec_specific.getDiscriminator() !=
+ CodecConfiguration::CodecSpecific::hidl_discriminator::aptxConfig) {
+ LOG(WARNING) << __func__
+ << ": Invalid CodecSpecific=" << toString(codec_specific);
+ return false;
+ }
+ const AptxParameters aptx_data = codec_specific.aptxConfig();
+ if (!IsSingleBit(static_cast<uint32_t>(aptx_data.sampleRate), 0xff) ||
+ !IsSingleBit(static_cast<uint32_t>(aptx_data.channelMode), 0x03) ||
+ !IsSingleBit(static_cast<uint32_t>(aptx_data.bitsPerSample), 0x07)) {
+ LOG(WARNING) << __func__
+ << ": Invalid CodecSpecific=" << toString(codec_specific);
+ return false;
+ } else if ((aptx_data.sampleRate &
+ kDefaultOffloadAptxHdCapability.sampleRate) &&
+ (aptx_data.channelMode &
+ kDefaultOffloadAptxHdCapability.channelMode) &&
+ (aptx_data.bitsPerSample &
+ kDefaultOffloadAptxHdCapability.bitsPerSample)) {
+ return true;
+ }
+ LOG(WARNING) << __func__
+ << ": Unsupported CodecSpecific=" << toString(codec_specific);
+ return false;
+}
+
+std::vector<::android::hardware::bluetooth::audio::V2_0::PcmParameters>
+GetSoftwarePcmCapabilities() {
+ return std::vector<
+ ::android::hardware::bluetooth::audio::V2_0::PcmParameters>(
+ 1, kDefaultSoftwarePcmCapabilities);
+}
+
+std::vector<PcmParameters> GetSoftwarePcmCapabilities_2_1() {
+ return std::vector<PcmParameters>(1, kDefaultSoftwarePcmCapabilities_2_1);
+}
+
+std::vector<CodecCapabilities> GetOffloadCodecCapabilities(
+ const ::android::hardware::bluetooth::audio::V2_0::SessionType&
+ session_type) {
+ return GetOffloadCodecCapabilities(static_cast<SessionType>(session_type));
+}
+
+std::vector<CodecCapabilities> GetOffloadCodecCapabilities(
+ const SessionType& session_type) {
+ if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
+ return std::vector<CodecCapabilities>(0);
+ }
+ std::vector<CodecCapabilities> offload_a2dp_codec_capabilities =
+ kDefaultOffloadA2dpCodecCapabilities;
+ for (auto& codec_capability : offload_a2dp_codec_capabilities) {
+ switch (codec_capability.codecType) {
+ case CodecType::SBC:
+ codec_capability.capabilities.sbcCapabilities(
+ kDefaultOffloadSbcCapability);
+ break;
+ case CodecType::AAC:
+ codec_capability.capabilities.aacCapabilities(
+ kDefaultOffloadAacCapability);
+ break;
+ case CodecType::LDAC:
+ codec_capability.capabilities.ldacCapabilities(
+ kDefaultOffloadLdacCapability);
+ break;
+ case CodecType::APTX:
+ codec_capability.capabilities.aptxCapabilities(
+ kDefaultOffloadAptxCapability);
+ break;
+ case CodecType::APTX_HD:
+ codec_capability.capabilities.aptxCapabilities(
+ kDefaultOffloadAptxHdCapability);
+ break;
+ case CodecType::UNKNOWN:
+ codec_capability = {};
+ break;
+ }
+ }
+ return offload_a2dp_codec_capabilities;
+}
+
+bool IsSoftwarePcmConfigurationValid(
+ const ::android::hardware::bluetooth::audio::V2_0::PcmParameters&
+ pcm_config) {
+ if ((pcm_config.sampleRate !=
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_44100 &&
+ pcm_config.sampleRate !=
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_48000 &&
+ pcm_config.sampleRate !=
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_88200 &&
+ pcm_config.sampleRate !=
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_96000 &&
+ pcm_config.sampleRate !=
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_16000 &&
+ pcm_config.sampleRate !=
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_24000) ||
+ (pcm_config.bitsPerSample != BitsPerSample::BITS_16 &&
+ pcm_config.bitsPerSample != BitsPerSample::BITS_24 &&
+ pcm_config.bitsPerSample != BitsPerSample::BITS_32) ||
+ (pcm_config.channelMode != ChannelMode::MONO &&
+ pcm_config.channelMode != ChannelMode::STEREO)) {
+ LOG(WARNING) << __func__
+ << ": Invalid PCM Configuration=" << toString(pcm_config);
+ return false;
+ } else if (pcm_config.sampleRate &
+ kDefaultSoftwarePcmCapabilities.sampleRate &&
+ pcm_config.bitsPerSample &
+ kDefaultSoftwarePcmCapabilities.bitsPerSample &&
+ pcm_config.channelMode &
+ kDefaultSoftwarePcmCapabilities.channelMode) {
+ return true;
+ }
+ LOG(WARNING) << __func__
+ << ": Unsupported PCM Configuration=" << toString(pcm_config);
+ return false;
+}
+
+bool IsSoftwarePcmConfigurationValid_2_1(const PcmParameters& pcm_config) {
+ if ((pcm_config.sampleRate != SampleRate::RATE_44100 &&
+ pcm_config.sampleRate != SampleRate::RATE_48000 &&
+ pcm_config.sampleRate != SampleRate::RATE_88200 &&
+ pcm_config.sampleRate != SampleRate::RATE_96000 &&
+ pcm_config.sampleRate != SampleRate::RATE_16000 &&
+ pcm_config.sampleRate != SampleRate::RATE_24000) ||
+ (pcm_config.bitsPerSample != BitsPerSample::BITS_16 &&
+ pcm_config.bitsPerSample != BitsPerSample::BITS_24 &&
+ pcm_config.bitsPerSample != BitsPerSample::BITS_32) ||
+ (pcm_config.channelMode != ChannelMode::MONO &&
+ pcm_config.channelMode != ChannelMode::STEREO)) {
+ LOG(WARNING) << __func__
+ << ": Invalid PCM Configuration=" << toString(pcm_config);
+ return false;
+ } else if (pcm_config.sampleRate &
+ kDefaultSoftwarePcmCapabilities_2_1.sampleRate &&
+ pcm_config.bitsPerSample &
+ kDefaultSoftwarePcmCapabilities_2_1.bitsPerSample &&
+ pcm_config.channelMode &
+ kDefaultSoftwarePcmCapabilities_2_1.channelMode &&
+ pcm_config.dataIntervalUs != 0) {
+ return true;
+ }
+ LOG(WARNING) << __func__
+ << ": Unsupported PCM Configuration=" << toString(pcm_config);
+ return false;
+}
+
+bool IsOffloadCodecConfigurationValid(const SessionType& session_type,
+ const CodecConfiguration& codec_config) {
+ if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
+ LOG(ERROR) << __func__
+ << ": Invalid SessionType=" << toString(session_type);
+ return false;
+ } else if (codec_config.encodedAudioBitrate < 0x00000001 ||
+ 0x00ffffff < codec_config.encodedAudioBitrate) {
+ LOG(ERROR) << __func__ << ": Unsupported Codec Configuration="
+ << toString(codec_config);
+ return false;
+ }
+ const CodecConfiguration::CodecSpecific& codec_specific = codec_config.config;
+ switch (codec_config.codecType) {
+ case CodecType::SBC:
+ if (IsOffloadSbcConfigurationValid(codec_specific)) {
+ return true;
+ }
+ return false;
+ case CodecType::AAC:
+ if (IsOffloadAacConfigurationValid(codec_specific)) {
+ return true;
+ }
+ return false;
+ case CodecType::LDAC:
+ if (IsOffloadLdacConfigurationValid(codec_specific)) {
+ return true;
+ }
+ return false;
+ case CodecType::APTX:
+ if (IsOffloadAptxConfigurationValid(codec_specific)) {
+ return true;
+ }
+ return false;
+ case CodecType::APTX_HD:
+ if (IsOffloadAptxHdConfigurationValid(codec_specific)) {
+ return true;
+ }
+ return false;
+ case CodecType::UNKNOWN:
+ return false;
+ }
+ return false;
+}
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace android
diff --git a/bluetooth/audio/2.1/default/session/BluetoothAudioSupportedCodecsDB.h b/bluetooth/audio/2.1/default/session/BluetoothAudioSupportedCodecsDB.h
new file mode 100644
index 0000000..9b2f680
--- /dev/null
+++ b/bluetooth/audio/2.1/default/session/BluetoothAudioSupportedCodecsDB.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/bluetooth/audio/2.0/types.h>
+#include <android/hardware/bluetooth/audio/2.1/types.h>
+
+namespace android {
+namespace bluetooth {
+namespace audio {
+
+using ::android::hardware::bluetooth::audio::V2_0::CodecCapabilities;
+using ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration;
+using ::android::hardware::bluetooth::audio::V2_1::PcmParameters;
+using ::android::hardware::bluetooth::audio::V2_1::SessionType;
+
+std::vector<::android::hardware::bluetooth::audio::V2_0::PcmParameters>
+GetSoftwarePcmCapabilities();
+std::vector<PcmParameters> GetSoftwarePcmCapabilities_2_1();
+std::vector<CodecCapabilities> GetOffloadCodecCapabilities(
+ const SessionType& session_type);
+std::vector<CodecCapabilities> GetOffloadCodecCapabilities(
+ const ::android::hardware::bluetooth::audio::V2_0::SessionType&
+ session_type);
+
+bool IsSoftwarePcmConfigurationValid_2_1(const PcmParameters& pcm_config);
+bool IsSoftwarePcmConfigurationValid(
+ const ::android::hardware::bluetooth::audio::V2_0::PcmParameters&
+ pcm_config);
+bool IsOffloadCodecConfigurationValid(const SessionType& session_type,
+ const CodecConfiguration& codec_config);
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace android
diff --git a/bluetooth/audio/2.1/types.hal b/bluetooth/audio/2.1/types.hal
new file mode 100644
index 0000000..5604c38
--- /dev/null
+++ b/bluetooth/audio/2.1/types.hal
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio@2.1;
+
+import @2.0::PcmParameters;
+import @2.0::SessionType;
+import @2.0::SampleRate;
+import @2.0::ChannelMode;
+import @2.0::BitsPerSample;
+import @2.0::CodecConfiguration;
+import @2.0::CodecCapabilities;
+
+enum SessionType : @2.0::SessionType {
+ /** Used when encoded by Bluetooth Stack and streaming to LE Audio device */
+ LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
+ /** Used when decoded by Bluetooth Stack and streaming to audio framework */
+ LE_AUDIO_SOFTWARE_DECODED_DATAPATH,
+ /** Encoding is done by HW an there is control only */
+ LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ /** Decoding is done by HW an there is control only */
+ LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+};
+
+enum SampleRate : @2.0::SampleRate {
+ RATE_8000 = 0x100,
+ RATE_32000 = 0x200,
+};
+
+/** Used for Software Encoding audio feed parameters */
+struct PcmParameters {
+ SampleRate sampleRate;
+ ChannelMode channelMode;
+ BitsPerSample bitsPerSample;
+ /** Data interval for data transfer */
+ uint32_t dataIntervalUs;
+};
+
+/** Used to configure either a Hardware or Software Encoding session based on session type */
+safe_union AudioConfiguration {
+ PcmParameters pcmConfig;
+ CodecConfiguration codecConfig;
+};
+
+/** Used to specify the capabilities of the different session types */
+safe_union AudioCapabilities {
+ PcmParameters pcmCapabilities;
+ CodecCapabilities codecCapabilities;
+};
diff --git a/bluetooth/audio/2.1/vts/OWNERS b/bluetooth/audio/2.1/vts/OWNERS
new file mode 100644
index 0000000..b6c0813
--- /dev/null
+++ b/bluetooth/audio/2.1/vts/OWNERS
@@ -0,0 +1,3 @@
+include platform/system/bt:/OWNERS
+
+cheneyni@google.com
diff --git a/bluetooth/audio/2.1/vts/functional/Android.bp b/bluetooth/audio/2.1/vts/functional/Android.bp
new file mode 100644
index 0000000..6ec5537
--- /dev/null
+++ b/bluetooth/audio/2.1/vts/functional/Android.bp
@@ -0,0 +1,14 @@
+cc_test {
+ name: "VtsHalBluetoothAudioV2_1TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: ["VtsHalBluetoothAudioV2_1TargetTest.cpp"],
+ static_libs: [
+ "android.hardware.audio.common@5.0",
+ "android.hardware.bluetooth.audio@2.1",
+ "android.hardware.bluetooth.audio@2.0",
+ ],
+ shared_libs: [
+ "libfmq",
+ ],
+ test_suites: ["general-tests", "vts"],
+}
diff --git a/bluetooth/audio/2.1/vts/functional/VtsHalBluetoothAudioV2_1TargetTest.cpp b/bluetooth/audio/2.1/vts/functional/VtsHalBluetoothAudioV2_1TargetTest.cpp
new file mode 100644
index 0000000..c0ec907
--- /dev/null
+++ b/bluetooth/audio/2.1/vts/functional/VtsHalBluetoothAudioV2_1TargetTest.cpp
@@ -0,0 +1,1209 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "bluetooth_audio_hidl_hal_test"
+
+#include <VtsHalHidlTargetCallbackBase.h>
+#include <android-base/logging.h>
+#include <android/hardware/bluetooth/audio/2.0/IBluetoothAudioPort.h>
+#include <android/hardware/bluetooth/audio/2.1/IBluetoothAudioProvider.h>
+#include <android/hardware/bluetooth/audio/2.1/IBluetoothAudioProvidersFactory.h>
+#include <fmq/MessageQueue.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/ServiceManagement.h>
+#include <utils/Log.h>
+
+using ::android::sp;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::kSynchronizedReadWrite;
+using ::android::hardware::MessageQueue;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::audio::common::V5_0::SourceMetadata;
+using ::android::hardware::bluetooth::audio::V2_0::AacObjectType;
+using ::android::hardware::bluetooth::audio::V2_0::AacParameters;
+using ::android::hardware::bluetooth::audio::V2_0::AacVariableBitRate;
+using ::android::hardware::bluetooth::audio::V2_0::AptxParameters;
+using ::android::hardware::bluetooth::audio::V2_0::AudioCapabilities;
+using ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
+using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
+using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
+using ::android::hardware::bluetooth::audio::V2_0::CodecCapabilities;
+using ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration;
+using ::android::hardware::bluetooth::audio::V2_0::CodecType;
+using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioPort;
+using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioProvider;
+using ::android::hardware::bluetooth::audio::V2_0::LdacChannelMode;
+using ::android::hardware::bluetooth::audio::V2_0::LdacParameters;
+using ::android::hardware::bluetooth::audio::V2_0::LdacQualityIndex;
+using ::android::hardware::bluetooth::audio::V2_0::PcmParameters;
+using ::android::hardware::bluetooth::audio::V2_0::SbcAllocMethod;
+using ::android::hardware::bluetooth::audio::V2_0::SbcBlockLength;
+using ::android::hardware::bluetooth::audio::V2_0::SbcChannelMode;
+using ::android::hardware::bluetooth::audio::V2_0::SbcNumSubbands;
+using ::android::hardware::bluetooth::audio::V2_0::SbcParameters;
+using ::android::hardware::bluetooth::audio::V2_0::SessionType;
+using ::android::hardware::bluetooth::audio::V2_1::
+ IBluetoothAudioProvidersFactory;
+using ::android::hardware::bluetooth::audio::V2_1::SampleRate;
+
+using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+using BluetoothAudioStatus =
+ ::android::hardware::bluetooth::audio::V2_0::Status;
+using CodecSpecificConfig = ::android::hardware::bluetooth::audio::V2_0::
+ CodecConfiguration::CodecSpecific;
+
+namespace {
+constexpr android::hardware::bluetooth::audio::V2_0::SampleRate
+ a2dp_sample_rates[5] = {
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_UNKNOWN,
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_44100,
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_48000,
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_88200,
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_96000};
+constexpr BitsPerSample a2dp_bits_per_samples[4] = {
+ BitsPerSample::BITS_UNKNOWN, BitsPerSample::BITS_16, BitsPerSample::BITS_24,
+ BitsPerSample::BITS_32};
+constexpr ChannelMode a2dp_channel_modes[3] = {
+ ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
+constexpr CodecType a2dp_codec_types[6] = {CodecType::UNKNOWN, CodecType::SBC,
+ CodecType::AAC, CodecType::APTX,
+ CodecType::APTX_HD, CodecType::LDAC};
+
+template <typename T>
+std::vector<T> ExtractValuesFromBitmask(T bitmasks, uint32_t bitfield,
+ bool supported) {
+ std::vector<T> retval;
+ if (!supported) {
+ retval.push_back(static_cast<T>(bitfield));
+ }
+ uint32_t test_bit = 0x00000001;
+ while (test_bit <= static_cast<uint32_t>(bitmasks) && test_bit <= bitfield) {
+ if ((bitfield & test_bit)) {
+ if ((!(bitmasks & test_bit) && !supported) ||
+ ((bitmasks & test_bit) && supported)) {
+ retval.push_back(static_cast<T>(test_bit));
+ }
+ }
+ if (test_bit == 0x80000000) {
+ break;
+ }
+ test_bit <<= 1;
+ }
+ return retval;
+}
+} // namespace
+
+// The base test class for Bluetooth Audio HAL.
+class BluetoothAudioProvidersFactoryHidlTest
+ : public ::testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ providers_factory_ =
+ IBluetoothAudioProvidersFactory::getService(GetParam());
+ ASSERT_NE(providers_factory_, nullptr);
+ }
+
+ virtual void TearDown() override { providers_factory_ = nullptr; }
+
+ // A simple test implementation of IBluetoothAudioPort.
+ class BluetoothAudioPort : public ::testing::VtsHalHidlTargetCallbackBase<
+ BluetoothAudioProvidersFactoryHidlTest>,
+ public IBluetoothAudioPort {
+ BluetoothAudioProvidersFactoryHidlTest& parent_;
+
+ public:
+ BluetoothAudioPort(BluetoothAudioProvidersFactoryHidlTest& parent)
+ : parent_(parent) {}
+ virtual ~BluetoothAudioPort() = default;
+
+ Return<void> startStream() override {
+ parent_.audio_provider_->streamStarted(BluetoothAudioStatus::SUCCESS);
+ return Void();
+ }
+
+ Return<void> suspendStream() override {
+ parent_.audio_provider_->streamSuspended(BluetoothAudioStatus::SUCCESS);
+ return Void();
+ }
+
+ Return<void> stopStream() override { return Void(); }
+
+ Return<void> getPresentationPosition(getPresentationPosition_cb _hidl_cb) {
+ _hidl_cb(BluetoothAudioStatus::SUCCESS, 0, 0, {.tvSec = 0, .tvNSec = 0});
+ return Void();
+ }
+
+ Return<void> updateMetadata(const SourceMetadata& sourceMetadata __unused) {
+ return Void();
+ }
+ };
+
+ void GetProviderCapabilitiesHelper(const SessionType& session_type) {
+ temp_provider_capabilities_.clear();
+ auto hidl_cb = [&temp_capabilities = this->temp_provider_capabilities_](
+ const hidl_vec<AudioCapabilities>& audioCapabilities) {
+ for (auto audioCapability : audioCapabilities)
+ temp_capabilities.push_back(audioCapability);
+ };
+ auto hidl_retval =
+ providers_factory_->getProviderCapabilities(session_type, hidl_cb);
+ // HIDL calls should not be failed and callback has to be executed
+ ASSERT_TRUE(hidl_retval.isOk());
+ if (session_type == SessionType::UNKNOWN) {
+ ASSERT_TRUE(temp_provider_capabilities_.empty());
+ } else if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
+ // All software paths are mandatory and must have exact 1 "PcmParameters"
+ ASSERT_EQ(temp_provider_capabilities_.size(), 1);
+ ASSERT_EQ(temp_provider_capabilities_[0].getDiscriminator(),
+ AudioCapabilities::hidl_discriminator::pcmCapabilities);
+ } else {
+ uint32_t codec_type_bitmask = 0x00000000;
+ // empty capability means offload is unsupported
+ for (auto audio_capability : temp_provider_capabilities_) {
+ ASSERT_EQ(audio_capability.getDiscriminator(),
+ AudioCapabilities::hidl_discriminator::codecCapabilities);
+ const CodecCapabilities& codec_capabilities =
+ audio_capability.codecCapabilities();
+ // Every codec can present once at most
+ ASSERT_EQ(codec_type_bitmask &
+ static_cast<uint32_t>(codec_capabilities.codecType),
+ 0);
+ switch (codec_capabilities.codecType) {
+ case CodecType::SBC:
+ ASSERT_EQ(codec_capabilities.capabilities.getDiscriminator(),
+ CodecCapabilities::Capabilities::hidl_discriminator::
+ sbcCapabilities);
+ break;
+ case CodecType::AAC:
+ ASSERT_EQ(codec_capabilities.capabilities.getDiscriminator(),
+ CodecCapabilities::Capabilities::hidl_discriminator::
+ aacCapabilities);
+ break;
+ case CodecType::APTX:
+ FALLTHROUGH_INTENDED;
+ case CodecType::APTX_HD:
+ ASSERT_EQ(codec_capabilities.capabilities.getDiscriminator(),
+ CodecCapabilities::Capabilities::hidl_discriminator::
+ aptxCapabilities);
+ break;
+ case CodecType::LDAC:
+ ASSERT_EQ(codec_capabilities.capabilities.getDiscriminator(),
+ CodecCapabilities::Capabilities::hidl_discriminator::
+ ldacCapabilities);
+ break;
+ case CodecType::UNKNOWN:
+ break;
+ }
+ codec_type_bitmask |= codec_capabilities.codecType;
+ }
+ }
+ }
+
+ void GetProviderCapabilitiesHelper_2_1(
+ const android::hardware::bluetooth::audio::V2_1::SessionType&
+ session_type) {
+ temp_provider_capabilities_2_1_.clear();
+ auto hidl_cb =
+ [&temp_capabilities = this->temp_provider_capabilities_2_1_](
+ const hidl_vec<
+ android::hardware::bluetooth::audio::V2_1::AudioCapabilities>&
+ audioCapabilities) {
+ for (auto audioCapability : audioCapabilities)
+ temp_capabilities.push_back(audioCapability);
+ };
+ auto hidl_retval =
+ providers_factory_->getProviderCapabilities_2_1(session_type, hidl_cb);
+ // HIDL calls should not be failed and callback has to be executed
+ ASSERT_TRUE(hidl_retval.isOk());
+
+ // All software paths are mandatory and must have exact 1 "PcmParameters"
+ ASSERT_EQ(temp_provider_capabilities_2_1_.size(), 1);
+ ASSERT_EQ(temp_provider_capabilities_2_1_[0].getDiscriminator(),
+ android::hardware::bluetooth::audio::V2_1::AudioCapabilities::
+ hidl_discriminator::pcmCapabilities);
+ }
+
+ // This helps to open the specified provider and check the openProvider()
+ // has corruct return values. BUT, to keep it simple, it does not consider
+ // the capability, and please do so at the SetUp of each session's test.
+ void OpenProviderHelper(const SessionType& session_type) {
+ BluetoothAudioStatus cb_status;
+ auto hidl_cb = [&cb_status, &local_provider = this->audio_provider_](
+ BluetoothAudioStatus status,
+ const sp<IBluetoothAudioProvider>& provider) {
+ cb_status = status;
+ local_provider = provider;
+ };
+ auto hidl_retval = providers_factory_->openProvider(session_type, hidl_cb);
+ // HIDL calls should not be failed and callback has to be executed
+ ASSERT_TRUE(hidl_retval.isOk());
+ if (cb_status == BluetoothAudioStatus::SUCCESS) {
+ ASSERT_NE(session_type, SessionType::UNKNOWN);
+ ASSERT_NE(audio_provider_, nullptr);
+ audio_port_ = new BluetoothAudioPort(*this);
+ } else {
+ // A2DP_HARDWARE_OFFLOAD_DATAPATH is optional
+ ASSERT_TRUE(session_type == SessionType::UNKNOWN ||
+ session_type == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
+ ASSERT_EQ(cb_status, BluetoothAudioStatus::FAILURE);
+ ASSERT_EQ(audio_provider_, nullptr);
+ }
+ }
+
+ // This helps to open the specified provider and check the openProvider_2_1()
+ // has corruct return values. BUT, to keep it simple, it does not consider
+ // the capability, and please do so at the SetUp of each session's test.
+ void OpenProviderHelper_2_1(
+ const android::hardware::bluetooth::audio::V2_1::SessionType&
+ session_type) {
+ BluetoothAudioStatus cb_status;
+ auto hidl_cb = [&cb_status, &local_provider = this->audio_provider_2_1_](
+ BluetoothAudioStatus status,
+ const sp<android::hardware::bluetooth::audio::V2_1::
+ IBluetoothAudioProvider>& provider) {
+ cb_status = status;
+ local_provider = provider;
+ };
+ auto hidl_retval =
+ providers_factory_->openProvider_2_1(session_type, hidl_cb);
+ // HIDL calls should not be failed and callback has to be executed
+ ASSERT_TRUE(hidl_retval.isOk());
+ if (cb_status == BluetoothAudioStatus::SUCCESS) {
+ ASSERT_NE(
+ session_type,
+ android::hardware::bluetooth::audio::V2_1::SessionType::UNKNOWN);
+ ASSERT_NE(audio_provider_2_1_, nullptr);
+ audio_port_ = new BluetoothAudioPort(*this);
+ } else {
+ ASSERT_TRUE(
+ session_type ==
+ android::hardware::bluetooth::audio::V2_1::SessionType::UNKNOWN);
+ ASSERT_EQ(cb_status, BluetoothAudioStatus::FAILURE);
+ ASSERT_EQ(audio_provider_2_1_, nullptr);
+ }
+ }
+
+ bool IsPcmParametersSupported(const PcmParameters& pcm_parameters) {
+ if (temp_provider_capabilities_.size() != 1 ||
+ temp_provider_capabilities_[0].getDiscriminator() !=
+ AudioCapabilities::hidl_discriminator::pcmCapabilities) {
+ return false;
+ }
+ auto pcm_capability = temp_provider_capabilities_[0].pcmCapabilities();
+ bool is_parameter_valid =
+ (pcm_parameters.sampleRate != android::hardware::bluetooth::audio::
+ V2_0::SampleRate::RATE_UNKNOWN &&
+ pcm_parameters.channelMode != ChannelMode::UNKNOWN &&
+ pcm_parameters.bitsPerSample != BitsPerSample::BITS_UNKNOWN);
+ bool is_parameter_in_capability =
+ (pcm_capability.sampleRate & pcm_parameters.sampleRate &&
+ pcm_capability.channelMode & pcm_parameters.channelMode &&
+ pcm_capability.bitsPerSample & pcm_parameters.bitsPerSample);
+ return is_parameter_valid && is_parameter_in_capability;
+ }
+
+ bool IsPcmParametersSupported_2_1(
+ const android::hardware::bluetooth::audio::V2_1::PcmParameters&
+ pcm_parameters) {
+ if (temp_provider_capabilities_2_1_.size() != 1 ||
+ temp_provider_capabilities_2_1_[0].getDiscriminator() !=
+ android::hardware::bluetooth::audio::V2_1::AudioCapabilities::
+ hidl_discriminator::pcmCapabilities) {
+ return false;
+ }
+ auto pcm_capability = temp_provider_capabilities_2_1_[0].pcmCapabilities();
+ bool is_parameter_valid =
+ (pcm_parameters.sampleRate != SampleRate::RATE_UNKNOWN &&
+ pcm_parameters.channelMode != ChannelMode::UNKNOWN &&
+ pcm_parameters.bitsPerSample != BitsPerSample::BITS_UNKNOWN &&
+ pcm_parameters.dataIntervalUs != 0);
+ bool is_parameter_in_capability =
+ (pcm_capability.sampleRate & pcm_parameters.sampleRate &&
+ pcm_capability.channelMode & pcm_parameters.channelMode &&
+ pcm_capability.bitsPerSample & pcm_parameters.bitsPerSample);
+ return is_parameter_valid && is_parameter_in_capability;
+ }
+
+ sp<IBluetoothAudioProvidersFactory> providers_factory_;
+
+ // temp storage saves the specified provider capability by
+ // GetProviderCapabilitiesHelper()
+ std::vector<AudioCapabilities> temp_provider_capabilities_;
+ std::vector<android::hardware::bluetooth::audio::V2_1::AudioCapabilities>
+ temp_provider_capabilities_2_1_;
+
+ // audio_provider_ is for the Bluetooth stack to report session started/ended
+ // and handled audio stream started / suspended
+ sp<IBluetoothAudioProvider> audio_provider_;
+ sp<android::hardware::bluetooth::audio::V2_1::IBluetoothAudioProvider>
+ audio_provider_2_1_;
+
+ // audio_port_ is for the Audio HAL to send stream start/suspend/stop commands
+ // to Bluetooth stack
+ sp<IBluetoothAudioPort> audio_port_;
+
+ static constexpr SessionType session_types_[4] = {
+ SessionType::UNKNOWN, SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH,
+ SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH};
+};
+
+/**
+ * Test whether we can get the FactoryService from HIDL
+ */
+TEST_P(BluetoothAudioProvidersFactoryHidlTest, GetProvidersFactoryService) {}
+
+/**
+ * Test whether we can open a provider for each provider returned by
+ * getProviderCapabilities() with non-empty capabalities
+ */
+TEST_P(BluetoothAudioProvidersFactoryHidlTest,
+ OpenProviderAndCheckCapabilitiesBySession) {
+ for (auto session_type : session_types_) {
+ GetProviderCapabilitiesHelper(session_type);
+ OpenProviderHelper(session_type);
+ // We must be able to open a provider if its getProviderCapabilities()
+ // returns non-empty list.
+ EXPECT_TRUE(temp_provider_capabilities_.empty() ||
+ audio_provider_ != nullptr);
+ }
+}
+
+/**
+ * openProvider A2DP_SOFTWARE_ENCODING_DATAPATH
+ */
+class BluetoothAudioProviderA2dpSoftwareHidlTest
+ : public BluetoothAudioProvidersFactoryHidlTest {
+ public:
+ virtual void SetUp() override {
+ BluetoothAudioProvidersFactoryHidlTest::SetUp();
+ GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
+ OpenProviderHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
+ ASSERT_NE(audio_provider_, nullptr);
+ }
+
+ virtual void TearDown() override {
+ audio_port_ = nullptr;
+ audio_provider_ = nullptr;
+ BluetoothAudioProvidersFactoryHidlTest::TearDown();
+ }
+};
+
+/**
+ * Test whether we can open a provider of type
+ */
+TEST_P(BluetoothAudioProviderA2dpSoftwareHidlTest, OpenA2dpSoftwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
+ * different PCM config
+ */
+TEST_P(BluetoothAudioProviderA2dpSoftwareHidlTest,
+ StartAndEndA2dpSoftwareSessionWithPossiblePcmConfig) {
+ bool is_codec_config_valid;
+ std::unique_ptr<DataMQ> tempDataMQ;
+ auto hidl_cb = [&is_codec_config_valid, &tempDataMQ](
+ BluetoothAudioStatus status,
+ const DataMQ::Descriptor& dataMQ) {
+ if (is_codec_config_valid) {
+ ASSERT_EQ(status, BluetoothAudioStatus::SUCCESS);
+ ASSERT_TRUE(dataMQ.isHandleValid());
+ tempDataMQ.reset(new DataMQ(dataMQ));
+ } else {
+ EXPECT_EQ(status, BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION);
+ EXPECT_FALSE(dataMQ.isHandleValid());
+ }
+ };
+ AudioConfiguration audio_config = {};
+ PcmParameters pcm_parameters = {};
+ for (auto sample_rate : a2dp_sample_rates) {
+ pcm_parameters.sampleRate = sample_rate;
+ for (auto bits_per_sample : a2dp_bits_per_samples) {
+ pcm_parameters.bitsPerSample = bits_per_sample;
+ for (auto channel_mode : a2dp_channel_modes) {
+ pcm_parameters.channelMode = channel_mode;
+ is_codec_config_valid = IsPcmParametersSupported(pcm_parameters);
+ audio_config.pcmConfig(pcm_parameters);
+ auto hidl_retval =
+ audio_provider_->startSession(audio_port_, audio_config, hidl_cb);
+ // HIDL calls should not be failed and callback has to be executed
+ ASSERT_TRUE(hidl_retval.isOk());
+ if (is_codec_config_valid) {
+ EXPECT_TRUE(tempDataMQ != nullptr && tempDataMQ->isValid());
+ }
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ } // ChannelMode
+ } // BitsPerSampple
+ } // SampleRate
+}
+
+/**
+ * openProvider A2DP_HARDWARE_OFFLOAD_DATAPATH
+ */
+class BluetoothAudioProviderA2dpHardwareHidlTest
+ : public BluetoothAudioProvidersFactoryHidlTest {
+ public:
+ virtual void SetUp() override {
+ BluetoothAudioProvidersFactoryHidlTest::SetUp();
+ GetProviderCapabilitiesHelper(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
+ OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
+ ASSERT_TRUE(temp_provider_capabilities_.empty() ||
+ audio_provider_ != nullptr);
+ }
+
+ virtual void TearDown() override {
+ audio_port_ = nullptr;
+ audio_provider_ = nullptr;
+ BluetoothAudioProvidersFactoryHidlTest::TearDown();
+ }
+
+ bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
+
+ void GetOffloadCodecCapabilityHelper(const CodecType& codec_type) {
+ temp_codec_capabilities_ = {};
+ for (auto codec_capability : temp_provider_capabilities_) {
+ if (codec_capability.codecCapabilities().codecType != codec_type) {
+ continue;
+ }
+ temp_codec_capabilities_ = codec_capability.codecCapabilities();
+ }
+ }
+
+ std::vector<CodecSpecificConfig> GetSbcCodecSpecificSupportedList(
+ bool supported) {
+ std::vector<CodecSpecificConfig> sbc_codec_specifics;
+ GetOffloadCodecCapabilityHelper(CodecType::SBC);
+ if (temp_codec_capabilities_.codecType != CodecType::SBC) {
+ return sbc_codec_specifics;
+ }
+ // parse the capability
+ SbcParameters sbc_capability =
+ temp_codec_capabilities_.capabilities.sbcCapabilities();
+ if (sbc_capability.minBitpool > sbc_capability.maxBitpool) {
+ return sbc_codec_specifics;
+ }
+ std::vector<android::hardware::bluetooth::audio::V2_0::SampleRate>
+ sample_rates = ExtractValuesFromBitmask<
+ android::hardware::bluetooth::audio::V2_0::SampleRate>(
+ sbc_capability.sampleRate, 0xff, supported);
+ std::vector<SbcChannelMode> channel_modes =
+ ExtractValuesFromBitmask<SbcChannelMode>(sbc_capability.channelMode,
+ 0x0f, supported);
+ std::vector<SbcBlockLength> block_lengths =
+ ExtractValuesFromBitmask<SbcBlockLength>(sbc_capability.blockLength,
+ 0xf0, supported);
+ std::vector<SbcNumSubbands> num_subbandss =
+ ExtractValuesFromBitmask<SbcNumSubbands>(sbc_capability.numSubbands,
+ 0x0c, supported);
+ std::vector<SbcAllocMethod> alloc_methods =
+ ExtractValuesFromBitmask<SbcAllocMethod>(sbc_capability.allocMethod,
+ 0x03, supported);
+ std::vector<BitsPerSample> bits_per_samples =
+ ExtractValuesFromBitmask<BitsPerSample>(sbc_capability.bitsPerSample,
+ 0x07, supported);
+ // combine those parameters into one list of
+ // CodecConfiguration::CodecSpecific
+ CodecSpecificConfig codec_specific = {};
+ SbcParameters sbc_data;
+ for (auto sample_rate : sample_rates) {
+ for (auto channel_mode : channel_modes) {
+ for (auto block_length : block_lengths) {
+ for (auto num_subbands : num_subbandss) {
+ for (auto alloc_method : alloc_methods) {
+ for (auto bits_per_sample : bits_per_samples) {
+ sbc_data = {.sampleRate = sample_rate,
+ .channelMode = channel_mode,
+ .blockLength = block_length,
+ .numSubbands = num_subbands,
+ .allocMethod = alloc_method,
+ .bitsPerSample = bits_per_sample,
+ .minBitpool = sbc_capability.minBitpool,
+ .maxBitpool = sbc_capability.maxBitpool};
+ codec_specific.sbcConfig(sbc_data);
+ sbc_codec_specifics.push_back(codec_specific);
+ }
+ }
+ }
+ }
+ }
+ }
+ return sbc_codec_specifics;
+ }
+
+ std::vector<CodecSpecificConfig> GetAacCodecSpecificSupportedList(
+ bool supported) {
+ std::vector<CodecSpecificConfig> aac_codec_specifics;
+ GetOffloadCodecCapabilityHelper(CodecType::AAC);
+ if (temp_codec_capabilities_.codecType != CodecType::AAC) {
+ return aac_codec_specifics;
+ }
+ // parse the capability
+ AacParameters aac_capability =
+ temp_codec_capabilities_.capabilities.aacCapabilities();
+ std::vector<AacObjectType> object_types =
+ ExtractValuesFromBitmask<AacObjectType>(aac_capability.objectType, 0xf0,
+ supported);
+ std::vector<android::hardware::bluetooth::audio::V2_0::SampleRate>
+ sample_rates = ExtractValuesFromBitmask<
+ android::hardware::bluetooth::audio::V2_0::SampleRate>(
+ aac_capability.sampleRate, 0xff, supported);
+ std::vector<ChannelMode> channel_modes =
+ ExtractValuesFromBitmask<ChannelMode>(aac_capability.channelMode, 0x03,
+ supported);
+ std::vector<AacVariableBitRate> variable_bit_rate_enableds = {
+ AacVariableBitRate::DISABLED};
+ if (aac_capability.variableBitRateEnabled == AacVariableBitRate::ENABLED) {
+ variable_bit_rate_enableds.push_back(AacVariableBitRate::ENABLED);
+ }
+ std::vector<BitsPerSample> bits_per_samples =
+ ExtractValuesFromBitmask<BitsPerSample>(aac_capability.bitsPerSample,
+ 0x07, supported);
+ // combine those parameters into one list of
+ // CodecConfiguration::CodecSpecific
+ CodecSpecificConfig codec_specific = {};
+ AacParameters aac_data;
+ for (auto object_type : object_types) {
+ for (auto sample_rate : sample_rates) {
+ for (auto channel_mode : channel_modes) {
+ for (auto variable_bit_rate_enabled : variable_bit_rate_enableds) {
+ for (auto bits_per_sample : bits_per_samples) {
+ aac_data = {.objectType = object_type,
+ .sampleRate = sample_rate,
+ .channelMode = channel_mode,
+ .variableBitRateEnabled = variable_bit_rate_enabled,
+ .bitsPerSample = bits_per_sample};
+ codec_specific.aacConfig(aac_data);
+ aac_codec_specifics.push_back(codec_specific);
+ }
+ }
+ }
+ }
+ }
+ return aac_codec_specifics;
+ }
+
+ std::vector<CodecSpecificConfig> GetLdacCodecSpecificSupportedList(
+ bool supported) {
+ std::vector<CodecSpecificConfig> ldac_codec_specifics;
+ GetOffloadCodecCapabilityHelper(CodecType::LDAC);
+ if (temp_codec_capabilities_.codecType != CodecType::LDAC) {
+ return ldac_codec_specifics;
+ }
+ // parse the capability
+ LdacParameters ldac_capability =
+ temp_codec_capabilities_.capabilities.ldacCapabilities();
+ std::vector<android::hardware::bluetooth::audio::V2_0::SampleRate>
+ sample_rates = ExtractValuesFromBitmask<
+ android::hardware::bluetooth::audio::V2_0::SampleRate>(
+ ldac_capability.sampleRate, 0xff, supported);
+ std::vector<LdacChannelMode> channel_modes =
+ ExtractValuesFromBitmask<LdacChannelMode>(ldac_capability.channelMode,
+ 0x07, supported);
+ std::vector<LdacQualityIndex> quality_indexes = {
+ LdacQualityIndex::QUALITY_HIGH, LdacQualityIndex::QUALITY_MID,
+ LdacQualityIndex::QUALITY_LOW, LdacQualityIndex::QUALITY_ABR};
+ std::vector<BitsPerSample> bits_per_samples =
+ ExtractValuesFromBitmask<BitsPerSample>(ldac_capability.bitsPerSample,
+ 0x07, supported);
+ // combine those parameters into one list of
+ // CodecConfiguration::CodecSpecific
+ CodecSpecificConfig codec_specific = {};
+ LdacParameters ldac_data;
+ for (auto sample_rate : sample_rates) {
+ for (auto channel_mode : channel_modes) {
+ for (auto quality_index : quality_indexes) {
+ for (auto bits_per_sample : bits_per_samples) {
+ ldac_data = {.sampleRate = sample_rate,
+ .channelMode = channel_mode,
+ .qualityIndex = quality_index,
+ .bitsPerSample = bits_per_sample};
+ codec_specific.ldacConfig(ldac_data);
+ ldac_codec_specifics.push_back(codec_specific);
+ }
+ }
+ }
+ }
+ return ldac_codec_specifics;
+ }
+
+ std::vector<CodecSpecificConfig> GetAptxCodecSpecificSupportedList(
+ bool is_hd, bool supported) {
+ std::vector<CodecSpecificConfig> aptx_codec_specifics;
+ GetOffloadCodecCapabilityHelper(
+ (is_hd ? CodecType::APTX_HD : CodecType::APTX));
+ if ((is_hd && temp_codec_capabilities_.codecType != CodecType::APTX_HD) ||
+ (!is_hd && temp_codec_capabilities_.codecType != CodecType::APTX)) {
+ return aptx_codec_specifics;
+ }
+ // parse the capability
+ AptxParameters aptx_capability =
+ temp_codec_capabilities_.capabilities.aptxCapabilities();
+ std::vector<android::hardware::bluetooth::audio::V2_0::SampleRate>
+ sample_rates = ExtractValuesFromBitmask<
+ android::hardware::bluetooth::audio::V2_0::SampleRate>(
+ aptx_capability.sampleRate, 0xff, supported);
+ std::vector<ChannelMode> channel_modes =
+ ExtractValuesFromBitmask<ChannelMode>(aptx_capability.channelMode, 0x03,
+ supported);
+ std::vector<BitsPerSample> bits_per_samples =
+ ExtractValuesFromBitmask<BitsPerSample>(aptx_capability.bitsPerSample,
+ 0x07, supported);
+ // combine those parameters into one list of
+ // CodecConfiguration::CodecSpecific
+ CodecSpecificConfig codec_specific = {};
+ AptxParameters aptx_data;
+ for (auto sample_rate : sample_rates) {
+ for (auto channel_mode : channel_modes) {
+ for (auto bits_per_sample : bits_per_samples) {
+ aptx_data = {.sampleRate = sample_rate,
+ .channelMode = channel_mode,
+ .bitsPerSample = bits_per_sample};
+ codec_specific.aptxConfig(aptx_data);
+ aptx_codec_specifics.push_back(codec_specific);
+ }
+ }
+ }
+ return aptx_codec_specifics;
+ }
+
+ // temp storage saves the specified codec capability by
+ // GetOffloadCodecCapabilityHelper()
+ CodecCapabilities temp_codec_capabilities_;
+};
+
+/**
+ * Test whether we can open a provider of type
+ */
+TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest, OpenA2dpHardwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
+ * SBC hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
+ StartAndEndA2dpSbcHardwareSession) {
+ if (!IsOffloadSupported()) {
+ return;
+ }
+
+ CodecConfiguration codec_config = {};
+ codec_config.codecType = CodecType::SBC;
+ codec_config.encodedAudioBitrate = 328000;
+ codec_config.peerMtu = 1005;
+ codec_config.isScmstEnabled = false;
+ AudioConfiguration audio_config = {};
+ std::vector<CodecSpecificConfig> sbc_codec_specifics =
+ GetSbcCodecSpecificSupportedList(true);
+ auto hidl_cb = [](BluetoothAudioStatus status,
+ const DataMQ::Descriptor& dataMQ) {
+ EXPECT_EQ(status, BluetoothAudioStatus::SUCCESS);
+ EXPECT_FALSE(dataMQ.isHandleValid());
+ };
+ for (auto codec_specific : sbc_codec_specifics) {
+ codec_config.config = codec_specific;
+ audio_config.codecConfig(codec_config);
+ auto hidl_retval =
+ audio_provider_->startSession(audio_port_, audio_config, hidl_cb);
+ // HIDL calls should not be failed and callback has to be executed
+ ASSERT_TRUE(hidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
+ * AAC hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
+ StartAndEndA2dpAacHardwareSession) {
+ if (!IsOffloadSupported()) {
+ return;
+ }
+
+ CodecConfiguration codec_config = {};
+ codec_config.codecType = CodecType::AAC;
+ codec_config.encodedAudioBitrate = 320000;
+ codec_config.peerMtu = 1005;
+ codec_config.isScmstEnabled = false;
+ AudioConfiguration audio_config = {};
+ std::vector<CodecSpecificConfig> aac_codec_specifics =
+ GetAacCodecSpecificSupportedList(true);
+ auto hidl_cb = [](BluetoothAudioStatus status,
+ const DataMQ::Descriptor& dataMQ) {
+ EXPECT_EQ(status, BluetoothAudioStatus::SUCCESS);
+ EXPECT_FALSE(dataMQ.isHandleValid());
+ };
+ for (auto codec_specific : aac_codec_specifics) {
+ codec_config.config = codec_specific;
+ audio_config.codecConfig(codec_config);
+ auto hidl_retval =
+ audio_provider_->startSession(audio_port_, audio_config, hidl_cb);
+ // HIDL calls should not be failed and callback has to be executed
+ ASSERT_TRUE(hidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
+ * LDAC hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
+ StartAndEndA2dpLdacHardwareSession) {
+ if (!IsOffloadSupported()) {
+ return;
+ }
+
+ CodecConfiguration codec_config = {};
+ codec_config.codecType = CodecType::LDAC;
+ codec_config.encodedAudioBitrate = 990000;
+ codec_config.peerMtu = 1005;
+ codec_config.isScmstEnabled = false;
+ AudioConfiguration audio_config = {};
+ std::vector<CodecSpecificConfig> ldac_codec_specifics =
+ GetLdacCodecSpecificSupportedList(true);
+ auto hidl_cb = [](BluetoothAudioStatus status,
+ const DataMQ::Descriptor& dataMQ) {
+ EXPECT_EQ(status, BluetoothAudioStatus::SUCCESS);
+ EXPECT_FALSE(dataMQ.isHandleValid());
+ };
+ for (auto codec_specific : ldac_codec_specifics) {
+ codec_config.config = codec_specific;
+ audio_config.codecConfig(codec_config);
+ auto hidl_retval =
+ audio_provider_->startSession(audio_port_, audio_config, hidl_cb);
+ // HIDL calls should not be failed and callback has to be executed
+ ASSERT_TRUE(hidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
+ * AptX hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
+ StartAndEndA2dpAptxHardwareSession) {
+ if (!IsOffloadSupported()) {
+ return;
+ }
+
+ for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
+ CodecConfiguration codec_config = {};
+ codec_config.codecType = codec_type;
+ codec_config.encodedAudioBitrate =
+ (codec_type == CodecType::APTX ? 352000 : 576000);
+ codec_config.peerMtu = 1005;
+ codec_config.isScmstEnabled = false;
+ AudioConfiguration audio_config = {};
+ std::vector<CodecSpecificConfig> aptx_codec_specifics =
+ GetAptxCodecSpecificSupportedList(
+ (codec_type == CodecType::APTX_HD ? true : false), true);
+ auto hidl_cb = [](BluetoothAudioStatus status,
+ const DataMQ::Descriptor& dataMQ) {
+ EXPECT_EQ(status, BluetoothAudioStatus::SUCCESS);
+ EXPECT_FALSE(dataMQ.isHandleValid());
+ };
+ for (auto codec_specific : aptx_codec_specifics) {
+ codec_config.config = codec_specific;
+ audio_config.codecConfig(codec_config);
+ auto hidl_retval =
+ audio_provider_->startSession(audio_port_, audio_config, hidl_cb);
+ // HIDL calls should not be failed and callback has to be executed
+ ASSERT_TRUE(hidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+ }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
+ * an invalid codec config
+ */
+TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
+ StartAndEndA2dpHardwareSessionInvalidCodecConfig) {
+ if (!IsOffloadSupported()) {
+ return;
+ }
+ ASSERT_NE(audio_provider_, nullptr);
+
+ std::vector<CodecSpecificConfig> codec_specifics;
+ for (auto codec_type : a2dp_codec_types) {
+ switch (codec_type) {
+ case CodecType::SBC:
+ codec_specifics = GetSbcCodecSpecificSupportedList(false);
+ break;
+ case CodecType::AAC:
+ codec_specifics = GetAacCodecSpecificSupportedList(false);
+ break;
+ case CodecType::LDAC:
+ codec_specifics = GetLdacCodecSpecificSupportedList(false);
+ break;
+ case CodecType::APTX:
+ codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
+ break;
+ case CodecType::APTX_HD:
+ codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
+ break;
+ case CodecType::UNKNOWN:
+ codec_specifics.clear();
+ break;
+ }
+ if (codec_specifics.empty()) {
+ continue;
+ }
+
+ CodecConfiguration codec_config = {};
+ codec_config.codecType = codec_type;
+ codec_config.encodedAudioBitrate = 328000;
+ codec_config.peerMtu = 1005;
+ codec_config.isScmstEnabled = false;
+ AudioConfiguration audio_config = {};
+ auto hidl_cb = [](BluetoothAudioStatus status,
+ const DataMQ::Descriptor& dataMQ) {
+ EXPECT_EQ(status, BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION);
+ EXPECT_FALSE(dataMQ.isHandleValid());
+ };
+ for (auto codec_specific : codec_specifics) {
+ codec_config.config = codec_specific;
+ audio_config.codecConfig(codec_config);
+ auto hidl_retval =
+ audio_provider_->startSession(audio_port_, audio_config, hidl_cb);
+ // HIDL calls should not be failed and callback has to be executed
+ ASSERT_TRUE(hidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+ }
+}
+
+/**
+ * openProvider HEARING_AID_SOFTWARE_ENCODING_DATAPATH
+ */
+class BluetoothAudioProviderHearingAidSoftwareHidlTest
+ : public BluetoothAudioProvidersFactoryHidlTest {
+ public:
+ virtual void SetUp() override {
+ BluetoothAudioProvidersFactoryHidlTest::SetUp();
+ GetProviderCapabilitiesHelper(
+ SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
+ OpenProviderHelper(SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
+ ASSERT_NE(audio_provider_, nullptr);
+ }
+
+ virtual void TearDown() override {
+ audio_port_ = nullptr;
+ audio_provider_ = nullptr;
+ BluetoothAudioProvidersFactoryHidlTest::TearDown();
+ }
+
+ static constexpr android::hardware::bluetooth::audio::V2_0::SampleRate
+ hearing_aid_sample_rates_[3] = {
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_UNKNOWN,
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_16000,
+ android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_24000};
+ static constexpr BitsPerSample hearing_aid_bits_per_samples_[3] = {
+ BitsPerSample::BITS_UNKNOWN, BitsPerSample::BITS_16,
+ BitsPerSample::BITS_24};
+ static constexpr ChannelMode hearing_aid_channel_modes_[3] = {
+ ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
+};
+
+/**
+ * Test whether each provider of type
+ * SessionType::HEARING_AID_HARDWARE_ENCODING_DATAPATH can be started and
+ * stopped with SBC hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderHearingAidSoftwareHidlTest,
+ OpenHearingAidSoftwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH can be started and
+ * stopped with different PCM config
+ */
+TEST_P(BluetoothAudioProviderHearingAidSoftwareHidlTest,
+ StartAndEndHearingAidSessionWithPossiblePcmConfig) {
+ bool is_codec_config_valid;
+ std::unique_ptr<DataMQ> tempDataMQ;
+ auto hidl_cb = [&is_codec_config_valid, &tempDataMQ](
+ BluetoothAudioStatus status,
+ const DataMQ::Descriptor& dataMQ) {
+ if (is_codec_config_valid) {
+ ASSERT_EQ(status, BluetoothAudioStatus::SUCCESS);
+ ASSERT_TRUE(dataMQ.isHandleValid());
+ tempDataMQ.reset(new DataMQ(dataMQ));
+ } else {
+ EXPECT_EQ(status, BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION);
+ EXPECT_FALSE(dataMQ.isHandleValid());
+ }
+ };
+ AudioConfiguration audio_config = {};
+ PcmParameters pcm_parameters = {};
+ for (auto sample_rate : hearing_aid_sample_rates_) {
+ pcm_parameters.sampleRate = sample_rate;
+ for (auto bits_per_sample : hearing_aid_bits_per_samples_) {
+ pcm_parameters.bitsPerSample = bits_per_sample;
+ for (auto channel_mode : hearing_aid_channel_modes_) {
+ pcm_parameters.channelMode = channel_mode;
+ is_codec_config_valid = IsPcmParametersSupported(pcm_parameters);
+ audio_config.pcmConfig(pcm_parameters);
+ auto hidl_retval =
+ audio_provider_->startSession(audio_port_, audio_config, hidl_cb);
+ // HIDL calls should not be failed and callback has to be executed
+ ASSERT_TRUE(hidl_retval.isOk());
+ if (is_codec_config_valid) {
+ EXPECT_TRUE(tempDataMQ != nullptr && tempDataMQ->isValid());
+ }
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ } // ChannelMode
+ } // BitsPerSampple
+ } // SampleRate
+}
+
+/**
+ * openProvider LE_AUDIO_SOFTWARE_ENCODING_DATAPATH
+ */
+class BluetoothAudioProviderLeAudioOutputSoftwareHidlTest
+ : public BluetoothAudioProvidersFactoryHidlTest {
+ public:
+ virtual void SetUp() override {
+ BluetoothAudioProvidersFactoryHidlTest::SetUp();
+ GetProviderCapabilitiesHelper_2_1(
+ android::hardware::bluetooth::audio::V2_1::SessionType::
+ LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
+ OpenProviderHelper_2_1(
+ android::hardware::bluetooth::audio::V2_1::SessionType::
+ LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
+ ASSERT_NE(audio_provider_2_1_, nullptr);
+ }
+
+ virtual void TearDown() override {
+ audio_port_ = nullptr;
+ audio_provider_2_1_ = nullptr;
+ BluetoothAudioProvidersFactoryHidlTest::TearDown();
+ }
+
+ static constexpr SampleRate le_audio_output_sample_rates_[3] = {
+ SampleRate::RATE_UNKNOWN, SampleRate::RATE_16000, SampleRate::RATE_24000};
+ static constexpr BitsPerSample le_audio_output_bits_per_samples_[3] = {
+ BitsPerSample::BITS_UNKNOWN, BitsPerSample::BITS_16,
+ BitsPerSample::BITS_24};
+ static constexpr ChannelMode le_audio_output_channel_modes_[3] = {
+ ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
+ static constexpr uint32_t le_audio_output_data_interval_us_[2] = {
+ 0 /* Invalid */, 10000 /* Valid 10ms */};
+};
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
+ * stopped
+ */
+TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareHidlTest,
+ OpenLeAudioOutputSoftwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
+ * stopped with different PCM config
+ */
+TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareHidlTest,
+ StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
+ bool is_codec_config_valid;
+ std::unique_ptr<DataMQ> tempDataMQ;
+ auto hidl_cb = [&is_codec_config_valid, &tempDataMQ](
+ BluetoothAudioStatus status,
+ const DataMQ::Descriptor& dataMQ) {
+ if (is_codec_config_valid) {
+ ASSERT_EQ(status, BluetoothAudioStatus::SUCCESS);
+ ASSERT_TRUE(dataMQ.isHandleValid());
+ tempDataMQ.reset(new DataMQ(dataMQ));
+ } else {
+ EXPECT_EQ(status, BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION);
+ EXPECT_FALSE(dataMQ.isHandleValid());
+ }
+ };
+ android::hardware::bluetooth::audio::V2_1::AudioConfiguration audio_config =
+ {};
+ android::hardware::bluetooth::audio::V2_1::PcmParameters pcm_parameters = {};
+ for (auto sample_rate : le_audio_output_sample_rates_) {
+ pcm_parameters.sampleRate = sample_rate;
+ for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
+ pcm_parameters.bitsPerSample = bits_per_sample;
+ for (auto channel_mode : le_audio_output_channel_modes_) {
+ pcm_parameters.channelMode = channel_mode;
+ for (auto data_interval_us : le_audio_output_data_interval_us_) {
+ pcm_parameters.dataIntervalUs = data_interval_us;
+ is_codec_config_valid = IsPcmParametersSupported_2_1(pcm_parameters);
+ audio_config.pcmConfig(pcm_parameters);
+ auto hidl_retval = audio_provider_2_1_->startSession_2_1(
+ audio_port_, audio_config, hidl_cb);
+ // HIDL calls should not be failed and callback has to be executed
+ ASSERT_TRUE(hidl_retval.isOk());
+ if (is_codec_config_valid) {
+ EXPECT_TRUE(tempDataMQ != nullptr && tempDataMQ->isValid());
+ }
+ EXPECT_TRUE(audio_provider_2_1_->endSession().isOk());
+ } // uint32_t (data interval in microseconds)
+ } // ChannelMode
+ } // BitsPerSampple
+ } // SampleRate
+}
+
+/**
+ * openProvider LE_AUDIO_SOFTWARE_DECODED_DATAPATH
+ */
+class BluetoothAudioProviderLeAudioInputSoftwareHidlTest
+ : public BluetoothAudioProvidersFactoryHidlTest {
+ public:
+ virtual void SetUp() override {
+ BluetoothAudioProvidersFactoryHidlTest::SetUp();
+ GetProviderCapabilitiesHelper_2_1(
+ android::hardware::bluetooth::audio::V2_1::SessionType::
+ LE_AUDIO_SOFTWARE_DECODED_DATAPATH);
+ OpenProviderHelper_2_1(android::hardware::bluetooth::audio::V2_1::
+ SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH);
+ ASSERT_NE(audio_provider_2_1_, nullptr);
+ }
+
+ virtual void TearDown() override {
+ audio_port_ = nullptr;
+ audio_provider_2_1_ = nullptr;
+ BluetoothAudioProvidersFactoryHidlTest::TearDown();
+ }
+
+ static constexpr SampleRate le_audio_output_sample_rates_[3] = {
+ SampleRate::RATE_UNKNOWN, SampleRate::RATE_16000, SampleRate::RATE_24000};
+ static constexpr BitsPerSample le_audio_output_bits_per_samples_[3] = {
+ BitsPerSample::BITS_UNKNOWN, BitsPerSample::BITS_16,
+ BitsPerSample::BITS_24};
+ static constexpr ChannelMode le_audio_output_channel_modes_[3] = {
+ ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
+ static constexpr uint32_t le_audio_output_data_interval_us_[2] = {
+ 0 /* Invalid */, 10000 /* Valid 10ms */};
+};
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH can be started and
+ * stopped
+ */
+TEST_P(BluetoothAudioProviderLeAudioInputSoftwareHidlTest,
+ OpenLeAudioInputSoftwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH can be started and
+ * stopped with different PCM config
+ */
+TEST_P(BluetoothAudioProviderLeAudioInputSoftwareHidlTest,
+ StartAndEndLeAudioInputSessionWithPossiblePcmConfig) {
+ bool is_codec_config_valid;
+ std::unique_ptr<DataMQ> tempDataMQ;
+ auto hidl_cb = [&is_codec_config_valid, &tempDataMQ](
+ BluetoothAudioStatus status,
+ const DataMQ::Descriptor& dataMQ) {
+ if (is_codec_config_valid) {
+ ASSERT_EQ(status, BluetoothAudioStatus::SUCCESS);
+ ASSERT_TRUE(dataMQ.isHandleValid());
+ tempDataMQ.reset(new DataMQ(dataMQ));
+ } else {
+ EXPECT_EQ(status, BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION);
+ EXPECT_FALSE(dataMQ.isHandleValid());
+ }
+ };
+ android::hardware::bluetooth::audio::V2_1::AudioConfiguration audio_config =
+ {};
+ android::hardware::bluetooth::audio::V2_1::PcmParameters pcm_parameters = {};
+ for (auto sample_rate : le_audio_output_sample_rates_) {
+ pcm_parameters.sampleRate = sample_rate;
+ for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
+ pcm_parameters.bitsPerSample = bits_per_sample;
+ for (auto channel_mode : le_audio_output_channel_modes_) {
+ pcm_parameters.channelMode = channel_mode;
+ for (auto data_interval_us : le_audio_output_data_interval_us_) {
+ pcm_parameters.dataIntervalUs = data_interval_us;
+ is_codec_config_valid = IsPcmParametersSupported_2_1(pcm_parameters);
+ audio_config.pcmConfig(pcm_parameters);
+ auto hidl_retval = audio_provider_2_1_->startSession_2_1(
+ audio_port_, audio_config, hidl_cb);
+ // HIDL calls should not be failed and callback has to be executed
+ ASSERT_TRUE(hidl_retval.isOk());
+ if (is_codec_config_valid) {
+ EXPECT_TRUE(tempDataMQ != nullptr && tempDataMQ->isValid());
+ } else {
+ EXPECT_TRUE(tempDataMQ == nullptr);
+ }
+ EXPECT_TRUE(audio_provider_2_1_->endSession().isOk());
+ } // uint32_t (data interval in microseconds)
+ } // ChannelMode
+ } // BitsPerSampple
+ } // SampleRate
+}
+
+static const std::vector<std::string> kAudioInstances =
+ android::hardware::getAllHalInstanceNames(
+ IBluetoothAudioProvidersFactory::descriptor);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProvidersFactoryHidlTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProvidersFactoryHidlTest,
+ testing::ValuesIn(kAudioInstances),
+ android::hardware::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderA2dpSoftwareHidlTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderA2dpSoftwareHidlTest,
+ testing::ValuesIn(kAudioInstances),
+ android::hardware::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderA2dpHardwareHidlTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderA2dpHardwareHidlTest,
+ testing::ValuesIn(kAudioInstances),
+ android::hardware::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderHearingAidSoftwareHidlTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderHearingAidSoftwareHidlTest,
+ testing::ValuesIn(kAudioInstances),
+ android::hardware::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderLeAudioOutputSoftwareHidlTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderLeAudioOutputSoftwareHidlTest,
+ testing::ValuesIn(kAudioInstances),
+ android::hardware::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderLeAudioInputSoftwareHidlTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderLeAudioInputSoftwareHidlTest,
+ testing::ValuesIn(kAudioInstances),
+ android::hardware::PrintInstanceNameToString);
diff --git a/camera/provider/2.4/default/Android.bp b/camera/provider/2.4/default/Android.bp
index 627ddf4..bbb21c7 100644
--- a/camera/provider/2.4/default/Android.bp
+++ b/camera/provider/2.4/default/Android.bp
@@ -76,7 +76,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: ["."],
}
@@ -150,6 +150,7 @@
"android.hidl.memory@1.0",
"libbinder",
"libcamera_metadata",
+ "libcutils",
"libhardware",
"libhidlbase",
"liblog",
diff --git a/camera/provider/2.4/default/service.cpp b/camera/provider/2.4/default/service.cpp
index 4475f7d..84f4839 100644
--- a/camera/provider/2.4/default/service.cpp
+++ b/camera/provider/2.4/default/service.cpp
@@ -22,6 +22,8 @@
#include <android/hardware/camera/provider/2.4/ICameraProvider.h>
#include <binder/ProcessState.h>
+#include <cutils/memory.h>
+#include <cutils/properties.h>
#include <hidl/LegacySupport.h>
using android::status_t;
@@ -41,6 +43,12 @@
// The camera HAL may communicate to other vendor components via
// /dev/vndbinder
android::ProcessState::initWithDriver("/dev/vndbinder");
+
+ // b/166675194
+ if (property_get_bool("ro.vendor.camera.provider24.disable_mem_init", false)) {
+ process_disable_memory_mitigations();
+ }
+
status_t status;
if (kLazyService) {
status = defaultLazyPassthroughServiceImplementation<ICameraProvider>("legacy/0",
diff --git a/common/aidl/Android.bp b/common/aidl/Android.bp
index 9ea4cdf..8029efa 100644
--- a/common/aidl/Android.bp
+++ b/common/aidl/Android.bp
@@ -6,13 +6,14 @@
enabled: true,
support_system_process: true,
},
+ vndk_use_version: "2",
srcs: [
"android/hardware/common/*.aidl",
],
stability: "vintf",
backend: {
java: {
- enabled: false,
+ sdk_version: "module_current",
},
cpp: {
enabled: false,
diff --git a/common/fmq/aidl/Android.bp b/common/fmq/aidl/Android.bp
new file mode 100644
index 0000000..004adab
--- /dev/null
+++ b/common/fmq/aidl/Android.bp
@@ -0,0 +1,21 @@
+aidl_interface {
+ name: "android.hardware.common.fmq",
+ host_supported: true,
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
+ srcs: [
+ "android/hardware/common/fmq/*.aidl",
+ ],
+ stability: "vintf",
+ backend: {
+ java: {
+ enabled: false,
+ },
+ cpp: {
+ enabled: false,
+ },
+ },
+}
diff --git a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/GrantorDescriptor.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/GrantorDescriptor.aidl
similarity index 96%
rename from common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/GrantorDescriptor.aidl
rename to common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/GrantorDescriptor.aidl
index 07bceb0..7ac1930 100644
--- a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/GrantorDescriptor.aidl
+++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/GrantorDescriptor.aidl
@@ -15,7 +15,7 @@
// 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.common;
+package android.hardware.common.fmq;
@VintfStability
parcelable GrantorDescriptor {
int offset;
diff --git a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/MQDescriptor.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/MQDescriptor.aidl
similarity index 91%
rename from common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/MQDescriptor.aidl
rename to common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/MQDescriptor.aidl
index c9fe1d7..2607369 100644
--- a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/MQDescriptor.aidl
+++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/MQDescriptor.aidl
@@ -15,10 +15,10 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.common;
+package android.hardware.common.fmq;
@VintfStability
parcelable MQDescriptor {
- android.hardware.common.GrantorDescriptor[] grantors;
+ android.hardware.common.fmq.GrantorDescriptor[] grantors;
ParcelFileDescriptor fileDescriptor;
int quantum;
int flags;
diff --git a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/SynchronizedReadWrite.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/SynchronizedReadWrite.aidl
similarity index 96%
rename from common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/SynchronizedReadWrite.aidl
rename to common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/SynchronizedReadWrite.aidl
index aec3d6d..2142bdb 100644
--- a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/SynchronizedReadWrite.aidl
+++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/SynchronizedReadWrite.aidl
@@ -15,7 +15,7 @@
// 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.common;
+package android.hardware.common.fmq;
@VintfStability
enum SynchronizedReadWrite {
EMPTY = 0,
diff --git a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/UnsynchronizedWrite.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/UnsynchronizedWrite.aidl
similarity index 96%
rename from common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/UnsynchronizedWrite.aidl
rename to common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/UnsynchronizedWrite.aidl
index e390d20..1220674 100644
--- a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/UnsynchronizedWrite.aidl
+++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/UnsynchronizedWrite.aidl
@@ -15,7 +15,7 @@
// 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.common;
+package android.hardware.common.fmq;
@VintfStability
enum UnsynchronizedWrite {
EMPTY = 0,
diff --git a/common/aidl/android/hardware/common/GrantorDescriptor.aidl b/common/fmq/aidl/android/hardware/common/fmq/GrantorDescriptor.aidl
similarity index 95%
rename from common/aidl/android/hardware/common/GrantorDescriptor.aidl
rename to common/fmq/aidl/android/hardware/common/fmq/GrantorDescriptor.aidl
index 3552e9e..ca69d94 100644
--- a/common/aidl/android/hardware/common/GrantorDescriptor.aidl
+++ b/common/fmq/aidl/android/hardware/common/fmq/GrantorDescriptor.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.hardware.common;
+package android.hardware.common.fmq;
/*
* Included in MQDescriptor, for use with libfmq.
diff --git a/common/aidl/android/hardware/common/MQDescriptor.aidl b/common/fmq/aidl/android/hardware/common/fmq/MQDescriptor.aidl
similarity index 94%
rename from common/aidl/android/hardware/common/MQDescriptor.aidl
rename to common/fmq/aidl/android/hardware/common/fmq/MQDescriptor.aidl
index 7e89b15..82917d6 100644
--- a/common/aidl/android/hardware/common/MQDescriptor.aidl
+++ b/common/fmq/aidl/android/hardware/common/fmq/MQDescriptor.aidl
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package android.hardware.common;
+package android.hardware.common.fmq;
-import android.hardware.common.GrantorDescriptor;
+import android.hardware.common.fmq.GrantorDescriptor;
/*
* For use with libfmq. This is created from an instance of AidlMessageQueue,
diff --git a/common/aidl/android/hardware/common/SynchronizedReadWrite.aidl b/common/fmq/aidl/android/hardware/common/fmq/SynchronizedReadWrite.aidl
similarity index 95%
rename from common/aidl/android/hardware/common/SynchronizedReadWrite.aidl
rename to common/fmq/aidl/android/hardware/common/fmq/SynchronizedReadWrite.aidl
index ef93bf2..8c33442 100644
--- a/common/aidl/android/hardware/common/SynchronizedReadWrite.aidl
+++ b/common/fmq/aidl/android/hardware/common/fmq/SynchronizedReadWrite.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.hardware.common;
+package android.hardware.common.fmq;
/*
* For use with android.hardware.common.MQDescriptor to specify which type of
diff --git a/common/aidl/android/hardware/common/UnsynchronizedWrite.aidl b/common/fmq/aidl/android/hardware/common/fmq/UnsynchronizedWrite.aidl
similarity index 95%
rename from common/aidl/android/hardware/common/UnsynchronizedWrite.aidl
rename to common/fmq/aidl/android/hardware/common/fmq/UnsynchronizedWrite.aidl
index aa27c8d..24c4cce 100644
--- a/common/aidl/android/hardware/common/UnsynchronizedWrite.aidl
+++ b/common/fmq/aidl/android/hardware/common/fmq/UnsynchronizedWrite.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.hardware.common;
+package android.hardware.common.fmq;
/*
* For use with android.hardware.common.MQDescriptor to specify which type of
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index d22aa68..b2a815f 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -13,46 +13,6 @@
// limitations under the License.
vintf_compatibility_matrix {
- name: "framework_compatibility_matrix.legacy.xml",
- stem: "compatibility_matrix.legacy.xml",
- srcs: [
- "compatibility_matrix.legacy.xml",
- ],
- kernel_configs: [
- // legacy uses O kernel requirements
- "kernel_config_o_3.18",
- "kernel_config_o_4.4",
- "kernel_config_o_4.9",
- ],
-}
-
-vintf_compatibility_matrix {
- name: "framework_compatibility_matrix.1.xml",
- stem: "compatibility_matrix.1.xml",
- srcs: [
- "compatibility_matrix.1.xml",
- ],
- kernel_configs: [
- "kernel_config_o_3.18",
- "kernel_config_o_4.4",
- "kernel_config_o_4.9",
- ],
-}
-
-vintf_compatibility_matrix {
- name: "framework_compatibility_matrix.2.xml",
- stem: "compatibility_matrix.2.xml",
- srcs: [
- "compatibility_matrix.2.xml",
- ],
- kernel_configs: [
- "kernel_config_o_mr1_3.18",
- "kernel_config_o_mr1_4.4",
- "kernel_config_o_mr1_4.9",
- ],
-}
-
-vintf_compatibility_matrix {
name: "framework_compatibility_matrix.3.xml",
stem: "compatibility_matrix.3.xml",
srcs: [
diff --git a/compatibility_matrices/Android.mk b/compatibility_matrices/Android.mk
index 96191c8..3951666 100644
--- a/compatibility_matrices/Android.mk
+++ b/compatibility_matrices/Android.mk
@@ -33,7 +33,7 @@
LOCAL_SRC_FILES := compatibility_matrix.empty.xml
else
-# DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE specify an absolute path
+# DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE specifies absolute paths
LOCAL_GENERATED_SOURCES := $(DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE)
# Enforce that DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE does not specify required HALs
@@ -77,7 +77,7 @@
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_RELATIVE_PATH := vintf
-# DEVICE_PRODUCT_COMPATIBILITY_MATRIX_FILE specify an absolute path
+# DEVICE_PRODUCT_COMPATIBILITY_MATRIX_FILE specifies absolute paths
LOCAL_GENERATED_SOURCES := $(DEVICE_PRODUCT_COMPATIBILITY_MATRIX_FILE)
# Enforce that DEVICE_PRODUCT_COMPATIBILITY_MATRIX_FILE does not specify required HALs
@@ -92,9 +92,6 @@
endif # DEVICE_PRODUCT_COMPATIBILITY_MATRIX_FILE
my_system_matrix_deps := \
- framework_compatibility_matrix.legacy.xml \
- framework_compatibility_matrix.1.xml \
- framework_compatibility_matrix.2.xml \
framework_compatibility_matrix.3.xml \
framework_compatibility_matrix.4.xml \
framework_compatibility_matrix.5.xml \
diff --git a/compatibility_matrices/CleanSpec.mk b/compatibility_matrices/CleanSpec.mk
index 9b150ed..5b351a5 100644
--- a/compatibility_matrices/CleanSpec.mk
+++ b/compatibility_matrices/CleanSpec.mk
@@ -45,3 +45,6 @@
#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/vintf/compatibility_matrix.device.xml)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/vintf/compatibility_matrix.legacy.xml)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/vintf/compatibility_matrix.1.xml)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/vintf/compatibility_matrix.2.xml)
diff --git a/compatibility_matrices/compatibility_matrix.1.xml b/compatibility_matrices/compatibility_matrix.1.xml
deleted file mode 100644
index cccf24f..0000000
--- a/compatibility_matrices/compatibility_matrix.1.xml
+++ /dev/null
@@ -1,326 +0,0 @@
-<compatibility-matrix version="1.0" type="framework" level="1">
- <hal format="hidl" optional="false">
- <name>android.hardware.audio</name>
- <version>2.0</version>
- <interface>
- <name>IDevicesFactory</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="false">
- <name>android.hardware.audio.effect</name>
- <version>2.0</version>
- <interface>
- <name>IEffectsFactory</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.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.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</version>
- <interface>
- <name>IBroadcastRadioFactory</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.camera.provider</name>
- <version>2.4</version>
- <interface>
- <name>ICameraProvider</name>
- <instance>legacy/0</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.configstore</name>
- <version>1.0</version>
- <interface>
- <name>ISurfaceFlingerConfigs</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="false">
- <name>android.hardware.drm</name>
- <version>1.0</version>
- <interface>
- <name>ICryptoFactory</name>
- <instance>default</instance>
- </interface>
- <interface>
- <name>IDrmFactory</name>
- <instance>default</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="false">
- <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>1.0</version>
- <interface>
- <name>IGnss</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="false">
- <name>android.hardware.graphics.allocator</name>
- <version>2.0</version>
- <interface>
- <name>IAllocator</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="false">
- <name>android.hardware.graphics.composer</name>
- <version>2.1</version>
- <interface>
- <name>IComposer</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="false">
- <name>android.hardware.graphics.mapper</name>
- <version>2.0</version>
- <interface>
- <name>IMapper</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.health</name>
- <version>1.0</version>
- <interface>
- <name>IHealth</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="false">
- <name>android.hardware.keymaster</name>
- <version>3.0</version>
- <interface>
- <name>IKeymasterDevice</name>
- <instance>default</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="false">
- <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.nfc</name>
- <version>1.0</version>
- <interface>
- <name>INfc</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.power</name>
- <version>1.0</version>
- <interface>
- <name>IPower</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.radio</name>
- <version>1.0</version>
- <interface>
- <name>IRadio</name>
- <instance>slot1</instance>
- </interface>
- <interface>
- <name>ISap</name>
- <instance>slot1</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.radio.deprecated</name>
- <version>1.0</version>
- <interface>
- <name>IOemHook</name>
- <instance>slot1</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.sensors</name>
- <version>1.0</version>
- <interface>
- <name>ISensors</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.soundtrigger</name>
- <version>2.0</version>
- <interface>
- <name>ISoundTriggerHw</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.thermal</name>
- <version>1.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</version>
- <interface>
- <name>IUsb</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.vibrator</name>
- <version>1.0</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.wifi</name>
- <version>1.0</version>
- <interface>
- <name>IWifi</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.wifi.supplicant</name>
- <version>1.0</version>
- <interface>
- <name>ISupplicant</name>
- <instance>default</instance>
- </interface>
- </hal>
-</compatibility-matrix>
diff --git a/compatibility_matrices/compatibility_matrix.2.xml b/compatibility_matrices/compatibility_matrix.2.xml
deleted file mode 100644
index d4f9809..0000000
--- a/compatibility_matrices/compatibility_matrix.2.xml
+++ /dev/null
@@ -1,374 +0,0 @@
-<compatibility-matrix version="1.0" type="framework" level="2">
- <hal format="hidl" optional="false">
- <name>android.hardware.audio</name>
- <version>2.0</version>
- <interface>
- <name>IDevicesFactory</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="false">
- <name>android.hardware.audio.effect</name>
- <version>2.0</version>
- <interface>
- <name>IEffectsFactory</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.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.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.camera.provider</name>
- <version>2.4</version>
- <interface>
- <name>ICameraProvider</name>
- <instance>legacy/0</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.cas</name>
- <version>1.0</version>
- <interface>
- <name>IMediaCasService</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.configstore</name>
- <version>1.0</version>
- <interface>
- <name>ISurfaceFlingerConfigs</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="false">
- <name>android.hardware.drm</name>
- <version>1.0</version>
- <interface>
- <name>ICryptoFactory</name>
- <instance>default</instance>
- </interface>
- <interface>
- <name>IDrmFactory</name>
- <instance>default</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="false">
- <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>1.0</version>
- <interface>
- <name>IGnss</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="false">
- <name>android.hardware.graphics.allocator</name>
- <version>2.0</version>
- <interface>
- <name>IAllocator</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="false">
- <name>android.hardware.graphics.composer</name>
- <version>2.1</version>
- <interface>
- <name>IComposer</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="false">
- <name>android.hardware.graphics.mapper</name>
- <version>2.0</version>
- <interface>
- <name>IMapper</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.health</name>
- <version>1.0</version>
- <interface>
- <name>IHealth</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="false">
- <name>android.hardware.keymaster</name>
- <version>3.0</version>
- <interface>
- <name>IKeymasterDevice</name>
- <instance>default</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="false">
- <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.nfc</name>
- <version>1.0</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-1</version>
- <interface>
- <name>IPower</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.radio</name>
- <version>1.0-1</version>
- <interface>
- <name>IRadio</name>
- <instance>slot1</instance>
- </interface>
- <interface>
- <name>ISap</name>
- <instance>slot1</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.radio.deprecated</name>
- <version>1.0</version>
- <interface>
- <name>IOemHook</name>
- <instance>slot1</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.sensors</name>
- <version>1.0</version>
- <interface>
- <name>ISensors</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.soundtrigger</name>
- <version>2.0</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>1.0-1</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-1</version>
- <interface>
- <name>IUsb</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.vibrator</name>
- <version>1.0-1</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-1</version>
- <interface>
- <name>IWifi</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.wifi.offload</name>
- <version>1.0</version>
- <interface>
- <name>IOffload</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.wifi.supplicant</name>
- <version>1.0</version>
- <interface>
- <name>ISupplicant</name>
- <instance>default</instance>
- </interface>
- </hal>
-</compatibility-matrix>
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 9400543..d1d254b 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -96,6 +96,13 @@
<instance>default</instance>
</interface>
</hal>
+ <hal format="aidl" optional="true">
+ <name>android.hardware.biometrics.face</name>
+ <interface>
+ <name>IFace</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
<hal format="hidl" optional="true">
<name>android.hardware.biometrics.fingerprint</name>
<version>2.1-3</version>
@@ -121,7 +128,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.bluetooth.audio</name>
- <version>2.0</version>
+ <version>2.0-1</version>
<interface>
<name>IBluetoothAudioProvidersFactory</name>
<instance>default</instance>
@@ -177,7 +184,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.contexthub</name>
- <version>1.0-1</version>
+ <version>1.0-2</version>
<interface>
<name>IContexthub</name>
<instance>default</instance>
@@ -381,7 +388,7 @@
</interface>
</hal>
<hal format="aidl" optional="true">
- <name>android.hardware.powerstats</name>
+ <name>android.hardware.power.stats</name>
<interface>
<name>IPowerStats</name>
<instance>default</instance>
@@ -547,7 +554,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.wifi</name>
- <version>1.0-5</version>
+ <version>1.3-5</version>
<interface>
<name>IWifi</name>
<instance>default</instance>
@@ -563,7 +570,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.wifi.supplicant</name>
- <version>1.0-4</version>
+ <version>1.2-4</version>
<interface>
<name>ISupplicant</name>
<instance>default</instance>
diff --git a/compatibility_matrices/compatibility_matrix.legacy.xml b/compatibility_matrices/compatibility_matrix.legacy.xml
deleted file mode 100644
index 8a4d2ee..0000000
--- a/compatibility_matrices/compatibility_matrix.legacy.xml
+++ /dev/null
@@ -1,326 +0,0 @@
-<compatibility-matrix version="1.0" type="framework" level="legacy">
- <hal format="hidl" optional="false">
- <name>android.hardware.audio</name>
- <version>2.0</version>
- <interface>
- <name>IDevicesFactory</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="false">
- <name>android.hardware.audio.effect</name>
- <version>2.0</version>
- <interface>
- <name>IEffectsFactory</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.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.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</version>
- <interface>
- <name>IBroadcastRadioFactory</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.camera.provider</name>
- <version>2.4</version>
- <interface>
- <name>ICameraProvider</name>
- <instance>legacy/0</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.configstore</name>
- <version>1.0</version>
- <interface>
- <name>ISurfaceFlingerConfigs</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="false">
- <name>android.hardware.drm</name>
- <version>1.0</version>
- <interface>
- <name>ICryptoFactory</name>
- <instance>default</instance>
- </interface>
- <interface>
- <name>IDrmFactory</name>
- <instance>default</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>1.0</version>
- <interface>
- <name>IGnss</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="false">
- <name>android.hardware.graphics.allocator</name>
- <version>2.0</version>
- <interface>
- <name>IAllocator</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="false">
- <name>android.hardware.graphics.composer</name>
- <version>2.1</version>
- <interface>
- <name>IComposer</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="false">
- <name>android.hardware.graphics.mapper</name>
- <version>2.0</version>
- <interface>
- <name>IMapper</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.health</name>
- <version>1.0</version>
- <interface>
- <name>IHealth</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="false">
- <name>android.hardware.keymaster</name>
- <version>3.0</version>
- <interface>
- <name>IKeymasterDevice</name>
- <instance>default</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="false">
- <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.nfc</name>
- <version>1.0</version>
- <interface>
- <name>INfc</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.power</name>
- <version>1.0</version>
- <interface>
- <name>IPower</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.radio</name>
- <version>1.0</version>
- <interface>
- <name>IRadio</name>
- <instance>slot1</instance>
- </interface>
- <interface>
- <name>ISap</name>
- <instance>slot1</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.radio.deprecated</name>
- <version>1.0</version>
- <interface>
- <name>IOemHook</name>
- <instance>slot1</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.sensors</name>
- <version>1.0</version>
- <interface>
- <name>ISensors</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.soundtrigger</name>
- <version>2.0</version>
- <interface>
- <name>ISoundTriggerHw</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.thermal</name>
- <version>1.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</version>
- <interface>
- <name>IUsb</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.vibrator</name>
- <version>1.0</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.wifi</name>
- <version>1.0</version>
- <interface>
- <name>IWifi</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.wifi.supplicant</name>
- <version>1.0</version>
- <interface>
- <name>ISupplicant</name>
- <instance>default</instance>
- </interface>
- </hal>
-</compatibility-matrix>
diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp
index 20b7281..6725a98 100644
--- a/compatibility_matrices/exclude/fcm_exclude.cpp
+++ b/compatibility_matrices/exclude/fcm_exclude.cpp
@@ -53,12 +53,26 @@
// AIDL
"android.hardware.biometrics.common",
"android.hardware.common",
+ "android.hardware.common.fmq",
"android.hardware.graphics.common",
"android.hardware.keymaster",
// Fastboot HAL is only used by recovery. Recovery is owned by OEM. Framework
// does not depend on this HAL, hence it is not declared in any manifests or matrices.
"android.hardware.fastboot@1.0",
+ "android.hardware.fastboot@1.1",
+
+ // Deprecated HALs.
+ // HIDL
+ // TODO(b/171260360) Remove when HAL definition is removed
+ "android.hardware.audio.effect@2.0",
+ "android.hardware.audio@2.0",
+ // TODO(b/171260613) Remove when HAL definition is removed
+ "android.hardware.health@1.0",
+ // TODO(b/171260670) Remove when HAL definition is removed
+ "android.hardware.nfc@1.0",
+ // TODO(b/171260715) Remove when HAL definition is removed
+ "android.hardware.radio.deprecated@1.0",
};
auto package_has_prefix = [&](const std::string& prefix) {
diff --git a/contexthub/1.0/vts/functional/OWNERS b/contexthub/1.0/vts/functional/OWNERS
index 161b2f0..1a33a9e 100644
--- a/contexthub/1.0/vts/functional/OWNERS
+++ b/contexthub/1.0/vts/functional/OWNERS
@@ -5,4 +5,3 @@
#VTS team
dshi@google.com
-trong@google.com
diff --git a/contexthub/1.1/default/Android.bp b/contexthub/1.1/default/Android.bp
index 86858c0..5c9ec4e 100644
--- a/contexthub/1.1/default/Android.bp
+++ b/contexthub/1.1/default/Android.bp
@@ -38,5 +38,8 @@
"liblog",
"libutils",
],
+ header_libs: [
+ "android.hardware.contexthub@1.X-common-impl",
+ ],
vintf_fragments: ["android.hardware.contexthub@1.1.xml"],
}
diff --git a/contexthub/1.1/default/Contexthub.cpp b/contexthub/1.1/default/Contexthub.cpp
index 19cc262..e7fde84 100644
--- a/contexthub/1.1/default/Contexthub.cpp
+++ b/contexthub/1.1/default/Contexthub.cpp
@@ -23,81 +23,6 @@
namespace V1_1 {
namespace implementation {
-using ::android::hardware::contexthub::V1_0::ContextHub;
-using ::android::hardware::contexthub::V1_0::HubAppInfo;
-using ::android::hardware::contexthub::V1_0::Result;
-
-namespace {
-
-constexpr uint32_t kMockHubId = 0;
-
-} // anonymous namespace
-
-Return<void> Contexthub::getHubs(getHubs_cb _hidl_cb) {
- ContextHub hub = {};
- hub.name = "Mock Context Hub";
- hub.vendor = "AOSP";
- hub.toolchain = "n/a";
- hub.platformVersion = 1;
- hub.toolchainVersion = 1;
- hub.hubId = kMockHubId;
- hub.peakMips = 1;
- hub.peakPowerDrawMw = 1;
- hub.maxSupportedMsgLen = 4096;
- hub.chrePlatformId = UINT64_C(0x476f6f6754000000);
- hub.chreApiMajorVersion = 1;
- hub.chreApiMinorVersion = 4;
-
- // Report a single mock hub
- std::vector<ContextHub> hubs;
- hubs.push_back(hub);
-
- _hidl_cb(hubs);
- return Void();
-}
-
-Return<Result> Contexthub::registerCallback(uint32_t hubId, const sp<IContexthubCallback>& cb) {
- if (hubId == kMockHubId) {
- mCallback = cb;
- return Result::OK;
- }
- return Result::BAD_PARAMS;
-}
-
-// We don't expose any nanoapps, therefore all nanoapp-related API calls return with BAD_PARAMS
-Return<Result> Contexthub::sendMessageToHub(uint32_t /*hubId*/, const ContextHubMsg& /*msg*/) {
- return Result::BAD_PARAMS;
-}
-
-Return<Result> Contexthub::loadNanoApp(uint32_t /*hubId*/, const NanoAppBinary& /*appBinary*/,
- uint32_t /*transactionId*/) {
- return Result::BAD_PARAMS;
-}
-
-Return<Result> Contexthub::unloadNanoApp(uint32_t /*hubId*/, uint64_t /*appId*/,
- uint32_t /*transactionId*/) {
- return Result::BAD_PARAMS;
-}
-
-Return<Result> Contexthub::enableNanoApp(uint32_t /*hubId*/, uint64_t /*appId*/,
- uint32_t /*transactionId*/) {
- return Result::BAD_PARAMS;
-}
-
-Return<Result> Contexthub::disableNanoApp(uint32_t /*hubId*/, uint64_t /*appId*/,
- uint32_t /*transactionId*/) {
- return Result::BAD_PARAMS;
-}
-
-Return<Result> Contexthub::queryApps(uint32_t hubId) {
- if (hubId == kMockHubId && mCallback != nullptr) {
- std::vector<HubAppInfo> nanoapps;
- mCallback->handleAppsInfo(nanoapps);
- return Result::OK;
- }
- return Result::BAD_PARAMS;
-}
-
Return<void> Contexthub::onSettingChanged(Setting /*setting*/, SettingValue /*newValue*/) {
return Void();
}
diff --git a/contexthub/1.1/default/Contexthub.h b/contexthub/1.1/default/Contexthub.h
index 0da61d1..1468fcf 100644
--- a/contexthub/1.1/default/Contexthub.h
+++ b/contexthub/1.1/default/Contexthub.h
@@ -15,6 +15,8 @@
*/
#pragma once
+#include "ContextHub.h"
+
#include <android/hardware/contexthub/1.1/IContexthub.h>
namespace android {
@@ -23,30 +25,11 @@
namespace V1_1 {
namespace implementation {
-class Contexthub : public V1_1::IContexthub {
- using ContextHubMsg = ::android::hardware::contexthub::V1_0::ContextHubMsg;
- using IContexthubCallback = ::android::hardware::contexthub::V1_0::IContexthubCallback;
- using NanoAppBinary = ::android::hardware::contexthub::V1_0::NanoAppBinary;
- using Result = ::android::hardware::contexthub::V1_0::Result;
-
+class Contexthub
+ : public ::android::hardware::contexthub::V1_X::implementation::ContextHub<IContexthub> {
public:
- // Methods from V1_0::IContexthub
- Return<void> getHubs(getHubs_cb _hidl_cb) override;
- Return<Result> registerCallback(uint32_t hubId,
- const ::android::sp<IContexthubCallback>& cb) override;
- Return<Result> sendMessageToHub(uint32_t hubId, const ContextHubMsg& msg) override;
- Return<Result> loadNanoApp(uint32_t hubId, const NanoAppBinary& appBinary,
- uint32_t transactionId) override;
- Return<Result> unloadNanoApp(uint32_t hubId, uint64_t appId, uint32_t transactionId) override;
- Return<Result> enableNanoApp(uint32_t hubId, uint64_t appId, uint32_t transactionId) override;
- Return<Result> disableNanoApp(uint32_t hubId, uint64_t appId, uint32_t transactionId) override;
- Return<Result> queryApps(uint32_t hubId) override;
-
// Methods from V1_1::IContexthub
Return<void> onSettingChanged(Setting setting, SettingValue newValue) override;
-
- private:
- sp<IContexthubCallback> mCallback;
};
} // namespace implementation
diff --git a/contexthub/1.1/vts/functional/OWNERS b/contexthub/1.1/vts/functional/OWNERS
index 161b2f0..1a33a9e 100644
--- a/contexthub/1.1/vts/functional/OWNERS
+++ b/contexthub/1.1/vts/functional/OWNERS
@@ -5,4 +5,3 @@
#VTS team
dshi@google.com
-trong@google.com
diff --git a/contexthub/1.2/Android.bp b/contexthub/1.2/Android.bp
new file mode 100644
index 0000000..e819482
--- /dev/null
+++ b/contexthub/1.2/Android.bp
@@ -0,0 +1,16 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.contexthub@1.2",
+ root: "android.hardware",
+ srcs: [
+ "types.hal",
+ "IContexthub.hal",
+ ],
+ interfaces: [
+ "android.hardware.contexthub@1.0",
+ "android.hardware.contexthub@1.1",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: true,
+}
diff --git a/contexthub/1.2/IContexthub.hal b/contexthub/1.2/IContexthub.hal
new file mode 100644
index 0000000..819fc1d
--- /dev/null
+++ b/contexthub/1.2/IContexthub.hal
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.contexthub@1.2;
+
+import @1.1::IContexthub;
+import @1.1::SettingValue;
+
+interface IContexthub extends @1.1::IContexthub {
+ /**
+ * Notification sent by the framework to indicate that the user
+ * has changed a setting.
+ *
+ * @param setting User setting that has been modified.
+ * @param newValue The update value of the user setting.
+ */
+ onSettingChanged_1_2(Setting setting, @1.1::SettingValue newValue);
+};
diff --git a/contexthub/1.2/default/Android.bp b/contexthub/1.2/default/Android.bp
new file mode 100644
index 0000000..49b54fc
--- /dev/null
+++ b/contexthub/1.2/default/Android.bp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+cc_binary {
+ name: "android.hardware.contexthub@1.2-service.mock",
+ defaults: ["hidl_defaults"],
+ vendor: true,
+ relative_install_path: "hw",
+ init_rc: ["android.hardware.contexthub@1.2-service.rc"],
+ srcs: [
+ "Contexthub.cpp",
+ "service.cpp",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ shared_libs: [
+ "android.hardware.contexthub@1.0",
+ "android.hardware.contexthub@1.1",
+ "android.hardware.contexthub@1.2",
+ "libbase",
+ "libcutils",
+ "libhardware",
+ "libhidlbase",
+ "liblog",
+ "libutils",
+ ],
+ header_libs: [
+ "android.hardware.contexthub@1.X-common-impl",
+ ],
+ vintf_fragments: ["android.hardware.contexthub@1.2.xml"],
+}
diff --git a/contexthub/1.2/default/Contexthub.cpp b/contexthub/1.2/default/Contexthub.cpp
new file mode 100644
index 0000000..d7ac7bf
--- /dev/null
+++ b/contexthub/1.2/default/Contexthub.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "Contexthub.h"
+
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace contexthub {
+namespace V1_2 {
+namespace implementation {
+
+Return<void> Contexthub::onSettingChanged(SettingV1_1 /*setting*/, SettingValue /*newValue*/) {
+ return Void();
+}
+
+Return<void> Contexthub::onSettingChanged_1_2(Setting /*setting*/, SettingValue /*newValue*/) {
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_2
+} // namespace contexthub
+} // namespace hardware
+} // namespace android
diff --git a/contexthub/1.2/default/Contexthub.h b/contexthub/1.2/default/Contexthub.h
new file mode 100644
index 0000000..d2f8d69
--- /dev/null
+++ b/contexthub/1.2/default/Contexthub.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "ContextHub.h"
+
+#include <android/hardware/contexthub/1.2/IContexthub.h>
+
+namespace android {
+namespace hardware {
+namespace contexthub {
+namespace V1_2 {
+namespace implementation {
+
+class Contexthub
+ : public ::android::hardware::contexthub::V1_X::implementation::ContextHub<IContexthub> {
+ using SettingValue = ::android::hardware::contexthub::V1_1::SettingValue;
+ using SettingV1_1 = ::android::hardware::contexthub::V1_1::Setting;
+
+ public:
+ // Methods from V1_1::IContexthub
+ Return<void> onSettingChanged(SettingV1_1 setting, SettingValue newValue) override;
+
+ // Methods from V1_2::IContexthub
+ Return<void> onSettingChanged_1_2(Setting setting, SettingValue newValue) override;
+};
+
+} // namespace implementation
+} // namespace V1_2
+} // namespace contexthub
+} // namespace hardware
+} // namespace android
diff --git a/contexthub/1.2/default/OWNERS b/contexthub/1.2/default/OWNERS
new file mode 100644
index 0000000..90c2330
--- /dev/null
+++ b/contexthub/1.2/default/OWNERS
@@ -0,0 +1,3 @@
+arthuri@google.com
+bduddie@google.com
+stange@google.com
diff --git a/contexthub/1.2/default/android.hardware.contexthub@1.2-service.rc b/contexthub/1.2/default/android.hardware.contexthub@1.2-service.rc
new file mode 100644
index 0000000..936222a
--- /dev/null
+++ b/contexthub/1.2/default/android.hardware.contexthub@1.2-service.rc
@@ -0,0 +1,7 @@
+service vendor.contexthub-hal-1.2-mock /vendor/bin/hw/android.hardware.contexthub@1.2-service.mock
+ interface android.hardware.contexthub@1.0::IContexthub default
+ interface android.hardware.contexthub@1.1::IContexthub default
+ interface android.hardware.contexthub@1.2::IContexthub default
+ class hal
+ user context_hub
+ group context_hub
diff --git a/contexthub/1.2/default/android.hardware.contexthub@1.2.xml b/contexthub/1.2/default/android.hardware.contexthub@1.2.xml
new file mode 100644
index 0000000..ec6c684
--- /dev/null
+++ b/contexthub/1.2/default/android.hardware.contexthub@1.2.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.contexthub</name>
+ <transport>hwbinder</transport>
+ <version>1.2</version>
+ <interface>
+ <name>IContexthub</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/contexthub/1.2/default/service.cpp b/contexthub/1.2/default/service.cpp
new file mode 100644
index 0000000..41cb753
--- /dev/null
+++ b/contexthub/1.2/default/service.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.contexthub@1.2-service"
+
+#include <android/hardware/contexthub/1.2/IContexthub.h>
+#include <hidl/HidlTransportSupport.h>
+#include <log/log.h>
+#include <utils/StrongPointer.h>
+#include "Contexthub.h"
+
+using ::android::hardware::configureRpcThreadpool;
+using ::android::hardware::joinRpcThreadpool;
+using ::android::hardware::contexthub::V1_2::IContexthub;
+using ::android::hardware::contexthub::V1_2::implementation::Contexthub;
+
+int main() {
+ configureRpcThreadpool(1, true /* callerWillJoin */);
+
+ ::android::sp<IContexthub> contexthub = new Contexthub();
+ if (contexthub->registerAsService() != ::android::OK) {
+ ALOGE("Failed to register Contexthub HAL instance");
+ return 1;
+ }
+
+ joinRpcThreadpool();
+ ALOGE("Service exited");
+ return 1;
+}
diff --git a/contexthub/1.2/types.hal b/contexthub/1.2/types.hal
new file mode 100644
index 0000000..38f9f7a
--- /dev/null
+++ b/contexthub/1.2/types.hal
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.contexthub@1.2;
+
+import @1.1::Setting;
+
+/**
+ * Used to indicate the type of user setting that has changed.
+ */
+enum Setting : @1.1::Setting {
+ /**
+ * Indicates that the WiFi capabilities can be used in CHRE. This setting
+ * follows the overall availability of WiFi-related functionality within
+ * the Android framework, for example if WiFi is disabled for connectivity
+ * purposes but is enabled for location purposes (scanning), then
+ * WIFI_AVAILABLE is enabled.
+ */
+ WIFI_AVAILABLE,
+ AIRPLANE_MODE,
+};
diff --git a/powerstats/aidl/vts/Android.bp b/contexthub/1.2/vts/functional/Android.bp
similarity index 69%
copy from powerstats/aidl/vts/Android.bp
copy to contexthub/1.2/vts/functional/Android.bp
index c61022e..6e425be 100644
--- a/powerstats/aidl/vts/Android.bp
+++ b/contexthub/1.2/vts/functional/Android.bp
@@ -1,3 +1,4 @@
+//
// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -11,19 +12,17 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
+//
cc_test {
- name: "VtsHalPowerStatsTargetTest",
- defaults: [
- "VtsHalTargetTestDefaults",
- "use_libaidlvintf_gtest_helper_static",
- ],
- srcs: ["VtsHalPowerStatsTargetTest.cpp"],
- shared_libs: [
- "libbinder_ndk",
- ],
+ name: "VtsHalContexthubV1_2TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: ["VtsHalContexthubV1_2TargetTest.cpp"],
static_libs: [
- "android.hardware.powerstats-ndk_platform",
+ "android.hardware.contexthub@1.0",
+ "android.hardware.contexthub@1.1",
+ "android.hardware.contexthub@1.2",
+ "VtsHalContexthubUtils",
],
test_suites: [
"general-tests",
diff --git a/contexthub/1.2/vts/functional/OWNERS b/contexthub/1.2/vts/functional/OWNERS
new file mode 100644
index 0000000..1a33a9e
--- /dev/null
+++ b/contexthub/1.2/vts/functional/OWNERS
@@ -0,0 +1,7 @@
+#Context Hub team
+arthuri@google.com
+bduddie@google.com
+stange@google.com
+
+#VTS team
+dshi@google.com
diff --git a/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp b/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp
new file mode 100644
index 0000000..77883c2
--- /dev/null
+++ b/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "contexthub_hidl_hal_test"
+
+#include "ContexthubCallbackBase.h"
+#include "ContexthubHidlTestBase.h"
+#include "VtsHalContexthubUtils.h"
+
+#include <android-base/logging.h>
+#include <android/hardware/contexthub/1.0/IContexthub.h>
+#include <android/hardware/contexthub/1.1/IContexthub.h>
+#include <android/hardware/contexthub/1.2/IContexthub.h>
+#include <android/log.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+#include <log/log.h>
+
+#include <cinttypes>
+
+using ::android::hardware::contexthub::V1_1::SettingValue;
+using ::android::hardware::contexthub::V1_2::IContexthub;
+using ::android::hardware::contexthub::V1_2::Setting;
+using ::android::hardware::contexthub::vts_utils::ContexthubCallbackBase;
+using ::android::hardware::contexthub::vts_utils::ContexthubHidlTestBase;
+using ::android::hardware::contexthub::vts_utils::getHalAndHubIdList;
+
+namespace {
+
+const std::vector<std::tuple<std::string, std::string>> kTestParameters =
+ getHalAndHubIdList<IContexthub>();
+
+class ContexthubHidlTest : public ContexthubHidlTestBase<IContexthub> {};
+
+// In VTS, we only test that sending the values doesn't cause things to blow up - other test
+// suites verify the expected E2E behavior in CHRE
+TEST_P(ContexthubHidlTest, TestOnWifiSettingChanged) {
+ ASSERT_OK(registerCallback(new ContexthubCallbackBase()));
+ hubApi->onSettingChanged_1_2(Setting::WIFI_AVAILABLE, SettingValue::DISABLED);
+ hubApi->onSettingChanged_1_2(Setting::WIFI_AVAILABLE, SettingValue::ENABLED);
+ ASSERT_OK(registerCallback(nullptr));
+}
+
+TEST_P(ContexthubHidlTest, TestOnAirplaneModeSettingChanged) {
+ ASSERT_OK(registerCallback(new ContexthubCallbackBase()));
+ hubApi->onSettingChanged_1_2(Setting::AIRPLANE_MODE, SettingValue::DISABLED);
+ hubApi->onSettingChanged_1_2(Setting::AIRPLANE_MODE, SettingValue::ENABLED);
+ ASSERT_OK(registerCallback(nullptr));
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ContexthubHidlTest);
+INSTANTIATE_TEST_SUITE_P(HubIdSpecificTests, ContexthubHidlTest, testing::ValuesIn(kTestParameters),
+ android::hardware::PrintInstanceTupleNameToString<>);
+
+} // anonymous namespace
diff --git a/powerstats/aidl/Android.bp b/contexthub/common/default/1.X/Android.bp
similarity index 63%
copy from powerstats/aidl/Android.bp
copy to contexthub/common/default/1.X/Android.bp
index 1aa58cb..691a1b7 100644
--- a/powerstats/aidl/Android.bp
+++ b/contexthub/common/default/1.X/Android.bp
@@ -1,3 +1,4 @@
+//
// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -12,24 +13,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-aidl_interface {
- name: "android.hardware.powerstats",
+cc_library_headers {
+ name: "android.hardware.contexthub@1.X-common-impl",
vendor_available: true,
- srcs: [
- "android/hardware/powerstats/*.aidl",
+ defaults: ["hidl_defaults"],
+ export_include_dirs: ["."],
+ shared_libs: [
+ "android.hardware.contexthub@1.0",
+ "libbinder",
+ "libcutils",
+ "libhidlbase",
+ "libutils",
],
- stability: "vintf",
- backend: {
- java: {
- platform_apis: true,
- },
- ndk: {
- vndk: {
- enabled: true,
- },
- },
- cpp: {
- enabled: false,
- },
- },
}
diff --git a/contexthub/common/default/1.X/ContextHub.h b/contexthub/common/default/1.X/ContextHub.h
new file mode 100644
index 0000000..73d0631
--- /dev/null
+++ b/contexthub/common/default/1.X/ContextHub.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_CONTEXTHUB_V1_X_CONTEXTHUB_H
+#define ANDROID_HARDWARE_CONTEXTHUB_V1_X_CONTEXTHUB_H
+
+#include <android/hardware/contexthub/1.0/IContexthub.h>
+#include <android/hardware/contexthub/1.0/types.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace contexthub {
+namespace V1_X {
+namespace implementation {
+
+template <class IContextHubInterface>
+struct ContextHub : public IContextHubInterface {
+ using ContextHubMsg = ::android::hardware::contexthub::V1_0::ContextHubMsg;
+ using HubAppInfo = ::android::hardware::contexthub::V1_0::HubAppInfo;
+ using IContexthubCallback = ::android::hardware::contexthub::V1_0::IContexthubCallback;
+ using NanoAppBinary = ::android::hardware::contexthub::V1_0::NanoAppBinary;
+ using Result = ::android::hardware::contexthub::V1_0::Result;
+ using getHubs_cb = ::android::hardware::contexthub::V1_0::IContexthub::getHubs_cb;
+
+ public:
+ Return<void> getHubs(getHubs_cb _hidl_cb) override {
+ ::android::hardware::contexthub::V1_0::ContextHub hub = {};
+ hub.name = "Mock Context Hub";
+ hub.vendor = "AOSP";
+ hub.toolchain = "n/a";
+ hub.platformVersion = 1;
+ hub.toolchainVersion = 1;
+ hub.hubId = kMockHubId;
+ hub.peakMips = 1;
+ hub.peakPowerDrawMw = 1;
+ hub.maxSupportedMsgLen = 4096;
+ hub.chrePlatformId = UINT64_C(0x476f6f6754000000);
+ hub.chreApiMajorVersion = 1;
+ hub.chreApiMinorVersion = 4;
+
+ // Report a single mock hub
+ std::vector<::android::hardware::contexthub::V1_0::ContextHub> hubs;
+ hubs.push_back(hub);
+
+ _hidl_cb(hubs);
+ return Void();
+ }
+
+ Return<Result> registerCallback(uint32_t hubId, const sp<IContexthubCallback>& cb) override {
+ if (hubId == kMockHubId) {
+ mCallback = cb;
+ return Result::OK;
+ }
+ return Result::BAD_PARAMS;
+ }
+
+ // We don't expose any nanoapps, therefore all nanoapp-related API calls return with BAD_PARAMS
+ Return<Result> sendMessageToHub(uint32_t /*hubId*/, const ContextHubMsg& /*msg*/) override {
+ return Result::BAD_PARAMS;
+ }
+
+ Return<Result> loadNanoApp(uint32_t /*hubId*/, const NanoAppBinary& /*appBinary*/,
+ uint32_t /*transactionId*/) override {
+ return Result::BAD_PARAMS;
+ }
+
+ Return<Result> unloadNanoApp(uint32_t /*hubId*/, uint64_t /*appId*/,
+ uint32_t /*transactionId*/) override {
+ return Result::BAD_PARAMS;
+ }
+
+ Return<Result> enableNanoApp(uint32_t /*hubId*/, uint64_t /*appId*/,
+ uint32_t /*transactionId*/) override {
+ return Result::BAD_PARAMS;
+ }
+
+ Return<Result> disableNanoApp(uint32_t /*hubId*/, uint64_t /*appId*/,
+ uint32_t /*transactionId*/) override {
+ return Result::BAD_PARAMS;
+ }
+
+ Return<Result> queryApps(uint32_t hubId) override {
+ if (hubId == kMockHubId && mCallback != nullptr) {
+ std::vector<HubAppInfo> nanoapps;
+ mCallback->handleAppsInfo(nanoapps);
+ return Result::OK;
+ }
+ return Result::BAD_PARAMS;
+ }
+
+ private:
+ static constexpr uint32_t kMockHubId = 0;
+
+ sp<IContexthubCallback> mCallback;
+};
+
+} // namespace implementation
+} // namespace V1_X
+} // namespace contexthub
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_CONTEXTHUB_V1_X_CONTEXTHUB_H
diff --git a/current.txt b/current.txt
index fc0cc07..27b2310 100644
--- a/current.txt
+++ b/current.txt
@@ -780,7 +780,5 @@
# HALs released in Android S
# NOTE: waiting to freeze HALs until later in the release
# NOTE: new HALs are recommended to be in AIDL
-57d183b10b13ec0a8e542c0b3d61991ae541c60e85dbbc5499bb21dfd068cbb8 android.hardware.wifi.supplicant@1.4::types
-17818b6b1952a75e4364ae82c534b9d2f5c0a9765a56256b16faa5a5cf45d3a8 android.hardware.wifi.supplicant@1.4::ISupplicant
-8342b5f6ec8f48ad2b741128aede010995d0b5709257b7ec09bb469b4f61ef1a android.hardware.wifi.supplicant@1.4::ISupplicantStaIface
-6f969b191f0b699ceab0573548f1ac505853e56e704711edc51b51976d4f87ad android.hardware.wifi.supplicant@1.4::ISupplicantStaNetwork
+6e64b33f1b720b66b0deb5e08dee37a99deaa94e2e9ebf7806703cabab56e21d android.hardware.contexthub@1.2::IContexthub
+3fb83f4539cab2c7bf9fdbecf7265d1c1dd6e8de9694046fe512b493c127ccea android.hardware.contexthub@1.2::types
diff --git a/fastboot/1.1/Android.bp b/fastboot/1.1/Android.bp
new file mode 100644
index 0000000..46306cf
--- /dev/null
+++ b/fastboot/1.1/Android.bp
@@ -0,0 +1,14 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.fastboot@1.1",
+ root: "android.hardware",
+ srcs: [
+ "IFastboot.hal",
+ ],
+ interfaces: [
+ "android.hardware.fastboot@1.0",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: true,
+}
diff --git a/fastboot/1.1/IFastboot.hal b/fastboot/1.1/IFastboot.hal
new file mode 100644
index 0000000..c8f1ad0
--- /dev/null
+++ b/fastboot/1.1/IFastboot.hal
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.fastboot@1.1;
+import android.hardware.fastboot@1.0;
+
+/**
+ * IFastboot interface implements vendor specific fastboot commands.
+ */
+interface IFastboot extends @1.0::IFastboot {
+ /**
+ * Executes an OEM specific erase after fastboot erase userdata.
+ *
+ * @return result Returns the status SUCCESS if the operation is successful,
+ * NOT_SUPPORTED for unsupported command.
+ * INVALID_ARGUMENT for bad arguments,
+ * FAILURE_UNKNOWN for unknown error in the oem specific command.
+ */
+ doOemSpecificErase() generates (Result result);
+};
diff --git a/powerstats/aidl/default/Android.bp b/fastboot/1.1/default/Android.bp
similarity index 70%
copy from powerstats/aidl/default/Android.bp
copy to fastboot/1.1/default/Android.bp
index caecd88..980586b 100644
--- a/powerstats/aidl/default/Android.bp
+++ b/fastboot/1.1/default/Android.bp
@@ -1,3 +1,4 @@
+//
// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -12,19 +13,19 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-cc_binary {
- name: "android.hardware.powerstats-service.example",
+cc_library {
+ name: "android.hardware.fastboot@1.1-impl-mock",
+ recovery: true,
+ srcs: [
+ "Fastboot.cpp",
+ ],
relative_install_path: "hw",
- init_rc: ["powerstats-default.rc"],
- vintf_fragments: ["powerstats-default.xml"],
- vendor: true,
shared_libs: [
"libbase",
- "libbinder_ndk",
- "android.hardware.powerstats-ndk_platform",
- ],
- srcs: [
- "main.cpp",
- "PowerStats.cpp",
+ "libhidlbase",
+ "libutils",
+ "libcutils",
+ "android.hardware.fastboot@1.0",
+ "android.hardware.fastboot@1.1",
],
}
diff --git a/fastboot/1.1/default/Fastboot.cpp b/fastboot/1.1/default/Fastboot.cpp
new file mode 100644
index 0000000..0b502e0
--- /dev/null
+++ b/fastboot/1.1/default/Fastboot.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Fastboot.h"
+
+namespace android {
+namespace hardware {
+namespace fastboot {
+namespace V1_1 {
+namespace implementation {
+
+// Methods from ::android::hardware::fastboot::V1_1::IFastboot follow.
+Return<void> Fastboot::getPartitionType(const hidl_string& /* partitionName */,
+ getPartitionType_cb _hidl_cb) {
+ _hidl_cb(FileSystemType::RAW, {Status::SUCCESS, ""});
+ return Void();
+}
+
+Return<void> Fastboot::doOemCommand(const hidl_string& /* oemCmd */, doOemCommand_cb _hidl_cb) {
+ _hidl_cb({Status::FAILURE_UNKNOWN, "Command not supported in default implementation"});
+ return Void();
+}
+
+Return<void> Fastboot::getVariant(getVariant_cb _hidl_cb) {
+ _hidl_cb("NA", {Status::SUCCESS, ""});
+ return Void();
+}
+
+Return<void> Fastboot::getOffModeChargeState(getOffModeChargeState_cb _hidl_cb) {
+ _hidl_cb(false, {Status::SUCCESS, ""});
+ return Void();
+}
+
+Return<void> Fastboot::getBatteryVoltageFlashingThreshold(
+ getBatteryVoltageFlashingThreshold_cb _hidl_cb) {
+ _hidl_cb(0, {Status::SUCCESS, ""});
+ return Void();
+}
+
+Return<void> Fastboot::doOemSpecificErase(doOemSpecificErase_cb _hidl_cb) {
+ _hidl_cb({Status::NOT_SUPPORTED, "Command not supported in default implementation"});
+ return Void();
+}
+
+extern "C" IFastboot* HIDL_FETCH_IFastboot(const char* /* name */) {
+ return new Fastboot();
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace fastboot
+} // namespace hardware
+} // namespace android
diff --git a/fastboot/1.1/default/Fastboot.h b/fastboot/1.1/default/Fastboot.h
new file mode 100644
index 0000000..09b39c2
--- /dev/null
+++ b/fastboot/1.1/default/Fastboot.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <android/hardware/fastboot/1.1/IFastboot.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace fastboot {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::hidl_string;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::fastboot::V1_0::FileSystemType;
+using ::android::hardware::fastboot::V1_0::Status;
+using ::android::hardware::fastboot::V1_0::Result;
+
+struct Fastboot : public IFastboot {
+ // Methods from ::android::hardware::fastboot::V1_0::IFastboot follow.
+ Return<void> getPartitionType(const hidl_string& partitionName,
+ getPartitionType_cb _hidl_cb) override;
+ Return<void> doOemCommand(const hidl_string& oemCmd, doOemCommand_cb _hidl_cb) override;
+ Return<void> getVariant(getVariant_cb _hidl_cb) override;
+ Return<void> getOffModeChargeState(getOffModeChargeState_cb _hidl_cb) override;
+ Return<void> getBatteryVoltageFlashingThreshold(
+ getBatteryVoltageFlashingThreshold_cb _hidl_cb) override;
+ Return<void> doOemSpecificErase(doOemSpecificErase_cb _hidl_cb) override;
+};
+
+extern "C" IFastboot* HIDL_FETCH_IFastboot(const char* name);
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace fastboot
+} // namespace hardware
+} // namespace android
diff --git a/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp b/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp
index 97e7c27..237e8ec 100644
--- a/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp
+++ b/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp
@@ -39,6 +39,10 @@
using android::hardware::gnss::V1_0::IGnssMeasurement;
using android::sp;
+/*
+ * Since Utils.cpp depends on Gnss Hal 2.0, the tests for Gnss Hal 1.0 will use
+ * there own version of IsAutomotiveDevice() instead of the common version.
+ */
static bool IsAutomotiveDevice() {
char buffer[PROPERTY_VALUE_MAX] = {0};
property_get("ro.hardware.type", buffer, "");
@@ -492,9 +496,9 @@
* Verifies that modern hardware supports measurement capabilities.
*/
TEST_P(GnssHalTest, MeasurementCapabilites) {
- if (info_called_count_ > 0 && last_info_.yearOfHw >= 2016) {
- EXPECT_TRUE(last_capabilities_ & IGnssCallback::Capabilities::MEASUREMENTS);
- }
+ if (!IsAutomotiveDevice() && info_called_count_ > 0 && last_info_.yearOfHw >= 2016) {
+ EXPECT_TRUE(last_capabilities_ & IGnssCallback::Capabilities::MEASUREMENTS);
+ }
}
/*
@@ -529,4 +533,4 @@
}
return RUN_ALL_TESTS();
-}
\ No newline at end of file
+}
diff --git a/gnss/1.1/default/GnssDebug.cpp b/gnss/1.1/default/GnssDebug.cpp
index 471ed24..252f4e6 100644
--- a/gnss/1.1/default/GnssDebug.cpp
+++ b/gnss/1.1/default/GnssDebug.cpp
@@ -20,6 +20,7 @@
#include "Constants.h"
#include "GnssDebug.h"
+#include "MockLocation.h"
using namespace ::android::hardware::gnss::common;
@@ -32,17 +33,17 @@
// Methods from ::android::hardware::gnss::V1_0::IGnssDebug follow.
Return<void> GnssDebug::getDebugData(V1_0::IGnssDebug::getDebugData_cb _hidl_cb) {
PositionDebug positionDebug = {
- .valid = true,
- .latitudeDegrees = kMockLatitudeDegrees,
- .longitudeDegrees = kMockLongitudeDegrees,
- .altitudeMeters = kMockAltitudeMeters,
- .speedMetersPerSec = kMockSpeedMetersPerSec,
- .bearingDegrees = kMockBearingDegrees,
- .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
- .verticalAccuracyMeters = kMockVerticalAccuracyMeters,
- .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond,
- .bearingAccuracyDegrees = kMockBearingAccuracyDegrees,
- .ageSeconds = 0.99};
+ .valid = true,
+ .latitudeDegrees = gMockLatitudeDegrees,
+ .longitudeDegrees = gMockLongitudeDegrees,
+ .altitudeMeters = gMockAltitudeMeters,
+ .speedMetersPerSec = kMockSpeedMetersPerSec,
+ .bearingDegrees = kMockBearingDegrees,
+ .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
+ .verticalAccuracyMeters = kMockVerticalAccuracyMeters,
+ .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond,
+ .bearingAccuracyDegrees = kMockBearingAccuracyDegrees,
+ .ageSeconds = 0.99};
TimeDebug timeDebug = {.timeEstimate = kMockTimestamp,
.timeUncertaintyNs = 1000,
diff --git a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
index 51dcf0d..3e0058f 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
@@ -62,6 +62,15 @@
auto gnssMeasurement_1_0 = gnss_hal_->getExtensionGnssMeasurement();
ASSERT_TRUE(gnssMeasurement_2_0.isOk() && gnssMeasurement_1_1.isOk() &&
gnssMeasurement_1_0.isOk());
+
+ // CDD does not require Android Automotive OS devices to support
+ // GnssMeasurements.
+ if (Utils::isAutomotiveDevice()) {
+ ALOGI("Test GnssMeasurementExtension skipped. Android Automotive OS deice is not required "
+ "to support GNSS measurements.");
+ return;
+ }
+
sp<IGnssMeasurement_2_0> iGnssMeas_2_0 = gnssMeasurement_2_0;
sp<IGnssMeasurement_1_1> iGnssMeas_1_1 = gnssMeasurement_1_1;
sp<IGnssMeasurement_1_0> iGnssMeas_1_0 = gnssMeasurement_1_0;
diff --git a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp
index 16e634f..2902809 100644
--- a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp
@@ -63,6 +63,15 @@
auto gnssMeasurement_1_0 = gnss_hal_->getExtensionGnssMeasurement();
ASSERT_TRUE(gnssMeasurement_2_1.isOk() && gnssMeasurement_2_0.isOk() &&
gnssMeasurement_1_1.isOk() && gnssMeasurement_1_0.isOk());
+
+ // CDD does not require Android Automotive OS devices to support
+ // GnssMeasurements.
+ if (Utils::isAutomotiveDevice()) {
+ ALOGI("Test GnssMeasurementExtension skipped. Android Automotive OS de ice is not "
+ "required to support GNSS measurements.");
+ return;
+ }
+
sp<IGnssMeasurement_2_1> iGnssMeas_2_1 = gnssMeasurement_2_1;
sp<IGnssMeasurement_2_0> iGnssMeas_2_0 = gnssMeasurement_2_0;
sp<IGnssMeasurement_1_1> iGnssMeas_1_1 = gnssMeasurement_1_1;
diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateInfo.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl
similarity index 87%
rename from powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateInfo.aidl
rename to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl
index 9de66ba..89f5d53 100644
--- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateInfo.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl
@@ -15,9 +15,9 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.powerstats;
+package android.hardware.gnss;
@VintfStability
-parcelable PowerEntityStateInfo {
- int powerEntityStateId;
- String powerEntityStateName;
+parcelable BlocklistedSource {
+ android.hardware.gnss.GnssConstellationType constellation;
+ int svid;
}
diff --git a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/MQDescriptor.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl
similarity index 82%
copy from common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/MQDescriptor.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl
index c9fe1d7..30d0227 100644
--- a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/MQDescriptor.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl
@@ -15,11 +15,15 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.common;
-@VintfStability
-parcelable MQDescriptor {
- android.hardware.common.GrantorDescriptor[] grantors;
- ParcelFileDescriptor fileDescriptor;
- int quantum;
- int flags;
+package android.hardware.gnss;
+@Backing(type="int") @VintfStability
+enum GnssConstellationType {
+ UNKNOWN = 0,
+ GPS = 1,
+ SBAS = 2,
+ GLONASS = 3,
+ QZSS = 4,
+ BEIDOU = 5,
+ GALILEO = 6,
+ IRNSS = 7,
}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
index 33377ca..146577e 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
@@ -18,5 +18,9 @@
package android.hardware.gnss;
@VintfStability
interface IGnss {
+ void setCallback(in android.hardware.gnss.IGnssCallback callback);
+ void close();
android.hardware.gnss.IGnssPsds getExtensionPsds();
+ android.hardware.gnss.IGnssConfiguration getExtensionGnssConfiguration();
+ const int ERROR_INVALID_ARGUMENT = 1;
}
diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateInfo.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
similarity index 86%
copy from powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateInfo.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
index 9de66ba..62870d6 100644
--- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateInfo.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
@@ -15,9 +15,9 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.powerstats;
+package android.hardware.gnss;
@VintfStability
-parcelable PowerEntityStateInfo {
- int powerEntityStateId;
- String powerEntityStateName;
+interface IGnssCallback {
+ void gnssSetCapabilitiesCb(in int capabilities);
+ const int CAPABILITY_SATELLITE_BLOCKLIST = 1;
}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl
new file mode 100644
index 0000000..5af30cf
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl
@@ -0,0 +1,35 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files 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.gnss;
+@VintfStability
+interface IGnssConfiguration {
+ void setSuplVersion(in int version);
+ void setSuplMode(in int mode);
+ void setLppProfile(in int lppProfile);
+ void setGlonassPositioningProtocol(in int protocol);
+ void setEmergencySuplPdn(in boolean enable);
+ void setEsExtensionSec(in int emergencyExtensionSeconds);
+ void setBlocklist(in android.hardware.gnss.BlocklistedSource[] blocklist);
+ const int SUPL_MODE_MSB = 1;
+ const int SUPL_MODE_MSA = 2;
+ const int LPP_PROFILE_USER_PLANE = 1;
+ const int LPP_PROFILE_CONTROL_PLANE = 2;
+ const int GLONASS_POS_PROTOCOL_RRC_CPLANE = 1;
+ const int GLONASS_POS_PROTOCOL_RRLP_UPLANE = 2;
+ const int GLONASS_POS_PROTOCOL_LPP_UPLANE = 4;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl
index 352a694..ddef928 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl
@@ -18,6 +18,6 @@
package android.hardware.gnss;
@VintfStability
interface IGnssPsds {
- boolean injectPsdsData(in android.hardware.gnss.PsdsType psdsType, in byte[] psdsData);
- boolean setCallback(in android.hardware.gnss.IGnssPsdsCallback callback);
+ void injectPsdsData(in android.hardware.gnss.PsdsType psdsType, in byte[] psdsData);
+ void setCallback(in android.hardware.gnss.IGnssPsdsCallback callback);
}
diff --git a/powerstats/aidl/android/hardware/powerstats/PowerEntityStateResidencyResult.aidl b/gnss/aidl/android/hardware/gnss/BlocklistedSource.aidl
similarity index 61%
copy from powerstats/aidl/android/hardware/powerstats/PowerEntityStateResidencyResult.aidl
copy to gnss/aidl/android/hardware/gnss/BlocklistedSource.aidl
index 555ae4c..2fde5b2 100644
--- a/powerstats/aidl/android/hardware/powerstats/PowerEntityStateResidencyResult.aidl
+++ b/gnss/aidl/android/hardware/gnss/BlocklistedSource.aidl
@@ -14,19 +14,23 @@
* limitations under the License.
*/
-package android.hardware.powerstats;
+package android.hardware.gnss;
-import android.hardware.powerstats.PowerEntityStateResidencyData;
+import android.hardware.gnss.GnssConstellationType;
+/**
+ * Represents a blocklisted source.
+ */
@VintfStability
-parcelable PowerEntityStateResidencyResult {
+parcelable BlocklistedSource {
/**
- * Unique ID of the corresponding PowerEntity
+ * Defines the constellation of the given satellite(s).
*/
- int powerEntityId;
- /**
- * Residency data for each state the PowerEntity's state space
- */
- PowerEntityStateResidencyData[] stateResidencyData;
-}
+ GnssConstellationType constellation;
+ /**
+ * Satellite (space vehicle) ID number, as defined in GnssSvInfo::svid, or 0 to blocklist all
+ * svid's for the specified constellation.
+ */
+ int svid;
+}
\ No newline at end of file
diff --git a/gnss/aidl/android/hardware/gnss/GnssConstellationType.aidl b/gnss/aidl/android/hardware/gnss/GnssConstellationType.aidl
new file mode 100644
index 0000000..af3e089
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/GnssConstellationType.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss;
+
+/**
+ * GNSS constellation type
+ *
+ * This is to specify the navigation satellite system, for example, as listed in Section 3.5 in
+ * RINEX Version 3.04.
+ */
+@VintfStability
+@Backing(type="int")
+enum GnssConstellationType {
+ UNKNOWN = 0,
+ /** Global Positioning System. */
+ GPS = 1,
+ /** Satellite-Based Augmentation System. */
+ SBAS = 2,
+ /** Global Navigation Satellite System. */
+ GLONASS = 3,
+ /** Quasi-Zenith Satellite System. */
+ QZSS = 4,
+ /** BeiDou Navigation Satellite System. */
+ BEIDOU = 5,
+ /** Galileo Navigation Satellite System. */
+ GALILEO = 6,
+ /** Indian Regional Navigation Satellite System. */
+ IRNSS = 7,
+}
\ No newline at end of file
diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl
index 1da254c..24632aa 100644
--- a/gnss/aidl/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl
@@ -16,7 +16,9 @@
package android.hardware.gnss;
+import android.hardware.gnss.IGnssCallback;
import android.hardware.gnss.IGnssPsds;
+import android.hardware.gnss.IGnssConfiguration;
/**
* Represents the standard GNSS (Global Navigation Satellite System) interface.
@@ -25,9 +27,52 @@
interface IGnss {
/**
+ * All GNSS Binder calls may return a ServiceSpecificException with the following error
+ * codes.
+ */
+ const int ERROR_INVALID_ARGUMENT = 1;
+
+ /**
+ * Opens the interface and provides the callback routines to the implementation of this
+ * interface.
+ *
+ * The framework calls this method to instruct the GPS engine to prepare for serving requests
+ * from the framework. The GNSS HAL implementation must respond to all GNSS requests from the
+ * framework upon successful return from this method until cleanup() method is called to
+ * close this interface.
+ *
+ * @param callback Callback interface for IGnss.
+ */
+ void setCallback(in IGnssCallback callback);
+
+ /**
+ * Closes the interface.
+ *
+ * The close() method is called by the framework to tell the GNSS HAL implementation to
+ * clear the callback and not expect any GNSS requests in the immediate future - e.g. this may
+ * be called when location is disabled by a user setting or low battery conditions. The GNSS HAL
+ * implementation must immediately stop responding to any existing requests until the
+ * setCallback() method is called again and the requests are re-initiated by the framework.
+ *
+ * After this method is called, the GNSS HAL implementation may choose to modify GNSS hardware
+ * states to save power. It is expected that when setCallback() method is called again to
+ * reopen this interface, to serve requests, there may be some minor delays in GNSS response
+ * requests as hardware readiness states are restored, not to exceed those that occur on normal
+ * device boot up.
+ */
+ void close();
+
+ /**
* This method returns the IGnssPsds interface.
*
* @return Handle to the IGnssPsds interface.
*/
IGnssPsds getExtensionPsds();
+
+ /**
+ * This method returns the IGnssConfiguration interface.
+ *
+ * @return Handle to the IGnssConfiguration interface.
+ */
+ IGnssConfiguration getExtensionGnssConfiguration();
}
\ No newline at end of file
diff --git a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
new file mode 100644
index 0000000..a46a018
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss;
+
+import android.hardware.gnss.IGnssPsds;
+import android.hardware.gnss.IGnssConfiguration;
+
+/**
+ * This interface is required for the HAL to communicate certain information
+ * like status and location info back to the framework, the framework implements
+ * the interfaces and passes a handle to the HAL.
+ */
+@VintfStability
+interface IGnssCallback {
+
+ /** Capability bit mask indicating GNSS supports blocklisting satellites */
+ const int CAPABILITY_SATELLITE_BLOCKLIST = 1 << 0;
+
+ /**
+ * Callback to inform framework of the GNSS HAL implementation's capabilities.
+ *
+ * @param capabilities Capability parameter is a bit field of the Capability bit masks.
+ */
+ void gnssSetCapabilitiesCb(in int capabilities);
+}
\ No newline at end of file
diff --git a/gnss/aidl/android/hardware/gnss/IGnssConfiguration.aidl b/gnss/aidl/android/hardware/gnss/IGnssConfiguration.aidl
new file mode 100644
index 0000000..e0ad357
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssConfiguration.aidl
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss;
+
+import android.hardware.gnss.BlocklistedSource;
+
+/**
+ * Extended interface for GNSS Configuration support.
+ */
+@VintfStability
+interface IGnssConfiguration {
+
+ /** SUPL mode bitmask for Mobile Station Based. */
+ const int SUPL_MODE_MSB = 0x01;
+
+ /** SUPL mode bitmask for Mobile Station Assisted. */
+ const int SUPL_MODE_MSA = 0x02;
+
+ /** LPP profile settings bitmask for enabling LTE Positioning Protocol User Plane. */
+ const int LPP_PROFILE_USER_PLANE = 0x01;
+
+ /** LPP profile settings bitmask for enabling LTE Positioning Protocol Control Plane. */
+ const int LPP_PROFILE_CONTROL_PLANE = 0x02;
+
+ /** A-Glonass positioning protocol bitmask for Radio Resource Control (RRC) Control Plane. */
+ const int GLONASS_POS_PROTOCOL_RRC_CPLANE = 0x01;
+
+ /** A-Glonass positioning protocol bitmask for Radio Resource Location User Plane. */
+ const int GLONASS_POS_PROTOCOL_RRLP_UPLANE = 0x02;
+
+ /** A-Glonass positioning protocol bitmask for LTE Positioning Protocol User Plane. */
+ const int GLONASS_POS_PROTOCOL_LPP_UPLANE = 0x04;
+
+ /**
+ * This method sets the SUPL version requested by Carrier. The GNSS HAL must use this version
+ * of the SUPL protocol if supported.
+ *
+ * @param version SUPL version requested by carrier. This is a bit mask with bits 0:7
+ * representing a service indicator field, bits 8:15 representing the minor version and bits
+ * 16:23 representing the major version.
+ */
+ void setSuplVersion(in int version);
+
+ /**
+ * This method sets the SUPL mode.
+ *
+ * @param mode Bitmask that specifies the SUPL mode which is set with the SUPL_MODE_* constants.
+ */
+ void setSuplMode(in int mode);
+
+ /**
+ * This method sets the LTE Positioning Profile configuration.
+ *
+ * @param lppProfile Bitmask that specifies the LTE Positioning Profile configuration to be set
+ * as per the LPP_PROFILE_* constants. If none of the bits are set, the default setting is
+ * Radio Resource Location Protocol (RRLP).
+ */
+ void setLppProfile(in int lppProfile);
+
+ /**
+ * This method selects positioning protocol on A-Glonass system.
+ *
+ * @param protocol Bitmask that specifies the positioning protocol to be set as per
+ * GLONASS_POS_PROTOCOL_* constants.
+ */
+ void setGlonassPositioningProtocol(in int protocol);
+
+ /**
+ * This method configures which PDN to use.
+ *
+ * @param enable Use emergency PDN if true and regular PDN if false.
+ */
+ void setEmergencySuplPdn(in boolean enable);
+
+ /**
+ * This method sets the emergency session extension duration. The GNSS HAL
+ * implementation must serve emergency SUPL and Control Plane network initiated
+ * location requests for this extra duration after the user initiated emergency
+ * session ends.
+ *
+ * @param emergencyExtensionSeconds Number of seconds to extend the emergency
+ * session duration post emergency call.
+ */
+ void setEsExtensionSec(in int emergencyExtensionSeconds);
+
+ /**
+ * Injects a vector of BlocklistedSource(s) which the HAL must not use to calculate the
+ * GNSS location output.
+ *
+ * The superset of all satellite sources provided, including wildcards, in the latest call
+ * to this method, is the set of satellites sources that must not be used in calculating
+ * location.
+ *
+ * All measurements from the specified satellites, across frequency bands, are blocklisted
+ * together.
+ *
+ * If this method is never called after the IGnssConfiguration.hal connection is made on boot,
+ * or is called with an empty vector, then no satellites are to be blocklisted as a result of
+ * this API.
+ *
+ * This blocklist must be considered as an additional source of which satellites
+ * should not be trusted for location on top of existing sources of similar information
+ * such as satellite broadcast health being unhealthy and measurement outlier removal.
+ *
+ * @param blocklist The BlocklistedSource(s) of satellites the HAL must not use.
+ */
+ void setBlocklist(in BlocklistedSource[] blocklist);
+}
\ No newline at end of file
diff --git a/gnss/aidl/android/hardware/gnss/IGnssPsds.aidl b/gnss/aidl/android/hardware/gnss/IGnssPsds.aidl
index 6f53d6f..7c46096 100644
--- a/gnss/aidl/android/hardware/gnss/IGnssPsds.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnssPsds.aidl
@@ -32,18 +32,14 @@
* @param psdsType Type of PSDS data.
* @param psdsData GNSS PSDS data. Framework must not parse the data since the data format is
* opaque to framework.
- *
- * @return True if the operation is successful.
*/
- boolean injectPsdsData(in PsdsType psdsType, in byte[] psdsData);
+ void injectPsdsData(in PsdsType psdsType, in byte[] psdsData);
/**
* Opens the PSDS interface and provides the callback routines to the implementation of this
* interface.
*
* @param callback Handle to the IGnssPsdsCallback interface.
- *
- * @return True if the operation is successful.
*/
- boolean setCallback(in IGnssPsdsCallback callback);
+ void setCallback(in IGnssPsdsCallback callback);
}
\ No newline at end of file
diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp
index 8c4ee40..1fe43c3 100644
--- a/gnss/aidl/default/Android.bp
+++ b/gnss/aidl/default/Android.bp
@@ -17,8 +17,13 @@
cc_binary {
name: "android.hardware.gnss-service.example",
relative_install_path: "hw",
- init_rc: ["gnss-default.rc"],
- vintf_fragments: ["gnss-default.xml"],
+ init_rc: [
+ "gnss-default.rc",
+ ],
+ vintf_fragments: [
+ "gnss-default.xml",
+ "gnss@2.1-service.xml",
+ ],
vendor: true,
cflags: [
"-Wall",
@@ -27,12 +32,26 @@
shared_libs: [
"libbase",
"libbinder_ndk",
+ "libhidlbase",
+ "libutils",
"liblog",
+ "android.hardware.gnss@2.1",
+ "android.hardware.gnss@2.0",
+ "android.hardware.gnss@1.1",
+ "android.hardware.gnss@1.0",
+ "android.hardware.gnss.measurement_corrections@1.1",
+ "android.hardware.gnss.measurement_corrections@1.0",
+ "android.hardware.gnss.visibility_control@1.0",
"android.hardware.gnss-ndk_platform",
],
srcs: [
"Gnss.cpp",
+ "GnssHidlHal.cpp",
"GnssPsds.cpp",
+ "GnssConfiguration.cpp",
"service.cpp",
],
+ static_libs: [
+ "android.hardware.gnss@common-default-lib",
+ ],
}
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index 2a35924..b4d92fd 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -18,14 +18,51 @@
#include "Gnss.h"
#include <log/log.h>
+#include "GnssConfiguration.h"
#include "GnssPsds.h"
namespace aidl::android::hardware::gnss {
+std::shared_ptr<IGnssCallback> Gnss::sGnssCallback = nullptr;
+
+ndk::ScopedAStatus Gnss::setCallback(const std::shared_ptr<IGnssCallback>& callback) {
+ ALOGD("Gnss::setCallback");
+ if (callback == nullptr) {
+ ALOGE("%s: Null callback ignored", __func__);
+ return ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+ }
+
+ sGnssCallback = callback;
+
+ int capabilities = (int)IGnssCallback::CAPABILITY_SATELLITE_BLOCKLIST;
+ auto status = sGnssCallback->gnssSetCapabilitiesCb(capabilities);
+ if (!status.isOk()) {
+ ALOGE("%s: Unable to invoke callback.gnssSetCapabilities", __func__);
+ }
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Gnss::close() {
+ ALOGD("Gnss::close");
+ sGnssCallback = nullptr;
+ return ndk::ScopedAStatus::ok();
+}
+
ndk::ScopedAStatus Gnss::getExtensionPsds(std::shared_ptr<IGnssPsds>* iGnssPsds) {
ALOGD("Gnss::getExtensionPsds");
*iGnssPsds = SharedRefBase::make<GnssPsds>();
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus Gnss::getExtensionGnssConfiguration(
+ std::shared_ptr<IGnssConfiguration>* iGnssConfiguration) {
+ ALOGD("Gnss::getExtensionGnssConfiguration");
+ if (mGnssConfiguration == nullptr) {
+ mGnssConfiguration = SharedRefBase::make<GnssConfiguration>();
+ }
+ *iGnssConfiguration = mGnssConfiguration;
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
index 9864e9d..61d7cf7 100644
--- a/gnss/aidl/default/Gnss.h
+++ b/gnss/aidl/default/Gnss.h
@@ -17,12 +17,24 @@
#pragma once
#include <aidl/android/hardware/gnss/BnGnss.h>
+#include <aidl/android/hardware/gnss/BnGnssConfiguration.h>
#include <aidl/android/hardware/gnss/BnGnssPsds.h>
+#include "GnssConfiguration.h"
namespace aidl::android::hardware::gnss {
class Gnss : public BnGnss {
+ public:
+ ndk::ScopedAStatus setCallback(const std::shared_ptr<IGnssCallback>& callback) override;
+ ndk::ScopedAStatus close() override;
ndk::ScopedAStatus getExtensionPsds(std::shared_ptr<IGnssPsds>* iGnssPsds) override;
+ ndk::ScopedAStatus getExtensionGnssConfiguration(
+ std::shared_ptr<IGnssConfiguration>* iGnssConfiguration) override;
+
+ std::shared_ptr<GnssConfiguration> mGnssConfiguration;
+
+ private:
+ static std::shared_ptr<IGnssCallback> sGnssCallback;
};
} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssConfiguration.cpp b/gnss/aidl/default/GnssConfiguration.cpp
new file mode 100644
index 0000000..30e0d8c
--- /dev/null
+++ b/gnss/aidl/default/GnssConfiguration.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssConfigurationAidl"
+
+#include "GnssConfiguration.h"
+#include <log/log.h>
+
+namespace aidl::android::hardware::gnss {
+
+ndk::ScopedAStatus GnssConfiguration::setBlocklist(const vector<BlocklistedSource>& sourceList) {
+ ALOGD("GnssConfiguration::setBlocklist");
+ std::unique_lock<std::recursive_mutex> lock(mMutex);
+ mBlocklistedConstellationSet.clear();
+ mBlocklistedSourceSet.clear();
+ for (const auto& source : sourceList) {
+ if (source.svid == 0) {
+ // Wildcard blocklist, i.e., blocklist entire constellation.
+ mBlocklistedConstellationSet.insert(source.constellation);
+ } else {
+ mBlocklistedSourceSet.insert(source);
+ }
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+bool GnssConfiguration::isBlocklistedV2_1(const GnssSvInfoV2_1& gnssSvInfo) const {
+ std::unique_lock<std::recursive_mutex> lock(mMutex);
+ if (mBlocklistedConstellationSet.find(static_cast<GnssConstellationType>(
+ gnssSvInfo.v2_0.constellation)) != mBlocklistedConstellationSet.end()) {
+ return true;
+ }
+ BlocklistedSource source = {
+ .constellation = static_cast<GnssConstellationType>(gnssSvInfo.v2_0.constellation),
+ .svid = gnssSvInfo.v2_0.v1_0.svid};
+ return (mBlocklistedSourceSet.find(source) != mBlocklistedSourceSet.end());
+}
+
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssConfiguration.h b/gnss/aidl/default/GnssConfiguration.h
new file mode 100644
index 0000000..25fa16e
--- /dev/null
+++ b/gnss/aidl/default/GnssConfiguration.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/gnss/BnGnssConfiguration.h>
+#include <android/hardware/gnss/2.1/IGnssCallback.h>
+#include <mutex>
+#include <unordered_set>
+#include <vector>
+
+namespace aidl::android::hardware::gnss {
+
+using android::hardware::gnss::GnssConstellationType;
+
+struct BlocklistedSourceHash {
+ inline int operator()(const BlocklistedSource& source) const {
+ return int(source.constellation) * 1000 + int(source.svid);
+ }
+};
+
+struct BlocklistedSourceEqual {
+ inline bool operator()(const BlocklistedSource& s1, const BlocklistedSource& s2) const {
+ return (s1.constellation == s2.constellation) && (s1.svid == s2.svid);
+ }
+};
+
+using GnssSvInfoV2_1 = ::android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo;
+using std::vector;
+using BlocklistedSourceSet =
+ std::unordered_set<BlocklistedSource, BlocklistedSourceHash, BlocklistedSourceEqual>;
+using BlocklistedConstellationSet = std::unordered_set<GnssConstellationType>;
+
+struct GnssConfiguration : public BnGnssConfiguration {
+ public:
+ ndk::ScopedAStatus setSuplVersion(int) override { return ndk::ScopedAStatus::ok(); }
+
+ ndk::ScopedAStatus setSuplMode(int) override { return ndk::ScopedAStatus::ok(); }
+
+ ndk::ScopedAStatus setLppProfile(int) override { return ndk::ScopedAStatus::ok(); }
+
+ ndk::ScopedAStatus setGlonassPositioningProtocol(int) override {
+ return ndk::ScopedAStatus::ok();
+ }
+
+ ndk::ScopedAStatus setEmergencySuplPdn(bool) override { return ndk::ScopedAStatus::ok(); }
+
+ ndk::ScopedAStatus setEsExtensionSec(int) override { return ndk::ScopedAStatus::ok(); }
+
+ ndk::ScopedAStatus setBlocklist(const vector<BlocklistedSource>& blocklist) override;
+
+ bool isBlocklistedV2_1(const GnssSvInfoV2_1& gnssSvInfo) const;
+
+ private:
+ BlocklistedSourceSet mBlocklistedSourceSet;
+ BlocklistedConstellationSet mBlocklistedConstellationSet;
+ mutable std::recursive_mutex mMutex;
+};
+
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssHidlHal.cpp b/gnss/aidl/default/GnssHidlHal.cpp
new file mode 100644
index 0000000..11fc806
--- /dev/null
+++ b/gnss/aidl/default/GnssHidlHal.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssHidlHal"
+
+#include "GnssHidlHal.h"
+//#include <android/hardware/gnss/1.0/IGnssCallback.h>
+
+namespace aidl::android::hardware::gnss {
+
+namespace V1_0 = ::android::hardware::gnss::V1_0;
+
+GnssHidlHal::GnssHidlHal(const std::shared_ptr<Gnss>& gnssAidl) : mGnssAidl(gnssAidl) {
+ Gnss* iGnss = mGnssAidl.get();
+ std::shared_ptr<IGnssConfiguration> iGnssConfiguration;
+ auto status = iGnss->getExtensionGnssConfiguration(&iGnssConfiguration);
+ if (!status.isOk()) {
+ ALOGE("Failed to getExtensionGnssConfiguration.");
+ } else {
+ mGnssConfigurationAidl = iGnss->mGnssConfiguration;
+ }
+};
+
+hidl_vec<GnssSvInfo> GnssHidlHal::filterBlocklistedSatellitesV2_1(
+ hidl_vec<GnssSvInfo> gnssSvInfoList) {
+ ALOGD("filterBlocklistSatellitesV2_1 - overridden by GnssHidlHal class");
+ if (mGnssConfigurationAidl == nullptr) {
+ ALOGE("Handle to AIDL GnssConfiguration is not available.");
+ return gnssSvInfoList;
+ }
+ for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) {
+ if (mGnssConfigurationAidl->isBlocklistedV2_1(gnssSvInfoList[i])) {
+ ALOGD("Blocklisted constellation: %d, svid: %d",
+ (int)gnssSvInfoList[i].v2_0.constellation, gnssSvInfoList[i].v2_0.v1_0.svid);
+ gnssSvInfoList[i].v2_0.v1_0.svFlag &=
+ ~static_cast<uint8_t>(V1_0::IGnssCallback::GnssSvFlags::USED_IN_FIX);
+ }
+ }
+ return gnssSvInfoList;
+}
+
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssHidlHal.h b/gnss/aidl/default/GnssHidlHal.h
new file mode 100644
index 0000000..50aad3a
--- /dev/null
+++ b/gnss/aidl/default/GnssHidlHal.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "Gnss.h"
+#include "GnssConfiguration.h"
+#include "v2_1/GnssTemplate.h"
+
+namespace aidl::android::hardware::gnss {
+
+using ::android::hardware::gnss::common::implementation::GnssTemplate;
+using GnssSvInfo = ::android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo;
+
+class GnssHidlHal : public GnssTemplate<::android::hardware::gnss::V2_1::IGnss> {
+ public:
+ GnssHidlHal(const std::shared_ptr<Gnss>& gnssAidl);
+
+ private:
+ hidl_vec<GnssSvInfo> filterBlocklistedSatellitesV2_1(
+ hidl_vec<GnssSvInfo> gnssSvInfoList) override;
+
+ std::shared_ptr<Gnss> mGnssAidl;
+ std::shared_ptr<GnssConfiguration> mGnssConfigurationAidl;
+};
+
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssPsds.cpp b/gnss/aidl/default/GnssPsds.cpp
index c354217..6512af6 100644
--- a/gnss/aidl/default/GnssPsds.cpp
+++ b/gnss/aidl/default/GnssPsds.cpp
@@ -17,27 +17,28 @@
#define LOG_TAG "GnssPsdsAidl"
#include "GnssPsds.h"
-
+#include <aidl/android/hardware/gnss/BnGnss.h>
#include <log/log.h>
namespace aidl::android::hardware::gnss {
std::shared_ptr<IGnssPsdsCallback> GnssPsds::sCallback = nullptr;
-ndk::ScopedAStatus GnssPsds::setCallback(const std::shared_ptr<IGnssPsdsCallback>& callback,
- bool* success) {
+ndk::ScopedAStatus GnssPsds::setCallback(const std::shared_ptr<IGnssPsdsCallback>& callback) {
ALOGD("setCallback");
std::unique_lock<std::mutex> lock(mMutex);
sCallback = callback;
- *success = true;
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus GnssPsds::injectPsdsData(PsdsType psdsType, const std::vector<uint8_t>& psdsData,
- bool* success) {
+ndk::ScopedAStatus GnssPsds::injectPsdsData(PsdsType psdsType,
+ const std::vector<uint8_t>& psdsData) {
ALOGD("injectPsdsData. psdsType: %d, psdsData: %d bytes", static_cast<int>(psdsType),
static_cast<int>(psdsData.size()));
- *success = (psdsData.size() > 0);
- return ndk::ScopedAStatus::ok();
+ if (psdsData.size() > 0) {
+ return ndk::ScopedAStatus::ok();
+ } else {
+ return ndk::ScopedAStatus::fromServiceSpecificError(IGnss::ERROR_INVALID_ARGUMENT);
+ }
}
} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssPsds.h b/gnss/aidl/default/GnssPsds.h
index fc65bc1..de9e68f 100644
--- a/gnss/aidl/default/GnssPsds.h
+++ b/gnss/aidl/default/GnssPsds.h
@@ -22,10 +22,9 @@
struct GnssPsds : public BnGnssPsds {
public:
- ndk::ScopedAStatus setCallback(const std::shared_ptr<IGnssPsdsCallback>& callback,
- bool* success) override;
- ndk::ScopedAStatus injectPsdsData(PsdsType psdsType, const std::vector<uint8_t>& psdsData,
- bool* success) override;
+ ndk::ScopedAStatus setCallback(const std::shared_ptr<IGnssPsdsCallback>& callback) override;
+ ndk::ScopedAStatus injectPsdsData(PsdsType psdsType,
+ const std::vector<uint8_t>& psdsData) override;
private:
// Guarded by mMutex
diff --git a/gnss/aidl/default/gnss@2.1-service.xml b/gnss/aidl/default/gnss@2.1-service.xml
new file mode 100644
index 0000000..12a1fdf
--- /dev/null
+++ b/gnss/aidl/default/gnss@2.1-service.xml
@@ -0,0 +1,12 @@
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.gnss</name>
+ <transport>hwbinder</transport>
+ <version>2.1</version>
+ <version>1.1</version>
+ <interface>
+ <name>IGnss</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/gnss/aidl/default/service.cpp b/gnss/aidl/default/service.cpp
index c79a271..09f1ad2 100644
--- a/gnss/aidl/default/service.cpp
+++ b/gnss/aidl/default/service.cpp
@@ -14,22 +14,45 @@
* limitations under the License.
*/
-#include "Gnss.h"
+#define LOG_TAG "Gnss-main"
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+#include <log/log.h>
+#include <pthread.h>
+#include "Gnss.h"
+#include "GnssHidlHal.h"
using aidl::android::hardware::gnss::Gnss;
+using aidl::android::hardware::gnss::GnssHidlHal;
+using ::android::OK;
+using ::android::sp;
+using ::android::hardware::configureRpcThreadpool;
+using ::android::hardware::joinRpcThreadpool;
+using ::android::hardware::gnss::V2_1::IGnss;
int main() {
- ABinderProcess_setThreadPoolMaxThreadCount(0);
- std::shared_ptr<Gnss> vib = ndk::SharedRefBase::make<Gnss>();
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
+ std::shared_ptr<Gnss> gnssAidl = ndk::SharedRefBase::make<Gnss>();
const std::string instance = std::string() + Gnss::descriptor + "/default";
- binder_status_t status = AServiceManager_addService(vib->asBinder().get(), instance.c_str());
+ binder_status_t status =
+ AServiceManager_addService(gnssAidl->asBinder().get(), instance.c_str());
CHECK(status == STATUS_OK);
+ sp<IGnss> gnss = new GnssHidlHal(gnssAidl);
+ configureRpcThreadpool(1, true /* will join */);
+ if (gnss->registerAsService() != OK) {
+ ALOGE("Could not register gnss 2.1 service.");
+ return 0;
+ }
+
+ joinRpcThreadpool();
ABinderProcess_joinThreadPool();
+
return EXIT_FAILURE; // should not reach
}
diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp
index e57b421..48a0e21 100644
--- a/gnss/aidl/vts/Android.bp
+++ b/gnss/aidl/vts/Android.bp
@@ -18,14 +18,25 @@
"VtsHalTargetTestDefaults",
"use_libaidlvintf_gtest_helper_static",
],
- srcs: ["VtsHalGnssTargetTest.cpp"],
+ srcs: [
+ "gnss_hal_test.cpp",
+ "gnss_hal_test_cases.cpp",
+ "GnssCallbackAidl.cpp",
+ "VtsHalGnssTargetTest.cpp",
+ ],
shared_libs: [
+ "android.hardware.gnss@2.1",
+ "android.hardware.gnss@2.0",
+ "android.hardware.gnss@1.1",
+ "android.hardware.gnss@1.0",
"libbinder",
],
static_libs: [
"android.hardware.gnss-cpp",
+ "android.hardware.gnss@common-vts-lib",
],
test_suites: [
+ "general-tests",
"vts",
],
}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl b/gnss/aidl/vts/GnssCallbackAidl.cpp
similarity index 68%
copy from biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl
copy to gnss/aidl/vts/GnssCallbackAidl.cpp
index a51b188..f5c745b 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl
+++ b/gnss/aidl/vts/GnssCallbackAidl.cpp
@@ -14,13 +14,11 @@
* limitations under the License.
*/
-package android.hardware.biometrics.fingerprint;
+#include "GnssCallbackAidl.h"
+#include <log/log.h>
-@VintfStability
-oneway interface IGenerateChallengeCallback {
- /**
- * Notifies the framework when a challenge is successfully generated.
- */
- void onChallengeGenerated(in int sensorId, in int userId, in long challenge);
+android::binder::Status GnssCallbackAidl::gnssSetCapabilitiesCb(const int capabilities) {
+ ALOGI("Capabilities received %d", capabilities);
+ capabilities_cbq_.store(capabilities);
+ return android::binder::Status::ok();
}
-
diff --git a/gnss/aidl/vts/GnssCallbackAidl.h b/gnss/aidl/vts/GnssCallbackAidl.h
new file mode 100644
index 0000000..7f802ea
--- /dev/null
+++ b/gnss/aidl/vts/GnssCallbackAidl.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/gnss/BnGnssCallback.h>
+#include "GnssCallbackEventQueue.h"
+
+/* Callback class for data & Event. */
+class GnssCallbackAidl : public android::hardware::gnss::BnGnssCallback {
+ public:
+ GnssCallbackAidl() : capabilities_cbq_("capabilities"){};
+ ~GnssCallbackAidl(){};
+
+ android::binder::Status gnssSetCapabilitiesCb(const int capabilities) override;
+
+ int last_capabilities_;
+ android::hardware::gnss::common::GnssCallbackEventQueue<int> capabilities_cbq_;
+};
\ No newline at end of file
diff --git a/gnss/aidl/vts/VtsHalGnssTargetTest.cpp b/gnss/aidl/vts/VtsHalGnssTargetTest.cpp
index e7ffc05..4bba92b 100644
--- a/gnss/aidl/vts/VtsHalGnssTargetTest.cpp
+++ b/gnss/aidl/vts/VtsHalGnssTargetTest.cpp
@@ -13,60 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include <aidl/Gtest.h>
-#include <aidl/Vintf.h>
+
+#include "gnss_hal_test.h"
#include <android/hardware/gnss/IGnss.h>
-#include <android/hardware/gnss/IGnssPsds.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
using android::ProcessState;
-using android::sp;
-using android::String16;
-using android::binder::Status;
-using android::hardware::gnss::IGnss;
-using android::hardware::gnss::IGnssPsds;
-using android::hardware::gnss::PsdsType;
-class GnssAidlHalTest : public testing::TestWithParam<std::string> {
- public:
- virtual void SetUp() override {
- gnss_hal_ = android::waitForDeclaredService<IGnss>(String16(GetParam().c_str()));
- ASSERT_NE(gnss_hal_, nullptr);
- }
-
- sp<IGnss> gnss_hal_;
-};
-
-/*
- * SetupTeardownCreateCleanup:
- * Requests the gnss HAL then calls cleanup
- *
- * Empty test fixture to verify basic Setup & Teardown
- */
-TEST_P(GnssAidlHalTest, SetupTeardownCreateCleanup) {}
-
-/*
- * TestPsdsExtension:
- * 1. Gets the PsdsExtension and verifies that it returns a non-null extension.
- * 2. Injects empty PSDS data and verifies that it returns false.
- */
-TEST_P(GnssAidlHalTest, TestPsdsExtension) {
- sp<IGnssPsds> iGnssPsds;
- auto status = gnss_hal_->getExtensionPsds(&iGnssPsds);
- ASSERT_TRUE(status.isOk());
- ASSERT_TRUE(iGnssPsds != nullptr);
-
- bool success;
- status = iGnssPsds->injectPsdsData(PsdsType::LONG_TERM, std::vector<uint8_t>(), &success);
- ASSERT_TRUE(status.isOk());
- ASSERT_FALSE(success);
-}
-
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GnssAidlHalTest);
-INSTANTIATE_TEST_SUITE_P(, GnssAidlHalTest,
- testing::ValuesIn(android::getAidlHalInstanceNames(IGnss::descriptor)),
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GnssHalTest);
+INSTANTIATE_TEST_SUITE_P(, GnssHalTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IGnssAidl::descriptor)),
android::PrintInstanceNameToString);
int main(int argc, char** argv) {
diff --git a/gnss/aidl/vts/gnss_hal_test.cpp b/gnss/aidl/vts/gnss_hal_test.cpp
new file mode 100644
index 0000000..2447bf8
--- /dev/null
+++ b/gnss/aidl/vts/gnss_hal_test.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "gnss_hal_test.h"
+#include <hidl/ServiceManagement.h>
+
+using GnssConstellationTypeAidl = android::hardware::gnss::GnssConstellationType;
+
+void GnssHalTest::SetUp() {
+ // Get AIDL handle
+ aidl_gnss_hal_ = android::waitForDeclaredService<IGnssAidl>(String16(GetParam().c_str()));
+ ASSERT_NE(aidl_gnss_hal_, nullptr);
+
+ const auto& hidlInstanceNames = android::hardware::getAllHalInstanceNames(
+ android::hardware::gnss::V2_1::IGnss::descriptor);
+ gnss_hal_ = IGnss_V2_1::getService(hidlInstanceNames[0]);
+ ASSERT_NE(gnss_hal_, nullptr);
+
+ SetUpGnssCallback();
+}
+
+void GnssHalTest::SetUpGnssCallback() {
+ aidl_gnss_cb_ = new GnssCallbackAidl();
+ ASSERT_NE(aidl_gnss_cb_, nullptr);
+
+ auto status = aidl_gnss_hal_->setCallback(aidl_gnss_cb_);
+ if (!status.isOk()) {
+ ALOGE("Failed to setCallback");
+ }
+
+ ASSERT_TRUE(status.isOk());
+
+ /*
+ * Capabilities callback should trigger.
+ */
+ EXPECT_TRUE(aidl_gnss_cb_->capabilities_cbq_.retrieve(aidl_gnss_cb_->last_capabilities_,
+ TIMEOUT_SEC));
+
+ EXPECT_EQ(aidl_gnss_cb_->capabilities_cbq_.calledCount(), 1);
+
+ // Invoke the super method.
+ GnssHalTestTemplate<IGnss_V2_1>::SetUpGnssCallback();
+}
diff --git a/gnss/aidl/vts/gnss_hal_test.h b/gnss/aidl/vts/gnss_hal_test.h
new file mode 100644
index 0000000..eb5301e
--- /dev/null
+++ b/gnss/aidl/vts/gnss_hal_test.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+
+#include <android/hardware/gnss/IGnss.h>
+#include <binder/IServiceManager.h>
+
+#include <android/hardware/gnss/2.1/IGnss.h>
+#include "GnssCallbackAidl.h"
+#include "v2_1/gnss_hal_test_template.h"
+
+using IGnss_V2_1 = android::hardware::gnss::V2_1::IGnss;
+
+using android::ProcessState;
+using android::sp;
+using android::String16;
+using IGnssAidl = android::hardware::gnss::IGnss;
+using android::hardware::gnss::BlocklistedSource;
+using android::hardware::gnss::IGnssConfiguration;
+
+// The main test class for GNSS HAL.
+class GnssHalTest : public GnssHalTestTemplate<IGnss_V2_1> {
+ public:
+ GnssHalTest(){};
+ ~GnssHalTest(){};
+ virtual void SetUp() override;
+ virtual void SetUpGnssCallback() override;
+
+ sp<IGnssAidl> aidl_gnss_hal_;
+ sp<GnssCallbackAidl> aidl_gnss_cb_; // Primary callback interface
+};
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
new file mode 100644
index 0000000..2b8a447
--- /dev/null
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -0,0 +1,450 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssHalTestCases"
+
+#include <android/hardware/gnss/IGnssPsds.h>
+#include "gnss_hal_test.h"
+
+using android::sp;
+using android::hardware::gnss::BlocklistedSource;
+using GnssConstellationTypeAidl = android::hardware::gnss::GnssConstellationType;
+using android::hardware::gnss::IGnssConfiguration;
+using android::hardware::gnss::IGnssPsds;
+using android::hardware::gnss::PsdsType;
+
+/*
+ * SetupTeardownCreateCleanup:
+ * Requests the gnss HAL then calls cleanup
+ *
+ * Empty test fixture to verify basic Setup & Teardown
+ */
+TEST_P(GnssHalTest, SetupTeardownCreateCleanup) {}
+
+/*
+ * TestPsdsExtension:
+ * 1. Gets the PsdsExtension and verifies that it returns a non-null extension.
+ * 2. Injects empty PSDS data and verifies that it returns false.
+ */
+TEST_P(GnssHalTest, TestPsdsExtension) {
+ sp<IGnssPsds> iGnssPsds;
+ auto status = aidl_gnss_hal_->getExtensionPsds(&iGnssPsds);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_TRUE(iGnssPsds != nullptr);
+
+ status = iGnssPsds->injectPsdsData(PsdsType::LONG_TERM, std::vector<uint8_t>());
+ ASSERT_TRUE(status.isOk());
+}
+
+/*
+ * FindStrongFrequentNonGpsSource:
+ *
+ * Search through a GnssSvStatus list for the strongest non-GPS satellite observed enough times
+ *
+ * returns the strongest source,
+ * or a source with constellation == UNKNOWN if none are found sufficient times
+ */
+BlocklistedSource FindStrongFrequentNonGpsSource(
+ const std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_list,
+ const int min_observations) {
+ struct ComparableBlocklistedSource {
+ BlocklistedSource id;
+
+ ComparableBlocklistedSource() {
+ id.constellation = GnssConstellationTypeAidl::UNKNOWN;
+ id.svid = 0;
+ }
+
+ bool operator<(const ComparableBlocklistedSource& compare) const {
+ return ((id.svid < compare.id.svid) || ((id.svid == compare.id.svid) &&
+ (id.constellation < compare.id.constellation)));
+ }
+ };
+
+ struct SignalCounts {
+ int observations;
+ float max_cn0_dbhz;
+ };
+
+ std::map<ComparableBlocklistedSource, SignalCounts> mapSignals;
+
+ for (const auto& sv_info_vec : sv_info_list) {
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ if ((gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX) &&
+ (gnss_sv.v2_0.constellation != GnssConstellationType::GPS)) {
+ ComparableBlocklistedSource source;
+ source.id.svid = gnss_sv.v2_0.v1_0.svid;
+ source.id.constellation =
+ static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation);
+
+ const auto& itSignal = mapSignals.find(source);
+ if (itSignal == mapSignals.end()) {
+ SignalCounts counts;
+ counts.observations = 1;
+ counts.max_cn0_dbhz = gnss_sv.v2_0.v1_0.cN0Dbhz;
+ mapSignals.insert(
+ std::pair<ComparableBlocklistedSource, SignalCounts>(source, counts));
+ } else {
+ itSignal->second.observations++;
+ if (itSignal->second.max_cn0_dbhz < gnss_sv.v2_0.v1_0.cN0Dbhz) {
+ itSignal->second.max_cn0_dbhz = gnss_sv.v2_0.v1_0.cN0Dbhz;
+ }
+ }
+ }
+ }
+ }
+
+ float max_cn0_dbhz_with_sufficient_count = 0.;
+ int total_observation_count = 0;
+ int blocklisted_source_count_observation = 0;
+
+ ComparableBlocklistedSource source_to_blocklist; // initializes to zero = UNKNOWN constellation
+ for (auto const& pairSignal : mapSignals) {
+ total_observation_count += pairSignal.second.observations;
+ if ((pairSignal.second.observations >= min_observations) &&
+ (pairSignal.second.max_cn0_dbhz > max_cn0_dbhz_with_sufficient_count)) {
+ source_to_blocklist = pairSignal.first;
+ blocklisted_source_count_observation = pairSignal.second.observations;
+ max_cn0_dbhz_with_sufficient_count = pairSignal.second.max_cn0_dbhz;
+ }
+ }
+ ALOGD("Among %d observations, chose svid %d, constellation %d, "
+ "with %d observations at %.1f max CNo",
+ total_observation_count, source_to_blocklist.id.svid,
+ (int)source_to_blocklist.id.constellation, blocklisted_source_count_observation,
+ max_cn0_dbhz_with_sufficient_count);
+
+ return source_to_blocklist.id;
+}
+
+/*
+ * BlocklistIndividualSatellites:
+ *
+ * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus for common satellites (strongest and one other.)
+ * 2a & b) Turns off location, and blocklists common satellites.
+ * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus does not use those satellites.
+ * 4a & b) Turns off location, and send in empty blocklist.
+ * 5a) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus does re-use at least the previously strongest satellite
+ * 5b) Retry a few times, in case GNSS search strategy takes a while to reacquire even the
+ * formerly strongest satellite
+ */
+TEST_P(GnssHalTest, BlocklistIndividualSatellites) {
+ if (!(aidl_gnss_cb_->last_capabilities_ &
+ (int)GnssCallbackAidl::CAPABILITY_SATELLITE_BLOCKLIST)) {
+ ALOGI("Test BlocklistIndividualSatellites skipped. SATELLITE_BLOCKLIST capability not "
+ "supported.");
+ return;
+ }
+
+ const int kLocationsToAwait = 3;
+ const int kRetriesToUnBlocklist = 10;
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+ int location_called_count = gnss_cb_->location_cbq_.calledCount();
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
+ sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
+
+ /*
+ * Identify strongest SV seen at least kLocationsToAwait -1 times
+ * Why -1? To avoid test flakiness in case of (plausible) slight flakiness in strongest signal
+ * observability (one epoch RF null)
+ */
+
+ const int kGnssSvInfoListTimeout = 2;
+ std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_vec_list;
+ int count = gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec_list, sv_info_list_cbq_size,
+ kGnssSvInfoListTimeout);
+
+ ASSERT_EQ(count, sv_info_list_cbq_size);
+
+ BlocklistedSource source_to_blocklist =
+ FindStrongFrequentNonGpsSource(sv_info_vec_list, kLocationsToAwait - 1);
+
+ if (source_to_blocklist.constellation == GnssConstellationTypeAidl::UNKNOWN) {
+ // Cannot find a non-GPS satellite. Let the test pass.
+ ALOGD("Cannot find a non-GPS satellite. Letting the test pass.");
+ return;
+ }
+
+ // Stop locations, blocklist the common SV
+ StopAndClearLocations();
+
+ sp<IGnssConfiguration> gnss_configuration_hal;
+ auto status = aidl_gnss_hal_->getExtensionGnssConfiguration(&gnss_configuration_hal);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_NE(gnss_configuration_hal, nullptr);
+
+ std::vector<BlocklistedSource> sources;
+ sources.resize(1);
+ sources[0] = source_to_blocklist;
+
+ status = gnss_configuration_hal->setBlocklist(sources);
+ ASSERT_TRUE(status.isOk());
+
+ // retry and ensure satellite not used
+ gnss_cb_->sv_info_list_cbq_.reset();
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+
+ // early exit if test is being run with insufficient signal
+ location_called_count = gnss_cb_->location_cbq_.calledCount();
+ if (location_called_count == 0) {
+ ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
+ }
+ ASSERT_TRUE(location_called_count > 0);
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
+ sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
+ for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+ hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ EXPECT_FALSE((gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
+ (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+ source_to_blocklist.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ }
+ }
+
+ // clear blocklist and restart - this time updating the blocklist while location is still on
+ sources.resize(0);
+
+ status = gnss_configuration_hal->setBlocklist(sources);
+ ASSERT_TRUE(status.isOk());
+
+ bool strongest_sv_is_reobserved = false;
+ // do several loops awaiting a few locations, allowing non-immediate reacquisition strategies
+ int unblocklist_loops_remaining = kRetriesToUnBlocklist;
+ while (!strongest_sv_is_reobserved && (unblocklist_loops_remaining-- > 0)) {
+ StopAndClearLocations();
+ gnss_cb_->sv_info_list_cbq_.reset();
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+
+ // early exit loop if test is being run with insufficient signal
+ location_called_count = gnss_cb_->location_cbq_.calledCount();
+ if (location_called_count == 0) {
+ ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
+ }
+ ASSERT_TRUE(location_called_count > 0);
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Clear blocklist, observed %d GnssSvInfo, while awaiting %d Locations"
+ ", tries remaining %d",
+ sv_info_list_cbq_size, kLocationsToAwait, unblocklist_loops_remaining);
+
+ for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+ hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ if ((gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
+ (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+ source_to_blocklist.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)) {
+ strongest_sv_is_reobserved = true;
+ break;
+ }
+ }
+ if (strongest_sv_is_reobserved) break;
+ }
+ }
+ EXPECT_TRUE(strongest_sv_is_reobserved);
+ StopAndClearLocations();
+}
+
+/*
+ * BlocklistConstellationLocationOff:
+ *
+ * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus for any non-GPS constellations.
+ * 2a & b) Turns off location, and blocklist first non-GPS constellations.
+ * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus does not use any constellation but GPS.
+ * 4a & b) Clean up by turning off location, and send in empty blocklist.
+ */
+TEST_P(GnssHalTest, BlocklistConstellationLocationOff) {
+ if (!(aidl_gnss_cb_->last_capabilities_ &
+ (int)GnssCallbackAidl::CAPABILITY_SATELLITE_BLOCKLIST)) {
+ ALOGI("Test BlocklistConstellationLocationOff skipped. SATELLITE_BLOCKLIST capability not "
+ "supported.");
+ return;
+ }
+
+ const int kLocationsToAwait = 3;
+ const int kGnssSvInfoListTimeout = 2;
+
+ // Find first non-GPS constellation to blocklist
+ GnssConstellationTypeAidl constellation_to_blocklist = static_cast<GnssConstellationTypeAidl>(
+ startLocationAndGetNonGpsConstellation(kLocationsToAwait, kGnssSvInfoListTimeout));
+
+ // Turns off location
+ StopAndClearLocations();
+
+ BlocklistedSource source_to_blocklist_1;
+ source_to_blocklist_1.constellation = constellation_to_blocklist;
+ source_to_blocklist_1.svid = 0; // documented wildcard for all satellites in this constellation
+
+ // IRNSS was added in 2.0. Always attempt to blocklist IRNSS to verify that the new enum is
+ // supported.
+ BlocklistedSource source_to_blocklist_2;
+ source_to_blocklist_2.constellation = GnssConstellationTypeAidl::IRNSS;
+ source_to_blocklist_2.svid = 0; // documented wildcard for all satellites in this constellation
+
+ sp<IGnssConfiguration> gnss_configuration_hal;
+ auto status = aidl_gnss_hal_->getExtensionGnssConfiguration(&gnss_configuration_hal);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_NE(gnss_configuration_hal, nullptr);
+
+ hidl_vec<BlocklistedSource> sources;
+ sources.resize(2);
+ sources[0] = source_to_blocklist_1;
+ sources[1] = source_to_blocklist_2;
+
+ status = gnss_configuration_hal->setBlocklist(sources);
+ ASSERT_TRUE(status.isOk());
+
+ // retry and ensure constellation not used
+ gnss_cb_->sv_info_list_cbq_.reset();
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations", sv_info_list_cbq_size,
+ kLocationsToAwait);
+ for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+ hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ EXPECT_FALSE((static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+ source_to_blocklist_1.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ EXPECT_FALSE((static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+ source_to_blocklist_2.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ }
+ }
+
+ // clean up
+ StopAndClearLocations();
+ sources.resize(0);
+ status = gnss_configuration_hal->setBlocklist(sources);
+ ASSERT_TRUE(status.isOk());
+}
+
+/*
+ * BlocklistConstellationLocationOn:
+ *
+ * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus for any non-GPS constellations.
+ * 2a & b) Blocklist first non-GPS constellation, and turn off location.
+ * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus does not use any constellation but GPS.
+ * 4a & b) Clean up by turning off location, and send in empty blocklist.
+ */
+TEST_P(GnssHalTest, BlocklistConstellationLocationOn) {
+ if (!(aidl_gnss_cb_->last_capabilities_ &
+ (int)GnssCallbackAidl::CAPABILITY_SATELLITE_BLOCKLIST)) {
+ ALOGI("Test BlocklistConstellationLocationOn skipped. SATELLITE_BLOCKLIST capability not "
+ "supported.");
+ return;
+ }
+
+ const int kLocationsToAwait = 3;
+ const int kGnssSvInfoListTimeout = 2;
+
+ // Find first non-GPS constellation to blocklist
+ GnssConstellationTypeAidl constellation_to_blocklist = static_cast<GnssConstellationTypeAidl>(
+ startLocationAndGetNonGpsConstellation(kLocationsToAwait, kGnssSvInfoListTimeout));
+
+ BlocklistedSource source_to_blocklist_1;
+ source_to_blocklist_1.constellation = constellation_to_blocklist;
+ source_to_blocklist_1.svid = 0; // documented wildcard for all satellites in this constellation
+
+ // IRNSS was added in 2.0. Always attempt to blocklist IRNSS to verify that the new enum is
+ // supported.
+ BlocklistedSource source_to_blocklist_2;
+ source_to_blocklist_2.constellation = GnssConstellationTypeAidl::IRNSS;
+ source_to_blocklist_2.svid = 0; // documented wildcard for all satellites in this constellation
+
+ sp<IGnssConfiguration> gnss_configuration_hal;
+ auto status = aidl_gnss_hal_->getExtensionGnssConfiguration(&gnss_configuration_hal);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_NE(gnss_configuration_hal, nullptr);
+
+ hidl_vec<BlocklistedSource> sources;
+ sources.resize(2);
+ sources[0] = source_to_blocklist_1;
+ sources[1] = source_to_blocklist_2;
+
+ status = gnss_configuration_hal->setBlocklist(sources);
+ ASSERT_TRUE(status.isOk());
+
+ // Turns off location
+ StopAndClearLocations();
+
+ // retry and ensure constellation not used
+ gnss_cb_->sv_info_list_cbq_.reset();
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations", sv_info_list_cbq_size,
+ kLocationsToAwait);
+ for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+ hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ EXPECT_FALSE((static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+ source_to_blocklist_1.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ EXPECT_FALSE((static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+ source_to_blocklist_2.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ }
+ }
+
+ // clean up
+ StopAndClearLocations();
+ sources.resize(0);
+ status = gnss_configuration_hal->setBlocklist(sources);
+ ASSERT_TRUE(status.isOk());
+}
diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp
index 8d9d4d4..730de4b 100644
--- a/gnss/common/utils/default/Android.bp
+++ b/gnss/common/utils/default/Android.bp
@@ -29,6 +29,7 @@
"v2_1/GnssDebug.cpp",
"v2_1/GnssMeasurement.cpp",
"v2_1/GnssMeasurementCorrections.cpp",
+ "MockLocation.cpp",
"Utils.cpp",
"NmeaFixInfo.cpp",
],
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl b/gnss/common/utils/default/MockLocation.cpp
similarity index 69%
rename from biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl
rename to gnss/common/utils/default/MockLocation.cpp
index eadba52..2d8e7c5 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl
+++ b/gnss/common/utils/default/MockLocation.cpp
@@ -14,13 +14,12 @@
* limitations under the License.
*/
-package android.hardware.biometrics.fingerprint;
+#include "MockLocation.h"
-@VintfStability
-oneway interface IRevokeChallengeCallback {
- /**
- * Notifies the framework when a challenge has been revoked.
- */
- void onChallengeRevoked(in int sensorId, in int userId, in long challenge);
-}
+namespace android::hardware::gnss::common {
+float gMockLatitudeDegrees{37.4219999};
+float gMockLongitudeDegrees{-122.0840575};
+float gMockAltitudeMeters{1.60062531};
+
+} // namespace android::hardware::gnss::common
diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp
index 386090e..fa83634 100644
--- a/gnss/common/utils/default/Utils.cpp
+++ b/gnss/common/utils/default/Utils.cpp
@@ -15,6 +15,7 @@
*/
#include <Constants.h>
+#include <MockLocation.h>
#include <Utils.h>
#include <utils/SystemClock.h>
@@ -141,9 +142,9 @@
V1_0::GnssLocation Utils::getMockLocationV1_0() {
V1_0::GnssLocation location = {
.gnssLocationFlags = 0xFF,
- .latitudeDegrees = kMockLatitudeDegrees,
- .longitudeDegrees = kMockLongitudeDegrees,
- .altitudeMeters = kMockAltitudeMeters,
+ .latitudeDegrees = gMockLatitudeDegrees,
+ .longitudeDegrees = gMockLongitudeDegrees,
+ .altitudeMeters = gMockAltitudeMeters,
.speedMetersPerSec = kMockSpeedMetersPerSec,
.bearingDegrees = kMockBearingDegrees,
.horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
diff --git a/gnss/common/utils/default/include/Constants.h b/gnss/common/utils/default/include/Constants.h
index 000a9ec..ad4e0eb 100644
--- a/gnss/common/utils/default/include/Constants.h
+++ b/gnss/common/utils/default/include/Constants.h
@@ -24,9 +24,6 @@
namespace gnss {
namespace common {
-const float kMockLatitudeDegrees = 37.4219999;
-const float kMockLongitudeDegrees = -122.0840575;
-const float kMockAltitudeMeters = 1.60062531;
const float kMockSpeedMetersPerSec = 0;
const float kMockBearingDegrees = 0;
const float kMockHorizontalAccuracyMeters = 5;
diff --git a/gnss/common/utils/default/include/MockLocation.h b/gnss/common/utils/default/include/MockLocation.h
new file mode 100644
index 0000000..cd8cb5d
--- /dev/null
+++ b/gnss/common/utils/default/include/MockLocation.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_gnss_common_MockLocation_H_
+#define android_hardware_gnss_common_MockLocation_H_
+
+#include <cstdint>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+extern float gMockLatitudeDegrees;
+extern float gMockLongitudeDegrees;
+extern float gMockAltitudeMeters;
+
+} // namespace common
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_gnss_common_MockLocation_H_
diff --git a/gnss/common/utils/default/include/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
index 1fe6c3e..7c3c58a 100644
--- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h
+++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
@@ -33,6 +33,7 @@
#include "GnssDebug.h"
#include "GnssMeasurement.h"
#include "GnssMeasurementCorrections.h"
+#include "MockLocation.h"
#include "NmeaFixInfo.h"
#include "Utils.h"
@@ -113,12 +114,17 @@
getExtensionMeasurementCorrections_1_1() override;
Return<sp<V2_1::IGnssAntennaInfo>> getExtensionGnssAntennaInfo() override;
+ Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
+
private:
std::unique_ptr<V2_0::GnssLocation> getLocationFromHW();
void reportLocation(const V2_0::GnssLocation&) const;
void reportLocation(const V1_0::GnssLocation&) const;
void reportSvStatus(const hidl_vec<GnssSvInfo>&) const;
+ Return<void> help(const hidl_handle& fd);
+ Return<void> setLocation(const hidl_handle& fd, const hidl_vec<hidl_string>& options);
+
static sp<V2_1::IGnssCallback> sGnssCallback_2_1;
static sp<V2_0::IGnssCallback> sGnssCallback_2_0;
static sp<V1_1::IGnssCallback> sGnssCallback_1_1;
@@ -127,12 +133,13 @@
std::atomic<long> mMinIntervalMs;
sp<GnssConfiguration> mGnssConfiguration;
std::atomic<bool> mIsActive;
- std::atomic<bool> mHardwareModeOn;
+ std::atomic<bool> mHardwareModeChecked;
std::atomic<int> mGnssFd;
std::thread mThread;
mutable std::mutex mMutex;
- hidl_vec<GnssSvInfo> filterBlacklistedSatellitesV2_1(hidl_vec<GnssSvInfo> gnssSvInfoList);
+ virtual hidl_vec<GnssSvInfo> filterBlocklistedSatellitesV2_1(
+ hidl_vec<GnssSvInfo> gnssSvInfoList);
};
template <class T_IGnss>
@@ -148,7 +155,7 @@
GnssTemplate<T_IGnss>::GnssTemplate()
: mMinIntervalMs(1000),
mGnssConfiguration{new GnssConfiguration()},
- mHardwareModeOn(false),
+ mHardwareModeChecked(false),
mGnssFd(-1) {}
template <class T_IGnss>
@@ -159,16 +166,18 @@
template <class T_IGnss>
std::unique_ptr<V2_0::GnssLocation> GnssTemplate<T_IGnss>::getLocationFromHW() {
char inputBuffer[INPUT_BUFFER_SIZE];
- if (mGnssFd == -1) {
+ if (!mHardwareModeChecked) {
mGnssFd = open(GNSS_PATH, O_RDWR | O_NONBLOCK);
+ if (mGnssFd == -1) {
+ ALOGW("Failed to open /dev/gnss0 errno: %d", errno);
+ }
+ mHardwareModeChecked = true;
}
if (mGnssFd == -1) {
- ALOGW("Failed to open /dev/gnss0 errno: %d", errno);
return nullptr;
}
- // Indicates it is a hardwareMode, don't report the default location.
- mHardwareModeOn = true;
+
int bytes_write = write(mGnssFd, CMD_GET_LOCATION, strlen(CMD_GET_LOCATION));
if (bytes_write <= 0) {
return nullptr;
@@ -206,14 +215,12 @@
mIsActive = true;
mThread = std::thread([this]() {
while (mIsActive == true) {
- auto svStatus = filterBlacklistedSatellitesV2_1(Utils::getMockSvInfoListV2_1());
+ auto svStatus = filterBlocklistedSatellitesV2_1(Utils::getMockSvInfoListV2_1());
this->reportSvStatus(svStatus);
auto currentLocation = getLocationFromHW();
- if (mHardwareModeOn) {
- if (currentLocation != nullptr) {
- // Only report location if the return from hardware is valid
- this->reportLocation(*currentLocation);
- }
+ if (mGnssFd != -1 && currentLocation != nullptr) {
+ // Only report location if the return from hardware is valid
+ this->reportLocation(*currentLocation);
} else {
if (sGnssCallback_2_1 != nullptr || sGnssCallback_2_0 != nullptr) {
const auto location = Utils::getMockLocationV2_0();
@@ -230,8 +237,9 @@
}
template <class T_IGnss>
-hidl_vec<GnssSvInfo> GnssTemplate<T_IGnss>::filterBlacklistedSatellitesV2_1(
+hidl_vec<GnssSvInfo> GnssTemplate<T_IGnss>::filterBlocklistedSatellitesV2_1(
hidl_vec<GnssSvInfo> gnssSvInfoList) {
+ ALOGD("filterBlocklistedSatellitesV2_1");
for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) {
if (mGnssConfiguration->isBlacklistedV2_1(gnssSvInfoList[i])) {
gnssSvInfoList[i].v2_0.v1_0.svFlag &=
@@ -637,4 +645,59 @@
}
}
+template <class T_IGnss>
+Return<void> GnssTemplate<T_IGnss>::setLocation(const hidl_handle& fd,
+ const hidl_vec<hidl_string>& options) {
+ auto lat = gMockLatitudeDegrees;
+ auto lon = gMockLongitudeDegrees;
+ auto ele = gMockAltitudeMeters;
+
+ for (size_t i = 1; i < options.size(); ++i) {
+ std::string option = options[i];
+ if (option.rfind("lat=", 0) == 0) {
+ option = option.substr(4);
+ lat = stof(option);
+ } else if (option.rfind("lon=", 0) == 0) {
+ option = option.substr(4);
+ lon = stof(option);
+ } else if (option.rfind("ele=", 0) == 0) {
+ option = option.substr(4);
+ ele = stof(option);
+ } else {
+ dprintf(fd->data[0], "unsupported location argument: %s\n", option.c_str());
+ }
+ }
+
+ gMockLatitudeDegrees = lat;
+ gMockLongitudeDegrees = lon;
+ gMockAltitudeMeters = ele;
+
+ dprintf(fd->data[0], "mock location updated to lat=%f lon=%f ele=%f\n", gMockLatitudeDegrees,
+ gMockLongitudeDegrees, gMockAltitudeMeters);
+
+ return Void();
+}
+
+template <class T_IGnss>
+Return<void> GnssTemplate<T_IGnss>::help(const hidl_handle& fd) {
+ dprintf(fd->data[0],
+ "invalid option for Gnss HAL; valid options are:\n"
+ "location lat=.. lon=.. ele=..\n");
+ return Void();
+}
+
+template <class T_IGnss>
+Return<void> GnssTemplate<T_IGnss>::debug(const hidl_handle& fd,
+ const hidl_vec<hidl_string>& options) {
+ if (options.size() == 0) {
+ return help(fd);
+ } else if (options[0] == "location") {
+ return setLocation(fd, options);
+ } else {
+ return help(fd);
+ }
+
+ return Void();
+}
+
} // namespace android::hardware::gnss::common::implementation
diff --git a/gnss/common/utils/default/v2_1/GnssDebug.cpp b/gnss/common/utils/default/v2_1/GnssDebug.cpp
index 492b970..d78b0b6 100644
--- a/gnss/common/utils/default/v2_1/GnssDebug.cpp
+++ b/gnss/common/utils/default/v2_1/GnssDebug.cpp
@@ -19,6 +19,7 @@
#include <log/log.h>
#include "Constants.h"
+#include "MockLocation.h"
#include "v2_1/GnssDebug.h"
using namespace ::android::hardware::gnss::common;
@@ -29,9 +30,9 @@
Return<void> GnssDebug::getDebugData(V1_0::IGnssDebug::getDebugData_cb _hidl_cb) {
PositionDebug positionDebug = {
.valid = true,
- .latitudeDegrees = kMockLatitudeDegrees,
- .longitudeDegrees = kMockLongitudeDegrees,
- .altitudeMeters = kMockAltitudeMeters,
+ .latitudeDegrees = gMockLatitudeDegrees,
+ .longitudeDegrees = gMockLongitudeDegrees,
+ .altitudeMeters = gMockAltitudeMeters,
.speedMetersPerSec = kMockSpeedMetersPerSec,
.bearingDegrees = kMockBearingDegrees,
.horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
diff --git a/gnss/common/utils/vts/Utils.cpp b/gnss/common/utils/vts/Utils.cpp
index 9bf68e6..9c84e80 100644
--- a/gnss/common/utils/vts/Utils.cpp
+++ b/gnss/common/utils/vts/Utils.cpp
@@ -17,6 +17,8 @@
#include <Utils.h>
#include "gtest/gtest.h"
+#include <cutils/properties.h>
+
namespace android {
namespace hardware {
namespace gnss {
@@ -194,6 +196,12 @@
}
}
+bool Utils::isAutomotiveDevice() {
+ char buffer[PROPERTY_VALUE_MAX] = {0};
+ property_get("ro.hardware.type", buffer, "");
+ return strncmp(buffer, "automotive", PROPERTY_VALUE_MAX) == 0;
+}
+
} // namespace common
} // namespace gnss
} // namespace hardware
diff --git a/gnss/common/utils/vts/include/Utils.h b/gnss/common/utils/vts/include/Utils.h
index 9c838b2..a4aad80 100644
--- a/gnss/common/utils/vts/include/Utils.h
+++ b/gnss/common/utils/vts/include/Utils.h
@@ -49,6 +49,8 @@
static const MeasurementCorrections_1_1 getMockMeasurementCorrections_1_1();
static GnssConstellationType_1_0 mapConstellationType(GnssConstellationType_2_0 constellation);
+
+ static bool isAutomotiveDevice();
};
} // namespace common
diff --git a/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h b/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h
index d057c61..1439158 100644
--- a/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h
+++ b/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h
@@ -119,7 +119,7 @@
* SetUpGnssCallback:
* Set GnssCallback and verify the result.
*/
- void SetUpGnssCallback();
+ virtual void SetUpGnssCallback();
/*
* StartAndCheckFirstLocation:
diff --git a/graphics/common/aidl/Android.bp b/graphics/common/aidl/Android.bp
index e594233..22e609d 100644
--- a/graphics/common/aidl/Android.bp
+++ b/graphics/common/aidl/Android.bp
@@ -6,6 +6,7 @@
enabled: true,
support_system_process: true,
},
+ vndk_use_version: "2",
srcs: [
"android/hardware/graphics/common/*.aidl",
],
diff --git a/graphics/composer/2.1/default/Android.bp b/graphics/composer/2.1/default/Android.bp
index 533687b..a367457 100644
--- a/graphics/composer/2.1/default/Android.bp
+++ b/graphics/composer/2.1/default/Android.bp
@@ -1,31 +1,3 @@
-cc_library_shared {
- name: "android.hardware.graphics.composer@2.1-impl",
- defaults: ["hidl_defaults"],
- vendor: true,
- relative_install_path: "hw",
- srcs: ["passthrough.cpp"],
- header_libs: [
- "android.hardware.graphics.composer@2.1-passthrough",
- ],
- shared_libs: [
- "android.hardware.graphics.composer@2.1",
- "android.hardware.graphics.composer@2.1-resources",
- "libbase",
- "libcutils",
- "libfmq",
- "libhardware",
- "libhidlbase",
- "liblog",
- "libsync",
- "libutils",
- "libhwc2on1adapter",
- "libhwc2onfbadapter",
- ],
- cflags: [
- "-DLOG_TAG=\"ComposerHal\""
- ],
-}
-
cc_binary {
name: "android.hardware.graphics.composer@2.1-service",
defaults: ["hidl_defaults"],
@@ -33,10 +5,20 @@
relative_install_path: "hw",
srcs: ["service.cpp"],
init_rc: ["android.hardware.graphics.composer@2.1-service.rc"],
+ header_libs: [
+ "android.hardware.graphics.composer@2.1-passthrough",
+ ],
shared_libs: [
"android.hardware.graphics.composer@2.1",
+ "android.hardware.graphics.composer@2.1-resources",
+ "libbase",
"libbinder",
+ "libcutils",
+ "libfmq",
+ "libhardware",
"libhidlbase",
+ "libhwc2on1adapter",
+ "libhwc2onfbadapter",
"liblog",
"libsync",
"libutils",
diff --git a/graphics/composer/2.1/default/passthrough.cpp b/graphics/composer/2.1/default/passthrough.cpp
deleted file mode 100644
index ef7ed7c..0000000
--- a/graphics/composer/2.1/default/passthrough.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <android/hardware/graphics/composer/2.1/IComposer.h>
-#include <composer-passthrough/2.1/HwcLoader.h>
-
-using android::hardware::graphics::composer::V2_1::IComposer;
-using android::hardware::graphics::composer::V2_1::passthrough::HwcLoader;
-
-extern "C" IComposer* HIDL_FETCH_IComposer(const char* /* name */) {
- return HwcLoader::load();
-}
diff --git a/graphics/composer/2.1/default/service.cpp b/graphics/composer/2.1/default/service.cpp
index 82a33f6..1276d2d 100644
--- a/graphics/composer/2.1/default/service.cpp
+++ b/graphics/composer/2.1/default/service.cpp
@@ -21,10 +21,11 @@
#include <android/hardware/graphics/composer/2.1/IComposer.h>
#include <binder/ProcessState.h>
+#include <composer-passthrough/2.1/HwcLoader.h>
#include <hidl/LegacySupport.h>
using android::hardware::graphics::composer::V2_1::IComposer;
-using android::hardware::defaultPassthroughServiceImplementation;
+using android::hardware::graphics::composer::V2_1::passthrough::HwcLoader;
int main() {
// the conventional HAL might start binder services
@@ -40,5 +41,19 @@
ALOGE("Couldn't set SCHED_FIFO: %d", errno);
}
- return defaultPassthroughServiceImplementation<IComposer>(4);
+ android::hardware::configureRpcThreadpool(4, true /* will join */);
+
+ android::sp<IComposer> composer = HwcLoader::load();
+ if (composer == nullptr) {
+ return 1;
+ }
+ if (composer->registerAsService() != android::NO_ERROR) {
+ ALOGE("failed to register service");
+ return 1;
+ }
+
+ android::hardware::joinRpcThreadpool();
+
+ ALOGE("service is terminating");
+ return 1;
}
diff --git a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h
index 47ead41..3d74af4 100644
--- a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h
+++ b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h
@@ -87,19 +87,28 @@
class HalEventCallback : public Hal::EventCallback {
public:
- HalEventCallback(const sp<IComposerCallback> callback, ComposerResources* resources)
- : mCallback(callback), mResources(resources) {}
+ HalEventCallback(Hal* hal, const sp<IComposerCallback> callback,
+ ComposerResources* resources)
+ : mHal(hal), mCallback(callback), mResources(resources) {}
- void onHotplug(Display display, IComposerCallback::Connection connected) {
- if (connected == IComposerCallback::Connection::CONNECTED) {
- mResources->addPhysicalDisplay(display);
- } else if (connected == IComposerCallback::Connection::DISCONNECTED) {
- mResources->removeDisplay(display);
- }
+ void onHotplug(Display display, IComposerCallback::Connection connected) {
+ if (connected == IComposerCallback::Connection::CONNECTED) {
+ if (mResources->hasDisplay(display)) {
+ // This is a subsequent hotplug "connected" for a display. This signals a
+ // display change and thus the framework may want to reallocate buffers. We
+ // need to free all cached handles, since they are holding a strong reference
+ // to the underlying buffers.
+ cleanDisplayResources(display);
+ mResources->removeDisplay(display);
+ }
+ mResources->addPhysicalDisplay(display);
+ } else if (connected == IComposerCallback::Connection::DISCONNECTED) {
+ mResources->removeDisplay(display);
+ }
- auto ret = mCallback->onHotplug(display, connected);
- ALOGE_IF(!ret.isOk(), "failed to send onHotplug: %s", ret.description().c_str());
- }
+ auto ret = mCallback->onHotplug(display, connected);
+ ALOGE_IF(!ret.isOk(), "failed to send onHotplug: %s", ret.description().c_str());
+ }
void onRefresh(Display display) {
mResources->setDisplayMustValidateState(display, true);
@@ -113,13 +122,64 @@
}
protected:
- const sp<IComposerCallback> mCallback;
- ComposerResources* const mResources;
+ Hal* const mHal;
+ const sp<IComposerCallback> mCallback;
+ ComposerResources* const mResources;
+
+ void cleanDisplayResources(Display display) {
+ size_t cacheSize;
+ Error err = mResources->getDisplayClientTargetCacheSize(display, &cacheSize);
+ if (err == Error::NONE) {
+ for (int slot = 0; slot < cacheSize; slot++) {
+ ComposerResources::ReplacedHandle replacedBuffer(/*isBuffer*/ true);
+ // Replace the buffer slots with NULLs. Keep the old handle until it is
+ // replaced in ComposerHal, otherwise we risk leaving a dangling pointer.
+ const native_handle_t* clientTarget = nullptr;
+ err = mResources->getDisplayClientTarget(display, slot, /*useCache*/ true,
+ /*rawHandle*/ nullptr, &clientTarget,
+ &replacedBuffer);
+ if (err != Error::NONE) {
+ continue;
+ }
+ const std::vector<hwc_rect_t> damage;
+ err = mHal->setClientTarget(display, clientTarget, /*fence*/ -1, 0, damage);
+ ALOGE_IF(err != Error::NONE,
+ "Can't clean slot %d of the client target buffer"
+ "cache for display %" PRIu64,
+ slot, display);
+ }
+ } else {
+ ALOGE("Can't clean client target cache for display %" PRIu64, display);
+ }
+
+ err = mResources->getDisplayOutputBufferCacheSize(display, &cacheSize);
+ if (err == Error::NONE) {
+ for (int slot = 0; slot < cacheSize; slot++) {
+ // Replace the buffer slots with NULLs. Keep the old handle until it is
+ // replaced in ComposerHal, otherwise we risk leaving a dangling pointer.
+ ComposerResources::ReplacedHandle replacedBuffer(/*isBuffer*/ true);
+ const native_handle_t* outputBuffer = nullptr;
+ err = mResources->getDisplayOutputBuffer(display, slot, /*useCache*/ true,
+ /*rawHandle*/ nullptr, &outputBuffer,
+ &replacedBuffer);
+ if (err != Error::NONE) {
+ continue;
+ }
+ err = mHal->setOutputBuffer(display, outputBuffer, /*fence*/ -1);
+ ALOGE_IF(err != Error::NONE,
+ "Can't clean slot %d of the output buffer cache"
+ "for display %" PRIu64,
+ slot, display);
+ }
+ } else {
+ ALOGE("Can't clean output buffer cache for display %" PRIu64, display);
+ }
+ }
};
Return<void> registerCallback(const sp<IComposerCallback>& callback) override {
// no locking as we require this function to be called only once
- mHalEventCallback = std::make_unique<HalEventCallback>(callback, mResources.get());
+ mHalEventCallback = std::make_unique<HalEventCallback>(mHal, callback, mResources.get());
mHal->registerEventCallback(mHalEventCallback.get());
return Void();
}
diff --git a/graphics/composer/2.1/utils/resources/ComposerResources.cpp b/graphics/composer/2.1/utils/resources/ComposerResources.cpp
index 21f6035..e52bf71 100644
--- a/graphics/composer/2.1/utils/resources/ComposerResources.cpp
+++ b/graphics/composer/2.1/utils/resources/ComposerResources.cpp
@@ -144,6 +144,10 @@
}
}
+size_t ComposerHandleCache::getCacheSize() const {
+ return mHandles.size();
+}
+
bool ComposerHandleCache::initCache(HandleType type, uint32_t cacheSize) {
// already initialized
if (mHandleType != HandleType::INVALID) {
@@ -220,6 +224,14 @@
return mClientTargetCache.initCache(ComposerHandleCache::HandleType::BUFFER, cacheSize);
}
+size_t ComposerDisplayResource::getClientTargetCacheSize() const {
+ return mClientTargetCache.getCacheSize();
+}
+
+size_t ComposerDisplayResource::getOutputBufferCacheSize() const {
+ return mOutputBufferCache.getCacheSize();
+}
+
bool ComposerDisplayResource::isVirtual() const {
return mType == DisplayType::VIRTUAL;
}
@@ -293,6 +305,10 @@
mDisplayResources.clear();
}
+bool ComposerResources::hasDisplay(Display display) {
+ return mDisplayResources.count(display) > 0;
+}
+
Error ComposerResources::addPhysicalDisplay(Display display) {
auto displayResource = createDisplayResource(ComposerDisplayResource::DisplayType::PHYSICAL, 0);
@@ -327,6 +343,26 @@
: Error::BAD_PARAMETER;
}
+Error ComposerResources::getDisplayClientTargetCacheSize(Display display, size_t* outCacheSize) {
+ std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
+ ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
+ if (!displayResource) {
+ return Error::BAD_DISPLAY;
+ }
+ *outCacheSize = displayResource->getClientTargetCacheSize();
+ return Error::NONE;
+}
+
+Error ComposerResources::getDisplayOutputBufferCacheSize(Display display, size_t* outCacheSize) {
+ std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
+ ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
+ if (!displayResource) {
+ return Error::BAD_DISPLAY;
+ }
+ *outCacheSize = displayResource->getOutputBufferCacheSize();
+ return Error::NONE;
+}
+
Error ComposerResources::addLayer(Display display, Layer layer, uint32_t bufferCacheSize) {
auto layerResource = createLayerResource(bufferCacheSize);
diff --git a/graphics/composer/2.1/utils/resources/include/composer-resources/2.1/ComposerResources.h b/graphics/composer/2.1/utils/resources/include/composer-resources/2.1/ComposerResources.h
index 3738278..de78a59 100644
--- a/graphics/composer/2.1/utils/resources/include/composer-resources/2.1/ComposerResources.h
+++ b/graphics/composer/2.1/utils/resources/include/composer-resources/2.1/ComposerResources.h
@@ -74,6 +74,7 @@
ComposerHandleCache& operator=(const ComposerHandleCache&) = delete;
bool initCache(HandleType type, uint32_t cacheSize);
+ size_t getCacheSize() const;
Error lookupCache(uint32_t slot, const native_handle_t** outHandle);
Error updateCache(uint32_t slot, const native_handle_t* handle,
const native_handle** outReplacedHandle);
@@ -120,7 +121,8 @@
uint32_t outputBufferCacheSize);
bool initClientTargetCache(uint32_t cacheSize);
-
+ size_t getClientTargetCacheSize() const;
+ size_t getOutputBufferCacheSize() const;
bool isVirtual() const;
Error getClientTarget(uint32_t slot, bool fromCache, const native_handle_t* inHandle,
@@ -162,12 +164,15 @@
std::function<void(Display display, bool isVirtual, const std::vector<Layer>& layers)>;
void clear(RemoveDisplay removeDisplay);
+ bool hasDisplay(Display display);
Error addPhysicalDisplay(Display display);
Error addVirtualDisplay(Display display, uint32_t outputBufferCacheSize);
Error removeDisplay(Display display);
Error setDisplayClientTargetCacheSize(Display display, uint32_t clientTargetCacheSize);
+ Error getDisplayClientTargetCacheSize(Display display, size_t* outCacheSize);
+ Error getDisplayOutputBufferCacheSize(Display display, size_t* outCacheSize);
Error addLayer(Display display, Layer layer, uint32_t bufferCacheSize);
Error removeLayer(Display display, Layer layer);
@@ -177,7 +182,8 @@
bool mustValidateDisplay(Display display);
// When a buffer in the cache is replaced by a new one, we must keep it
- // alive until it has been replaced in ComposerHal.
+ // alive until it has been replaced in ComposerHal because it is still using
+ // the old buffer.
class ReplacedHandle {
public:
explicit ReplacedHandle(bool isBuffer) : mIsBuffer(isBuffer) {}
diff --git a/graphics/mapper/2.0/utils/hal/include/mapper-hal/2.0/Mapper.h b/graphics/mapper/2.0/utils/hal/include/mapper-hal/2.0/Mapper.h
index 8134174..0067105 100644
--- a/graphics/mapper/2.0/utils/hal/include/mapper-hal/2.0/Mapper.h
+++ b/graphics/mapper/2.0/utils/hal/include/mapper-hal/2.0/Mapper.h
@@ -85,11 +85,7 @@
return Error::BAD_BUFFER;
}
- Error error = mHal->freeBuffer(bufferHandle);
- if (error == Error::NONE) {
- removeImportedBuffer(buffer);
- }
- return error;
+ return freeImportedBuffer(bufferHandle);
}
Return<void> lock(void* buffer, uint64_t cpuUsage, const V2_0::IMapper::Rect& accessRegion,
@@ -160,8 +156,8 @@
return static_cast<void*>(bufferHandle);
}
- virtual native_handle_t* removeImportedBuffer(void* buffer) {
- return static_cast<native_handle_t*>(buffer);
+ virtual Error freeImportedBuffer(native_handle_t* bufferHandle) {
+ return mHal->freeBuffer(bufferHandle);
}
virtual native_handle_t* getImportedBuffer(void* buffer) const {
diff --git a/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/GrallocLoader.h b/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/GrallocLoader.h
index 85a91c3..f2e0064 100644
--- a/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/GrallocLoader.h
+++ b/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/GrallocLoader.h
@@ -56,17 +56,14 @@
return *singleton;
}
+ std::mutex* getMutex() { return &mMutex; }
+
void* add(native_handle_t* bufferHandle) {
std::lock_guard<std::mutex> lock(mMutex);
return mBufferHandles.insert(bufferHandle).second ? bufferHandle : nullptr;
}
- native_handle_t* remove(void* buffer) {
- auto bufferHandle = static_cast<native_handle_t*>(buffer);
-
- std::lock_guard<std::mutex> lock(mMutex);
- return mBufferHandles.erase(bufferHandle) == 1 ? bufferHandle : nullptr;
- }
+ void removeLocked(native_handle* bufferHandle) { mBufferHandles.erase(bufferHandle); }
native_handle_t* get(void* buffer) {
auto bufferHandle = static_cast<native_handle_t*>(buffer);
@@ -95,8 +92,13 @@
return GrallocImportedBufferPool::getInstance().add(bufferHandle);
}
- native_handle_t* removeImportedBuffer(void* buffer) override {
- return GrallocImportedBufferPool::getInstance().remove(buffer);
+ Error freeImportedBuffer(native_handle_t* bufferHandle) override {
+ std::lock_guard<std::mutex> lock(*GrallocImportedBufferPool::getInstance().getMutex());
+ Error error = this->mHal->freeBuffer(bufferHandle);
+ if (error == Error::NONE) {
+ GrallocImportedBufferPool::getInstance().removeLocked(bufferHandle);
+ }
+ return error;
}
native_handle_t* getImportedBuffer(void* buffer) const override {
diff --git a/graphics/mapper/2.1/utils/hal/include/mapper-hal/2.1/Mapper.h b/graphics/mapper/2.1/utils/hal/include/mapper-hal/2.1/Mapper.h
index 038f572..b4a2bedc 100644
--- a/graphics/mapper/2.1/utils/hal/include/mapper-hal/2.1/Mapper.h
+++ b/graphics/mapper/2.1/utils/hal/include/mapper-hal/2.1/Mapper.h
@@ -46,7 +46,7 @@
return Error::BAD_BUFFER;
}
- return mHal->validateBufferSize(bufferHandle, descriptorInfo, stride);
+ return this->mHal->validateBufferSize(bufferHandle, descriptorInfo, stride);
}
Return<void> getTransportSize(void* buffer, IMapper::getTransportSize_cb hidl_cb) {
@@ -58,7 +58,7 @@
uint32_t numFds = 0;
uint32_t numInts = 0;
- Error error = mHal->getTransportSize(bufferHandle, &numFds, &numInts);
+ Error error = this->mHal->getTransportSize(bufferHandle, &numFds, &numInts);
hidl_cb(error, numFds, numInts);
return Void();
}
@@ -66,7 +66,7 @@
Return<void> createDescriptor_2_1(const IMapper::BufferDescriptorInfo& descriptorInfo,
IMapper::createDescriptor_2_1_cb hidl_cb) override {
BufferDescriptor descriptor;
- Error error = mHal->createDescriptor_2_1(descriptorInfo, &descriptor);
+ Error error = this->mHal->createDescriptor_2_1(descriptorInfo, &descriptor);
hidl_cb(error, descriptor);
return Void();
}
@@ -74,7 +74,6 @@
private:
using BaseType2_0 = V2_0::hal::detail::MapperImpl<Interface, Hal>;
using BaseType2_0::getImportedBuffer;
- using BaseType2_0::mHal;
};
} // namespace detail
diff --git a/graphics/mapper/4.0/vts/functional/Android.bp b/graphics/mapper/4.0/vts/functional/Android.bp
index 03abc89..8bda425 100644
--- a/graphics/mapper/4.0/vts/functional/Android.bp
+++ b/graphics/mapper/4.0/vts/functional/Android.bp
@@ -19,7 +19,7 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalGraphicsMapperV4_0TargetTest.cpp"],
static_libs: [
- "android.hardware.graphics.common-ndk_platform",
+ "android.hardware.graphics.common-unstable-ndk_platform",
"android.hardware.graphics.mapper@4.0-vts",
"libgralloctypes",
"libsync",
diff --git a/health/1.0/default/Android.bp b/health/1.0/default/Android.bp
index b815eae..aab9cc7 100644
--- a/health/1.0/default/Android.bp
+++ b/health/1.0/default/Android.bp
@@ -4,7 +4,7 @@
recovery_available: true,
srcs: ["convert.cpp"],
include_dirs: [
- "system/core/base/include",
+ "system/libbase/include",
],
header_libs: ["libhealthd_headers"],
export_header_lib_headers: ["libhealthd_headers"],
diff --git a/health/1.0/default/android.hardware.health@1.0-service.rc b/health/1.0/default/android.hardware.health@1.0-service.rc
index 405784f..569dc88 100644
--- a/health/1.0/default/android.hardware.health@1.0-service.rc
+++ b/health/1.0/default/android.hardware.health@1.0-service.rc
@@ -2,4 +2,4 @@
class hal
user system
group system
- capabilities WAKE_ALARM
+ capabilities WAKE_ALARM BLOCK_SUSPEND
diff --git a/health/1.0/default/libhealthd/Android.bp b/health/1.0/default/libhealthd/Android.bp
index a90d50d..43463eb 100644
--- a/health/1.0/default/libhealthd/Android.bp
+++ b/health/1.0/default/libhealthd/Android.bp
@@ -6,6 +6,6 @@
vendor_available: true,
recovery_available: true,
cflags: ["-Werror"],
- include_dirs: ["system/core/base/include"],
+ include_dirs: ["system/libbase/include"],
header_libs: ["libhealthd_headers"],
}
diff --git a/health/2.1/default/android.hardware.health@2.1-service.rc b/health/2.1/default/android.hardware.health@2.1-service.rc
index b6d9e3b..8728257 100644
--- a/health/2.1/default/android.hardware.health@2.1-service.rc
+++ b/health/2.1/default/android.hardware.health@2.1-service.rc
@@ -2,5 +2,5 @@
class hal charger
user system
group system
- capabilities WAKE_ALARM
+ capabilities WAKE_ALARM BLOCK_SUSPEND
file /dev/kmsg w
diff --git a/powerstats/aidl/vts/Android.bp b/neuralnetworks/1.0/utils/Android.bp
similarity index 61%
copy from powerstats/aidl/vts/Android.bp
copy to neuralnetworks/1.0/utils/Android.bp
index c61022e..57a052f 100644
--- a/powerstats/aidl/vts/Android.bp
+++ b/neuralnetworks/1.0/utils/Android.bp
@@ -1,3 +1,4 @@
+//
// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -11,22 +12,22 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
+//
-cc_test {
- name: "VtsHalPowerStatsTargetTest",
- defaults: [
- "VtsHalTargetTestDefaults",
- "use_libaidlvintf_gtest_helper_static",
- ],
- srcs: ["VtsHalPowerStatsTargetTest.cpp"],
- shared_libs: [
- "libbinder_ndk",
- ],
+cc_library_static {
+ name: "neuralnetworks_utils_hal_1_0",
+ defaults: ["neuralnetworks_utils_defaults"],
+ srcs: ["src/*"],
+ local_include_dirs: ["include/nnapi/hal/1.0/"],
+ export_include_dirs: ["include"],
static_libs: [
- "android.hardware.powerstats-ndk_platform",
+ "neuralnetworks_types",
+ "neuralnetworks_utils_hal_common",
],
- test_suites: [
- "general-tests",
- "vts",
+ shared_libs: [
+ "android.hardware.neuralnetworks@1.0",
+ ],
+ export_static_lib_headers: [
+ "neuralnetworks_utils_hal_common",
],
}
diff --git a/neuralnetworks/1.0/utils/OWNERS b/neuralnetworks/1.0/utils/OWNERS
new file mode 100644
index 0000000..e4feee3
--- /dev/null
+++ b/neuralnetworks/1.0/utils/OWNERS
@@ -0,0 +1,11 @@
+# Neuralnetworks team
+butlermichael@google.com
+dgross@google.com
+galarragas@google.com
+jeanluc@google.com
+levp@google.com
+miaowang@google.com
+pszczepaniak@google.com
+slavash@google.com
+vddang@google.com
+xusongw@google.com
diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Conversions.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Conversions.h
new file mode 100644
index 0000000..8ad98cb
--- /dev/null
+++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Conversions.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_CONVERSIONS_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_CONVERSIONS_H
+
+#include <android/hardware/neuralnetworks/1.0/types.h>
+#include <nnapi/Result.h>
+#include <nnapi/Types.h>
+#include <nnapi/hal/CommonUtils.h>
+
+namespace android::nn {
+
+Result<OperandType> convert(const hal::V1_0::OperandType& operandType);
+Result<OperationType> convert(const hal::V1_0::OperationType& operationType);
+Result<Operand::LifeTime> convert(const hal::V1_0::OperandLifeTime& lifetime);
+Result<DeviceStatus> convert(const hal::V1_0::DeviceStatus& deviceStatus);
+Result<Capabilities::PerformanceInfo> convert(const hal::V1_0::PerformanceInfo& performanceInfo);
+Result<Capabilities> convert(const hal::V1_0::Capabilities& capabilities);
+Result<DataLocation> convert(const hal::V1_0::DataLocation& location);
+Result<Operand> convert(const hal::V1_0::Operand& operand);
+Result<Operation> convert(const hal::V1_0::Operation& operation);
+Result<Model::OperandValues> convert(const hardware::hidl_vec<uint8_t>& operandValues);
+Result<Memory> convert(const hardware::hidl_memory& memory);
+Result<Model> convert(const hal::V1_0::Model& model);
+Result<Request::Argument> convert(const hal::V1_0::RequestArgument& requestArgument);
+Result<Request> convert(const hal::V1_0::Request& request);
+Result<ErrorStatus> convert(const hal::V1_0::ErrorStatus& status);
+
+} // namespace android::nn
+
+namespace android::hardware::neuralnetworks::V1_0::utils {
+
+nn::Result<OperandType> convert(const nn::OperandType& operandType);
+nn::Result<OperationType> convert(const nn::OperationType& operationType);
+nn::Result<OperandLifeTime> convert(const nn::Operand::LifeTime& lifetime);
+nn::Result<DeviceStatus> convert(const nn::DeviceStatus& deviceStatus);
+nn::Result<PerformanceInfo> convert(const nn::Capabilities::PerformanceInfo& performanceInfo);
+nn::Result<Capabilities> convert(const nn::Capabilities& capabilities);
+nn::Result<DataLocation> convert(const nn::DataLocation& location);
+nn::Result<Operand> convert(const nn::Operand& operand);
+nn::Result<Operation> convert(const nn::Operation& operation);
+nn::Result<hidl_vec<uint8_t>> convert(const nn::Model::OperandValues& operandValues);
+nn::Result<hidl_memory> convert(const nn::Memory& memory);
+nn::Result<Model> convert(const nn::Model& model);
+nn::Result<RequestArgument> convert(const nn::Request::Argument& requestArgument);
+nn::Result<hidl_memory> convert(const nn::Request::MemoryPool& memoryPool);
+nn::Result<Request> convert(const nn::Request& request);
+nn::Result<ErrorStatus> convert(const nn::ErrorStatus& status);
+
+} // namespace android::hardware::neuralnetworks::V1_0::utils
+
+#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_CONVERSIONS_H
diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h
new file mode 100644
index 0000000..ec8da06
--- /dev/null
+++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_H
+
+#include "nnapi/hal/1.0/Conversions.h"
+
+#include <android-base/logging.h>
+#include <android/hardware/neuralnetworks/1.0/types.h>
+#include <nnapi/Result.h>
+#include <nnapi/Types.h>
+#include <nnapi/Validation.h>
+
+namespace android::hardware::neuralnetworks::V1_0::utils {
+
+constexpr auto kVersion = nn::Version::ANDROID_OC_MR1;
+
+template <typename Type>
+nn::Result<void> validate(const Type& halObject) {
+ const auto canonical = NN_TRY(nn::convert(halObject));
+ const auto version = NN_TRY(nn::validate(canonical));
+ if (version > utils::kVersion) {
+ return NN_ERROR() << "";
+ }
+ return {};
+}
+
+template <typename Type>
+bool valid(const Type& halObject) {
+ const auto result = utils::validate(halObject);
+ if (!result.has_value()) {
+ LOG(ERROR) << result.error();
+ }
+ return result.has_value();
+}
+
+template <typename Type>
+decltype(nn::convert(std::declval<Type>())) validatedConvertToCanonical(const Type& halObject) {
+ auto canonical = NN_TRY(nn::convert(halObject));
+ const auto version = NN_TRY(nn::validate(canonical));
+ if (version > utils::kVersion) {
+ return NN_ERROR() << "";
+ }
+ return canonical;
+}
+
+} // namespace android::hardware::neuralnetworks::V1_0::utils
+
+#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_H
diff --git a/neuralnetworks/1.0/utils/src/Assertions.cpp b/neuralnetworks/1.0/utils/src/Assertions.cpp
new file mode 100644
index 0000000..0f00951
--- /dev/null
+++ b/neuralnetworks/1.0/utils/src/Assertions.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/hardware/neuralnetworks/1.0/types.h>
+#include <nnapi/OperandTypes.h>
+#include <nnapi/OperationTypes.h>
+#include <nnapi/Types.h>
+#include <type_traits>
+
+namespace {
+
+#define COMPARE_ENUMS_TYPES(lhsType, rhsType) \
+ static_assert( \
+ std::is_same_v< \
+ std::underlying_type_t<::android::hardware::neuralnetworks::V1_0::lhsType>, \
+ std::underlying_type_t<::android::nn::rhsType>>, \
+ "::android::hardware::neuralnetworks::V1_0::" #lhsType \
+ " does not have the same underlying type as ::android::nn::" #rhsType)
+
+COMPARE_ENUMS_TYPES(OperandType, OperandType);
+COMPARE_ENUMS_TYPES(OperationType, OperationType);
+COMPARE_ENUMS_TYPES(ErrorStatus, ErrorStatus);
+COMPARE_ENUMS_TYPES(OperandLifeTime, Operand::LifeTime);
+
+#undef COMPARE_ENUMS_TYPES
+
+#define COMPARE_ENUMS_FULL(lhsSymbol, rhsSymbol, lhsType, rhsType) \
+ static_assert( \
+ static_cast< \
+ std::underlying_type_t<::android::hardware::neuralnetworks::V1_0::lhsType>>( \
+ ::android::hardware::neuralnetworks::V1_0::lhsType::lhsSymbol) == \
+ static_cast<std::underlying_type_t<::android::nn::rhsType>>( \
+ ::android::nn::rhsType::rhsSymbol), \
+ "::android::hardware::neuralnetworks::V1_0::" #lhsType "::" #lhsSymbol \
+ " does not match ::android::nn::" #rhsType "::" #rhsSymbol)
+
+#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, symbol, OperandType, OperandType)
+
+COMPARE_ENUMS(FLOAT32);
+COMPARE_ENUMS(INT32);
+COMPARE_ENUMS(UINT32);
+COMPARE_ENUMS(TENSOR_FLOAT32);
+COMPARE_ENUMS(TENSOR_INT32);
+COMPARE_ENUMS(TENSOR_QUANT8_ASYMM);
+COMPARE_ENUMS(OEM);
+COMPARE_ENUMS(TENSOR_OEM_BYTE);
+
+#undef COMPARE_ENUMS
+
+#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, symbol, OperationType, OperationType)
+
+COMPARE_ENUMS(ADD);
+COMPARE_ENUMS(AVERAGE_POOL_2D);
+COMPARE_ENUMS(CONCATENATION);
+COMPARE_ENUMS(CONV_2D);
+COMPARE_ENUMS(DEPTHWISE_CONV_2D);
+COMPARE_ENUMS(DEPTH_TO_SPACE);
+COMPARE_ENUMS(DEQUANTIZE);
+COMPARE_ENUMS(EMBEDDING_LOOKUP);
+COMPARE_ENUMS(FLOOR);
+COMPARE_ENUMS(FULLY_CONNECTED);
+COMPARE_ENUMS(HASHTABLE_LOOKUP);
+COMPARE_ENUMS(L2_NORMALIZATION);
+COMPARE_ENUMS(L2_POOL_2D);
+COMPARE_ENUMS(LOCAL_RESPONSE_NORMALIZATION);
+COMPARE_ENUMS(LOGISTIC);
+COMPARE_ENUMS(LSH_PROJECTION);
+COMPARE_ENUMS(LSTM);
+COMPARE_ENUMS(MAX_POOL_2D);
+COMPARE_ENUMS(MUL);
+COMPARE_ENUMS(RELU);
+COMPARE_ENUMS(RELU1);
+COMPARE_ENUMS(RELU6);
+COMPARE_ENUMS(RESHAPE);
+COMPARE_ENUMS(RESIZE_BILINEAR);
+COMPARE_ENUMS(RNN);
+COMPARE_ENUMS(SOFTMAX);
+COMPARE_ENUMS(SPACE_TO_DEPTH);
+COMPARE_ENUMS(SVDF);
+COMPARE_ENUMS(TANH);
+COMPARE_ENUMS(OEM_OPERATION);
+
+#undef COMPARE_ENUMS
+
+#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, symbol, ErrorStatus, ErrorStatus)
+
+COMPARE_ENUMS(NONE);
+COMPARE_ENUMS(DEVICE_UNAVAILABLE);
+COMPARE_ENUMS(GENERAL_FAILURE);
+COMPARE_ENUMS(OUTPUT_INSUFFICIENT_SIZE);
+COMPARE_ENUMS(INVALID_ARGUMENT);
+
+#undef COMPARE_ENUMS
+
+#define COMPARE_ENUMS(lhsSymbol, rhsSymbol) \
+ COMPARE_ENUMS_FULL(lhsSymbol, rhsSymbol, OperandLifeTime, Operand::LifeTime)
+
+COMPARE_ENUMS(TEMPORARY_VARIABLE, TEMPORARY_VARIABLE);
+COMPARE_ENUMS(MODEL_INPUT, SUBGRAPH_INPUT);
+COMPARE_ENUMS(MODEL_OUTPUT, SUBGRAPH_OUTPUT);
+COMPARE_ENUMS(CONSTANT_COPY, CONSTANT_COPY);
+COMPARE_ENUMS(CONSTANT_REFERENCE, CONSTANT_REFERENCE);
+COMPARE_ENUMS(NO_VALUE, NO_VALUE);
+
+#undef COMPARE_ENUMS
+
+#undef COMPARE_ENUMS_FULL
+
+} // anonymous namespace
diff --git a/neuralnetworks/1.0/utils/src/Conversions.cpp b/neuralnetworks/1.0/utils/src/Conversions.cpp
new file mode 100644
index 0000000..4a58f3b
--- /dev/null
+++ b/neuralnetworks/1.0/utils/src/Conversions.cpp
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Conversions.h"
+
+#include <android-base/logging.h>
+#include <android/hardware/neuralnetworks/1.0/types.h>
+#include <nnapi/OperandTypes.h>
+#include <nnapi/OperationTypes.h>
+#include <nnapi/Result.h>
+#include <nnapi/SharedMemory.h>
+#include <nnapi/Types.h>
+#include <nnapi/hal/CommonUtils.h>
+
+#include <algorithm>
+#include <functional>
+#include <iterator>
+#include <memory>
+#include <type_traits>
+#include <utility>
+#include <variant>
+
+namespace {
+
+template <typename Type>
+constexpr std::underlying_type_t<Type> underlyingType(Type value) {
+ return static_cast<std::underlying_type_t<Type>>(value);
+}
+
+} // namespace
+
+namespace android::nn {
+namespace {
+
+using hardware::hidl_memory;
+using hardware::hidl_vec;
+
+template <typename Input>
+using ConvertOutput = std::decay_t<decltype(convert(std::declval<Input>()).value())>;
+
+template <typename Type>
+Result<std::vector<ConvertOutput<Type>>> convert(const hidl_vec<Type>& arguments) {
+ std::vector<ConvertOutput<Type>> canonical;
+ canonical.reserve(arguments.size());
+ for (const auto& argument : arguments) {
+ canonical.push_back(NN_TRY(nn::convert(argument)));
+ }
+ return canonical;
+}
+
+} // anonymous namespace
+
+Result<OperandType> convert(const hal::V1_0::OperandType& operandType) {
+ return static_cast<OperandType>(operandType);
+}
+
+Result<OperationType> convert(const hal::V1_0::OperationType& operationType) {
+ return static_cast<OperationType>(operationType);
+}
+
+Result<Operand::LifeTime> convert(const hal::V1_0::OperandLifeTime& lifetime) {
+ return static_cast<Operand::LifeTime>(lifetime);
+}
+
+Result<DeviceStatus> convert(const hal::V1_0::DeviceStatus& deviceStatus) {
+ return static_cast<DeviceStatus>(deviceStatus);
+}
+
+Result<Capabilities::PerformanceInfo> convert(const hal::V1_0::PerformanceInfo& performanceInfo) {
+ return Capabilities::PerformanceInfo{
+ .execTime = performanceInfo.execTime,
+ .powerUsage = performanceInfo.powerUsage,
+ };
+}
+
+Result<Capabilities> convert(const hal::V1_0::Capabilities& capabilities) {
+ const auto quantized8Performance = NN_TRY(convert(capabilities.quantized8Performance));
+ const auto float32Performance = NN_TRY(convert(capabilities.float32Performance));
+
+ auto table = hal::utils::makeQuantized8PerformanceConsistentWithP(float32Performance,
+ quantized8Performance);
+
+ return Capabilities{
+ .relaxedFloat32toFloat16PerformanceScalar = float32Performance,
+ .relaxedFloat32toFloat16PerformanceTensor = float32Performance,
+ .operandPerformance = std::move(table),
+ };
+}
+
+Result<DataLocation> convert(const hal::V1_0::DataLocation& location) {
+ return DataLocation{
+ .poolIndex = location.poolIndex,
+ .offset = location.offset,
+ .length = location.length,
+ };
+}
+
+Result<Operand> convert(const hal::V1_0::Operand& operand) {
+ return Operand{
+ .type = NN_TRY(convert(operand.type)),
+ .dimensions = operand.dimensions,
+ .scale = operand.scale,
+ .zeroPoint = operand.zeroPoint,
+ .lifetime = NN_TRY(convert(operand.lifetime)),
+ .location = NN_TRY(convert(operand.location)),
+ };
+}
+
+Result<Operation> convert(const hal::V1_0::Operation& operation) {
+ return Operation{
+ .type = NN_TRY(convert(operation.type)),
+ .inputs = operation.inputs,
+ .outputs = operation.outputs,
+ };
+}
+
+Result<Model::OperandValues> convert(const hidl_vec<uint8_t>& operandValues) {
+ return Model::OperandValues(operandValues.data(), operandValues.size());
+}
+
+Result<Memory> convert(const hidl_memory& memory) {
+ return createSharedMemoryFromHidlMemory(memory);
+}
+
+Result<Model> convert(const hal::V1_0::Model& model) {
+ auto operations = NN_TRY(convert(model.operations));
+
+ // Verify number of consumers.
+ const auto numberOfConsumers =
+ hal::utils::countNumberOfConsumers(model.operands.size(), operations);
+ CHECK(model.operands.size() == numberOfConsumers.size());
+ for (size_t i = 0; i < model.operands.size(); ++i) {
+ if (model.operands[i].numberOfConsumers != numberOfConsumers[i]) {
+ return NN_ERROR() << "Invalid numberOfConsumers for operand " << i << ", expected "
+ << numberOfConsumers[i] << " but found "
+ << model.operands[i].numberOfConsumers;
+ }
+ }
+
+ auto main = Model::Subgraph{
+ .operands = NN_TRY(convert(model.operands)),
+ .operations = std::move(operations),
+ .inputIndexes = model.inputIndexes,
+ .outputIndexes = model.outputIndexes,
+ };
+
+ return Model{
+ .main = std::move(main),
+ .operandValues = NN_TRY(convert(model.operandValues)),
+ .pools = NN_TRY(convert(model.pools)),
+ };
+}
+
+Result<Request::Argument> convert(const hal::V1_0::RequestArgument& argument) {
+ const auto lifetime = argument.hasNoValue ? Request::Argument::LifeTime::NO_VALUE
+ : Request::Argument::LifeTime::POOL;
+ return Request::Argument{
+ .lifetime = lifetime,
+ .location = NN_TRY(convert(argument.location)),
+ .dimensions = argument.dimensions,
+ };
+}
+
+Result<Request> convert(const hal::V1_0::Request& request) {
+ auto memories = NN_TRY(convert(request.pools));
+ std::vector<Request::MemoryPool> pools;
+ pools.reserve(memories.size());
+ std::move(memories.begin(), memories.end(), std::back_inserter(pools));
+
+ return Request{
+ .inputs = NN_TRY(convert(request.inputs)),
+ .outputs = NN_TRY(convert(request.outputs)),
+ .pools = std::move(pools),
+ };
+}
+
+Result<ErrorStatus> convert(const hal::V1_0::ErrorStatus& status) {
+ switch (status) {
+ case hal::V1_0::ErrorStatus::NONE:
+ case hal::V1_0::ErrorStatus::DEVICE_UNAVAILABLE:
+ case hal::V1_0::ErrorStatus::GENERAL_FAILURE:
+ case hal::V1_0::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE:
+ case hal::V1_0::ErrorStatus::INVALID_ARGUMENT:
+ return static_cast<ErrorStatus>(status);
+ }
+ return NN_ERROR() << "Invalid ErrorStatus " << underlyingType(status);
+}
+
+} // namespace android::nn
+
+namespace android::hardware::neuralnetworks::V1_0::utils {
+namespace {
+
+template <typename Input>
+using ConvertOutput = std::decay_t<decltype(convert(std::declval<Input>()).value())>;
+
+template <typename Type>
+nn::Result<hidl_vec<ConvertOutput<Type>>> convert(const std::vector<Type>& arguments) {
+ hidl_vec<ConvertOutput<Type>> halObject(arguments.size());
+ for (size_t i = 0; i < arguments.size(); ++i) {
+ halObject[i] = NN_TRY(utils::convert(arguments[i]));
+ }
+ return halObject;
+}
+
+} // anonymous namespace
+
+nn::Result<OperandType> convert(const nn::OperandType& operandType) {
+ return static_cast<OperandType>(operandType);
+}
+
+nn::Result<OperationType> convert(const nn::OperationType& operationType) {
+ return static_cast<OperationType>(operationType);
+}
+
+nn::Result<OperandLifeTime> convert(const nn::Operand::LifeTime& lifetime) {
+ if (lifetime == nn::Operand::LifeTime::POINTER) {
+ return NN_ERROR() << "Model cannot be converted because it contains pointer-based memory";
+ }
+ return static_cast<OperandLifeTime>(lifetime);
+}
+
+nn::Result<DeviceStatus> convert(const nn::DeviceStatus& deviceStatus) {
+ return static_cast<DeviceStatus>(deviceStatus);
+}
+
+nn::Result<PerformanceInfo> convert(const nn::Capabilities::PerformanceInfo& performanceInfo) {
+ return PerformanceInfo{
+ .execTime = performanceInfo.execTime,
+ .powerUsage = performanceInfo.powerUsage,
+ };
+}
+
+nn::Result<Capabilities> convert(const nn::Capabilities& capabilities) {
+ return Capabilities{
+ .float32Performance = NN_TRY(convert(
+ capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_FLOAT32))),
+ .quantized8Performance = NN_TRY(convert(
+ capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_QUANT8_ASYMM))),
+ };
+}
+
+nn::Result<DataLocation> convert(const nn::DataLocation& location) {
+ return DataLocation{
+ .poolIndex = location.poolIndex,
+ .offset = location.offset,
+ .length = location.length,
+ };
+}
+
+nn::Result<Operand> convert(const nn::Operand& operand) {
+ return Operand{
+ .type = NN_TRY(convert(operand.type)),
+ .dimensions = operand.dimensions,
+ .numberOfConsumers = 0,
+ .scale = operand.scale,
+ .zeroPoint = operand.zeroPoint,
+ .lifetime = NN_TRY(convert(operand.lifetime)),
+ .location = NN_TRY(convert(operand.location)),
+ };
+}
+
+nn::Result<Operation> convert(const nn::Operation& operation) {
+ return Operation{
+ .type = NN_TRY(convert(operation.type)),
+ .inputs = operation.inputs,
+ .outputs = operation.outputs,
+ };
+}
+
+nn::Result<hidl_vec<uint8_t>> convert(const nn::Model::OperandValues& operandValues) {
+ return hidl_vec<uint8_t>(operandValues.data(), operandValues.data() + operandValues.size());
+}
+
+nn::Result<hidl_memory> convert(const nn::Memory& memory) {
+ const auto hidlMemory = hidl_memory(memory.name, memory.handle->handle(), memory.size);
+ // Copy memory to force the native_handle_t to be copied.
+ auto copiedMemory = hidlMemory;
+ return copiedMemory;
+}
+
+nn::Result<Model> convert(const nn::Model& model) {
+ if (!hal::utils::hasNoPointerData(model)) {
+ return NN_ERROR() << "Mdoel cannot be converted because it contains pointer-based memory";
+ }
+
+ auto operands = NN_TRY(convert(model.main.operands));
+
+ // Update number of consumers.
+ const auto numberOfConsumers =
+ hal::utils::countNumberOfConsumers(operands.size(), model.main.operations);
+ CHECK(operands.size() == numberOfConsumers.size());
+ for (size_t i = 0; i < operands.size(); ++i) {
+ operands[i].numberOfConsumers = numberOfConsumers[i];
+ }
+
+ return Model{
+ .operands = std::move(operands),
+ .operations = NN_TRY(convert(model.main.operations)),
+ .inputIndexes = model.main.inputIndexes,
+ .outputIndexes = model.main.outputIndexes,
+ .operandValues = NN_TRY(convert(model.operandValues)),
+ .pools = NN_TRY(convert(model.pools)),
+ };
+}
+
+nn::Result<RequestArgument> convert(const nn::Request::Argument& requestArgument) {
+ if (requestArgument.lifetime == nn::Request::Argument::LifeTime::POINTER) {
+ return NN_ERROR() << "Request cannot be converted because it contains pointer-based memory";
+ }
+ const bool hasNoValue = requestArgument.lifetime == nn::Request::Argument::LifeTime::NO_VALUE;
+ return RequestArgument{
+ .hasNoValue = hasNoValue,
+ .location = NN_TRY(convert(requestArgument.location)),
+ .dimensions = requestArgument.dimensions,
+ };
+}
+
+nn::Result<hidl_memory> convert(const nn::Request::MemoryPool& memoryPool) {
+ return convert(std::get<nn::Memory>(memoryPool));
+}
+
+nn::Result<Request> convert(const nn::Request& request) {
+ if (!hal::utils::hasNoPointerData(request)) {
+ return NN_ERROR() << "Request cannot be converted because it contains pointer-based memory";
+ }
+
+ return Request{
+ .inputs = NN_TRY(convert(request.inputs)),
+ .outputs = NN_TRY(convert(request.outputs)),
+ .pools = NN_TRY(convert(request.pools)),
+ };
+}
+
+nn::Result<ErrorStatus> convert(const nn::ErrorStatus& status) {
+ switch (status) {
+ case nn::ErrorStatus::NONE:
+ case nn::ErrorStatus::DEVICE_UNAVAILABLE:
+ case nn::ErrorStatus::GENERAL_FAILURE:
+ case nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE:
+ case nn::ErrorStatus::INVALID_ARGUMENT:
+ return static_cast<ErrorStatus>(status);
+ default:
+ return ErrorStatus::GENERAL_FAILURE;
+ }
+}
+
+} // namespace android::hardware::neuralnetworks::V1_0::utils
diff --git a/neuralnetworks/1.1/utils/Android.bp b/neuralnetworks/1.1/utils/Android.bp
new file mode 100644
index 0000000..85a32c5
--- /dev/null
+++ b/neuralnetworks/1.1/utils/Android.bp
@@ -0,0 +1,35 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_library_static {
+ name: "neuralnetworks_utils_hal_1_1",
+ defaults: ["neuralnetworks_utils_defaults"],
+ srcs: ["src/*"],
+ local_include_dirs: ["include/nnapi/hal/1.1/"],
+ export_include_dirs: ["include"],
+ static_libs: [
+ "neuralnetworks_types",
+ "neuralnetworks_utils_hal_common",
+ "neuralnetworks_utils_hal_1_0",
+ ],
+ shared_libs: [
+ "android.hardware.neuralnetworks@1.0",
+ "android.hardware.neuralnetworks@1.1",
+ ],
+ export_static_lib_headers: [
+ "neuralnetworks_utils_hal_common",
+ ],
+}
diff --git a/neuralnetworks/1.1/utils/OWNERS b/neuralnetworks/1.1/utils/OWNERS
new file mode 100644
index 0000000..e4feee3
--- /dev/null
+++ b/neuralnetworks/1.1/utils/OWNERS
@@ -0,0 +1,11 @@
+# Neuralnetworks team
+butlermichael@google.com
+dgross@google.com
+galarragas@google.com
+jeanluc@google.com
+levp@google.com
+miaowang@google.com
+pszczepaniak@google.com
+slavash@google.com
+vddang@google.com
+xusongw@google.com
diff --git a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Conversions.h b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Conversions.h
new file mode 100644
index 0000000..d0c5397
--- /dev/null
+++ b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Conversions.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_CONVERSIONS_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_CONVERSIONS_H
+
+#include <android/hardware/neuralnetworks/1.1/types.h>
+#include <nnapi/Result.h>
+#include <nnapi/Types.h>
+#include <nnapi/hal/CommonUtils.h>
+
+namespace android::nn {
+
+Result<OperationType> convert(const hal::V1_1::OperationType& operationType);
+Result<Capabilities> convert(const hal::V1_1::Capabilities& capabilities);
+Result<Operation> convert(const hal::V1_1::Operation& operation);
+Result<Model> convert(const hal::V1_1::Model& model);
+Result<ExecutionPreference> convert(const hal::V1_1::ExecutionPreference& executionPreference);
+
+} // namespace android::nn
+
+namespace android::hardware::neuralnetworks::V1_1::utils {
+
+nn::Result<OperationType> convert(const nn::OperationType& operationType);
+nn::Result<Capabilities> convert(const nn::Capabilities& capabilities);
+nn::Result<Operation> convert(const nn::Operation& operation);
+nn::Result<Model> convert(const nn::Model& model);
+nn::Result<ExecutionPreference> convert(const nn::ExecutionPreference& executionPreference);
+
+} // namespace android::hardware::neuralnetworks::V1_1::utils
+
+#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_CONVERSIONS_H
diff --git a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h
new file mode 100644
index 0000000..6f9aa60
--- /dev/null
+++ b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_UTILS_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_UTILS_H
+
+#include "nnapi/hal/1.1/Conversions.h"
+
+#include <android-base/logging.h>
+#include <android/hardware/neuralnetworks/1.1/types.h>
+#include <nnapi/Result.h>
+#include <nnapi/Types.h>
+#include <nnapi/Validation.h>
+#include <nnapi/hal/1.0/Conversions.h>
+
+namespace android::hardware::neuralnetworks::V1_1::utils {
+
+constexpr auto kDefaultExecutionPreference = ExecutionPreference::FAST_SINGLE_ANSWER;
+constexpr auto kVersion = nn::Version::ANDROID_P;
+
+template <typename Type>
+nn::Result<void> validate(const Type& halObject) {
+ const auto canonical = NN_TRY(nn::convert(halObject));
+ const auto version = NN_TRY(nn::validate(canonical));
+ if (version > utils::kVersion) {
+ return NN_ERROR() << "";
+ }
+ return {};
+}
+
+template <typename Type>
+bool valid(const Type& halObject) {
+ const auto result = utils::validate(halObject);
+ if (!result.has_value()) {
+ LOG(ERROR) << result.error();
+ }
+ return result.has_value();
+}
+
+template <typename Type>
+decltype(nn::convert(std::declval<Type>())) validatedConvertToCanonical(const Type& halObject) {
+ auto canonical = NN_TRY(nn::convert(halObject));
+ const auto version = NN_TRY(nn::validate(canonical));
+ if (version > utils::kVersion) {
+ return NN_ERROR() << "";
+ }
+ return canonical;
+}
+
+} // namespace android::hardware::neuralnetworks::V1_1::utils
+
+#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_UTILS_H
diff --git a/neuralnetworks/1.1/utils/src/Assertions.cpp b/neuralnetworks/1.1/utils/src/Assertions.cpp
new file mode 100644
index 0000000..ba4a388
--- /dev/null
+++ b/neuralnetworks/1.1/utils/src/Assertions.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/hardware/neuralnetworks/1.1/types.h>
+#include <nnapi/OperandTypes.h>
+#include <nnapi/OperationTypes.h>
+#include <nnapi/Types.h>
+#include <type_traits>
+
+namespace {
+
+#define COMPARE_ENUMS_TYPES(type) \
+ static_assert(std::is_same_v< \
+ std::underlying_type_t<::android::hardware::neuralnetworks::V1_1::type>, \
+ std::underlying_type_t<::android::nn::type>>, \
+ "::android::hardware::neuralnetworks::V1_1::" #type \
+ " does not have the same underlying type as ::android::nn::" #type)
+
+COMPARE_ENUMS_TYPES(OperationType);
+COMPARE_ENUMS_TYPES(ExecutionPreference);
+
+#undef COMPARE_ENUMS_TYPES
+
+#define COMPARE_ENUMS_FULL(symbol, type) \
+ static_assert( \
+ static_cast<std::underlying_type_t<::android::hardware::neuralnetworks::V1_1::type>>( \
+ ::android::hardware::neuralnetworks::V1_1::type::symbol) == \
+ static_cast<std::underlying_type_t<::android::nn::type>>( \
+ ::android::nn::type::symbol), \
+ "::android::hardware::neuralnetworks::V1_1::" #type "::" #symbol \
+ " does not match ::android::nn::" #type "::" #symbol)
+
+#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, OperationType)
+
+COMPARE_ENUMS(ADD);
+COMPARE_ENUMS(AVERAGE_POOL_2D);
+COMPARE_ENUMS(CONCATENATION);
+COMPARE_ENUMS(CONV_2D);
+COMPARE_ENUMS(DEPTHWISE_CONV_2D);
+COMPARE_ENUMS(DEPTH_TO_SPACE);
+COMPARE_ENUMS(DEQUANTIZE);
+COMPARE_ENUMS(EMBEDDING_LOOKUP);
+COMPARE_ENUMS(FLOOR);
+COMPARE_ENUMS(FULLY_CONNECTED);
+COMPARE_ENUMS(HASHTABLE_LOOKUP);
+COMPARE_ENUMS(L2_NORMALIZATION);
+COMPARE_ENUMS(L2_POOL_2D);
+COMPARE_ENUMS(LOCAL_RESPONSE_NORMALIZATION);
+COMPARE_ENUMS(LOGISTIC);
+COMPARE_ENUMS(LSH_PROJECTION);
+COMPARE_ENUMS(LSTM);
+COMPARE_ENUMS(MAX_POOL_2D);
+COMPARE_ENUMS(MUL);
+COMPARE_ENUMS(RELU);
+COMPARE_ENUMS(RELU1);
+COMPARE_ENUMS(RELU6);
+COMPARE_ENUMS(RESHAPE);
+COMPARE_ENUMS(RESIZE_BILINEAR);
+COMPARE_ENUMS(RNN);
+COMPARE_ENUMS(SOFTMAX);
+COMPARE_ENUMS(SPACE_TO_DEPTH);
+COMPARE_ENUMS(SVDF);
+COMPARE_ENUMS(TANH);
+COMPARE_ENUMS(BATCH_TO_SPACE_ND);
+COMPARE_ENUMS(DIV);
+COMPARE_ENUMS(MEAN);
+COMPARE_ENUMS(PAD);
+COMPARE_ENUMS(SPACE_TO_BATCH_ND);
+COMPARE_ENUMS(SQUEEZE);
+COMPARE_ENUMS(STRIDED_SLICE);
+COMPARE_ENUMS(SUB);
+COMPARE_ENUMS(TRANSPOSE);
+COMPARE_ENUMS(OEM_OPERATION);
+
+#undef COMPARE_ENUMS
+
+#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, ExecutionPreference)
+
+COMPARE_ENUMS(LOW_POWER);
+COMPARE_ENUMS(FAST_SINGLE_ANSWER);
+COMPARE_ENUMS(SUSTAINED_SPEED);
+
+#undef COMPARE_ENUMS
+
+#undef COMPARE_ENUMS_FULL
+
+} // anonymous namespace
diff --git a/neuralnetworks/1.1/utils/src/Conversions.cpp b/neuralnetworks/1.1/utils/src/Conversions.cpp
new file mode 100644
index 0000000..7fee16b
--- /dev/null
+++ b/neuralnetworks/1.1/utils/src/Conversions.cpp
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Conversions.h"
+
+#include <android-base/logging.h>
+#include <android/hardware/neuralnetworks/1.0/types.h>
+#include <android/hardware/neuralnetworks/1.1/types.h>
+#include <nnapi/OperandTypes.h>
+#include <nnapi/OperationTypes.h>
+#include <nnapi/Result.h>
+#include <nnapi/SharedMemory.h>
+#include <nnapi/Types.h>
+#include <nnapi/hal/1.0/Conversions.h>
+#include <nnapi/hal/CommonUtils.h>
+
+#include <algorithm>
+#include <functional>
+#include <iterator>
+#include <type_traits>
+#include <utility>
+
+namespace android::nn {
+namespace {
+
+using hardware::hidl_vec;
+
+template <typename Input>
+using convertOutput = std::decay_t<decltype(convert(std::declval<Input>()).value())>;
+
+template <typename Type>
+Result<std::vector<convertOutput<Type>>> convert(const hidl_vec<Type>& arguments) {
+ std::vector<convertOutput<Type>> canonical;
+ canonical.reserve(arguments.size());
+ for (const auto& argument : arguments) {
+ canonical.push_back(NN_TRY(nn::convert(argument)));
+ }
+ return canonical;
+}
+
+} // anonymous namespace
+
+Result<OperationType> convert(const hal::V1_1::OperationType& operationType) {
+ return static_cast<OperationType>(operationType);
+}
+
+Result<Capabilities> convert(const hal::V1_1::Capabilities& capabilities) {
+ const auto quantized8Performance = NN_TRY(convert(capabilities.quantized8Performance));
+ const auto float32Performance = NN_TRY(convert(capabilities.float32Performance));
+ const auto relaxedFloat32toFloat16Performance =
+ NN_TRY(convert(capabilities.relaxedFloat32toFloat16Performance));
+
+ auto table = hal::utils::makeQuantized8PerformanceConsistentWithP(float32Performance,
+ quantized8Performance);
+
+ return Capabilities{
+ .relaxedFloat32toFloat16PerformanceScalar = relaxedFloat32toFloat16Performance,
+ .relaxedFloat32toFloat16PerformanceTensor = relaxedFloat32toFloat16Performance,
+ .operandPerformance = std::move(table),
+ };
+}
+
+Result<Operation> convert(const hal::V1_1::Operation& operation) {
+ return Operation{
+ .type = NN_TRY(convert(operation.type)),
+ .inputs = operation.inputs,
+ .outputs = operation.outputs,
+ };
+}
+
+Result<Model> convert(const hal::V1_1::Model& model) {
+ auto operations = NN_TRY(convert(model.operations));
+
+ // Verify number of consumers.
+ const auto numberOfConsumers =
+ hal::utils::countNumberOfConsumers(model.operands.size(), operations);
+ CHECK(model.operands.size() == numberOfConsumers.size());
+ for (size_t i = 0; i < model.operands.size(); ++i) {
+ if (model.operands[i].numberOfConsumers != numberOfConsumers[i]) {
+ return NN_ERROR() << "Invalid numberOfConsumers for operand " << i << ", expected "
+ << numberOfConsumers[i] << " but found "
+ << model.operands[i].numberOfConsumers;
+ }
+ }
+
+ auto main = Model::Subgraph{
+ .operands = NN_TRY(convert(model.operands)),
+ .operations = std::move(operations),
+ .inputIndexes = model.inputIndexes,
+ .outputIndexes = model.outputIndexes,
+ };
+
+ return Model{
+ .main = std::move(main),
+ .operandValues = NN_TRY(convert(model.operandValues)),
+ .pools = NN_TRY(convert(model.pools)),
+ .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
+ };
+}
+
+Result<ExecutionPreference> convert(const hal::V1_1::ExecutionPreference& executionPreference) {
+ return static_cast<ExecutionPreference>(executionPreference);
+}
+
+} // namespace android::nn
+
+namespace android::hardware::neuralnetworks::V1_1::utils {
+namespace {
+
+using utils::convert;
+
+nn::Result<V1_0::PerformanceInfo> convert(
+ const nn::Capabilities::PerformanceInfo& performanceInfo) {
+ return V1_0::utils::convert(performanceInfo);
+}
+
+nn::Result<V1_0::Operand> convert(const nn::Operand& operand) {
+ return V1_0::utils::convert(operand);
+}
+
+nn::Result<hidl_vec<uint8_t>> convert(const nn::Model::OperandValues& operandValues) {
+ return V1_0::utils::convert(operandValues);
+}
+
+nn::Result<hidl_memory> convert(const nn::Memory& memory) {
+ return V1_0::utils::convert(memory);
+}
+
+template <typename Input>
+using convertOutput = std::decay_t<decltype(convert(std::declval<Input>()).value())>;
+
+template <typename Type>
+nn::Result<hidl_vec<convertOutput<Type>>> convert(const std::vector<Type>& arguments) {
+ hidl_vec<convertOutput<Type>> halObject(arguments.size());
+ for (size_t i = 0; i < arguments.size(); ++i) {
+ halObject[i] = NN_TRY(convert(arguments[i]));
+ }
+ return halObject;
+}
+
+} // anonymous namespace
+
+nn::Result<OperationType> convert(const nn::OperationType& operationType) {
+ return static_cast<OperationType>(operationType);
+}
+
+nn::Result<Capabilities> convert(const nn::Capabilities& capabilities) {
+ return Capabilities{
+ .float32Performance = NN_TRY(convert(
+ capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_FLOAT32))),
+ .quantized8Performance = NN_TRY(convert(
+ capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_QUANT8_ASYMM))),
+ .relaxedFloat32toFloat16Performance =
+ NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
+ };
+}
+
+nn::Result<Operation> convert(const nn::Operation& operation) {
+ return Operation{
+ .type = NN_TRY(convert(operation.type)),
+ .inputs = operation.inputs,
+ .outputs = operation.outputs,
+ };
+}
+
+nn::Result<Model> convert(const nn::Model& model) {
+ if (!hal::utils::hasNoPointerData(model)) {
+ return NN_ERROR() << "Mdoel cannot be converted because it contains pointer-based memory";
+ }
+
+ auto operands = NN_TRY(convert(model.main.operands));
+
+ // Update number of consumers.
+ const auto numberOfConsumers =
+ hal::utils::countNumberOfConsumers(operands.size(), model.main.operations);
+ CHECK(operands.size() == numberOfConsumers.size());
+ for (size_t i = 0; i < operands.size(); ++i) {
+ operands[i].numberOfConsumers = numberOfConsumers[i];
+ }
+
+ return Model{
+ .operands = std::move(operands),
+ .operations = NN_TRY(convert(model.main.operations)),
+ .inputIndexes = model.main.inputIndexes,
+ .outputIndexes = model.main.outputIndexes,
+ .operandValues = NN_TRY(convert(model.operandValues)),
+ .pools = NN_TRY(convert(model.pools)),
+ .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
+ };
+}
+
+nn::Result<ExecutionPreference> convert(const nn::ExecutionPreference& executionPreference) {
+ return static_cast<ExecutionPreference>(executionPreference);
+}
+
+} // namespace android::hardware::neuralnetworks::V1_1::utils
diff --git a/neuralnetworks/1.2/utils/Android.bp b/neuralnetworks/1.2/utils/Android.bp
new file mode 100644
index 0000000..a1dd3d0
--- /dev/null
+++ b/neuralnetworks/1.2/utils/Android.bp
@@ -0,0 +1,37 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_library_static {
+ name: "neuralnetworks_utils_hal_1_2",
+ defaults: ["neuralnetworks_utils_defaults"],
+ srcs: ["src/*"],
+ local_include_dirs: ["include/nnapi/hal/1.2/"],
+ export_include_dirs: ["include"],
+ static_libs: [
+ "neuralnetworks_types",
+ "neuralnetworks_utils_hal_common",
+ "neuralnetworks_utils_hal_1_0",
+ "neuralnetworks_utils_hal_1_1",
+ ],
+ shared_libs: [
+ "android.hardware.neuralnetworks@1.0",
+ "android.hardware.neuralnetworks@1.1",
+ "android.hardware.neuralnetworks@1.2",
+ ],
+ export_static_lib_headers: [
+ "neuralnetworks_utils_hal_common",
+ ],
+}
diff --git a/neuralnetworks/1.2/utils/OWNERS b/neuralnetworks/1.2/utils/OWNERS
new file mode 100644
index 0000000..e4feee3
--- /dev/null
+++ b/neuralnetworks/1.2/utils/OWNERS
@@ -0,0 +1,11 @@
+# Neuralnetworks team
+butlermichael@google.com
+dgross@google.com
+galarragas@google.com
+jeanluc@google.com
+levp@google.com
+miaowang@google.com
+pszczepaniak@google.com
+slavash@google.com
+vddang@google.com
+xusongw@google.com
diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h
new file mode 100644
index 0000000..81bf792
--- /dev/null
+++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_CONVERSIONS_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_CONVERSIONS_H
+
+#include <android/hardware/neuralnetworks/1.2/types.h>
+#include <nnapi/Result.h>
+#include <nnapi/Types.h>
+#include <nnapi/hal/CommonUtils.h>
+
+namespace android::nn {
+
+Result<OperandType> convert(const hal::V1_2::OperandType& operandType);
+Result<OperationType> convert(const hal::V1_2::OperationType& operationType);
+Result<DeviceType> convert(const hal::V1_2::DeviceType& deviceType);
+Result<Capabilities> convert(const hal::V1_2::Capabilities& capabilities);
+Result<Capabilities::OperandPerformance> convert(
+ const hal::V1_2::Capabilities::OperandPerformance& operandPerformance);
+Result<Operation> convert(const hal::V1_2::Operation& operation);
+Result<Operand::SymmPerChannelQuantParams> convert(
+ const hal::V1_2::SymmPerChannelQuantParams& symmPerChannelQuantParams);
+Result<Operand> convert(const hal::V1_2::Operand& operand);
+Result<Operand::ExtraParams> convert(const hal::V1_2::Operand::ExtraParams& extraParams);
+Result<Model> convert(const hal::V1_2::Model& model);
+Result<Model::ExtensionNameAndPrefix> convert(
+ const hal::V1_2::Model::ExtensionNameAndPrefix& extensionNameAndPrefix);
+Result<OutputShape> convert(const hal::V1_2::OutputShape& outputShape);
+Result<MeasureTiming> convert(const hal::V1_2::MeasureTiming& measureTiming);
+Result<Timing> convert(const hal::V1_2::Timing& timing);
+Result<Extension> convert(const hal::V1_2::Extension& extension);
+Result<Extension::OperandTypeInformation> convert(
+ const hal::V1_2::Extension::OperandTypeInformation& operandTypeInformation);
+Result<NativeHandle> convert(const hardware::hidl_handle& handle);
+
+Result<std::vector<Extension>> convert(const hardware::hidl_vec<hal::V1_2::Extension>& extensions);
+Result<std::vector<NativeHandle>> convert(const hardware::hidl_vec<hardware::hidl_handle>& handles);
+Result<std::vector<OutputShape>> convert(
+ const hardware::hidl_vec<hal::V1_2::OutputShape>& outputShapes);
+
+} // namespace android::nn
+
+namespace android::hardware::neuralnetworks::V1_2::utils {
+
+nn::Result<OperandType> convert(const nn::OperandType& operandType);
+nn::Result<OperationType> convert(const nn::OperationType& operationType);
+nn::Result<DeviceType> convert(const nn::DeviceType& deviceType);
+nn::Result<Capabilities> convert(const nn::Capabilities& capabilities);
+nn::Result<Capabilities::OperandPerformance> convert(
+ const nn::Capabilities::OperandPerformance& operandPerformance);
+nn::Result<Operation> convert(const nn::Operation& operation);
+nn::Result<SymmPerChannelQuantParams> convert(
+ const nn::Operand::SymmPerChannelQuantParams& symmPerChannelQuantParams);
+nn::Result<Operand> convert(const nn::Operand& operand);
+nn::Result<Operand::ExtraParams> convert(const nn::Operand::ExtraParams& extraParams);
+nn::Result<Model> convert(const nn::Model& model);
+nn::Result<Model::ExtensionNameAndPrefix> convert(
+ const nn::Model::ExtensionNameAndPrefix& extensionNameAndPrefix);
+nn::Result<OutputShape> convert(const nn::OutputShape& outputShape);
+nn::Result<MeasureTiming> convert(const nn::MeasureTiming& measureTiming);
+nn::Result<Timing> convert(const nn::Timing& timing);
+nn::Result<Extension> convert(const nn::Extension& extension);
+nn::Result<Extension::OperandTypeInformation> convert(
+ const nn::Extension::OperandTypeInformation& operandTypeInformation);
+nn::Result<hidl_handle> convert(const nn::NativeHandle& handle);
+
+nn::Result<hidl_vec<Extension>> convert(const std::vector<nn::Extension>& extensions);
+nn::Result<hidl_vec<hidl_handle>> convert(const std::vector<nn::NativeHandle>& handles);
+nn::Result<hidl_vec<OutputShape>> convert(const std::vector<nn::OutputShape>& outputShapes);
+
+} // namespace android::hardware::neuralnetworks::V1_2::utils
+
+#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_CONVERSIONS_H
diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h
new file mode 100644
index 0000000..b1c2f1a
--- /dev/null
+++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_H
+
+#include "nnapi/hal/1.2/Conversions.h"
+
+#include <android-base/logging.h>
+#include <android/hardware/neuralnetworks/1.2/types.h>
+#include <nnapi/Result.h>
+#include <nnapi/Types.h>
+#include <nnapi/Validation.h>
+#include <nnapi/hal/1.0/Conversions.h>
+#include <nnapi/hal/1.1/Conversions.h>
+
+#include <limits>
+
+namespace android::hardware::neuralnetworks::V1_2::utils {
+
+constexpr auto kDefaultMesaureTiming = MeasureTiming::NO;
+constexpr auto kNoTiming = Timing{.timeOnDevice = std::numeric_limits<uint64_t>::max(),
+ .timeInDriver = std::numeric_limits<uint64_t>::max()};
+constexpr auto kVersion = nn::Version::ANDROID_Q;
+
+template <typename Type>
+nn::Result<void> validate(const Type& halObject) {
+ const auto canonical = NN_TRY(nn::convert(halObject));
+ const auto version = NN_TRY(nn::validate(canonical));
+ if (version > utils::kVersion) {
+ return NN_ERROR() << "";
+ }
+ return {};
+}
+
+template <typename Type>
+bool valid(const Type& halObject) {
+ const auto result = utils::validate(halObject);
+ if (!result.has_value()) {
+ LOG(ERROR) << result.error();
+ }
+ return result.has_value();
+}
+
+template <typename Type>
+decltype(nn::convert(std::declval<Type>())) validatedConvertToCanonical(const Type& halObject) {
+ auto canonical = NN_TRY(nn::convert(halObject));
+ const auto version = NN_TRY(nn::validate(canonical));
+ if (version > utils::kVersion) {
+ return NN_ERROR() << "";
+ }
+ return canonical;
+}
+
+} // namespace android::hardware::neuralnetworks::V1_2::utils
+
+#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_H
diff --git a/neuralnetworks/1.2/utils/src/Assertions.cpp b/neuralnetworks/1.2/utils/src/Assertions.cpp
new file mode 100644
index 0000000..9d9716a
--- /dev/null
+++ b/neuralnetworks/1.2/utils/src/Assertions.cpp
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/hardware/neuralnetworks/1.2/types.h>
+#include <nnapi/OperandTypes.h>
+#include <nnapi/OperationTypes.h>
+#include <nnapi/Types.h>
+#include <type_traits>
+
+namespace {
+
+#define COMPARE_ENUMS_TYPES(type) \
+ static_assert(std::is_same_v< \
+ std::underlying_type_t<::android::hardware::neuralnetworks::V1_2::type>, \
+ std::underlying_type_t<::android::nn::type>>, \
+ "::android::hardware::neuralnetworks::V1_2::" #type \
+ " does not have the same underlying type as ::android::nn::" #type)
+
+COMPARE_ENUMS_TYPES(OperandType);
+COMPARE_ENUMS_TYPES(OperationType);
+COMPARE_ENUMS_TYPES(DeviceType);
+COMPARE_ENUMS_TYPES(MeasureTiming);
+
+#undef COMPARE_ENUMS_TYPES
+
+#define COMPARE_ENUMS_FULL(symbol, type) \
+ static_assert( \
+ static_cast<std::underlying_type_t<::android::hardware::neuralnetworks::V1_2::type>>( \
+ ::android::hardware::neuralnetworks::V1_2::type::symbol) == \
+ static_cast<std::underlying_type_t<::android::nn::type>>( \
+ ::android::nn::type::symbol), \
+ "::android::hardware::neuralnetworks::V1_2::" #type "::" #symbol \
+ " does not match ::android::nn::" #type "::" #symbol)
+
+#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, OperandType)
+
+COMPARE_ENUMS(FLOAT32);
+COMPARE_ENUMS(INT32);
+COMPARE_ENUMS(UINT32);
+COMPARE_ENUMS(TENSOR_FLOAT32);
+COMPARE_ENUMS(TENSOR_INT32);
+COMPARE_ENUMS(TENSOR_QUANT8_ASYMM);
+COMPARE_ENUMS(BOOL);
+COMPARE_ENUMS(TENSOR_QUANT16_SYMM);
+COMPARE_ENUMS(TENSOR_FLOAT16);
+COMPARE_ENUMS(TENSOR_BOOL8);
+COMPARE_ENUMS(FLOAT16);
+COMPARE_ENUMS(TENSOR_QUANT8_SYMM_PER_CHANNEL);
+COMPARE_ENUMS(TENSOR_QUANT16_ASYMM);
+COMPARE_ENUMS(TENSOR_QUANT8_SYMM);
+COMPARE_ENUMS(OEM);
+COMPARE_ENUMS(TENSOR_OEM_BYTE);
+
+#undef COMPARE_ENUMS
+
+#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, OperationType)
+
+COMPARE_ENUMS(ADD);
+COMPARE_ENUMS(AVERAGE_POOL_2D);
+COMPARE_ENUMS(CONCATENATION);
+COMPARE_ENUMS(CONV_2D);
+COMPARE_ENUMS(DEPTHWISE_CONV_2D);
+COMPARE_ENUMS(DEPTH_TO_SPACE);
+COMPARE_ENUMS(DEQUANTIZE);
+COMPARE_ENUMS(EMBEDDING_LOOKUP);
+COMPARE_ENUMS(FLOOR);
+COMPARE_ENUMS(FULLY_CONNECTED);
+COMPARE_ENUMS(HASHTABLE_LOOKUP);
+COMPARE_ENUMS(L2_NORMALIZATION);
+COMPARE_ENUMS(L2_POOL_2D);
+COMPARE_ENUMS(LOCAL_RESPONSE_NORMALIZATION);
+COMPARE_ENUMS(LOGISTIC);
+COMPARE_ENUMS(LSH_PROJECTION);
+COMPARE_ENUMS(LSTM);
+COMPARE_ENUMS(MAX_POOL_2D);
+COMPARE_ENUMS(MUL);
+COMPARE_ENUMS(RELU);
+COMPARE_ENUMS(RELU1);
+COMPARE_ENUMS(RELU6);
+COMPARE_ENUMS(RESHAPE);
+COMPARE_ENUMS(RESIZE_BILINEAR);
+COMPARE_ENUMS(RNN);
+COMPARE_ENUMS(SOFTMAX);
+COMPARE_ENUMS(SPACE_TO_DEPTH);
+COMPARE_ENUMS(SVDF);
+COMPARE_ENUMS(TANH);
+COMPARE_ENUMS(BATCH_TO_SPACE_ND);
+COMPARE_ENUMS(DIV);
+COMPARE_ENUMS(MEAN);
+COMPARE_ENUMS(PAD);
+COMPARE_ENUMS(SPACE_TO_BATCH_ND);
+COMPARE_ENUMS(SQUEEZE);
+COMPARE_ENUMS(STRIDED_SLICE);
+COMPARE_ENUMS(SUB);
+COMPARE_ENUMS(TRANSPOSE);
+COMPARE_ENUMS(ABS);
+COMPARE_ENUMS(ARGMAX);
+COMPARE_ENUMS(ARGMIN);
+COMPARE_ENUMS(AXIS_ALIGNED_BBOX_TRANSFORM);
+COMPARE_ENUMS(BIDIRECTIONAL_SEQUENCE_LSTM);
+COMPARE_ENUMS(BIDIRECTIONAL_SEQUENCE_RNN);
+COMPARE_ENUMS(BOX_WITH_NMS_LIMIT);
+COMPARE_ENUMS(CAST);
+COMPARE_ENUMS(CHANNEL_SHUFFLE);
+COMPARE_ENUMS(DETECTION_POSTPROCESSING);
+COMPARE_ENUMS(EQUAL);
+COMPARE_ENUMS(EXP);
+COMPARE_ENUMS(EXPAND_DIMS);
+COMPARE_ENUMS(GATHER);
+COMPARE_ENUMS(GENERATE_PROPOSALS);
+COMPARE_ENUMS(GREATER);
+COMPARE_ENUMS(GREATER_EQUAL);
+COMPARE_ENUMS(GROUPED_CONV_2D);
+COMPARE_ENUMS(HEATMAP_MAX_KEYPOINT);
+COMPARE_ENUMS(INSTANCE_NORMALIZATION);
+COMPARE_ENUMS(LESS);
+COMPARE_ENUMS(LESS_EQUAL);
+COMPARE_ENUMS(LOG);
+COMPARE_ENUMS(LOGICAL_AND);
+COMPARE_ENUMS(LOGICAL_NOT);
+COMPARE_ENUMS(LOGICAL_OR);
+COMPARE_ENUMS(LOG_SOFTMAX);
+COMPARE_ENUMS(MAXIMUM);
+COMPARE_ENUMS(MINIMUM);
+COMPARE_ENUMS(NEG);
+COMPARE_ENUMS(NOT_EQUAL);
+COMPARE_ENUMS(PAD_V2);
+COMPARE_ENUMS(POW);
+COMPARE_ENUMS(PRELU);
+COMPARE_ENUMS(QUANTIZE);
+COMPARE_ENUMS(QUANTIZED_16BIT_LSTM);
+COMPARE_ENUMS(RANDOM_MULTINOMIAL);
+COMPARE_ENUMS(REDUCE_ALL);
+COMPARE_ENUMS(REDUCE_ANY);
+COMPARE_ENUMS(REDUCE_MAX);
+COMPARE_ENUMS(REDUCE_MIN);
+COMPARE_ENUMS(REDUCE_PROD);
+COMPARE_ENUMS(REDUCE_SUM);
+COMPARE_ENUMS(ROI_ALIGN);
+COMPARE_ENUMS(ROI_POOLING);
+COMPARE_ENUMS(RSQRT);
+COMPARE_ENUMS(SELECT);
+COMPARE_ENUMS(SIN);
+COMPARE_ENUMS(SLICE);
+COMPARE_ENUMS(SPLIT);
+COMPARE_ENUMS(SQRT);
+COMPARE_ENUMS(TILE);
+COMPARE_ENUMS(TOPK_V2);
+COMPARE_ENUMS(TRANSPOSE_CONV_2D);
+COMPARE_ENUMS(UNIDIRECTIONAL_SEQUENCE_LSTM);
+COMPARE_ENUMS(UNIDIRECTIONAL_SEQUENCE_RNN);
+COMPARE_ENUMS(RESIZE_NEAREST_NEIGHBOR);
+COMPARE_ENUMS(OEM_OPERATION);
+
+#undef COMPARE_ENUMS
+
+#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, DeviceType)
+
+COMPARE_ENUMS(OTHER);
+COMPARE_ENUMS(CPU);
+COMPARE_ENUMS(GPU);
+COMPARE_ENUMS(ACCELERATOR);
+
+#undef COMPARE_ENUMS
+
+#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, MeasureTiming)
+
+COMPARE_ENUMS(NO);
+COMPARE_ENUMS(YES);
+
+#undef COMPARE_ENUMS
+
+#undef COMPARE_ENUMS_FULL
+
+} // anonymous namespace
diff --git a/neuralnetworks/1.2/utils/src/Conversions.cpp b/neuralnetworks/1.2/utils/src/Conversions.cpp
new file mode 100644
index 0000000..fed314b
--- /dev/null
+++ b/neuralnetworks/1.2/utils/src/Conversions.cpp
@@ -0,0 +1,502 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Conversions.h"
+
+#include <android-base/logging.h>
+#include <android/hardware/neuralnetworks/1.2/types.h>
+#include <nnapi/OperandTypes.h>
+#include <nnapi/OperationTypes.h>
+#include <nnapi/Result.h>
+#include <nnapi/SharedMemory.h>
+#include <nnapi/TypeUtils.h>
+#include <nnapi/Types.h>
+#include <nnapi/hal/1.0/Conversions.h>
+#include <nnapi/hal/CommonUtils.h>
+
+#include <algorithm>
+#include <functional>
+#include <iterator>
+#include <memory>
+#include <type_traits>
+#include <utility>
+
+namespace {
+
+template <typename Type>
+constexpr std::underlying_type_t<Type> underlyingType(Type value) {
+ return static_cast<std::underlying_type_t<Type>>(value);
+}
+
+} // namespace
+
+namespace android::nn {
+namespace {
+
+constexpr bool validOperandType(OperandType operandType) {
+ switch (operandType) {
+ case OperandType::FLOAT32:
+ case OperandType::INT32:
+ case OperandType::UINT32:
+ case OperandType::TENSOR_FLOAT32:
+ case OperandType::TENSOR_INT32:
+ case OperandType::TENSOR_QUANT8_ASYMM:
+ case OperandType::BOOL:
+ case OperandType::TENSOR_QUANT16_SYMM:
+ case OperandType::TENSOR_FLOAT16:
+ case OperandType::TENSOR_BOOL8:
+ case OperandType::FLOAT16:
+ case OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL:
+ case OperandType::TENSOR_QUANT16_ASYMM:
+ case OperandType::TENSOR_QUANT8_SYMM:
+ case OperandType::OEM:
+ case OperandType::TENSOR_OEM_BYTE:
+ return true;
+ default:
+ break;
+ }
+ return isExtension(operandType);
+}
+
+using hardware::hidl_handle;
+using hardware::hidl_vec;
+
+template <typename Input>
+using ConvertOutput = std::decay_t<decltype(convert(std::declval<Input>()).value())>;
+
+template <typename Type>
+Result<std::vector<ConvertOutput<Type>>> convertVec(const hidl_vec<Type>& arguments) {
+ std::vector<ConvertOutput<Type>> canonical;
+ canonical.reserve(arguments.size());
+ for (const auto& argument : arguments) {
+ canonical.push_back(NN_TRY(nn::convert(argument)));
+ }
+ return canonical;
+}
+
+template <typename Type>
+Result<std::vector<ConvertOutput<Type>>> convert(const hidl_vec<Type>& arguments) {
+ return convertVec(arguments);
+}
+
+} // anonymous namespace
+
+Result<OperandType> convert(const hal::V1_2::OperandType& operandType) {
+ return static_cast<OperandType>(operandType);
+}
+
+Result<OperationType> convert(const hal::V1_2::OperationType& operationType) {
+ return static_cast<OperationType>(operationType);
+}
+
+Result<DeviceType> convert(const hal::V1_2::DeviceType& deviceType) {
+ return static_cast<DeviceType>(deviceType);
+}
+
+Result<Capabilities> convert(const hal::V1_2::Capabilities& capabilities) {
+ const bool validOperandTypes = std::all_of(
+ capabilities.operandPerformance.begin(), capabilities.operandPerformance.end(),
+ [](const hal::V1_2::Capabilities::OperandPerformance& operandPerformance) {
+ const auto maybeType = convert(operandPerformance.type);
+ return !maybeType.has_value() ? false : validOperandType(maybeType.value());
+ });
+ if (!validOperandTypes) {
+ return NN_ERROR()
+ << "Invalid OperandType when converting OperandPerformance in Capabilities";
+ }
+
+ const auto relaxedFloat32toFloat16PerformanceScalar =
+ NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceScalar));
+ const auto relaxedFloat32toFloat16PerformanceTensor =
+ NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceTensor));
+ auto operandPerformance = NN_TRY(convert(capabilities.operandPerformance));
+
+ auto table =
+ NN_TRY(Capabilities::OperandPerformanceTable::create(std::move(operandPerformance)));
+
+ return Capabilities{
+ .relaxedFloat32toFloat16PerformanceScalar = relaxedFloat32toFloat16PerformanceScalar,
+ .relaxedFloat32toFloat16PerformanceTensor = relaxedFloat32toFloat16PerformanceTensor,
+ .operandPerformance = std::move(table),
+ };
+}
+
+Result<Capabilities::OperandPerformance> convert(
+ const hal::V1_2::Capabilities::OperandPerformance& operandPerformance) {
+ return Capabilities::OperandPerformance{
+ .type = NN_TRY(convert(operandPerformance.type)),
+ .info = NN_TRY(convert(operandPerformance.info)),
+ };
+}
+
+Result<Operation> convert(const hal::V1_2::Operation& operation) {
+ return Operation{
+ .type = NN_TRY(convert(operation.type)),
+ .inputs = operation.inputs,
+ .outputs = operation.outputs,
+ };
+}
+
+Result<Operand::SymmPerChannelQuantParams> convert(
+ const hal::V1_2::SymmPerChannelQuantParams& symmPerChannelQuantParams) {
+ return Operand::SymmPerChannelQuantParams{
+ .scales = symmPerChannelQuantParams.scales,
+ .channelDim = symmPerChannelQuantParams.channelDim,
+ };
+}
+
+Result<Operand> convert(const hal::V1_2::Operand& operand) {
+ return Operand{
+ .type = NN_TRY(convert(operand.type)),
+ .dimensions = operand.dimensions,
+ .scale = operand.scale,
+ .zeroPoint = operand.zeroPoint,
+ .lifetime = NN_TRY(convert(operand.lifetime)),
+ .location = NN_TRY(convert(operand.location)),
+ .extraParams = NN_TRY(convert(operand.extraParams)),
+ };
+}
+
+Result<Operand::ExtraParams> convert(const hal::V1_2::Operand::ExtraParams& extraParams) {
+ using Discriminator = hal::V1_2::Operand::ExtraParams::hidl_discriminator;
+ switch (extraParams.getDiscriminator()) {
+ case Discriminator::none:
+ return Operand::NoParams{};
+ case Discriminator::channelQuant:
+ return convert(extraParams.channelQuant());
+ case Discriminator::extension:
+ return extraParams.extension();
+ }
+ return NN_ERROR() << "Unrecognized Operand::ExtraParams discriminator: "
+ << underlyingType(extraParams.getDiscriminator());
+}
+
+Result<Model> convert(const hal::V1_2::Model& model) {
+ auto operations = NN_TRY(convert(model.operations));
+
+ // Verify number of consumers.
+ const auto numberOfConsumers =
+ hal::utils::countNumberOfConsumers(model.operands.size(), operations);
+ CHECK(model.operands.size() == numberOfConsumers.size());
+ for (size_t i = 0; i < model.operands.size(); ++i) {
+ if (model.operands[i].numberOfConsumers != numberOfConsumers[i]) {
+ return NN_ERROR() << "Invalid numberOfConsumers for operand " << i << ", expected "
+ << numberOfConsumers[i] << " but found "
+ << model.operands[i].numberOfConsumers;
+ }
+ }
+
+ auto main = Model::Subgraph{
+ .operands = NN_TRY(convert(model.operands)),
+ .operations = std::move(operations),
+ .inputIndexes = model.inputIndexes,
+ .outputIndexes = model.outputIndexes,
+ };
+
+ return Model{
+ .main = std::move(main),
+ .operandValues = NN_TRY(convert(model.operandValues)),
+ .pools = NN_TRY(convert(model.pools)),
+ .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
+ .extensionNameToPrefix = NN_TRY(convert(model.extensionNameToPrefix)),
+ };
+}
+
+Result<Model::ExtensionNameAndPrefix> convert(
+ const hal::V1_2::Model::ExtensionNameAndPrefix& extensionNameAndPrefix) {
+ return Model::ExtensionNameAndPrefix{
+ .name = extensionNameAndPrefix.name,
+ .prefix = extensionNameAndPrefix.prefix,
+ };
+}
+
+Result<OutputShape> convert(const hal::V1_2::OutputShape& outputShape) {
+ return OutputShape{
+ .dimensions = outputShape.dimensions,
+ .isSufficient = outputShape.isSufficient,
+ };
+}
+
+Result<MeasureTiming> convert(const hal::V1_2::MeasureTiming& measureTiming) {
+ return static_cast<MeasureTiming>(measureTiming);
+}
+
+Result<Timing> convert(const hal::V1_2::Timing& timing) {
+ return Timing{.timeOnDevice = timing.timeOnDevice, .timeInDriver = timing.timeInDriver};
+}
+
+Result<Extension> convert(const hal::V1_2::Extension& extension) {
+ return Extension{
+ .name = extension.name,
+ .operandTypes = NN_TRY(convert(extension.operandTypes)),
+ };
+}
+
+Result<Extension::OperandTypeInformation> convert(
+ const hal::V1_2::Extension::OperandTypeInformation& operandTypeInformation) {
+ return Extension::OperandTypeInformation{
+ .type = operandTypeInformation.type,
+ .isTensor = operandTypeInformation.isTensor,
+ .byteSize = operandTypeInformation.byteSize,
+ };
+}
+
+Result<NativeHandle> convert(const hidl_handle& handle) {
+ auto* cloned = native_handle_clone(handle.getNativeHandle());
+ return ::android::NativeHandle::create(cloned, /*ownsHandle=*/true);
+}
+
+Result<std::vector<Extension>> convert(const hidl_vec<hal::V1_2::Extension>& extensions) {
+ return convertVec(extensions);
+}
+
+Result<std::vector<NativeHandle>> convert(const hidl_vec<hidl_handle>& handles) {
+ return convertVec(handles);
+}
+
+Result<std::vector<OutputShape>> convert(const hidl_vec<hal::V1_2::OutputShape>& outputShapes) {
+ return convertVec(outputShapes);
+}
+
+} // namespace android::nn
+
+namespace android::hardware::neuralnetworks::V1_2::utils {
+namespace {
+
+using utils::convert;
+
+nn::Result<V1_0::OperandLifeTime> convert(const nn::Operand::LifeTime& lifetime) {
+ return V1_0::utils::convert(lifetime);
+}
+
+nn::Result<V1_0::PerformanceInfo> convert(
+ const nn::Capabilities::PerformanceInfo& performanceInfo) {
+ return V1_0::utils::convert(performanceInfo);
+}
+
+nn::Result<V1_0::DataLocation> convert(const nn::DataLocation& location) {
+ return V1_0::utils::convert(location);
+}
+
+nn::Result<hidl_vec<uint8_t>> convert(const nn::Model::OperandValues& operandValues) {
+ return V1_0::utils::convert(operandValues);
+}
+
+nn::Result<hidl_memory> convert(const nn::Memory& memory) {
+ return V1_0::utils::convert(memory);
+}
+
+template <typename Input>
+using ConvertOutput = std::decay_t<decltype(convert(std::declval<Input>()).value())>;
+
+template <typename Type>
+nn::Result<hidl_vec<ConvertOutput<Type>>> convertVec(const std::vector<Type>& arguments) {
+ hidl_vec<ConvertOutput<Type>> halObject(arguments.size());
+ for (size_t i = 0; i < arguments.size(); ++i) {
+ halObject[i] = NN_TRY(convert(arguments[i]));
+ }
+ return halObject;
+}
+
+template <typename Type>
+nn::Result<hidl_vec<ConvertOutput<Type>>> convert(const std::vector<Type>& arguments) {
+ return convertVec(arguments);
+}
+
+nn::Result<Operand::ExtraParams> makeExtraParams(nn::Operand::NoParams /*noParams*/) {
+ return Operand::ExtraParams{};
+}
+
+nn::Result<Operand::ExtraParams> makeExtraParams(
+ const nn::Operand::SymmPerChannelQuantParams& channelQuant) {
+ Operand::ExtraParams ret;
+ ret.channelQuant(NN_TRY(convert(channelQuant)));
+ return ret;
+}
+
+nn::Result<Operand::ExtraParams> makeExtraParams(const nn::Operand::ExtensionParams& extension) {
+ Operand::ExtraParams ret;
+ ret.extension(extension);
+ return ret;
+}
+
+} // anonymous namespace
+
+nn::Result<OperandType> convert(const nn::OperandType& operandType) {
+ return static_cast<OperandType>(operandType);
+}
+
+nn::Result<OperationType> convert(const nn::OperationType& operationType) {
+ return static_cast<OperationType>(operationType);
+}
+
+nn::Result<DeviceType> convert(const nn::DeviceType& deviceType) {
+ switch (deviceType) {
+ case nn::DeviceType::UNKNOWN:
+ return NN_ERROR() << "Invalid DeviceType UNKNOWN";
+ case nn::DeviceType::OTHER:
+ case nn::DeviceType::CPU:
+ case nn::DeviceType::GPU:
+ case nn::DeviceType::ACCELERATOR:
+ return static_cast<DeviceType>(deviceType);
+ }
+ return NN_ERROR() << "Invalid DeviceType " << underlyingType(deviceType);
+}
+
+nn::Result<Capabilities> convert(const nn::Capabilities& capabilities) {
+ std::vector<nn::Capabilities::OperandPerformance> operandPerformance;
+ operandPerformance.reserve(capabilities.operandPerformance.asVector().size());
+ std::copy_if(capabilities.operandPerformance.asVector().begin(),
+ capabilities.operandPerformance.asVector().end(),
+ std::back_inserter(operandPerformance),
+ [](const nn::Capabilities::OperandPerformance& operandPerformance) {
+ return nn::validOperandType(operandPerformance.type);
+ });
+
+ return Capabilities{
+ .relaxedFloat32toFloat16PerformanceScalar =
+ NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
+ .relaxedFloat32toFloat16PerformanceTensor =
+ NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
+ .operandPerformance = NN_TRY(convert(operandPerformance)),
+ };
+}
+
+nn::Result<Capabilities::OperandPerformance> convert(
+ const nn::Capabilities::OperandPerformance& operandPerformance) {
+ return Capabilities::OperandPerformance{
+ .type = NN_TRY(convert(operandPerformance.type)),
+ .info = NN_TRY(convert(operandPerformance.info)),
+ };
+}
+
+nn::Result<Operation> convert(const nn::Operation& operation) {
+ return Operation{
+ .type = NN_TRY(convert(operation.type)),
+ .inputs = operation.inputs,
+ .outputs = operation.outputs,
+ };
+}
+
+nn::Result<SymmPerChannelQuantParams> convert(
+ const nn::Operand::SymmPerChannelQuantParams& symmPerChannelQuantParams) {
+ return SymmPerChannelQuantParams{
+ .scales = symmPerChannelQuantParams.scales,
+ .channelDim = symmPerChannelQuantParams.channelDim,
+ };
+}
+
+nn::Result<Operand> convert(const nn::Operand& operand) {
+ return Operand{
+ .type = NN_TRY(convert(operand.type)),
+ .dimensions = operand.dimensions,
+ .numberOfConsumers = 0,
+ .scale = operand.scale,
+ .zeroPoint = operand.zeroPoint,
+ .lifetime = NN_TRY(convert(operand.lifetime)),
+ .location = NN_TRY(convert(operand.location)),
+ .extraParams = NN_TRY(convert(operand.extraParams)),
+ };
+}
+
+nn::Result<Operand::ExtraParams> convert(const nn::Operand::ExtraParams& extraParams) {
+ return std::visit([](const auto& x) { return makeExtraParams(x); }, extraParams);
+}
+
+nn::Result<Model> convert(const nn::Model& model) {
+ if (!hal::utils::hasNoPointerData(model)) {
+ return NN_ERROR() << "Model cannot be converted because it contains pointer-based memory";
+ }
+
+ auto operands = NN_TRY(convert(model.main.operands));
+
+ // Update number of consumers.
+ const auto numberOfConsumers =
+ hal::utils::countNumberOfConsumers(operands.size(), model.main.operations);
+ CHECK(operands.size() == numberOfConsumers.size());
+ for (size_t i = 0; i < operands.size(); ++i) {
+ operands[i].numberOfConsumers = numberOfConsumers[i];
+ }
+
+ return Model{
+ .operands = std::move(operands),
+ .operations = NN_TRY(convert(model.main.operations)),
+ .inputIndexes = model.main.inputIndexes,
+ .outputIndexes = model.main.outputIndexes,
+ .operandValues = NN_TRY(convert(model.operandValues)),
+ .pools = NN_TRY(convert(model.pools)),
+ .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
+ .extensionNameToPrefix = NN_TRY(convert(model.extensionNameToPrefix)),
+ };
+}
+
+nn::Result<Model::ExtensionNameAndPrefix> convert(
+ const nn::Model::ExtensionNameAndPrefix& extensionNameAndPrefix) {
+ return Model::ExtensionNameAndPrefix{
+ .name = extensionNameAndPrefix.name,
+ .prefix = extensionNameAndPrefix.prefix,
+ };
+}
+
+nn::Result<OutputShape> convert(const nn::OutputShape& outputShape) {
+ return OutputShape{.dimensions = outputShape.dimensions,
+ .isSufficient = outputShape.isSufficient};
+}
+
+nn::Result<MeasureTiming> convert(const nn::MeasureTiming& measureTiming) {
+ return static_cast<MeasureTiming>(measureTiming);
+}
+
+nn::Result<Timing> convert(const nn::Timing& timing) {
+ return Timing{.timeOnDevice = timing.timeOnDevice, .timeInDriver = timing.timeInDriver};
+}
+
+nn::Result<Extension> convert(const nn::Extension& extension) {
+ return Extension{
+ .name = extension.name,
+ .operandTypes = NN_TRY(convert(extension.operandTypes)),
+ };
+}
+
+nn::Result<Extension::OperandTypeInformation> convert(
+ const nn::Extension::OperandTypeInformation& operandTypeInformation) {
+ return Extension::OperandTypeInformation{
+ .type = operandTypeInformation.type,
+ .isTensor = operandTypeInformation.isTensor,
+ .byteSize = operandTypeInformation.byteSize,
+ };
+}
+
+nn::Result<hidl_handle> convert(const nn::NativeHandle& handle) {
+ const auto hidlHandle = hidl_handle(handle->handle());
+ // Copy memory to force the native_handle_t to be copied.
+ auto copiedHandle = hidlHandle;
+ return copiedHandle;
+}
+
+nn::Result<hidl_vec<Extension>> convert(const std::vector<nn::Extension>& extensions) {
+ return convertVec(extensions);
+}
+
+nn::Result<hidl_vec<hidl_handle>> convert(const std::vector<nn::NativeHandle>& handles) {
+ return convertVec(handles);
+}
+
+nn::Result<hidl_vec<OutputShape>> convert(const std::vector<nn::OutputShape>& outputShapes) {
+ return convertVec(outputShapes);
+}
+
+} // namespace android::hardware::neuralnetworks::V1_2::utils
diff --git a/neuralnetworks/1.3/utils/Android.bp b/neuralnetworks/1.3/utils/Android.bp
new file mode 100644
index 0000000..279b250
--- /dev/null
+++ b/neuralnetworks/1.3/utils/Android.bp
@@ -0,0 +1,39 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_library_static {
+ name: "neuralnetworks_utils_hal_1_3",
+ defaults: ["neuralnetworks_utils_defaults"],
+ srcs: ["src/*"],
+ local_include_dirs: ["include/nnapi/hal/1.3/"],
+ export_include_dirs: ["include"],
+ static_libs: [
+ "neuralnetworks_types",
+ "neuralnetworks_utils_hal_common",
+ "neuralnetworks_utils_hal_1_0",
+ "neuralnetworks_utils_hal_1_1",
+ "neuralnetworks_utils_hal_1_2",
+ ],
+ shared_libs: [
+ "android.hardware.neuralnetworks@1.0",
+ "android.hardware.neuralnetworks@1.1",
+ "android.hardware.neuralnetworks@1.2",
+ "android.hardware.neuralnetworks@1.3",
+ ],
+ export_static_lib_headers: [
+ "neuralnetworks_utils_hal_common",
+ ],
+}
diff --git a/neuralnetworks/1.3/utils/OWNERS b/neuralnetworks/1.3/utils/OWNERS
new file mode 100644
index 0000000..e4feee3
--- /dev/null
+++ b/neuralnetworks/1.3/utils/OWNERS
@@ -0,0 +1,11 @@
+# Neuralnetworks team
+butlermichael@google.com
+dgross@google.com
+galarragas@google.com
+jeanluc@google.com
+levp@google.com
+miaowang@google.com
+pszczepaniak@google.com
+slavash@google.com
+vddang@google.com
+xusongw@google.com
diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h
new file mode 100644
index 0000000..43987a9
--- /dev/null
+++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_CONVERSIONS_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_CONVERSIONS_H
+
+#include <android/hardware/neuralnetworks/1.3/IPreparedModel.h>
+#include <android/hardware/neuralnetworks/1.3/types.h>
+#include <nnapi/Result.h>
+#include <nnapi/Types.h>
+#include <nnapi/hal/CommonUtils.h>
+
+namespace android::nn {
+
+Result<OperandType> convert(const hal::V1_3::OperandType& operandType);
+Result<OperationType> convert(const hal::V1_3::OperationType& operationType);
+Result<Priority> convert(const hal::V1_3::Priority& priority);
+Result<Capabilities> convert(const hal::V1_3::Capabilities& capabilities);
+Result<Capabilities::OperandPerformance> convert(
+ const hal::V1_3::Capabilities::OperandPerformance& operandPerformance);
+Result<Operation> convert(const hal::V1_3::Operation& operation);
+Result<Operand::LifeTime> convert(const hal::V1_3::OperandLifeTime& operandLifeTime);
+Result<Operand> convert(const hal::V1_3::Operand& operand);
+Result<Model> convert(const hal::V1_3::Model& model);
+Result<Model::Subgraph> convert(const hal::V1_3::Subgraph& subgraph);
+Result<BufferDesc> convert(const hal::V1_3::BufferDesc& bufferDesc);
+Result<BufferRole> convert(const hal::V1_3::BufferRole& bufferRole);
+Result<Request> convert(const hal::V1_3::Request& request);
+Result<Request::MemoryPool> convert(const hal::V1_3::Request::MemoryPool& memoryPool);
+Result<OptionalTimePoint> convert(const hal::V1_3::OptionalTimePoint& optionalTimePoint);
+Result<OptionalTimeoutDuration> convert(
+ const hal::V1_3::OptionalTimeoutDuration& optionalTimeoutDuration);
+Result<ErrorStatus> convert(const hal::V1_3::ErrorStatus& errorStatus);
+
+Result<std::vector<BufferRole>> convert(
+ const hardware::hidl_vec<hal::V1_3::BufferRole>& bufferRoles);
+
+} // namespace android::nn
+
+namespace android::hardware::neuralnetworks::V1_3::utils {
+
+nn::Result<OperandType> convert(const nn::OperandType& operandType);
+nn::Result<OperationType> convert(const nn::OperationType& operationType);
+nn::Result<Priority> convert(const nn::Priority& priority);
+nn::Result<Capabilities> convert(const nn::Capabilities& capabilities);
+nn::Result<Capabilities::OperandPerformance> convert(
+ const nn::Capabilities::OperandPerformance& operandPerformance);
+nn::Result<Operation> convert(const nn::Operation& operation);
+nn::Result<OperandLifeTime> convert(const nn::Operand::LifeTime& operandLifeTime);
+nn::Result<Operand> convert(const nn::Operand& operand);
+nn::Result<Model> convert(const nn::Model& model);
+nn::Result<Subgraph> convert(const nn::Model::Subgraph& subgraph);
+nn::Result<BufferDesc> convert(const nn::BufferDesc& bufferDesc);
+nn::Result<BufferRole> convert(const nn::BufferRole& bufferRole);
+nn::Result<Request> convert(const nn::Request& request);
+nn::Result<Request::MemoryPool> convert(const nn::Request::MemoryPool& memoryPool);
+nn::Result<OptionalTimePoint> convert(const nn::OptionalTimePoint& optionalTimePoint);
+nn::Result<OptionalTimeoutDuration> convert(
+ const nn::OptionalTimeoutDuration& optionalTimeoutDuration);
+nn::Result<ErrorStatus> convert(const nn::ErrorStatus& errorStatus);
+
+nn::Result<hidl_vec<BufferRole>> convert(const std::vector<nn::BufferRole>& bufferRoles);
+
+} // namespace android::hardware::neuralnetworks::V1_3::utils
+
+#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_CONVERSIONS_H
diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h
new file mode 100644
index 0000000..f8c975d
--- /dev/null
+++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_H
+
+#include "nnapi/hal/1.3/Conversions.h"
+
+#include <android-base/logging.h>
+#include <android/hardware/neuralnetworks/1.3/types.h>
+#include <nnapi/Result.h>
+#include <nnapi/Types.h>
+#include <nnapi/Validation.h>
+#include <nnapi/hal/1.0/Conversions.h>
+#include <nnapi/hal/1.1/Conversions.h>
+#include <nnapi/hal/1.2/Conversions.h>
+
+namespace android::hardware::neuralnetworks::V1_3::utils {
+
+constexpr auto kDefaultPriority = Priority::MEDIUM;
+constexpr auto kVersion = nn::Version::ANDROID_R;
+
+template <typename Type>
+nn::Result<void> validate(const Type& halObject) {
+ const auto canonical = NN_TRY(nn::convert(halObject));
+ const auto version = NN_TRY(nn::validate(canonical));
+ if (version > utils::kVersion) {
+ return NN_ERROR() << "";
+ }
+ return {};
+}
+
+template <typename Type>
+bool valid(const Type& halObject) {
+ const auto result = utils::validate(halObject);
+ if (!result.has_value()) {
+ LOG(ERROR) << result.error();
+ }
+ return result.has_value();
+}
+
+template <typename Type>
+decltype(nn::convert(std::declval<Type>())) validatedConvertToCanonical(const Type& halObject) {
+ auto canonical = NN_TRY(nn::convert(halObject));
+ const auto version = NN_TRY(nn::validate(canonical));
+ if (version > utils::kVersion) {
+ return NN_ERROR() << "";
+ }
+ return canonical;
+}
+
+} // namespace android::hardware::neuralnetworks::V1_3::utils
+
+#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_H
diff --git a/neuralnetworks/1.3/utils/src/Assertions.cpp b/neuralnetworks/1.3/utils/src/Assertions.cpp
new file mode 100644
index 0000000..96d647a
--- /dev/null
+++ b/neuralnetworks/1.3/utils/src/Assertions.cpp
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/hardware/neuralnetworks/1.3/types.h>
+#include <nnapi/OperandTypes.h>
+#include <nnapi/OperationTypes.h>
+#include <nnapi/Types.h>
+#include <type_traits>
+
+namespace {
+
+#define COMPARE_ENUMS_TYPES(lhsType, rhsType) \
+ static_assert( \
+ std::is_same_v< \
+ std::underlying_type_t<::android::hardware::neuralnetworks::V1_3::lhsType>, \
+ std::underlying_type_t<::android::nn::rhsType>>, \
+ "::android::hardware::neuralnetworks::V1_3::" #lhsType \
+ " does not have the same underlying type as ::android::nn::" #rhsType)
+
+COMPARE_ENUMS_TYPES(OperandType, OperandType);
+COMPARE_ENUMS_TYPES(OperationType, OperationType);
+COMPARE_ENUMS_TYPES(Priority, Priority);
+COMPARE_ENUMS_TYPES(OperandLifeTime, Operand::LifeTime);
+COMPARE_ENUMS_TYPES(ErrorStatus, ErrorStatus);
+
+#undef COMPARE_ENUMS_TYPES
+
+#define COMPARE_ENUMS_FULL(symbol, lhsType, rhsType) \
+ static_assert( \
+ static_cast< \
+ std::underlying_type_t<::android::hardware::neuralnetworks::V1_3::lhsType>>( \
+ ::android::hardware::neuralnetworks::V1_3::lhsType::symbol) == \
+ static_cast<std::underlying_type_t<::android::nn::rhsType>>( \
+ ::android::nn::rhsType::symbol), \
+ "::android::hardware::neuralnetworks::V1_3::" #lhsType "::" #symbol \
+ " does not match ::android::nn::" #rhsType "::" #symbol)
+
+#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, OperandType, OperandType)
+
+COMPARE_ENUMS(FLOAT32);
+COMPARE_ENUMS(INT32);
+COMPARE_ENUMS(UINT32);
+COMPARE_ENUMS(TENSOR_FLOAT32);
+COMPARE_ENUMS(TENSOR_INT32);
+COMPARE_ENUMS(TENSOR_QUANT8_ASYMM);
+COMPARE_ENUMS(BOOL);
+COMPARE_ENUMS(TENSOR_QUANT16_SYMM);
+COMPARE_ENUMS(TENSOR_FLOAT16);
+COMPARE_ENUMS(TENSOR_BOOL8);
+COMPARE_ENUMS(FLOAT16);
+COMPARE_ENUMS(TENSOR_QUANT8_SYMM_PER_CHANNEL);
+COMPARE_ENUMS(TENSOR_QUANT16_ASYMM);
+COMPARE_ENUMS(TENSOR_QUANT8_SYMM);
+COMPARE_ENUMS(TENSOR_QUANT8_ASYMM_SIGNED);
+COMPARE_ENUMS(SUBGRAPH);
+COMPARE_ENUMS(OEM);
+COMPARE_ENUMS(TENSOR_OEM_BYTE);
+
+#undef COMPARE_ENUMS
+
+#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, OperationType, OperationType)
+
+COMPARE_ENUMS(ADD);
+COMPARE_ENUMS(AVERAGE_POOL_2D);
+COMPARE_ENUMS(CONCATENATION);
+COMPARE_ENUMS(CONV_2D);
+COMPARE_ENUMS(DEPTHWISE_CONV_2D);
+COMPARE_ENUMS(DEPTH_TO_SPACE);
+COMPARE_ENUMS(DEQUANTIZE);
+COMPARE_ENUMS(EMBEDDING_LOOKUP);
+COMPARE_ENUMS(FLOOR);
+COMPARE_ENUMS(FULLY_CONNECTED);
+COMPARE_ENUMS(HASHTABLE_LOOKUP);
+COMPARE_ENUMS(L2_NORMALIZATION);
+COMPARE_ENUMS(L2_POOL_2D);
+COMPARE_ENUMS(LOCAL_RESPONSE_NORMALIZATION);
+COMPARE_ENUMS(LOGISTIC);
+COMPARE_ENUMS(LSH_PROJECTION);
+COMPARE_ENUMS(LSTM);
+COMPARE_ENUMS(MAX_POOL_2D);
+COMPARE_ENUMS(MUL);
+COMPARE_ENUMS(RELU);
+COMPARE_ENUMS(RELU1);
+COMPARE_ENUMS(RELU6);
+COMPARE_ENUMS(RESHAPE);
+COMPARE_ENUMS(RESIZE_BILINEAR);
+COMPARE_ENUMS(RNN);
+COMPARE_ENUMS(SOFTMAX);
+COMPARE_ENUMS(SPACE_TO_DEPTH);
+COMPARE_ENUMS(SVDF);
+COMPARE_ENUMS(TANH);
+COMPARE_ENUMS(BATCH_TO_SPACE_ND);
+COMPARE_ENUMS(DIV);
+COMPARE_ENUMS(MEAN);
+COMPARE_ENUMS(PAD);
+COMPARE_ENUMS(SPACE_TO_BATCH_ND);
+COMPARE_ENUMS(SQUEEZE);
+COMPARE_ENUMS(STRIDED_SLICE);
+COMPARE_ENUMS(SUB);
+COMPARE_ENUMS(TRANSPOSE);
+COMPARE_ENUMS(ABS);
+COMPARE_ENUMS(ARGMAX);
+COMPARE_ENUMS(ARGMIN);
+COMPARE_ENUMS(AXIS_ALIGNED_BBOX_TRANSFORM);
+COMPARE_ENUMS(BIDIRECTIONAL_SEQUENCE_LSTM);
+COMPARE_ENUMS(BIDIRECTIONAL_SEQUENCE_RNN);
+COMPARE_ENUMS(BOX_WITH_NMS_LIMIT);
+COMPARE_ENUMS(CAST);
+COMPARE_ENUMS(CHANNEL_SHUFFLE);
+COMPARE_ENUMS(DETECTION_POSTPROCESSING);
+COMPARE_ENUMS(EQUAL);
+COMPARE_ENUMS(EXP);
+COMPARE_ENUMS(EXPAND_DIMS);
+COMPARE_ENUMS(GATHER);
+COMPARE_ENUMS(GENERATE_PROPOSALS);
+COMPARE_ENUMS(GREATER);
+COMPARE_ENUMS(GREATER_EQUAL);
+COMPARE_ENUMS(GROUPED_CONV_2D);
+COMPARE_ENUMS(HEATMAP_MAX_KEYPOINT);
+COMPARE_ENUMS(INSTANCE_NORMALIZATION);
+COMPARE_ENUMS(LESS);
+COMPARE_ENUMS(LESS_EQUAL);
+COMPARE_ENUMS(LOG);
+COMPARE_ENUMS(LOGICAL_AND);
+COMPARE_ENUMS(LOGICAL_NOT);
+COMPARE_ENUMS(LOGICAL_OR);
+COMPARE_ENUMS(LOG_SOFTMAX);
+COMPARE_ENUMS(MAXIMUM);
+COMPARE_ENUMS(MINIMUM);
+COMPARE_ENUMS(NEG);
+COMPARE_ENUMS(NOT_EQUAL);
+COMPARE_ENUMS(PAD_V2);
+COMPARE_ENUMS(POW);
+COMPARE_ENUMS(PRELU);
+COMPARE_ENUMS(QUANTIZE);
+COMPARE_ENUMS(QUANTIZED_16BIT_LSTM);
+COMPARE_ENUMS(RANDOM_MULTINOMIAL);
+COMPARE_ENUMS(REDUCE_ALL);
+COMPARE_ENUMS(REDUCE_ANY);
+COMPARE_ENUMS(REDUCE_MAX);
+COMPARE_ENUMS(REDUCE_MIN);
+COMPARE_ENUMS(REDUCE_PROD);
+COMPARE_ENUMS(REDUCE_SUM);
+COMPARE_ENUMS(ROI_ALIGN);
+COMPARE_ENUMS(ROI_POOLING);
+COMPARE_ENUMS(RSQRT);
+COMPARE_ENUMS(SELECT);
+COMPARE_ENUMS(SIN);
+COMPARE_ENUMS(SLICE);
+COMPARE_ENUMS(SPLIT);
+COMPARE_ENUMS(SQRT);
+COMPARE_ENUMS(TILE);
+COMPARE_ENUMS(TOPK_V2);
+COMPARE_ENUMS(TRANSPOSE_CONV_2D);
+COMPARE_ENUMS(UNIDIRECTIONAL_SEQUENCE_LSTM);
+COMPARE_ENUMS(UNIDIRECTIONAL_SEQUENCE_RNN);
+COMPARE_ENUMS(RESIZE_NEAREST_NEIGHBOR);
+COMPARE_ENUMS(QUANTIZED_LSTM);
+COMPARE_ENUMS(IF);
+COMPARE_ENUMS(WHILE);
+COMPARE_ENUMS(ELU);
+COMPARE_ENUMS(HARD_SWISH);
+COMPARE_ENUMS(FILL);
+COMPARE_ENUMS(RANK);
+COMPARE_ENUMS(OEM_OPERATION);
+
+#undef COMPARE_ENUMS
+
+#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, Priority, Priority)
+
+COMPARE_ENUMS(LOW);
+COMPARE_ENUMS(MEDIUM);
+COMPARE_ENUMS(HIGH);
+
+#undef COMPARE_ENUMS
+
+#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, OperandLifeTime, Operand::LifeTime)
+
+COMPARE_ENUMS(TEMPORARY_VARIABLE);
+COMPARE_ENUMS(SUBGRAPH_INPUT);
+COMPARE_ENUMS(SUBGRAPH_OUTPUT);
+COMPARE_ENUMS(CONSTANT_COPY);
+COMPARE_ENUMS(CONSTANT_REFERENCE);
+COMPARE_ENUMS(NO_VALUE);
+COMPARE_ENUMS(SUBGRAPH);
+
+#undef COMPARE_ENUMS
+
+#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, ErrorStatus, ErrorStatus)
+
+COMPARE_ENUMS(NONE);
+COMPARE_ENUMS(DEVICE_UNAVAILABLE);
+COMPARE_ENUMS(GENERAL_FAILURE);
+COMPARE_ENUMS(OUTPUT_INSUFFICIENT_SIZE);
+COMPARE_ENUMS(INVALID_ARGUMENT);
+COMPARE_ENUMS(MISSED_DEADLINE_TRANSIENT);
+COMPARE_ENUMS(MISSED_DEADLINE_PERSISTENT);
+COMPARE_ENUMS(RESOURCE_EXHAUSTED_TRANSIENT);
+COMPARE_ENUMS(RESOURCE_EXHAUSTED_PERSISTENT);
+
+#undef COMPARE_ENUMS
+
+#undef COMPARE_ENUMS_FULL
+
+} // anonymous namespace
diff --git a/neuralnetworks/1.3/utils/src/Conversions.cpp b/neuralnetworks/1.3/utils/src/Conversions.cpp
new file mode 100644
index 0000000..4c54e3b
--- /dev/null
+++ b/neuralnetworks/1.3/utils/src/Conversions.cpp
@@ -0,0 +1,552 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Conversions.h"
+
+#include <android-base/logging.h>
+#include <android/hardware/neuralnetworks/1.3/types.h>
+#include <nnapi/OperandTypes.h>
+#include <nnapi/OperationTypes.h>
+#include <nnapi/Result.h>
+#include <nnapi/SharedMemory.h>
+#include <nnapi/TypeUtils.h>
+#include <nnapi/Types.h>
+#include <nnapi/hal/1.0/Conversions.h>
+#include <nnapi/hal/1.2/Conversions.h>
+#include <nnapi/hal/CommonUtils.h>
+
+#include <algorithm>
+#include <chrono>
+#include <functional>
+#include <iterator>
+#include <limits>
+#include <type_traits>
+#include <utility>
+
+namespace {
+
+template <typename Type>
+constexpr std::underlying_type_t<Type> underlyingType(Type value) {
+ return static_cast<std::underlying_type_t<Type>>(value);
+}
+
+} // namespace
+
+namespace android::nn {
+namespace {
+
+constexpr auto validOperandType(nn::OperandType operandType) {
+ switch (operandType) {
+ case nn::OperandType::FLOAT32:
+ case nn::OperandType::INT32:
+ case nn::OperandType::UINT32:
+ case nn::OperandType::TENSOR_FLOAT32:
+ case nn::OperandType::TENSOR_INT32:
+ case nn::OperandType::TENSOR_QUANT8_ASYMM:
+ case nn::OperandType::BOOL:
+ case nn::OperandType::TENSOR_QUANT16_SYMM:
+ case nn::OperandType::TENSOR_FLOAT16:
+ case nn::OperandType::TENSOR_BOOL8:
+ case nn::OperandType::FLOAT16:
+ case nn::OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL:
+ case nn::OperandType::TENSOR_QUANT16_ASYMM:
+ case nn::OperandType::TENSOR_QUANT8_SYMM:
+ case nn::OperandType::TENSOR_QUANT8_ASYMM_SIGNED:
+ case nn::OperandType::SUBGRAPH:
+ case nn::OperandType::OEM:
+ case nn::OperandType::TENSOR_OEM_BYTE:
+ return true;
+ }
+ return nn::isExtension(operandType);
+}
+
+using hardware::hidl_vec;
+
+template <typename Input>
+using ConvertOutput = std::decay_t<decltype(convert(std::declval<Input>()).value())>;
+
+template <typename Type>
+Result<std::vector<ConvertOutput<Type>>> convertVec(const hidl_vec<Type>& arguments) {
+ std::vector<ConvertOutput<Type>> canonical;
+ canonical.reserve(arguments.size());
+ for (const auto& argument : arguments) {
+ canonical.push_back(NN_TRY(nn::convert(argument)));
+ }
+ return canonical;
+}
+
+template <typename Type>
+Result<std::vector<ConvertOutput<Type>>> convert(const hidl_vec<Type>& arguments) {
+ return convertVec(arguments);
+}
+
+} // anonymous namespace
+
+Result<OperandType> convert(const hal::V1_3::OperandType& operandType) {
+ return static_cast<OperandType>(operandType);
+}
+
+Result<OperationType> convert(const hal::V1_3::OperationType& operationType) {
+ return static_cast<OperationType>(operationType);
+}
+
+Result<Priority> convert(const hal::V1_3::Priority& priority) {
+ return static_cast<Priority>(priority);
+}
+
+Result<Capabilities> convert(const hal::V1_3::Capabilities& capabilities) {
+ const bool validOperandTypes = std::all_of(
+ capabilities.operandPerformance.begin(), capabilities.operandPerformance.end(),
+ [](const hal::V1_3::Capabilities::OperandPerformance& operandPerformance) {
+ const auto maybeType = convert(operandPerformance.type);
+ return !maybeType.has_value() ? false : validOperandType(maybeType.value());
+ });
+ if (!validOperandTypes) {
+ return NN_ERROR()
+ << "Invalid OperandType when converting OperandPerformance in Capabilities";
+ }
+
+ auto operandPerformance = NN_TRY(convert(capabilities.operandPerformance));
+ auto table =
+ NN_TRY(Capabilities::OperandPerformanceTable::create(std::move(operandPerformance)));
+
+ return Capabilities{
+ .relaxedFloat32toFloat16PerformanceScalar =
+ NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
+ .relaxedFloat32toFloat16PerformanceTensor =
+ NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
+ .operandPerformance = std::move(table),
+ .ifPerformance = NN_TRY(convert(capabilities.ifPerformance)),
+ .whilePerformance = NN_TRY(convert(capabilities.whilePerformance)),
+ };
+}
+
+Result<Capabilities::OperandPerformance> convert(
+ const hal::V1_3::Capabilities::OperandPerformance& operandPerformance) {
+ return Capabilities::OperandPerformance{
+ .type = NN_TRY(convert(operandPerformance.type)),
+ .info = NN_TRY(convert(operandPerformance.info)),
+ };
+}
+
+Result<Operation> convert(const hal::V1_3::Operation& operation) {
+ return Operation{
+ .type = NN_TRY(convert(operation.type)),
+ .inputs = operation.inputs,
+ .outputs = operation.outputs,
+ };
+}
+
+Result<Operand::LifeTime> convert(const hal::V1_3::OperandLifeTime& operandLifeTime) {
+ return static_cast<Operand::LifeTime>(operandLifeTime);
+}
+
+Result<Operand> convert(const hal::V1_3::Operand& operand) {
+ return Operand{
+ .type = NN_TRY(convert(operand.type)),
+ .dimensions = operand.dimensions,
+ .scale = operand.scale,
+ .zeroPoint = operand.zeroPoint,
+ .lifetime = NN_TRY(convert(operand.lifetime)),
+ .location = NN_TRY(convert(operand.location)),
+ .extraParams = NN_TRY(convert(operand.extraParams)),
+ };
+}
+
+Result<Model> convert(const hal::V1_3::Model& model) {
+ return Model{
+ .main = NN_TRY(convert(model.main)),
+ .referenced = NN_TRY(convert(model.referenced)),
+ .operandValues = NN_TRY(convert(model.operandValues)),
+ .pools = NN_TRY(convert(model.pools)),
+ .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
+ .extensionNameToPrefix = NN_TRY(convert(model.extensionNameToPrefix)),
+ };
+}
+
+Result<Model::Subgraph> convert(const hal::V1_3::Subgraph& subgraph) {
+ auto operations = NN_TRY(convert(subgraph.operations));
+
+ // Verify number of consumers.
+ const auto numberOfConsumers =
+ hal::utils::countNumberOfConsumers(subgraph.operands.size(), operations);
+ CHECK(subgraph.operands.size() == numberOfConsumers.size());
+ for (size_t i = 0; i < subgraph.operands.size(); ++i) {
+ if (subgraph.operands[i].numberOfConsumers != numberOfConsumers[i]) {
+ return NN_ERROR() << "Invalid numberOfConsumers for operand " << i << ", expected "
+ << numberOfConsumers[i] << " but found "
+ << subgraph.operands[i].numberOfConsumers;
+ }
+ }
+
+ return Model::Subgraph{
+ .operands = NN_TRY(convert(subgraph.operands)),
+ .operations = std::move(operations),
+ .inputIndexes = subgraph.inputIndexes,
+ .outputIndexes = subgraph.outputIndexes,
+ };
+}
+
+Result<BufferDesc> convert(const hal::V1_3::BufferDesc& bufferDesc) {
+ return BufferDesc{.dimensions = bufferDesc.dimensions};
+}
+
+Result<BufferRole> convert(const hal::V1_3::BufferRole& bufferRole) {
+ return BufferRole{
+ .modelIndex = bufferRole.modelIndex,
+ .ioIndex = bufferRole.ioIndex,
+ .frequency = bufferRole.frequency,
+ };
+}
+
+Result<Request> convert(const hal::V1_3::Request& request) {
+ return Request{
+ .inputs = NN_TRY(convert(request.inputs)),
+ .outputs = NN_TRY(convert(request.outputs)),
+ .pools = NN_TRY(convert(request.pools)),
+ };
+}
+
+Result<Request::MemoryPool> convert(const hal::V1_3::Request::MemoryPool& memoryPool) {
+ using Discriminator = hal::V1_3::Request::MemoryPool::hidl_discriminator;
+ switch (memoryPool.getDiscriminator()) {
+ case Discriminator::hidlMemory:
+ return createSharedMemoryFromHidlMemory(memoryPool.hidlMemory());
+ case Discriminator::token:
+ return static_cast<Request::MemoryDomainToken>(memoryPool.token());
+ }
+ return NN_ERROR() << "Invalid Request::MemoryPool discriminator "
+ << underlyingType(memoryPool.getDiscriminator());
+}
+
+Result<OptionalTimePoint> convert(const hal::V1_3::OptionalTimePoint& optionalTimePoint) {
+ constexpr auto kTimePointMaxCount = TimePoint::max().time_since_epoch().count();
+ const auto makeTimePoint = [](uint64_t count) -> Result<OptionalTimePoint> {
+ if (count > kTimePointMaxCount) {
+ return NN_ERROR()
+ << "Unable to convert OptionalTimePoint because the count exceeds the max";
+ }
+ const auto nanoseconds = std::chrono::nanoseconds{count};
+ return TimePoint{nanoseconds};
+ };
+
+ using Discriminator = hal::V1_3::OptionalTimePoint::hidl_discriminator;
+ switch (optionalTimePoint.getDiscriminator()) {
+ case Discriminator::none:
+ return std::nullopt;
+ case Discriminator::nanosecondsSinceEpoch:
+ return makeTimePoint(optionalTimePoint.nanosecondsSinceEpoch());
+ }
+ return NN_ERROR() << "Invalid OptionalTimePoint discriminator "
+ << underlyingType(optionalTimePoint.getDiscriminator());
+}
+
+Result<OptionalTimeoutDuration> convert(
+ const hal::V1_3::OptionalTimeoutDuration& optionalTimeoutDuration) {
+ constexpr auto kTimeoutDurationMaxCount = TimeoutDuration::max().count();
+ const auto makeTimeoutDuration = [](uint64_t count) -> Result<OptionalTimeoutDuration> {
+ if (count > kTimeoutDurationMaxCount) {
+ return NN_ERROR()
+ << "Unable to convert OptionalTimeoutDuration because the count exceeds the max";
+ }
+ return TimeoutDuration{count};
+ };
+
+ using Discriminator = hal::V1_3::OptionalTimeoutDuration::hidl_discriminator;
+ switch (optionalTimeoutDuration.getDiscriminator()) {
+ case Discriminator::none:
+ return std::nullopt;
+ case Discriminator::nanoseconds:
+ return makeTimeoutDuration(optionalTimeoutDuration.nanoseconds());
+ }
+ return NN_ERROR() << "Invalid OptionalTimeoutDuration discriminator "
+ << underlyingType(optionalTimeoutDuration.getDiscriminator());
+}
+
+Result<ErrorStatus> convert(const hal::V1_3::ErrorStatus& status) {
+ switch (status) {
+ case hal::V1_3::ErrorStatus::NONE:
+ case hal::V1_3::ErrorStatus::DEVICE_UNAVAILABLE:
+ case hal::V1_3::ErrorStatus::GENERAL_FAILURE:
+ case hal::V1_3::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE:
+ case hal::V1_3::ErrorStatus::INVALID_ARGUMENT:
+ case hal::V1_3::ErrorStatus::MISSED_DEADLINE_TRANSIENT:
+ case hal::V1_3::ErrorStatus::MISSED_DEADLINE_PERSISTENT:
+ case hal::V1_3::ErrorStatus::RESOURCE_EXHAUSTED_TRANSIENT:
+ case hal::V1_3::ErrorStatus::RESOURCE_EXHAUSTED_PERSISTENT:
+ return static_cast<ErrorStatus>(status);
+ }
+ return NN_ERROR() << "Invalid ErrorStatus " << underlyingType(status);
+}
+
+Result<std::vector<BufferRole>> convert(
+ const hardware::hidl_vec<hal::V1_3::BufferRole>& bufferRoles) {
+ return convertVec(bufferRoles);
+}
+
+} // namespace android::nn
+
+namespace android::hardware::neuralnetworks::V1_3::utils {
+namespace {
+
+using utils::convert;
+
+nn::Result<V1_0::PerformanceInfo> convert(
+ const nn::Capabilities::PerformanceInfo& performanceInfo) {
+ return V1_0::utils::convert(performanceInfo);
+}
+
+nn::Result<V1_0::DataLocation> convert(const nn::DataLocation& dataLocation) {
+ return V1_0::utils::convert(dataLocation);
+}
+
+nn::Result<hidl_vec<uint8_t>> convert(const nn::Model::OperandValues& operandValues) {
+ return V1_0::utils::convert(operandValues);
+}
+
+nn::Result<hidl_memory> convert(const nn::Memory& memory) {
+ return V1_0::utils::convert(memory);
+}
+
+nn::Result<V1_0::RequestArgument> convert(const nn::Request::Argument& argument) {
+ return V1_0::utils::convert(argument);
+}
+
+nn::Result<V1_2::Operand::ExtraParams> convert(const nn::Operand::ExtraParams& extraParams) {
+ return V1_2::utils::convert(extraParams);
+}
+
+nn::Result<V1_2::Model::ExtensionNameAndPrefix> convert(
+ const nn::Model::ExtensionNameAndPrefix& extensionNameAndPrefix) {
+ return V1_2::utils::convert(extensionNameAndPrefix);
+}
+
+template <typename Input>
+using ConvertOutput = std::decay_t<decltype(convert(std::declval<Input>()).value())>;
+
+template <typename Type>
+nn::Result<hidl_vec<ConvertOutput<Type>>> convertVec(const std::vector<Type>& arguments) {
+ hidl_vec<ConvertOutput<Type>> halObject(arguments.size());
+ for (size_t i = 0; i < arguments.size(); ++i) {
+ halObject[i] = NN_TRY(convert(arguments[i]));
+ }
+ return halObject;
+}
+
+template <typename Type>
+nn::Result<hidl_vec<ConvertOutput<Type>>> convert(const std::vector<Type>& arguments) {
+ return convertVec(arguments);
+}
+
+nn::Result<Request::MemoryPool> makeMemoryPool(const nn::Memory& memory) {
+ Request::MemoryPool ret;
+ ret.hidlMemory(NN_TRY(convert(memory)));
+ return ret;
+}
+
+nn::Result<Request::MemoryPool> makeMemoryPool(const nn::Request::MemoryDomainToken& token) {
+ Request::MemoryPool ret;
+ ret.token(underlyingType(token));
+ return ret;
+}
+
+nn::Result<Request::MemoryPool> makeMemoryPool(
+ const std::shared_ptr<const nn::IBuffer>& /*buffer*/) {
+ return NN_ERROR() << "Unable to make memory pool from IBuffer";
+}
+
+} // anonymous namespace
+
+nn::Result<OperandType> convert(const nn::OperandType& operandType) {
+ return static_cast<OperandType>(operandType);
+}
+
+nn::Result<OperationType> convert(const nn::OperationType& operationType) {
+ return static_cast<OperationType>(operationType);
+}
+
+nn::Result<Priority> convert(const nn::Priority& priority) {
+ return static_cast<Priority>(priority);
+}
+
+nn::Result<Capabilities> convert(const nn::Capabilities& capabilities) {
+ std::vector<nn::Capabilities::OperandPerformance> operandPerformance;
+ operandPerformance.reserve(capabilities.operandPerformance.asVector().size());
+ std::copy_if(capabilities.operandPerformance.asVector().begin(),
+ capabilities.operandPerformance.asVector().end(),
+ std::back_inserter(operandPerformance),
+ [](const nn::Capabilities::OperandPerformance& operandPerformance) {
+ return nn::validOperandType(operandPerformance.type);
+ });
+
+ return Capabilities{
+ .relaxedFloat32toFloat16PerformanceScalar =
+ NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
+ .relaxedFloat32toFloat16PerformanceTensor =
+ NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
+ .operandPerformance = NN_TRY(convert(operandPerformance)),
+ .ifPerformance = NN_TRY(convert(capabilities.ifPerformance)),
+ .whilePerformance = NN_TRY(convert(capabilities.whilePerformance)),
+ };
+}
+
+nn::Result<Capabilities::OperandPerformance> convert(
+ const nn::Capabilities::OperandPerformance& operandPerformance) {
+ return Capabilities::OperandPerformance{
+ .type = NN_TRY(convert(operandPerformance.type)),
+ .info = NN_TRY(convert(operandPerformance.info)),
+ };
+}
+
+nn::Result<Operation> convert(const nn::Operation& operation) {
+ return Operation{
+ .type = NN_TRY(convert(operation.type)),
+ .inputs = operation.inputs,
+ .outputs = operation.outputs,
+ };
+}
+
+nn::Result<OperandLifeTime> convert(const nn::Operand::LifeTime& operandLifeTime) {
+ if (operandLifeTime == nn::Operand::LifeTime::POINTER) {
+ return NN_ERROR() << "Model cannot be converted because it contains pointer-based memory";
+ }
+ return static_cast<OperandLifeTime>(operandLifeTime);
+}
+
+nn::Result<Operand> convert(const nn::Operand& operand) {
+ return Operand{
+ .type = NN_TRY(convert(operand.type)),
+ .dimensions = operand.dimensions,
+ .numberOfConsumers = 0,
+ .scale = operand.scale,
+ .zeroPoint = operand.zeroPoint,
+ .lifetime = NN_TRY(convert(operand.lifetime)),
+ .location = NN_TRY(convert(operand.location)),
+ .extraParams = NN_TRY(convert(operand.extraParams)),
+ };
+}
+
+nn::Result<Model> convert(const nn::Model& model) {
+ if (!hal::utils::hasNoPointerData(model)) {
+ return NN_ERROR() << "Model cannot be converted because it contains pointer-based memory";
+ }
+
+ return Model{
+ .main = NN_TRY(convert(model.main)),
+ .referenced = NN_TRY(convert(model.referenced)),
+ .operandValues = NN_TRY(convert(model.operandValues)),
+ .pools = NN_TRY(convert(model.pools)),
+ .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
+ .extensionNameToPrefix = NN_TRY(convert(model.extensionNameToPrefix)),
+ };
+}
+
+nn::Result<Subgraph> convert(const nn::Model::Subgraph& subgraph) {
+ auto operands = NN_TRY(convert(subgraph.operands));
+
+ // Update number of consumers.
+ const auto numberOfConsumers =
+ hal::utils::countNumberOfConsumers(operands.size(), subgraph.operations);
+ CHECK(operands.size() == numberOfConsumers.size());
+ for (size_t i = 0; i < operands.size(); ++i) {
+ operands[i].numberOfConsumers = numberOfConsumers[i];
+ }
+
+ return Subgraph{
+ .operands = std::move(operands),
+ .operations = NN_TRY(convert(subgraph.operations)),
+ .inputIndexes = subgraph.inputIndexes,
+ .outputIndexes = subgraph.outputIndexes,
+ };
+}
+
+nn::Result<BufferDesc> convert(const nn::BufferDesc& bufferDesc) {
+ return BufferDesc{.dimensions = bufferDesc.dimensions};
+}
+
+nn::Result<BufferRole> convert(const nn::BufferRole& bufferRole) {
+ return BufferRole{
+ .modelIndex = bufferRole.modelIndex,
+ .ioIndex = bufferRole.ioIndex,
+ .frequency = bufferRole.frequency,
+ };
+}
+
+nn::Result<Request> convert(const nn::Request& request) {
+ if (!hal::utils::hasNoPointerData(request)) {
+ return NN_ERROR() << "Request cannot be converted because it contains pointer-based memory";
+ }
+
+ return Request{
+ .inputs = NN_TRY(convert(request.inputs)),
+ .outputs = NN_TRY(convert(request.outputs)),
+ .pools = NN_TRY(convert(request.pools)),
+ };
+}
+
+nn::Result<Request::MemoryPool> convert(const nn::Request::MemoryPool& memoryPool) {
+ return std::visit([](const auto& o) { return makeMemoryPool(o); }, memoryPool);
+}
+
+nn::Result<OptionalTimePoint> convert(const nn::OptionalTimePoint& optionalTimePoint) {
+ OptionalTimePoint ret;
+ if (optionalTimePoint.has_value()) {
+ const auto count = optionalTimePoint.value().time_since_epoch().count();
+ if (count < 0) {
+ return NN_ERROR() << "Unable to convert OptionalTimePoint because time since epoch "
+ "count is negative";
+ }
+ ret.nanosecondsSinceEpoch(count);
+ }
+ return ret;
+}
+
+nn::Result<OptionalTimeoutDuration> convert(
+ const nn::OptionalTimeoutDuration& optionalTimeoutDuration) {
+ OptionalTimeoutDuration ret;
+ if (optionalTimeoutDuration.has_value()) {
+ const auto count = optionalTimeoutDuration.value().count();
+ if (count < 0) {
+ return NN_ERROR()
+ << "Unable to convert OptionalTimeoutDuration because count is negative";
+ }
+ ret.nanoseconds(count);
+ }
+ return ret;
+}
+
+nn::Result<ErrorStatus> convert(const nn::ErrorStatus& errorStatus) {
+ switch (errorStatus) {
+ case nn::ErrorStatus::NONE:
+ case nn::ErrorStatus::DEVICE_UNAVAILABLE:
+ case nn::ErrorStatus::GENERAL_FAILURE:
+ case nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE:
+ case nn::ErrorStatus::INVALID_ARGUMENT:
+ case nn::ErrorStatus::MISSED_DEADLINE_TRANSIENT:
+ case nn::ErrorStatus::MISSED_DEADLINE_PERSISTENT:
+ case nn::ErrorStatus::RESOURCE_EXHAUSTED_TRANSIENT:
+ case nn::ErrorStatus::RESOURCE_EXHAUSTED_PERSISTENT:
+ return static_cast<ErrorStatus>(errorStatus);
+ default:
+ return ErrorStatus::GENERAL_FAILURE;
+ }
+}
+
+nn::Result<hidl_vec<BufferRole>> convert(const std::vector<nn::BufferRole>& bufferRoles) {
+ return convertVec(bufferRoles);
+}
+
+} // namespace android::hardware::neuralnetworks::V1_3::utils
diff --git a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp
index 914a01a..0a95695 100644
--- a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp
@@ -644,7 +644,7 @@
int n;
std::tie(n, outputShapes, timing, std::ignore) =
controller->compute(request10, testConfig.measureTiming, keys);
- executionStatus = nn::convertResultCodeToErrorStatus(n);
+ executionStatus = nn::convertToV1_3(nn::convertResultCodeToErrorStatus(n));
break;
}
diff --git a/neuralnetworks/1.3/vts/functional/TestAssertions.cpp b/neuralnetworks/1.3/vts/functional/TestAssertions.cpp
index a7569e6..1a40721 100644
--- a/neuralnetworks/1.3/vts/functional/TestAssertions.cpp
+++ b/neuralnetworks/1.3/vts/functional/TestAssertions.cpp
@@ -15,10 +15,16 @@
*/
#include <android/hardware/neuralnetworks/1.3/types.h>
+#include "ControlFlow.h"
#include "TestHarness.h"
namespace android::hardware::neuralnetworks::V1_3 {
+static_assert(static_cast<uint64_t>(LoopTimeoutDurationNs::DEFAULT) ==
+ nn::operation_while::kTimeoutNsDefault);
+static_assert(static_cast<uint64_t>(LoopTimeoutDurationNs::MAXIMUM) ==
+ nn::operation_while::kTimeoutNsMaximum);
+
// Make sure that the HIDL enums are compatible with the values defined in
// frameworks/ml/nn/tools/test_generator/test_harness/include/TestHarness.h.
using namespace test_helper;
diff --git a/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp b/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp
index 1ae8b3f..3b441fb 100644
--- a/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp
+++ b/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp
@@ -116,7 +116,7 @@
// execute and verify
const auto [n, outputShapes, timing, fallback] = burst->compute(request10, measure, keys);
- const ErrorStatus status = nn::convertResultCodeToErrorStatus(n);
+ const ErrorStatus status = nn::convertToV1_3(nn::convertResultCodeToErrorStatus(n));
EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, status);
EXPECT_EQ(outputShapes.size(), 0);
EXPECT_TRUE(badTiming(timing));
diff --git a/neuralnetworks/utils/OWNERS b/neuralnetworks/utils/OWNERS
new file mode 100644
index 0000000..e4feee3
--- /dev/null
+++ b/neuralnetworks/utils/OWNERS
@@ -0,0 +1,11 @@
+# Neuralnetworks team
+butlermichael@google.com
+dgross@google.com
+galarragas@google.com
+jeanluc@google.com
+levp@google.com
+miaowang@google.com
+pszczepaniak@google.com
+slavash@google.com
+vddang@google.com
+xusongw@google.com
diff --git a/powerstats/aidl/vts/Android.bp b/neuralnetworks/utils/common/Android.bp
similarity index 65%
copy from powerstats/aidl/vts/Android.bp
copy to neuralnetworks/utils/common/Android.bp
index c61022e..b61dc97 100644
--- a/powerstats/aidl/vts/Android.bp
+++ b/neuralnetworks/utils/common/Android.bp
@@ -1,3 +1,4 @@
+//
// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -11,22 +12,18 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
+//
-cc_test {
- name: "VtsHalPowerStatsTargetTest",
- defaults: [
- "VtsHalTargetTestDefaults",
- "use_libaidlvintf_gtest_helper_static",
- ],
- srcs: ["VtsHalPowerStatsTargetTest.cpp"],
- shared_libs: [
- "libbinder_ndk",
- ],
+cc_library_static {
+ name: "neuralnetworks_utils_hal_common",
+ defaults: ["neuralnetworks_utils_defaults"],
+ srcs: ["src/*"],
+ local_include_dirs: ["include/nnapi/hal"],
+ export_include_dirs: ["include"],
static_libs: [
- "android.hardware.powerstats-ndk_platform",
+ "neuralnetworks_types",
],
- test_suites: [
- "general-tests",
- "vts",
+ shared_libs: [
+ "libhidlbase",
],
}
diff --git a/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h b/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h
new file mode 100644
index 0000000..8c01368
--- /dev/null
+++ b/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_COMMON_UTILS_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_COMMON_UTILS_H
+
+#include <nnapi/Result.h>
+#include <nnapi/Types.h>
+#include <vector>
+
+// Shorthand
+namespace android::hardware::neuralnetworks {
+namespace hal = ::android::hardware::neuralnetworks;
+} // namespace android::hardware::neuralnetworks
+
+// Shorthand
+namespace android::nn {
+namespace hal = ::android::hardware::neuralnetworks;
+}
+
+namespace android::hardware::neuralnetworks::utils {
+
+nn::Capabilities::OperandPerformanceTable makeQuantized8PerformanceConsistentWithP(
+ const nn::Capabilities::PerformanceInfo& float32Performance,
+ const nn::Capabilities::PerformanceInfo& quantized8Performance);
+
+// Indicates if the object contains no pointer-based data that could be relocated to shared memory.
+bool hasNoPointerData(const nn::Model& model);
+bool hasNoPointerData(const nn::Request& request);
+
+// Relocate pointer-based data to shared memory.
+nn::Result<nn::Model> flushDataFromPointerToShared(const nn::Model& model);
+nn::Result<nn::Request> flushDataFromPointerToShared(const nn::Request& request);
+
+// Undoes `flushDataFromPointerToShared` on a Request object. More specifically,
+// `unflushDataFromSharedToPointer` copies the output shared memory data from the transformed
+// Request object back to the output pointer-based memory in the original Request object.
+nn::Result<void> unflushDataFromSharedToPointer(const nn::Request& request,
+ const nn::Request& requestInShared);
+
+std::vector<uint32_t> countNumberOfConsumers(size_t numberOfOperands,
+ const std::vector<nn::Operation>& operations);
+
+} // namespace android::hardware::neuralnetworks::utils
+
+#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_COMMON_UTILS_H
diff --git a/neuralnetworks/utils/common/src/CommonUtils.cpp b/neuralnetworks/utils/common/src/CommonUtils.cpp
new file mode 100644
index 0000000..667189b
--- /dev/null
+++ b/neuralnetworks/utils/common/src/CommonUtils.cpp
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "CommonUtils.h"
+
+#include <android-base/logging.h>
+#include <nnapi/Result.h>
+#include <nnapi/SharedMemory.h>
+#include <nnapi/TypeUtils.h>
+#include <nnapi/Types.h>
+#include <nnapi/Validation.h>
+
+#include <algorithm>
+#include <any>
+#include <optional>
+#include <variant>
+#include <vector>
+
+namespace android::hardware::neuralnetworks::utils {
+namespace {
+
+bool hasNoPointerData(const nn::Operand& operand);
+bool hasNoPointerData(const nn::Model::Subgraph& subgraph);
+bool hasNoPointerData(const nn::Request::Argument& argument);
+
+template <typename Type>
+bool hasNoPointerData(const std::vector<Type>& objects) {
+ return std::all_of(objects.begin(), objects.end(),
+ [](const auto& object) { return hasNoPointerData(object); });
+}
+
+bool hasNoPointerData(const nn::DataLocation& location) {
+ return std::visit([](auto ptr) { return ptr == nullptr; }, location.pointer);
+}
+
+bool hasNoPointerData(const nn::Operand& operand) {
+ return hasNoPointerData(operand.location);
+}
+
+bool hasNoPointerData(const nn::Model::Subgraph& subgraph) {
+ return hasNoPointerData(subgraph.operands);
+}
+
+bool hasNoPointerData(const nn::Request::Argument& argument) {
+ return hasNoPointerData(argument.location);
+}
+
+void copyPointersToSharedMemory(nn::Operand* operand, nn::ConstantMemoryBuilder* memoryBuilder) {
+ CHECK(operand != nullptr);
+ CHECK(memoryBuilder != nullptr);
+
+ if (operand->lifetime != nn::Operand::LifeTime::POINTER) {
+ return;
+ }
+
+ const void* data = std::visit([](auto ptr) { return static_cast<const void*>(ptr); },
+ operand->location.pointer);
+ CHECK(data != nullptr);
+ operand->lifetime = nn::Operand::LifeTime::CONSTANT_REFERENCE;
+ operand->location = memoryBuilder->append(data, operand->location.length);
+}
+
+void copyPointersToSharedMemory(nn::Model::Subgraph* subgraph,
+ nn::ConstantMemoryBuilder* memoryBuilder) {
+ CHECK(subgraph != nullptr);
+ std::for_each(subgraph->operands.begin(), subgraph->operands.end(),
+ [memoryBuilder](auto& operand) {
+ copyPointersToSharedMemory(&operand, memoryBuilder);
+ });
+}
+
+} // anonymous namespace
+
+nn::Capabilities::OperandPerformanceTable makeQuantized8PerformanceConsistentWithP(
+ const nn::Capabilities::PerformanceInfo& float32Performance,
+ const nn::Capabilities::PerformanceInfo& quantized8Performance) {
+ // In Android P, most data types are treated as having the same performance as
+ // TENSOR_QUANT8_ASYMM. This collection must be in sorted order.
+ std::vector<nn::Capabilities::OperandPerformance> operandPerformances = {
+ {.type = nn::OperandType::FLOAT32, .info = float32Performance},
+ {.type = nn::OperandType::INT32, .info = quantized8Performance},
+ {.type = nn::OperandType::UINT32, .info = quantized8Performance},
+ {.type = nn::OperandType::TENSOR_FLOAT32, .info = float32Performance},
+ {.type = nn::OperandType::TENSOR_INT32, .info = quantized8Performance},
+ {.type = nn::OperandType::TENSOR_QUANT8_ASYMM, .info = quantized8Performance},
+ {.type = nn::OperandType::OEM, .info = quantized8Performance},
+ {.type = nn::OperandType::TENSOR_OEM_BYTE, .info = quantized8Performance},
+ };
+ return nn::Capabilities::OperandPerformanceTable::create(std::move(operandPerformances))
+ .value();
+}
+
+bool hasNoPointerData(const nn::Model& model) {
+ return hasNoPointerData(model.main) && hasNoPointerData(model.referenced);
+}
+
+bool hasNoPointerData(const nn::Request& request) {
+ return hasNoPointerData(request.inputs) && hasNoPointerData(request.outputs);
+}
+
+nn::Result<nn::Model> flushDataFromPointerToShared(const nn::Model& model) {
+ auto modelInShared = model;
+
+ nn::ConstantMemoryBuilder memoryBuilder(modelInShared.pools.size());
+ copyPointersToSharedMemory(&modelInShared.main, &memoryBuilder);
+ std::for_each(modelInShared.referenced.begin(), modelInShared.referenced.end(),
+ [&memoryBuilder](auto& subgraph) {
+ copyPointersToSharedMemory(&subgraph, &memoryBuilder);
+ });
+
+ if (!memoryBuilder.empty()) {
+ auto memory = NN_TRY(memoryBuilder.finish());
+ modelInShared.pools.push_back(std::move(memory));
+ }
+
+ return modelInShared;
+}
+
+nn::Result<nn::Request> flushDataFromPointerToShared(const nn::Request& request) {
+ auto requestInShared = request;
+
+ // Change input pointers to shared memory.
+ nn::ConstantMemoryBuilder inputBuilder(requestInShared.pools.size());
+ for (auto& input : requestInShared.inputs) {
+ const auto& location = input.location;
+ if (input.lifetime != nn::Request::Argument::LifeTime::POINTER) {
+ continue;
+ }
+
+ input.lifetime = nn::Request::Argument::LifeTime::POOL;
+ const void* data = std::visit([](auto ptr) { return static_cast<const void*>(ptr); },
+ location.pointer);
+ CHECK(data != nullptr);
+ input.location = inputBuilder.append(data, location.length);
+ }
+
+ // Allocate input memory.
+ if (!inputBuilder.empty()) {
+ auto memory = NN_TRY(inputBuilder.finish());
+ requestInShared.pools.push_back(std::move(memory));
+ }
+
+ // Change output pointers to shared memory.
+ nn::MutableMemoryBuilder outputBuilder(requestInShared.pools.size());
+ for (auto& output : requestInShared.outputs) {
+ const auto& location = output.location;
+ if (output.lifetime != nn::Request::Argument::LifeTime::POINTER) {
+ continue;
+ }
+
+ output.lifetime = nn::Request::Argument::LifeTime::POOL;
+ output.location = outputBuilder.append(location.length);
+ }
+
+ // Allocate output memory.
+ if (!outputBuilder.empty()) {
+ auto memory = NN_TRY(outputBuilder.finish());
+ requestInShared.pools.push_back(std::move(memory));
+ }
+
+ return requestInShared;
+}
+
+nn::Result<void> unflushDataFromSharedToPointer(const nn::Request& request,
+ const nn::Request& requestInShared) {
+ if (requestInShared.pools.empty() ||
+ !std::holds_alternative<nn::Memory>(requestInShared.pools.back())) {
+ return {};
+ }
+
+ // Map the memory.
+ const auto& outputMemory = std::get<nn::Memory>(requestInShared.pools.back());
+ const auto [pointer, size, context] = NN_TRY(map(outputMemory));
+ const uint8_t* constantPointer =
+ std::visit([](const auto& o) { return static_cast<const uint8_t*>(o); }, pointer);
+
+ // Flush each output pointer.
+ CHECK_EQ(request.outputs.size(), requestInShared.outputs.size());
+ for (size_t i = 0; i < request.outputs.size(); ++i) {
+ const auto& location = request.outputs[i].location;
+ const auto& locationInShared = requestInShared.outputs[i].location;
+ if (!std::holds_alternative<void*>(location.pointer)) {
+ continue;
+ }
+
+ // Get output pointer and size.
+ void* data = std::get<void*>(location.pointer);
+ CHECK(data != nullptr);
+ const size_t length = location.length;
+
+ // Get output pool location.
+ CHECK(requestInShared.outputs[i].lifetime == nn::Request::Argument::LifeTime::POOL);
+ const size_t index = locationInShared.poolIndex;
+ const size_t offset = locationInShared.offset;
+ const size_t outputPoolIndex = requestInShared.pools.size() - 1;
+ CHECK(locationInShared.length == length);
+ CHECK(index == outputPoolIndex);
+
+ // Flush memory.
+ std::memcpy(data, constantPointer + offset, length);
+ }
+
+ return {};
+}
+
+std::vector<uint32_t> countNumberOfConsumers(size_t numberOfOperands,
+ const std::vector<nn::Operation>& operations) {
+ return nn::countNumberOfConsumers(numberOfOperands, operations);
+}
+
+} // namespace android::hardware::neuralnetworks::utils
diff --git a/powerstats/aidl/Android.bp b/power/stats/aidl/Android.bp
similarity index 91%
rename from powerstats/aidl/Android.bp
rename to power/stats/aidl/Android.bp
index 1aa58cb..1688b12 100644
--- a/powerstats/aidl/Android.bp
+++ b/power/stats/aidl/Android.bp
@@ -13,10 +13,10 @@
// limitations under the License.
aidl_interface {
- name: "android.hardware.powerstats",
+ name: "android.hardware.power.stats",
vendor_available: true,
srcs: [
- "android/hardware/powerstats/*.aidl",
+ "android/hardware/power/stats/*.aidl",
],
stability: "vintf",
backend: {
diff --git a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/UnsynchronizedWrite.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/ChannelInfo.aidl
similarity index 89%
copy from common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/UnsynchronizedWrite.aidl
copy to power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/ChannelInfo.aidl
index e390d20..209bec4 100644
--- a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/UnsynchronizedWrite.aidl
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/ChannelInfo.aidl
@@ -15,8 +15,9 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.common;
+package android.hardware.power.stats;
@VintfStability
-enum UnsynchronizedWrite {
- EMPTY = 0,
+parcelable ChannelInfo {
+ int channelId;
+ @utf8InCpp String channelName;
}
diff --git a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/UnsynchronizedWrite.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerId.aidl
similarity index 88%
copy from common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/UnsynchronizedWrite.aidl
copy to power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerId.aidl
index e390d20..7ca3b15 100644
--- a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/UnsynchronizedWrite.aidl
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerId.aidl
@@ -15,8 +15,9 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.common;
-@VintfStability
-enum UnsynchronizedWrite {
- EMPTY = 0,
+package android.hardware.power.stats;
+@Backing(type="int") @VintfStability
+enum EnergyConsumerId {
+ DISPLAY = 0,
+ GPS = 1,
}
diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyData.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl
similarity index 88%
copy from powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyData.aidl
copy to power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl
index 2e384da..6289a08 100644
--- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyData.aidl
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl
@@ -15,10 +15,10 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.powerstats;
+package android.hardware.power.stats;
@VintfStability
-parcelable EnergyData {
- int railIndex;
+parcelable EnergyConsumerResult {
+ android.hardware.power.stats.EnergyConsumerId energyConsumerId;
long timestampMs;
long energyUWs;
}
diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyData.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl
similarity index 91%
rename from powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyData.aidl
rename to power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl
index 2e384da..341909e 100644
--- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyData.aidl
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl
@@ -15,10 +15,10 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.powerstats;
+package android.hardware.power.stats;
@VintfStability
-parcelable EnergyData {
- int railIndex;
+parcelable EnergyMeasurement {
+ int channelId;
long timestampMs;
long energyUWs;
}
diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl
similarity index 64%
rename from powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl
rename to power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl
index 6772f6f..07013b0 100644
--- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl
@@ -15,11 +15,13 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.powerstats;
+package android.hardware.power.stats;
@VintfStability
interface IPowerStats {
- android.hardware.powerstats.EnergyData[] getEnergyData(in int[] railIndices);
- android.hardware.powerstats.PowerEntityInfo[] getPowerEntityInfo();
- android.hardware.powerstats.PowerEntityStateResidencyResult[] getPowerEntityStateResidencyData(in int[] powerEntityIds);
- android.hardware.powerstats.RailInfo[] getRailInfo();
+ android.hardware.power.stats.PowerEntityInfo[] getPowerEntityInfo();
+ android.hardware.power.stats.StateResidencyResult[] getStateResidency(in int[] powerEntityIds);
+ android.hardware.power.stats.EnergyConsumerId[] getEnergyConsumerInfo();
+ android.hardware.power.stats.EnergyConsumerResult[] getEnergyConsumed(in android.hardware.power.stats.EnergyConsumerId[] energyConsumerIds);
+ android.hardware.power.stats.ChannelInfo[] getEnergyMeterInfo();
+ android.hardware.power.stats.EnergyMeasurement[] readEnergyMeters(in int[] channelIds);
}
diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntityInfo.aidl
similarity index 89%
rename from powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl
rename to power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntityInfo.aidl
index 016af91..3b16362 100644
--- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntityInfo.aidl
@@ -15,10 +15,10 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.powerstats;
+package android.hardware.power.stats;
@VintfStability
parcelable PowerEntityInfo {
int powerEntityId;
- String powerEntityName;
- android.hardware.powerstats.PowerEntityStateInfo[] states;
+ @utf8InCpp String powerEntityName;
+ android.hardware.power.stats.StateInfo[] states;
}
diff --git a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/UnsynchronizedWrite.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateInfo.aidl
similarity index 90%
copy from common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/UnsynchronizedWrite.aidl
copy to power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateInfo.aidl
index e390d20..0db9ab1 100644
--- a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/UnsynchronizedWrite.aidl
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateInfo.aidl
@@ -15,8 +15,9 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.common;
+package android.hardware.power.stats;
@VintfStability
-enum UnsynchronizedWrite {
- EMPTY = 0,
+parcelable StateInfo {
+ int stateId;
+ @utf8InCpp String stateName;
}
diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateResidencyData.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidency.aidl
similarity index 90%
rename from powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateResidencyData.aidl
rename to power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidency.aidl
index 8a3b227..206c974 100644
--- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateResidencyData.aidl
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidency.aidl
@@ -15,10 +15,10 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.powerstats;
+package android.hardware.power.stats;
@VintfStability
-parcelable PowerEntityStateResidencyData {
- int powerEntityStateId;
+parcelable StateResidency {
+ int stateId;
long totalTimeInStateMs;
long totalStateEntryCount;
long lastEntryTimestampMs;
diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateInfo.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidencyResult.aidl
similarity index 86%
copy from powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateInfo.aidl
copy to power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidencyResult.aidl
index 9de66ba..dc41fef 100644
--- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateInfo.aidl
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidencyResult.aidl
@@ -15,9 +15,9 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.powerstats;
+package android.hardware.power.stats;
@VintfStability
-parcelable PowerEntityStateInfo {
- int powerEntityStateId;
- String powerEntityStateName;
+parcelable StateResidencyResult {
+ int powerEntityId;
+ android.hardware.power.stats.StateResidency[] stateResidencyData;
}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl b/power/stats/aidl/android/hardware/power/stats/ChannelInfo.aidl
similarity index 71%
rename from biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl
rename to power/stats/aidl/android/hardware/power/stats/ChannelInfo.aidl
index a51b188..a2ca6a6 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl
+++ b/power/stats/aidl/android/hardware/power/stats/ChannelInfo.aidl
@@ -14,13 +14,17 @@
* limitations under the License.
*/
-package android.hardware.biometrics.fingerprint;
+package android.hardware.power.stats;
@VintfStability
-oneway interface IGenerateChallengeCallback {
+parcelable ChannelInfo {
/**
- * Notifies the framework when a challenge is successfully generated.
+ * Unique ID of this ChannelInfo
*/
- void onChallengeGenerated(in int sensorId, in int userId, in long challenge);
+ int channelId;
+ /**
+ * Unique name of the ChannelInfo. Vendor/device specific. Opaque to framework
+ */
+ @utf8InCpp String channelName;
}
diff --git a/tests/safeunion/1.0/IOtherInterface.hal b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerId.aidl
similarity index 73%
rename from tests/safeunion/1.0/IOtherInterface.hal
rename to power/stats/aidl/android/hardware/power/stats/EnergyConsumerId.aidl
index cdaf847..4a6a677 100644
--- a/tests/safeunion/1.0/IOtherInterface.hal
+++ b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerId.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,8 +14,11 @@
* limitations under the License.
*/
-package android.hardware.tests.safeunion@1.0;
+package android.hardware.power.stats;
-interface IOtherInterface {
- concatTwoStrings(string a, string b) generates (string result);
-};
+@VintfStability
+@Backing(type="int")
+enum EnergyConsumerId {
+ DISPLAY = 0,
+ GPS = 1,
+}
\ No newline at end of file
diff --git a/powerstats/aidl/android/hardware/powerstats/EnergyData.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerResult.aidl
similarity index 68%
copy from powerstats/aidl/android/hardware/powerstats/EnergyData.aidl
copy to power/stats/aidl/android/hardware/power/stats/EnergyConsumerResult.aidl
index ec12c5e..d2b902a 100644
--- a/powerstats/aidl/android/hardware/powerstats/EnergyData.aidl
+++ b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerResult.aidl
@@ -14,21 +14,22 @@
* limitations under the License.
*/
-package android.hardware.powerstats;
+package android.hardware.power.stats;
+
+import android.hardware.power.stats.EnergyConsumerId;
@VintfStability
-parcelable EnergyData {
+parcelable EnergyConsumerResult {
/**
- * Index corresponding to the rail. This index matches
- * the index returned in RailInfo
+ * ID of the EnergyConsumer associated with this result
*/
- int railIndex;
+ EnergyConsumerId energyConsumerId;
/**
- * Time since device boot(CLOCK_BOOTTIME) in milli-seconds
+ * Time since boot in milliseconds
*/
long timestampMs;
/**
- * Accumulated energy since device boot in microwatt-seconds (uWs)
+ * Accumulated energy since boot in microwatt-seconds (uWs)
*/
long energyUWs;
}
diff --git a/powerstats/aidl/android/hardware/powerstats/EnergyData.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl
similarity index 69%
rename from powerstats/aidl/android/hardware/powerstats/EnergyData.aidl
rename to power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl
index ec12c5e..f873849 100644
--- a/powerstats/aidl/android/hardware/powerstats/EnergyData.aidl
+++ b/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl
@@ -14,21 +14,20 @@
* limitations under the License.
*/
-package android.hardware.powerstats;
+package android.hardware.power.stats;
@VintfStability
-parcelable EnergyData {
+parcelable EnergyMeasurement {
/**
- * Index corresponding to the rail. This index matches
- * the index returned in RailInfo
+ * ID of the Channel associated with this measurement
*/
- int railIndex;
+ int channelId;
/**
- * Time since device boot(CLOCK_BOOTTIME) in milli-seconds
+ * Time since boot in milliseconds
*/
long timestampMs;
/**
- * Accumulated energy since device boot in microwatt-seconds (uWs)
+ * Accumulated energy since boot in microwatt-seconds (uWs)
*/
long energyUWs;
}
diff --git a/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl b/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl
new file mode 100644
index 0000000..85a2ce0
--- /dev/null
+++ b/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.power.stats;
+
+import android.hardware.power.stats.ChannelInfo;
+import android.hardware.power.stats.EnergyConsumerId;
+import android.hardware.power.stats.EnergyConsumerResult;
+import android.hardware.power.stats.EnergyMeasurement;
+import android.hardware.power.stats.PowerEntityInfo;
+import android.hardware.power.stats.StateResidencyResult;
+
+@VintfStability
+interface IPowerStats {
+ /**
+ * Return information related to all supported PowerEntity(s) for which state residency data
+ * is available.
+ *
+ * A PowerEntity is defined as a platform subsystem, peripheral, or power domain that impacts
+ * the total device power consumption.
+ *
+ * @return List of information on each PowerEntity
+ */
+ PowerEntityInfo[] getPowerEntityInfo();
+
+ /**
+ * Reports the accumulated state residency for each requested PowerEntity.
+ *
+ * Each PowerEntity may reside in one of multiple states. It may also
+ * transition from one state to another. StateResidency is defined as
+ * an accumulation of time that a PowerEntity resided in each
+ * of its possible states, the number of times that each state was
+ * entered, and a timestamp corresponding to the last time that state
+ * was entered.
+ *
+ * Data is accumulated starting at device boot.
+ *
+ * @param powerEntityIds List of IDs of PowerEntities for which data is requested.
+ * Passing an empty list will return state residency for all available PowerEntitys.
+ * ID of each PowerEntity is contained in PowerEntityInfo.
+ *
+ * @return StateResidency since boot for each requested PowerEntity
+ *
+ * Returns the following service-specific exceptions in order of highest priority:
+ * - STATUS_BAD_VALUE if an invalid powerEntityId is provided
+ * - STATUS_FAILED_TRANSACTION if any StateResidencyResult fails to be returned
+ */
+ StateResidencyResult[] getStateResidency(in int[] powerEntityIds);
+
+ /**
+ * Return the list IDs for all supported EnergyConsumers for which energy consumption data is
+ * available.
+ *
+ * An EnergyConsumer is a device subsystem or peripheral that consumes energy. Energy
+ * consumption data may be used by framework for the purpose of power attribution.
+ *
+ * @return List of EnergyConsumersIds that are available.
+ */
+ EnergyConsumerId[] getEnergyConsumerInfo();
+
+ /**
+ * Reports the energy consumed since boot by each requested EnergyConsumer.
+ *
+ * @param energyConsumerIds List of IDs of EnergyConsumers for which data is requested.
+ * Passing an empty list will return state residency for all available EnergyConsumers.
+ *
+ * @return Energy consumed since boot for each requested EnergyConsumer
+ *
+ * Returns the following service-specific exceptions in order of highest priority:
+ * - STATUS_BAD_VALUE if an invalid energyConsumerId is provided
+ * - STATUS_FAILED_TRANSACTION if any EnergyConsumerResult fails to be returned
+ */
+ EnergyConsumerResult[] getEnergyConsumed(in EnergyConsumerId[] energyConsumerIds);
+
+ /**
+ * Return information related to all channels monitored by Energy Meters.
+ *
+ * An Energy Meter is a device that monitors energy and may support monitoring multiple
+ * channels simultaneously. A channel may correspond a bus, sense resistor, or power rail.
+ *
+ * @return Information about channels monitored by Energy Meters.
+ */
+ ChannelInfo[] getEnergyMeterInfo();
+
+ /**
+ * Reports accumulated energy since boot for each specified channel.
+ *
+ * @param channelIds IDs of channels for which data is requested.
+ * Passing an empty list will return energy measurements for all available channels.
+ * ID of each channel is contained in ChannelInfo.
+ *
+ * @return Energy measured since boot for each requested channel
+ *
+ * Returns the following service-specific exceptions in order of highest priority:
+ * - STATUS_BAD_VALUE if an invalid channelId is provided
+ * - STATUS_FAILED_TRANSACTION if any EnergyMeasurement fails to be returned
+ */
+ EnergyMeasurement[] readEnergyMeters(in int[] channelIds);
+}
\ No newline at end of file
diff --git a/powerstats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl b/power/stats/aidl/android/hardware/power/stats/PowerEntityInfo.aidl
similarity index 68%
rename from powerstats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl
rename to power/stats/aidl/android/hardware/power/stats/PowerEntityInfo.aidl
index 72222a6..002b343 100644
--- a/powerstats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl
+++ b/power/stats/aidl/android/hardware/power/stats/PowerEntityInfo.aidl
@@ -14,26 +14,22 @@
* limitations under the License.
*/
-package android.hardware.powerstats;
+package android.hardware.power.stats;
-import android.hardware.powerstats.PowerEntityStateInfo;
+import android.hardware.power.stats.StateInfo;
-/**
- * PowerEntityInfo contains information, such as the ID, name, and type of a
- * given PowerEntity.
- */
@VintfStability
parcelable PowerEntityInfo {
/**
- * Unique ID corresponding to the PowerEntity
+ * Unique ID of this PowerEntityInfo
*/
int powerEntityId;
/**
- * Name of the PowerEntity (opaque to the framework)
+ * Unique name of the PowerEntity. Vendor/device specific. Opaque to framework
*/
- String powerEntityName;
+ @utf8InCpp String powerEntityName;
/**
* List of states that the PowerEntity may reside in
*/
- PowerEntityStateInfo[] states;
+ StateInfo[] states;
}
\ No newline at end of file
diff --git a/powerstats/aidl/android/hardware/powerstats/PowerEntityStateInfo.aidl b/power/stats/aidl/android/hardware/power/stats/StateInfo.aidl
similarity index 69%
rename from powerstats/aidl/android/hardware/powerstats/PowerEntityStateInfo.aidl
rename to power/stats/aidl/android/hardware/power/stats/StateInfo.aidl
index 69fc798..5703f1e 100644
--- a/powerstats/aidl/android/hardware/powerstats/PowerEntityStateInfo.aidl
+++ b/power/stats/aidl/android/hardware/power/stats/StateInfo.aidl
@@ -14,17 +14,18 @@
* limitations under the License.
*/
-package android.hardware.powerstats;
+package android.hardware.power.stats;
@VintfStability
-parcelable PowerEntityStateInfo {
+parcelable StateInfo {
/**
- * ID corresponding to the state. Unique for a given PowerEntityStateSpace
+ * Unique (for a given PowerEntityInfo) ID of this StateInfo
*/
- int powerEntityStateId;
+ int stateId;
/**
- * Name of the state (opaque to the framework)
+ * Unique (for a given PowerEntityInfo) name of the state. Vendor/device specific.
+ * Opaque to framework
*/
- String powerEntityStateName;
+ @utf8InCpp String stateName;
}
diff --git a/powerstats/aidl/android/hardware/powerstats/PowerEntityStateResidencyData.aidl b/power/stats/aidl/android/hardware/power/stats/StateResidency.aidl
similarity index 71%
rename from powerstats/aidl/android/hardware/powerstats/PowerEntityStateResidencyData.aidl
rename to power/stats/aidl/android/hardware/power/stats/StateResidency.aidl
index a738457..a85ca33 100644
--- a/powerstats/aidl/android/hardware/powerstats/PowerEntityStateResidencyData.aidl
+++ b/power/stats/aidl/android/hardware/power/stats/StateResidency.aidl
@@ -14,31 +14,28 @@
* limitations under the License.
*/
-package android.hardware.powerstats;
+package android.hardware.power.stats;
/**
* Contains residency data for a single state
*/
@VintfStability
-parcelable PowerEntityStateResidencyData {
+parcelable StateResidency {
/**
- * Unique ID of the corresponding PowerEntityStateInfo
+ * ID of the state associated with this residency
*/
- int powerEntityStateId;
+ int stateId;
/**
* Total time in milliseconds that the corresponding PowerEntity resided
- * in this state since the PowerEntity was reset
+ * in this state since boot
*/
long totalTimeInStateMs;
/**
- * Total number of times that the state was entered since the corresponding
- * PowerEntity was reset
+ * Total number of times that the state was entered since boot
*/
long totalStateEntryCount;
/**
- * Last time this state was entered. Time in milliseconds since the
- * corresponding PowerEntity was reset
+ * Last time this state was entered. Time in milliseconds since boot
*/
long lastEntryTimestampMs;
-}
-
+}
\ No newline at end of file
diff --git a/powerstats/aidl/android/hardware/powerstats/PowerEntityStateResidencyResult.aidl b/power/stats/aidl/android/hardware/power/stats/StateResidencyResult.aidl
similarity index 68%
rename from powerstats/aidl/android/hardware/powerstats/PowerEntityStateResidencyResult.aidl
rename to power/stats/aidl/android/hardware/power/stats/StateResidencyResult.aidl
index 555ae4c..3356405 100644
--- a/powerstats/aidl/android/hardware/powerstats/PowerEntityStateResidencyResult.aidl
+++ b/power/stats/aidl/android/hardware/power/stats/StateResidencyResult.aidl
@@ -14,19 +14,19 @@
* limitations under the License.
*/
-package android.hardware.powerstats;
+package android.hardware.power.stats;
-import android.hardware.powerstats.PowerEntityStateResidencyData;
+import android.hardware.power.stats.StateResidency;
@VintfStability
-parcelable PowerEntityStateResidencyResult {
+parcelable StateResidencyResult {
/**
- * Unique ID of the corresponding PowerEntity
+ * ID of the PowerEntity associated with this result
*/
int powerEntityId;
/**
- * Residency data for each state the PowerEntity's state space
+ * Residency for each state in the PowerEntity's state space
*/
- PowerEntityStateResidencyData[] stateResidencyData;
+ StateResidency[] stateResidencyData;
}
diff --git a/powerstats/aidl/default/Android.bp b/power/stats/aidl/default/Android.bp
similarity index 80%
rename from powerstats/aidl/default/Android.bp
rename to power/stats/aidl/default/Android.bp
index caecd88..40b9447 100644
--- a/powerstats/aidl/default/Android.bp
+++ b/power/stats/aidl/default/Android.bp
@@ -13,15 +13,15 @@
// limitations under the License.
cc_binary {
- name: "android.hardware.powerstats-service.example",
+ name: "android.hardware.power.stats-service.example",
relative_install_path: "hw",
- init_rc: ["powerstats-default.rc"],
- vintf_fragments: ["powerstats-default.xml"],
+ init_rc: ["power.stats-default.rc"],
+ vintf_fragments: ["power.stats-default.xml"],
vendor: true,
shared_libs: [
"libbase",
"libbinder_ndk",
- "android.hardware.powerstats-ndk_platform",
+ "android.hardware.power.stats-ndk_platform",
],
srcs: [
"main.cpp",
diff --git a/power/stats/aidl/default/PowerStats.cpp b/power/stats/aidl/default/PowerStats.cpp
new file mode 100644
index 0000000..367ee95
--- /dev/null
+++ b/power/stats/aidl/default/PowerStats.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "PowerStats.h"
+
+#include <android-base/logging.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace power {
+namespace stats {
+
+ndk::ScopedAStatus PowerStats::getPowerEntityInfo(std::vector<PowerEntityInfo>* _aidl_return) {
+ (void)_aidl_return;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus PowerStats::getStateResidency(const std::vector<int32_t>& in_powerEntityIds,
+ std::vector<StateResidencyResult>* _aidl_return) {
+ (void)in_powerEntityIds;
+ (void)_aidl_return;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus PowerStats::getEnergyConsumerInfo(std::vector<EnergyConsumerId>* _aidl_return) {
+ (void)_aidl_return;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus PowerStats::getEnergyConsumed(
+ const std::vector<EnergyConsumerId>& in_energyConsumerIds,
+ std::vector<EnergyConsumerResult>* _aidl_return) {
+ (void)in_energyConsumerIds;
+ (void)_aidl_return;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus PowerStats::getEnergyMeterInfo(std::vector<ChannelInfo>* _aidl_return) {
+ (void)_aidl_return;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus PowerStats::readEnergyMeters(const std::vector<int32_t>& in_channelIds,
+ std::vector<EnergyMeasurement>* _aidl_return) {
+ (void)in_channelIds;
+ (void)_aidl_return;
+ return ndk::ScopedAStatus::ok();
+}
+
+} // namespace stats
+} // namespace power
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/power/stats/aidl/default/PowerStats.h b/power/stats/aidl/default/PowerStats.h
new file mode 100644
index 0000000..76ab2cb
--- /dev/null
+++ b/power/stats/aidl/default/PowerStats.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/power/stats/BnPowerStats.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace power {
+namespace stats {
+
+class PowerStats : public BnPowerStats {
+ public:
+ PowerStats() = default;
+ // Methods from aidl::android::hardware::power::stats::IPowerStats
+ ndk::ScopedAStatus getPowerEntityInfo(std::vector<PowerEntityInfo>* _aidl_return) override;
+ ndk::ScopedAStatus getStateResidency(const std::vector<int32_t>& in_powerEntityIds,
+ std::vector<StateResidencyResult>* _aidl_return) override;
+ ndk::ScopedAStatus getEnergyConsumerInfo(std::vector<EnergyConsumerId>* _aidl_return) override;
+ ndk::ScopedAStatus getEnergyConsumed(const std::vector<EnergyConsumerId>& in_energyConsumerIds,
+ std::vector<EnergyConsumerResult>* _aidl_return) override;
+ ndk::ScopedAStatus getEnergyMeterInfo(std::vector<ChannelInfo>* _aidl_return) override;
+ ndk::ScopedAStatus readEnergyMeters(const std::vector<int32_t>& in_channelIds,
+ std::vector<EnergyMeasurement>* _aidl_return) override;
+};
+
+} // namespace stats
+} // namespace power
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/powerstats/aidl/default/main.cpp b/power/stats/aidl/default/main.cpp
similarity index 95%
rename from powerstats/aidl/default/main.cpp
rename to power/stats/aidl/default/main.cpp
index 1496805..0469b4c 100644
--- a/powerstats/aidl/default/main.cpp
+++ b/power/stats/aidl/default/main.cpp
@@ -20,7 +20,7 @@
#include <android/binder_manager.h>
#include <android/binder_process.h>
-using aidl::android::hardware::powerstats::PowerStats;
+using aidl::android::hardware::power::stats::PowerStats;
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(0);
diff --git a/power/stats/aidl/default/power.stats-default.rc b/power/stats/aidl/default/power.stats-default.rc
new file mode 100644
index 0000000..6ff6754
--- /dev/null
+++ b/power/stats/aidl/default/power.stats-default.rc
@@ -0,0 +1,4 @@
+service vendor.power.stats-default /vendor/bin/hw/android.hardware.power.stats-service.example
+ class hal
+ user system
+ group system
diff --git a/powerstats/aidl/default/powerstats-default.xml b/power/stats/aidl/default/power.stats-default.xml
similarity index 72%
rename from powerstats/aidl/default/powerstats-default.xml
rename to power/stats/aidl/default/power.stats-default.xml
index e07513d..3b1a216 100644
--- a/powerstats/aidl/default/powerstats-default.xml
+++ b/power/stats/aidl/default/power.stats-default.xml
@@ -1,6 +1,6 @@
<manifest version="1.0" type="device">
<hal format="aidl">
- <name>android.hardware.powerstats</name>
+ <name>android.hardware.power.stats</name>
<fqname>IPowerStats/default</fqname>
</hal>
</manifest>
diff --git a/powerstats/aidl/vts/Android.bp b/power/stats/aidl/vts/Android.bp
similarity index 94%
rename from powerstats/aidl/vts/Android.bp
rename to power/stats/aidl/vts/Android.bp
index c61022e..930709f 100644
--- a/powerstats/aidl/vts/Android.bp
+++ b/power/stats/aidl/vts/Android.bp
@@ -23,7 +23,7 @@
"libbinder_ndk",
],
static_libs: [
- "android.hardware.powerstats-ndk_platform",
+ "android.hardware.power.stats-ndk_platform",
],
test_suites: [
"general-tests",
diff --git a/powerstats/aidl/vts/VtsHalPowerStatsTargetTest.cpp b/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp
similarity index 76%
rename from powerstats/aidl/vts/VtsHalPowerStatsTargetTest.cpp
rename to power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp
index b3cd233..1d30821 100644
--- a/powerstats/aidl/vts/VtsHalPowerStatsTargetTest.cpp
+++ b/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp
@@ -16,16 +16,17 @@
#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
-#include <aidl/android/hardware/powerstats/IPowerStats.h>
+#include <aidl/android/hardware/power/stats/IPowerStats.h>
#include <android-base/properties.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
-using aidl::android::hardware::powerstats::EnergyData;
-using aidl::android::hardware::powerstats::IPowerStats;
-using aidl::android::hardware::powerstats::PowerEntityInfo;
-using aidl::android::hardware::powerstats::PowerEntityStateResidencyResult;
-using aidl::android::hardware::powerstats::RailInfo;
+using aidl::android::hardware::power::stats::ChannelInfo;
+using aidl::android::hardware::power::stats::EnergyMeasurement;
+using aidl::android::hardware::power::stats::IPowerStats;
+using aidl::android::hardware::power::stats::PowerEntityInfo;
+using aidl::android::hardware::power::stats::StateResidencyResult;
+
using ndk::SpAIBinder;
class PowerStatsAidl : public testing::TestWithParam<std::string> {
@@ -39,9 +40,9 @@
std::shared_ptr<IPowerStats> powerstats;
};
-TEST_P(PowerStatsAidl, TestGetEnergyData) {
- std::vector<EnergyData> data;
- ASSERT_TRUE(powerstats->getEnergyData({}, &data).isOk());
+TEST_P(PowerStatsAidl, TestReadEnergyMeter) {
+ std::vector<EnergyMeasurement> data;
+ ASSERT_TRUE(powerstats->readEnergyMeters({}, &data).isOk());
}
// Each PowerEntity must have a valid name
@@ -83,7 +84,7 @@
for (auto info : infos) {
for (auto state : info.states) {
- EXPECT_NE(state.powerEntityStateName, "");
+ EXPECT_NE(state.stateName, "");
}
}
}
@@ -96,7 +97,7 @@
for (auto info : infos) {
std::set<std::string> stateNames;
for (auto state : info.states) {
- EXPECT_TRUE(stateNames.insert(state.powerEntityStateName).second);
+ EXPECT_TRUE(stateNames.insert(state.stateName).second);
}
}
}
@@ -107,21 +108,21 @@
ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk());
for (auto info : infos) {
- std::set<uint32_t> stateIds;
+ std::set<int32_t> stateIds;
for (auto state : info.states) {
- EXPECT_TRUE(stateIds.insert(state.powerEntityStateId).second);
+ EXPECT_TRUE(stateIds.insert(state.stateId).second);
}
}
}
-TEST_P(PowerStatsAidl, TestGetPowerEntityStateResidencyData) {
- std::vector<PowerEntityStateResidencyResult> data;
- ASSERT_TRUE(powerstats->getPowerEntityStateResidencyData({}, &data).isOk());
+TEST_P(PowerStatsAidl, TestGetStateResidency) {
+ std::vector<StateResidencyResult> results;
+ ASSERT_TRUE(powerstats->getStateResidency({}, &results).isOk());
}
-TEST_P(PowerStatsAidl, TestGetRailInfo) {
- std::vector<RailInfo> info;
- ASSERT_TRUE(powerstats->getRailInfo(&info).isOk());
+TEST_P(PowerStatsAidl, TestGetEnergyMeterInfo) {
+ std::vector<ChannelInfo> info;
+ ASSERT_TRUE(powerstats->getEnergyMeterInfo(&info).isOk());
}
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PowerStatsAidl);
diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateResidencyResult.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateResidencyResult.aidl
deleted file mode 100644
index fbe567e..0000000
--- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateResidencyResult.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files 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.powerstats;
-@VintfStability
-parcelable PowerEntityStateResidencyResult {
- int powerEntityId;
- android.hardware.powerstats.PowerEntityStateResidencyData[] stateResidencyData;
-}
diff --git a/powerstats/aidl/android/hardware/powerstats/IPowerStats.aidl b/powerstats/aidl/android/hardware/powerstats/IPowerStats.aidl
deleted file mode 100644
index 93d1448..0000000
--- a/powerstats/aidl/android/hardware/powerstats/IPowerStats.aidl
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.powerstats;
-
-import android.hardware.powerstats.EnergyData;
-import android.hardware.powerstats.PowerEntityInfo;
-import android.hardware.powerstats.PowerEntityStateResidencyResult;
-import android.hardware.powerstats.RailInfo;
-
-@VintfStability
-interface IPowerStats {
- /**
- * Rail level energy measurements for low frequency clients:
- * Reports accumulated energy since boot on each rail.
- *
- * @param railIndices Indices of rails for which data is required.
- * To get data for all rails pass an empty vector. Rail name to
- * index mapping can be queried from getRailInfo() API.
- * @return Energy values since boot for all requested rails.
- */
- EnergyData[] getEnergyData(in int[] railIndices);
-
- /**
- * PowerEntity information:
- * Reports information related to all supported PowerEntity(s) for which
- * data is available. A PowerEntity is defined as a platform subsystem,
- * peripheral, or power domain that impacts the total device power
- * consumption.
- *
- * @return List of information on each PowerEntity
- */
- PowerEntityInfo[] getPowerEntityInfo();
-
- /**
- * PowerEntity residencies for low frequency clients:
- * Reports accumulated residency data for each specified PowerEntity.
- * Each PowerEntity may reside in one of multiple states. It may also
- * transition to another state. Residency data is an accumulation of time
- * that a specified PowerEntity resided in each of its possible states,
- * the number of times that each state was entered, and a timestamp
- * corresponding to the last time that state was entered. Data is
- * accumulated starting from the last time the PowerEntity was reset.
- *
- * @param powerEntityId collection of IDs of PowerEntity(s) for which
- * residency data is requested. PowerEntity name to ID mapping may
- * be queried from getPowerEntityInfo(). To get state residency
- * data for all PowerEntity(s) pass an empty vector.
- * @return state residency data for each specified
- * PowerEntity that provides state residency data.
- */
- PowerEntityStateResidencyResult[] getPowerEntityStateResidencyData(in int[] powerEntityIds);
-
- /**
- * Rail information:
- * Reports information related to the rails being monitored.
- *
- * @return Information about monitored rails.
- */
- RailInfo[] getRailInfo();
-}
\ No newline at end of file
diff --git a/powerstats/aidl/android/hardware/powerstats/RailInfo.aidl b/powerstats/aidl/android/hardware/powerstats/RailInfo.aidl
deleted file mode 100644
index 4c05bfe..0000000
--- a/powerstats/aidl/android/hardware/powerstats/RailInfo.aidl
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.powerstats;
-
-@VintfStability
-parcelable RailInfo {
- /**
- * Index corresponding to the rail
- */
- int railIndex;
- /**
- * Name of the rail (opaque to the framework)
- */
- String railName;
- /**
- * Name of the subsystem to which this rail belongs (opaque to the framework)
- */
- String subsysName;
- /**
- * Hardware sampling rate in Hz
- */
- int samplingRateHz;
-}
-
diff --git a/powerstats/aidl/default/PowerStats.cpp b/powerstats/aidl/default/PowerStats.cpp
deleted file mode 100644
index 8d6a0ee..0000000
--- a/powerstats/aidl/default/PowerStats.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "PowerStats.h"
-
-#include <android-base/logging.h>
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace powerstats {
-
-ndk::ScopedAStatus PowerStats::getEnergyData(const std::vector<int32_t>& in_railIndices,
- std::vector<EnergyData>* _aidl_return) {
- (void)in_railIndices;
- (void)_aidl_return;
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus PowerStats::getPowerEntityInfo(std::vector<PowerEntityInfo>* _aidl_return) {
- (void)_aidl_return;
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus PowerStats::getPowerEntityStateResidencyData(
- const std::vector<int32_t>& in_powerEntityIds,
- std::vector<PowerEntityStateResidencyResult>* _aidl_return) {
- (void)in_powerEntityIds;
- (void)_aidl_return;
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus PowerStats::getRailInfo(std::vector<RailInfo>* _aidl_return) {
- (void)_aidl_return;
- return ndk::ScopedAStatus::ok();
-}
-
-} // namespace powerstats
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/powerstats/aidl/default/PowerStats.h b/powerstats/aidl/default/PowerStats.h
deleted file mode 100644
index 49240cb..0000000
--- a/powerstats/aidl/default/PowerStats.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <aidl/android/hardware/powerstats/BnPowerStats.h>
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace powerstats {
-
-class PowerStats : public BnPowerStats {
- public:
- PowerStats() = default;
- ndk::ScopedAStatus getEnergyData(const std::vector<int32_t>& in_railIndices,
- std::vector<EnergyData>* _aidl_return) override;
- ndk::ScopedAStatus getPowerEntityInfo(std::vector<PowerEntityInfo>* _aidl_return) override;
- ndk::ScopedAStatus getPowerEntityStateResidencyData(
- const std::vector<int32_t>& in_powerEntityIds,
- std::vector<PowerEntityStateResidencyResult>* _aidl_return) override;
- ndk::ScopedAStatus getRailInfo(std::vector<RailInfo>* _aidl_return) override;
-};
-
-} // namespace powerstats
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/powerstats/aidl/default/powerstats-default.rc b/powerstats/aidl/default/powerstats-default.rc
deleted file mode 100644
index 9b04be3..0000000
--- a/powerstats/aidl/default/powerstats-default.rc
+++ /dev/null
@@ -1,4 +0,0 @@
-service vendor.powerstats-default /vendor/bin/hw/android.hardware.powerstats-service.example
- class hal
- user system
- group system
diff --git a/radio/1.0/vts/functional/sap_hidl_hal_api.cpp b/radio/1.0/vts/functional/sap_hidl_hal_api.cpp
index 6c7870d..5359a87 100644
--- a/radio/1.0/vts/functional/sap_hidl_hal_api.cpp
+++ b/radio/1.0/vts/functional/sap_hidl_hal_api.cpp
@@ -61,10 +61,11 @@
EXPECT_EQ(std::cv_status::no_timeout, wait());
EXPECT_EQ(sapCb->sapResponseToken, token);
- ASSERT_TRUE(
- CheckAnyOfErrors(sapCb->sapResultCode,
- {SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_ALREADY_POWERED_OFF,
- SapResultCode::CARD_NOT_ACCESSSIBLE, SapResultCode::CARD_REMOVED}));
+ ASSERT_TRUE(CheckAnyOfErrors(
+ sapCb->sapResultCode,
+ {SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_ALREADY_POWERED_OFF,
+ SapResultCode::CARD_NOT_ACCESSSIBLE, SapResultCode::CARD_REMOVED,
+ SapResultCode::SUCCESS}));
LOG(DEBUG) << "apduReq finished";
}
@@ -79,10 +80,10 @@
EXPECT_EQ(std::cv_status::no_timeout, wait());
EXPECT_EQ(sapCb->sapResponseToken, token);
- ASSERT_TRUE(
- CheckAnyOfErrors(sapCb->sapResultCode,
- {SapResultCode::GENERIC_FAILURE, SapResultCode::DATA_NOT_AVAILABLE,
- SapResultCode::CARD_ALREADY_POWERED_OFF, SapResultCode::CARD_REMOVED}));
+ ASSERT_TRUE(CheckAnyOfErrors(sapCb->sapResultCode,
+ {SapResultCode::GENERIC_FAILURE, SapResultCode::DATA_NOT_AVAILABLE,
+ SapResultCode::CARD_ALREADY_POWERED_OFF,
+ SapResultCode::CARD_REMOVED, SapResultCode::SUCCESS}));
LOG(DEBUG) << "transferAtrReq finished";
}
@@ -98,10 +99,11 @@
EXPECT_EQ(std::cv_status::no_timeout, wait());
EXPECT_EQ(sapCb->sapResponseToken, token);
- ASSERT_TRUE(CheckAnyOfErrors(
- sapCb->sapResultCode, {SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_NOT_ACCESSSIBLE,
- SapResultCode::CARD_ALREADY_POWERED_OFF, SapResultCode::CARD_REMOVED,
- SapResultCode::CARD_ALREADY_POWERED_ON}));
+ ASSERT_TRUE(
+ CheckAnyOfErrors(sapCb->sapResultCode,
+ {SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_NOT_ACCESSSIBLE,
+ SapResultCode::CARD_ALREADY_POWERED_OFF, SapResultCode::CARD_REMOVED,
+ SapResultCode::CARD_ALREADY_POWERED_ON, SapResultCode::SUCCESS}));
LOG(DEBUG) << "powerReq finished";
}
@@ -117,9 +119,10 @@
EXPECT_EQ(sapCb->sapResponseToken, token);
ASSERT_TRUE(
- CheckAnyOfErrors(sapCb->sapResultCode,
- {SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_NOT_ACCESSSIBLE,
- SapResultCode::CARD_ALREADY_POWERED_OFF, SapResultCode::CARD_REMOVED}));
+ CheckAnyOfErrors(sapCb->sapResultCode,
+ {SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_NOT_ACCESSSIBLE,
+ SapResultCode::CARD_ALREADY_POWERED_OFF, SapResultCode::CARD_REMOVED,
+ SapResultCode::SUCCESS}));
LOG(DEBUG) << "resetSimReq finished";
}
@@ -134,8 +137,9 @@
EXPECT_EQ(std::cv_status::no_timeout, wait());
EXPECT_EQ(sapCb->sapResponseToken, token);
- ASSERT_TRUE(CheckAnyOfErrors(
- sapCb->sapResultCode, {SapResultCode::GENERIC_FAILURE, SapResultCode::DATA_NOT_AVAILABLE}));
+ ASSERT_TRUE(CheckAnyOfErrors(sapCb->sapResultCode,
+ {SapResultCode::GENERIC_FAILURE, SapResultCode::DATA_NOT_AVAILABLE,
+ SapResultCode::SUCCESS}));
LOG(DEBUG) << "transferCardReaderStatusReq finished";
}
@@ -151,6 +155,7 @@
EXPECT_EQ(std::cv_status::no_timeout, wait());
EXPECT_EQ(sapCb->sapResponseToken, token);
- EXPECT_EQ(SapResultCode::NOT_SUPPORTED, sapCb->sapResultCode);
+ ASSERT_TRUE(CheckAnyOfErrors(sapCb->sapResultCode,
+ {SapResultCode::NOT_SUPPORTED, SapResultCode::SUCCESS}));
LOG(DEBUG) << "setTransferProtocolReq finished";
}
diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal
index c3f15f4..ca40a17 100644
--- a/radio/1.6/IRadio.hal
+++ b/radio/1.6/IRadio.hal
@@ -16,6 +16,9 @@
package android.hardware.radio@1.6;
+
+import @1.0::CdmaSmsMessage;
+import @1.0::GsmSmsMessage;
import @1.2::DataRequestReason;
import @1.5::IRadio;
import @1.5::AccessNetwork;
@@ -32,6 +35,36 @@
*/
interface IRadio extends @1.5::IRadio {
/**
+ * Toggle radio on and off (for "airplane" mode)
+ * If the radio is turned off/on the radio modem subsystem
+ * is expected return to an initialized state. For instance,
+ * any voice and data calls must be terminated and all associated
+ * lists emptied.
+ *
+ * When setting radio power on to exit from airplane mode to place an emergency call on this
+ * logical modem, powerOn, forEmergencyCall and preferredForEmergencyCall must be true. In
+ * this case, this modem is optimized to scan only emergency call bands, until:
+ * 1) Emergency call is completed; or
+ * 2) Another setRadioPower_1_5 is issued with forEmergencyCall being false or
+ * preferredForEmergencyCall being false; or
+ * 3) Timeout after 30 seconds if dial or emergencyDial is not called.
+ * Once one of these conditions is reached, the modem should move into normal operation.
+ *
+ * @param serial Serial number of request.
+ * @param powerOn To turn on radio -> on = true, to turn off radio -> on = false.
+ * @param forEmergencyCall To indication to radio if this request is due to emergency call.
+ * No effect if powerOn is false.
+ * @param preferredForEmergencyCall indicate whether the following emergency call will be sent
+ * on this modem or not. No effect if forEmergencyCall is false, or powerOn is false.
+ *
+ * Response callback is IRadioConfigResponse. setRadioPowerResponse_1_6.
+
+ * Note this API is the same as the 1.5
+ */
+ oneway setRadioPower_1_6(int32_t serial, bool powerOn, bool forEmergencyCall,
+ bool preferredForEmergencyCall);
+
+ /**
* Returns the data call list. An entry is added when a setupDataCall() is issued and removed
* on a deactivateDataCall(). The list is emptied when setRadioPower() off/on issued or when
* the vendor HAL or modem crashes.
@@ -87,4 +120,89 @@
oneway setupDataCall_1_6(int32_t serial, AccessNetwork accessNetwork,
DataProfileInfo dataProfileInfo, bool roamingAllowed,
DataRequestReason reason, vec<LinkAddress> addresses, vec<string> dnses);
+
+ /**
+ * Send an SMS message
+ *
+ * @param serial Serial number of request.
+ * @param message GsmSmsMessage as defined in types.hal
+ *
+ * Response function is IRadioResponse.sendSmsResponse_1_6()
+ *
+ * Note this API is the same as the 1.0
+ *
+ * Based on the return error, caller decides to resend if sending sms
+ * fails. RadioError:SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332)
+ * and RadioError:GENERIC_FAILURE means no retry (i.e. error cause is 500)
+ */
+ oneway sendSms_1_6(int32_t serial, GsmSmsMessage message);
+
+ /**
+ * Send an SMS message. Identical to sendSms_1_6,
+ * except that more messages are expected to be sent soon. If possible,
+ * keep SMS relay protocol link open (eg TS 27.005 AT+CMMS command)
+ *
+ * @param serial Serial number of request.
+ * @param message GsmSmsMessage as defined in types.hal
+ *
+ * Response function is IRadioResponse.sendSMSExpectMoreResponse_1_6()
+ *
+ * Note this API is the same as the 1.0
+ *
+ * Based on the return error, caller decides to resend if sending sms
+ * fails. RadioError:SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332)
+ * and RadioError:GENERIC_FAILURE means no retry (i.e. error cause is 500)
+ */
+ oneway sendSMSExpectMore_1_6(int32_t serial, GsmSmsMessage message);
+
+ /**
+ * Send a CDMA SMS message
+ *
+ * @param serial Serial number of request.
+ * @param sms Cdma Sms to be sent described by CdmaSmsMessage in types.hal
+ *
+ * Response callback is IRadioResponse.sendCdmaSmsResponse_1_6()
+ *
+ * Note this API is the same as the 1.0
+ *
+ */
+ oneway sendCdmaSms_1_6(int32_t serial, CdmaSmsMessage sms);
+
+ /**
+ * Send an SMS message. Identical to sendCdmaSms_1_6,
+ * except that more messages are expected to be sent soon.
+ *
+ * @param serial Serial number of request.
+ * @param sms Cdma Sms to be sent described by CdmaSmsMessage in types.hal
+ *
+ * Response callback is IRadioResponse.sendCdmaSMSExpectMoreResponse_1_6()
+ *
+ * Note this API is the same as the 1.5
+ *
+ */
+ oneway sendCdmaSmsExpectMore_1_6(int32_t serial, CdmaSmsMessage sms);
+
+ /**
+ * Enable or disable E-UTRA-NR dual connectivity. If disabled then UE will not connect
+ * to secondary carrier.
+ *
+ * @param serial Serial number of request.
+ * @param nrDualConnectivityState expected NR dual connectivity state.
+ * 1. Enable NR dual connectivity {NrDualConnectivityState:ENABLE}
+ * 2. Disable NR dual connectivity {NrDualConnectivityState:DISABLE}
+ * 3. Disable NR dual connectivity and force secondary cell to be released
+ * {NrDualConnectivityState:DISABLE_IMMEDIATE}
+
+ * Response callback is IRadioResponse.enableNRDualConnectivityResponse()
+ */
+ oneway enableNrDualConnectivity(int32_t serial,
+ NrDualConnectivityState nrDualConnectivityState);
+
+ /**
+ * Is E-UTRA-NR Dual Connectivity enabled
+ *
+ * @param serial Serial number of request.
+ * Response callback is IRadioResponse.isNRDualConnectivityEnabledResponse()
+ */
+ oneway isNrDualConnectivityEnabled(int32_t serial);
};
diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal
index e91b9c1..4ff7e47 100644
--- a/radio/1.6/IRadioResponse.hal
+++ b/radio/1.6/IRadioResponse.hal
@@ -16,7 +16,8 @@
package android.hardware.radio@1.6;
-import @1.0::RadioResponseInfo;
+import @1.0::SendSmsResult;
+import @1.6::RadioResponseInfo;
import @1.5::IRadioResponse;
import @1.6::SetupDataCallResult;
@@ -26,6 +27,18 @@
interface IRadioResponse extends @1.5::IRadioResponse {
/**
* @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:INTERNAL_ERR
+ * RadioError:INVALID_ARGUMENTS
+ * RadioError:RF_HARDWARE_ISSUE
+ * RadioError:NO_RF_CALIBRATION_INFO
+ */
+ oneway setRadioPowerResponse_1_6(RadioResponseInfo info);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
* @param dcResponse SetupDataCallResult defined in types.hal
*
* Valid errors returned:
@@ -54,4 +67,159 @@
* RadioError:SIM_ABSENT
*/
oneway getDataCallListResponse_1_6(RadioResponseInfo info, vec<SetupDataCallResult> dcResponse);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ * @param sms Response to sms sent as defined by SendSmsResult in types.hal
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:SMS_SEND_FAIL_RETRY
+ * RadioError:NETWORK_REJECT
+ * RadioError:INVALID_STATE
+ * RadioError:INVALID_ARGUMENTS
+ * RadioError:NO_MEMORY
+ * RadioError:REQUEST_RATE_LIMITED
+ * RadioError:INVALID_SMS_FORMAT
+ * RadioError:SYSTEM_ERR
+ * RadioError:ENCODING_ERR
+ * RadioError:INVALID_SMSC_ADDRESS
+ * RadioError:MODEM_ERR
+ * RadioError:NETWORK_ERR
+ * RadioError:INTERNAL_ERR
+ * RadioError:REQUEST_NOT_SUPPORTED
+ * RadioError:INVALID_MODEM_STATE
+ * RadioError:NETWORK_NOT_READY
+ * RadioError:OPERATION_NOT_ALLOWED
+ * RadioError:NO_RESOURCES
+ * RadioError:CANCELLED
+ * RadioError:SIM_ABSENT
+ * RadioError:ACCESS_BARRED
+ * RadioError:BLOCKED_DUE_TO_CALL
+ */
+ oneway sendSmsResponse_1_6(RadioResponseInfo info, SendSmsResult sms);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ * @param sms Response to sms sent as defined by SendSmsResult in types.hal
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:SMS_SEND_FAIL_RETRY
+ * RadioError:NETWORK_REJECT
+ * RadioError:INVALID_STATE
+ * RadioError:INVALID_ARGUMENTS
+ * RadioError:NO_MEMORY
+ * RadioError:REQUEST_RATE_LIMITED
+ * RadioError:INVALID_SMS_FORMAT
+ * RadioError:SYSTEM_ERR
+ * RadioError:FDN_CHECK_FAILURE
+ * RadioError:ENCODING_ERR
+ * RadioError:INVALID_SMSC_ADDRESS
+ * RadioError:MODEM_ERR
+ * RadioError:NETWORK_ERR
+ * RadioError:INTERNAL_ERR
+ * RadioError:REQUEST_NOT_SUPPORTED
+ * RadioError:INVALID_MODEM_STATE
+ * RadioError:NETWORK_NOT_READY
+ * RadioError:OPERATION_NOT_ALLOWED
+ * RadioError:NO_RESOURCES
+ * RadioError:CANCELLED
+ * RadioError:SIM_ABSENT
+ * RadioError:ACCESS_BARRED
+ * RadioError:BLOCKED_DUE_TO_CALL
+ */
+ oneway sendSMSExpectMoreResponse_1_6(RadioResponseInfo info, SendSmsResult sms);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ * @param sms Sms result struct as defined by SendSmsResult in types.hal
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INVALID_ARGUMENTS
+ * RadioError:SMS_SEND_FAIL_RETRY
+ * RadioError:NETWORK_REJECT
+ * RadioError:INVALID_STATE
+ * RadioError:NO_MEMORY
+ * RadioError:REQUEST_RATE_LIMITED
+ * RadioError:INVALID_SMS_FORMAT
+ * RadioError:SYSTEM_ERR
+ * RadioError:FDN_CHECK_FAILURE
+ * RadioError:MODEM_ERR
+ * RadioError:NETWORK_ERR
+ * RadioError:ENCODING_ERR
+ * RadioError:INVALID_SMSC_ADDRESS
+ * RadioError:INTERNAL_ERR
+ * RadioError:SYSTEM_ERR
+ * RadioError:REQUEST_NOT_SUPPORTED
+ * RadioError:OPERATION_NOT_ALLOWED
+ * RadioError:ENCODING_ERR
+ * RadioError:NO_RESOURCES
+ * RadioError:CANCELLED
+ * RadioError:SIM_ABSENT
+ * RadioError:SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED
+ * RadioError:ACCESS_BARRED
+ * RadioError:BLOCKED_DUE_TO_CALL
+ */
+ oneway sendCdmaSmsResponse_1_6(RadioResponseInfo info, SendSmsResult sms);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ * @param sms Response to sms sent as defined by SendSmsResult in types.hal
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:SMS_SEND_FAIL_RETRY
+ * RadioError:NETWORK_REJECT
+ * RadioError:INVALID_STATE
+ * RadioError:INVALID_ARGUMENTS
+ * RadioError:NO_MEMORY
+ * RadioError:REQUEST_RATE_LIMITED
+ * RadioError:INVALID_SMS_FORMAT
+ * RadioError:SYSTEM_ERR
+ * RadioError:FDN_CHECK_FAILURE
+ * RadioError:ENCODING_ERR
+ * RadioError:INVALID_SMSC_ADDRESS
+ * RadioError:MODEM_ERR
+ * RadioError:NETWORK_ERR
+ * RadioError:INTERNAL_ERR
+ * RadioError:REQUEST_NOT_SUPPORTED
+ * RadioError:INVALID_MODEM_STATE
+ * RadioError:NETWORK_NOT_READY
+ * RadioError:OPERATION_NOT_ALLOWED
+ * RadioError:NO_RESOURCES
+ * RadioError:CANCELLED
+ * RadioError:SIM_ABSENT
+ * RadioError:SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED
+ * RadioError:ACCESS_BARRED
+ * RadioError:BLOCKED_DUE_TO_CALL
+ */
+ oneway sendCdmaSmsExpectMoreResponse_1_6(RadioResponseInfo info, SendSmsResult sms);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ */
+ oneway enableNrDualConnectivityResponse(RadioResponseInfo info);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * @param isEnabled Indicates whether NR dual connectivity is enabled or not, True if enabled
+ * else false.
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ */
+ oneway isNrDualConnectivityEnabledResponse(RadioResponseInfo info, bool isEnabled);
};
diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal
index 4bd3cd6..2e2e401 100644
--- a/radio/1.6/types.hal
+++ b/radio/1.6/types.hal
@@ -16,7 +16,12 @@
package android.hardware.radio@1.6;
-import @1.5::SetupDataCallResult;
+import @1.0::RadioError;
+import @1.0::RadioResponseType;
+import @1.4::DataCallFailCause;
+import @1.4::DataConnActiveStatus;
+import @1.4::PdpProtocolType;
+import @1.5::LinkAddress;
import android.hidl.safe_union@1.0::Monostate;
@@ -98,6 +103,44 @@
MAX = 65535
};
+enum RadioError : @1.0::RadioError {
+ /** 1X voice and SMS are not allowed simulteneously. */
+ SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED = 67,
+
+ /** Access is barred. */
+ ACCESS_BARRED = 68,
+
+ /**
+ * SMS is blocked due to call control, e.g., resource unavailable
+ * in the SMR entity.
+ */
+ BLOCKED_DUE_TO_CALL = 69,
+
+ /**
+ * Returned from setRadioPowerResponse when detecting RF HW issues. Some RF
+ * Front-End(RFFE) components like antenna are considered critical for modem
+ * to provide telephony service. This RadioError is used when modem detect
+ * such RFFE problem.
+ */
+ RF_HARDWARE_ISSUE = 70,
+
+ /**
+ * Returned from setRadioPowerResponse when detecting no RF calibration
+ * issue. Unlike RF_HARDWARE_ISSUE, this is a SW problem and no HW repair is
+ * needed.
+ */
+ NO_RF_CALIBRATION_INFO = 71,
+};
+
+/**
+ * Overwritten from @1.0::RadioResponseInfo in order to update the RadioError to 1.6 version.
+ */
+struct RadioResponseInfo {
+ RadioResponseType type; // Response type
+ int32_t serial; // Serial number of the request
+ RadioError error; // Response error
+};
+
/**
* Defines range of ports. start and end are the first and last port numbers
* (inclusive) in the range. Both start and end are in QosPortRange.MIN to
@@ -200,8 +243,72 @@
NO_FALLBACK_RETRY_SETUP_NORMAL = 3
};
+/**
+ * Overwritten from @1.5::SetupDataCallResult in order to change the suggestedRetryTime
+ * to 64-bit value. In the future, this must be extended instead of overwritten.
+ * Also added defaultQos, qosSessions, and handoverFailureMode in this version.
+ */
struct SetupDataCallResult {
- @1.5::SetupDataCallResult base;
+ /** Data call fail cause. DataCallFailCause.NONE if no error. */
+ DataCallFailCause cause;
+
+ /**
+ * If cause is not DataCallFailCause.NONE, this field indicates the network suggested data
+ * retry back-off time in milliseconds. Negative value indicates network does not give any
+ * suggestion. 0 indicates retry should be performed immediately. 0x7fffffffffffffff indicates
+ * the device should not retry data setup anymore.
+ */
+ uint64_t suggestedRetryTime;
+
+ /** Context ID, uniquely identifies this data connection. */
+ int32_t cid;
+
+ /** Data connection active status. */
+ DataConnActiveStatus active;
+
+ /**
+ * PDP protocol type. If cause is DataCallFailCause.ONLY_SINGLE_BEARER_ALLOWED, this is the
+ * protocol type supported, such as "IP" or "IPV6".
+ */
+ PdpProtocolType type;
+
+ /** The network interface name. */
+ string ifname;
+
+ /**
+ * List of link address.
+ */
+ vec<LinkAddress> addresses;
+
+ /**
+ * List of DNS server addresses, e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". Empty if no dns
+ * server addresses returned.
+ */
+ vec<string> dnses;
+
+ /**
+ * List of default gateway addresses, e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1".
+ * When empty, the addresses represent point to point connections.
+ */
+ vec<string> gateways;
+
+ /**
+ * List of P-CSCF(Proxy Call State Control Function) addresses via PCO(Protocol Configuration
+ * Option), e.g., "2001:db8::1 2001:db8::2 2001:db8::3". Empty if not IMS client.
+ */
+ vec<string> pcscf;
+
+ /**
+ * MTU received from network for IPv4.
+ * Value <= 0 means network has either not sent a value or sent an invalid value.
+ */
+ int32_t mtuV4;
+
+ /**
+ * MTU received from network for IPv6.
+ * Value <= 0 means network has either not sent a value or sent an invalid value.
+ */
+ int32_t mtuV6;
/** Default bearer QoS. Applicable to LTE and NR */
Qos defaultQos;
@@ -215,3 +322,24 @@
/** Specifies the fallback mode on an IWLAN handover failure. */
HandoverFailureMode handoverFailureMode;
};
+
+/**
+ * NR Dual connectivity state
+ */
+enum NrDualConnectivityState: int32_t {
+ /**
+ * Enable NR dual connectivity. Enabled state does not mean dual connectivity
+ * is active. It means device is allowed to connect to both primary and secondary.
+ */
+ ENABLE = 1,
+ /**
+ * Disable NR dual connectivity. Disabled state does not mean secondary cell is released.
+ * Modem will release it only if current bearer is released to avoid radio link failure.
+ */
+ DISABLE = 2,
+ /**
+ * Disable NR dual connectivity and force secondary cell to be released if dual connectivity
+ * was active. This may result in radio link failure.
+ */
+ DISABLE_IMMEDIATE= 3,
+};
diff --git a/radio/1.6/vts/functional/Android.bp b/radio/1.6/vts/functional/Android.bp
index a6cfc6f..db90f88 100644
--- a/radio/1.6/vts/functional/Android.bp
+++ b/radio/1.6/vts/functional/Android.bp
@@ -23,6 +23,7 @@
"radio_response.cpp",
"radio_indication.cpp",
"VtsHalRadioV1_6TargetTest.cpp",
+ "vts_test_util_v1_6.cpp",
],
static_libs: [
"RadioVtsTestUtilBase",
@@ -37,5 +38,8 @@
"android.hardware.radio.config@1.1",
],
header_libs: ["radio.util.header@1.0"],
- test_suites: ["general-tests", "vts"]
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
}
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
index 0bfce4d..01236c6 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
@@ -63,14 +63,235 @@
EXPECT_EQ(std::cv_status::no_timeout, wait());
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+ if (cardStatus.base.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_6->rspInfo.error,
+ {::android::hardware::radio::V1_6::RadioError::SIM_ABSENT,
+ ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE,
+ ::android::hardware::radio::V1_6::RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
+ } else if (cardStatus.base.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_6->rspInfo.error,
+ {::android::hardware::radio::V1_6::RadioError::NONE,
+ ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE,
+ ::android::hardware::radio::V1_6::RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
+ }
+}
+
+/*
+ * Test IRadio_1_6.sendSms() for the response returned.
+ */
+TEST_P(RadioHidlTest_v1_6, sendSms_1_6) {
+ LOG(DEBUG) << "sendSms";
+ serial = GetRandomSerialNumber();
+ GsmSmsMessage msg;
+ msg.smscPdu = "";
+ msg.pdu = "01000b916105770203f3000006d4f29c3e9b01";
+
+ radio_v1_6->sendSms(serial, msg);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
if (cardStatus.base.base.base.cardState == CardState::ABSENT) {
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error,
- {RadioError::SIM_ABSENT, RadioError::RADIO_NOT_AVAILABLE,
- RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
- } else if (cardStatus.base.base.base.cardState == CardState::PRESENT) {
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error,
- {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
- RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_6->rspInfo.error,
+ {::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS,
+ ::android::hardware::radio::V1_6::RadioError::INVALID_STATE,
+ ::android::hardware::radio::V1_6::RadioError::SIM_ABSENT},
+ CHECK_GENERAL_ERROR));
+ EXPECT_EQ(0, radioRsp_v1_6->sendSmsResult.errorCode);
}
+ LOG(DEBUG) << "sendSms finished";
+}
+
+/*
+ * Test IRadio_1_6.sendSMSExpectMore() for the response returned.
+ */
+TEST_P(RadioHidlTest_v1_6, sendSMSExpectMore_1_6) {
+ LOG(DEBUG) << "sendSMSExpectMore";
+ serial = GetRandomSerialNumber();
+ GsmSmsMessage msg;
+ msg.smscPdu = "";
+ msg.pdu = "01000b916105770203f3000006d4f29c3e9b01";
+
+ radio_v1_6->sendSMSExpectMore(serial, msg);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+
+ if (cardStatus.base.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_6->rspInfo.error,
+ {::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS,
+ ::android::hardware::radio::V1_6::RadioError::INVALID_STATE,
+ ::android::hardware::radio::V1_6::RadioError::SIM_ABSENT},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "sendSMSExpectMore finished";
+}
+
+/*
+ * Test IRadio_1_6.sendCdmaSms() for the response returned.
+ */
+TEST_P(RadioHidlTest_v1_6, sendCdmaSms_1_6) {
+ LOG(DEBUG) << "sendCdmaSms";
+ serial = GetRandomSerialNumber();
+
+ // Create a CdmaSmsAddress
+ CdmaSmsAddress cdmaSmsAddress;
+ cdmaSmsAddress.digitMode = CdmaSmsDigitMode::FOUR_BIT;
+ cdmaSmsAddress.numberMode = CdmaSmsNumberMode::NOT_DATA_NETWORK;
+ cdmaSmsAddress.numberType = CdmaSmsNumberType::UNKNOWN;
+ cdmaSmsAddress.numberPlan = CdmaSmsNumberPlan::UNKNOWN;
+ cdmaSmsAddress.digits = (std::vector<uint8_t>){11, 1, 6, 5, 10, 7, 7, 2, 10, 3, 10, 3};
+
+ // Create a CdmaSmsSubAddress
+ CdmaSmsSubaddress cdmaSmsSubaddress;
+ cdmaSmsSubaddress.subaddressType = CdmaSmsSubaddressType::NSAP;
+ cdmaSmsSubaddress.odd = false;
+ cdmaSmsSubaddress.digits = (std::vector<uint8_t>){};
+
+ // Create a CdmaSmsMessage
+ android::hardware::radio::V1_0::CdmaSmsMessage cdmaSmsMessage;
+ cdmaSmsMessage.teleserviceId = 4098;
+ cdmaSmsMessage.isServicePresent = false;
+ cdmaSmsMessage.serviceCategory = 0;
+ cdmaSmsMessage.address = cdmaSmsAddress;
+ cdmaSmsMessage.subAddress = cdmaSmsSubaddress;
+ cdmaSmsMessage.bearerData =
+ (std::vector<uint8_t>){15, 0, 3, 32, 3, 16, 1, 8, 16, 53, 76, 68, 6, 51, 106, 0};
+
+ radio_v1_6->sendCdmaSms(serial, cdmaSmsMessage);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+
+ if (cardStatus.base.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_6->rspInfo.error,
+ {::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS,
+ ::android::hardware::radio::V1_6::RadioError::INVALID_STATE,
+ ::android::hardware::radio::V1_6::RadioError::SIM_ABSENT},
+ CHECK_GENERAL_ERROR));
+ }
+ LOG(DEBUG) << "sendCdmaSms finished";
+}
+
+/*
+ * Test IRadio_1_6.sendCdmaSmsExpectMore() for the response returned.
+ */
+TEST_P(RadioHidlTest_v1_6, sendCdmaSmsExpectMore_1_6) {
+ serial = GetRandomSerialNumber();
+
+ // Create a CdmaSmsAddress
+ CdmaSmsAddress cdmaSmsAddress;
+ cdmaSmsAddress.digitMode = CdmaSmsDigitMode::FOUR_BIT;
+ cdmaSmsAddress.numberMode = CdmaSmsNumberMode::NOT_DATA_NETWORK;
+ cdmaSmsAddress.numberType = CdmaSmsNumberType::UNKNOWN;
+ cdmaSmsAddress.numberPlan = CdmaSmsNumberPlan::UNKNOWN;
+ cdmaSmsAddress.digits = (std::vector<uint8_t>){11, 1, 6, 5, 10, 7, 7, 2, 10, 3, 10, 3};
+
+ // Create a CdmaSmsSubAddress
+ CdmaSmsSubaddress cdmaSmsSubaddress;
+ cdmaSmsSubaddress.subaddressType = CdmaSmsSubaddressType::NSAP;
+ cdmaSmsSubaddress.odd = false;
+ cdmaSmsSubaddress.digits = (std::vector<uint8_t>){};
+
+ // Create a CdmaSmsMessage
+ android::hardware::radio::V1_0::CdmaSmsMessage cdmaSmsMessage;
+ cdmaSmsMessage.teleserviceId = 4098;
+ cdmaSmsMessage.isServicePresent = false;
+ cdmaSmsMessage.serviceCategory = 0;
+ cdmaSmsMessage.address = cdmaSmsAddress;
+ cdmaSmsMessage.subAddress = cdmaSmsSubaddress;
+ cdmaSmsMessage.bearerData =
+ (std::vector<uint8_t>){15, 0, 3, 32, 3, 16, 1, 8, 16, 53, 76, 68, 6, 51, 106, 0};
+
+ radio_v1_6->sendCdmaSmsExpectMore(serial, cdmaSmsMessage);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+
+ if (cardStatus.base.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_6->rspInfo.error,
+ {::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS,
+ ::android::hardware::radio::V1_6::RadioError::INVALID_STATE,
+ ::android::hardware::radio::V1_6::RadioError::SIM_ABSENT},
+ CHECK_GENERAL_ERROR));
+ }
+}
+
+/*
+ * Test IRadio.setRadioPower_1_6() for the response returned by
+ * IRadio.setRadioPowerResponse_1_6().
+ */
+TEST_P(RadioHidlTest_v1_6, setRadioPower_1_6_emergencyCall_cancelled) {
+ // Set radio power to off.
+ serial = GetRandomSerialNumber();
+ radio_v1_6->setRadioPower_1_6(serial, false, false, false);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+ EXPECT_EQ(::android::hardware::radio::V1_6::RadioError::NONE, radioRsp_v1_6->rspInfo.error);
+
+ // Set radio power to on with forEmergencyCall being true. This should put modem to only scan
+ // emergency call bands.
+ serial = GetRandomSerialNumber();
+ radio_v1_6->setRadioPower_1_6(serial, true, true, true);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+ EXPECT_EQ(::android::hardware::radio::V1_6::RadioError::NONE, radioRsp_v1_6->rspInfo.error);
+
+ // Set radio power to on with forEmergencyCall being false. This should put modem in regular
+ // operation modem.
+ serial = GetRandomSerialNumber();
+ radio_v1_6->setRadioPower_1_6(serial, true, false, false);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+ EXPECT_EQ(::android::hardware::radio::V1_6::RadioError::NONE, radioRsp_v1_6->rspInfo.error);
+}
+
+/*
+ * Test IRadio.enableNrDualConnectivity() for the response returned.
+ */
+TEST_P(RadioHidlTest_v1_6, enableNrDualConnectivity) {
+ serial = GetRandomSerialNumber();
+
+ Return<void> res =
+ radio_v1_6->enableNrDualConnectivity(serial, NrDualConnectivityState::DISABLE);
+ ASSERT_OK(res);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error,
+ {::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE,
+ ::android::hardware::radio::V1_6::RadioError::INTERNAL_ERR,
+ ::android::hardware::radio::V1_6::RadioError::NONE}));
+}
+
+/*
+ * Test IRadio.isNrDualConnectivityEnabled() for the response returned.
+ */
+TEST_P(RadioHidlTest_v1_6, isNrDualConnectivityEnabled) {
+ serial = GetRandomSerialNumber();
+
+ Return<void> res = radio_v1_6->isNrDualConnectivityEnabled(serial);
+ ASSERT_OK(res);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error,
+ {::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE,
+ ::android::hardware::radio::V1_6::RadioError::INTERNAL_ERR,
+ ::android::hardware::radio::V1_6::RadioError::NONE}));
}
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
index 114fd1a..79c3cde 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
@@ -30,10 +30,11 @@
radio_v1_6->setResponseFunctions(radioRsp_v1_6, radioInd_v1_6);
- getDataCallList();
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
- EXPECT_EQ(RadioError::NONE, radioRsp_v1_6->rspInfo.error);
+ updateSimCardStatus();
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo_v1_0.type);
+ EXPECT_EQ(serial, radioRsp_v1_6->rspInfo_v1_0.serial);
+ EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE,
+ radioRsp_v1_6->rspInfo_v1_0.error);
sp<::android::hardware::radio::config::V1_1::IRadioConfig> radioConfig =
::android::hardware::radio::config::V1_1::IRadioConfig::getService();
@@ -73,6 +74,12 @@
return status;
}
+void RadioHidlTest_v1_6::updateSimCardStatus() {
+ serial = GetRandomSerialNumber();
+ radio_v1_6->getIccCardStatus(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+}
+
void RadioHidlTest_v1_6::getDataCallList() {
serial = GetRandomSerialNumber();
radio_v1_6->getDataCallList_1_6(serial);
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
index 95a2d09..784bcd9 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
+++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
@@ -33,7 +33,7 @@
#include <android/hardware/radio/1.6/IRadioResponse.h>
#include <android/hardware/radio/1.6/types.h>
-#include "vts_test_util.h"
+#include "vts_test_util_v1_6.h"
using namespace ::android::hardware::radio::V1_6;
using namespace ::android::hardware::radio::V1_5;
@@ -66,14 +66,19 @@
public:
hidl_vec<RadioBandMode> radioBandModes;
- RadioResponseInfo rspInfo;
+ ::android::hardware::radio::V1_0::RadioResponseInfo rspInfo_v1_0;
+ ::android::hardware::radio::V1_6::RadioResponseInfo rspInfo;
// Call
hidl_vec<::android::hardware::radio::V1_2::Call> currentCalls;
+ // Sms
+ SendSmsResult sendSmsResult;
+
// Modem
bool isModemEnabled;
bool enableModemResponseToggle;
+ bool isNRDualConnectivityEnabled;
::android::hardware::hidl_bitfield<::android::hardware::radio::V1_4::RadioAccessFamily>
networkTypeBitmapResponse;
@@ -99,516 +104,673 @@
virtual ~RadioResponse_v1_6() = default;
Return<void> getIccCardStatusResponse(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::radio::V1_0::CardStatus& cardStatus);
- Return<void> supplyIccPinForAppResponse(const RadioResponseInfo& info,
- int32_t remainingRetries);
+ Return<void> supplyIccPinForAppResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ int32_t remainingRetries);
- Return<void> supplyIccPukForAppResponse(const RadioResponseInfo& info,
- int32_t remainingRetries);
+ Return<void> supplyIccPukForAppResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ int32_t remainingRetries);
- Return<void> supplyIccPin2ForAppResponse(const RadioResponseInfo& info,
- int32_t remainingRetries);
+ Return<void> supplyIccPin2ForAppResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ int32_t remainingRetries);
- Return<void> supplyIccPuk2ForAppResponse(const RadioResponseInfo& info,
- int32_t remainingRetries);
+ Return<void> supplyIccPuk2ForAppResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ int32_t remainingRetries);
- Return<void> changeIccPinForAppResponse(const RadioResponseInfo& info,
- int32_t remainingRetries);
+ Return<void> changeIccPinForAppResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ int32_t remainingRetries);
- Return<void> changeIccPin2ForAppResponse(const RadioResponseInfo& info,
- int32_t remainingRetries);
+ Return<void> changeIccPin2ForAppResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ int32_t remainingRetries);
- Return<void> supplyNetworkDepersonalizationResponse(const RadioResponseInfo& info,
- int32_t remainingRetries);
+ Return<void> supplyNetworkDepersonalizationResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ int32_t remainingRetries);
Return<void> getCurrentCallsResponse(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::hidl_vec<::android::hardware::radio::V1_0::Call>& calls);
- Return<void> dialResponse(const RadioResponseInfo& info);
+ Return<void> dialResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> getIMSIForAppResponse(const RadioResponseInfo& info,
- const ::android::hardware::hidl_string& imsi);
+ Return<void> getIMSIForAppResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const ::android::hardware::hidl_string& imsi);
- Return<void> hangupConnectionResponse(const RadioResponseInfo& info);
+ Return<void> hangupConnectionResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> hangupWaitingOrBackgroundResponse(const RadioResponseInfo& info);
+ Return<void> hangupWaitingOrBackgroundResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> hangupForegroundResumeBackgroundResponse(const RadioResponseInfo& info);
+ Return<void> hangupForegroundResumeBackgroundResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> switchWaitingOrHoldingAndActiveResponse(const RadioResponseInfo& info);
+ Return<void> switchWaitingOrHoldingAndActiveResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> conferenceResponse(const RadioResponseInfo& info);
+ Return<void> conferenceResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> rejectCallResponse(const RadioResponseInfo& info);
+ Return<void> rejectCallResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> getLastCallFailCauseResponse(const RadioResponseInfo& info,
- const LastCallFailCauseInfo& failCauseInfo);
+ Return<void> getLastCallFailCauseResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const LastCallFailCauseInfo& failCauseInfo);
Return<void> getSignalStrengthResponse(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::radio::V1_0::SignalStrength& sigStrength);
Return<void> getVoiceRegistrationStateResponse(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::radio::V1_0::VoiceRegStateResult& voiceRegResponse);
Return<void> getDataRegistrationStateResponse(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::radio::V1_0::DataRegStateResult& dataRegResponse);
- Return<void> getOperatorResponse(const RadioResponseInfo& info,
- const ::android::hardware::hidl_string& longName,
- const ::android::hardware::hidl_string& shortName,
- const ::android::hardware::hidl_string& numeric);
+ Return<void> getOperatorResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const ::android::hardware::hidl_string& longName,
+ const ::android::hardware::hidl_string& shortName,
+ const ::android::hardware::hidl_string& numeric);
- Return<void> setRadioPowerResponse(const RadioResponseInfo& info);
+ Return<void> setRadioPowerResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> sendDtmfResponse(const RadioResponseInfo& info);
+ Return<void> sendDtmfResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> sendSmsResponse(const RadioResponseInfo& info, const SendSmsResult& sms);
+ Return<void> sendSmsResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const SendSmsResult& sms);
- Return<void> sendSMSExpectMoreResponse(const RadioResponseInfo& info, const SendSmsResult& sms);
+ Return<void> sendSMSExpectMoreResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const SendSmsResult& sms);
Return<void> setupDataCallResponse(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const android::hardware::radio::V1_0::SetupDataCallResult& dcResponse);
- Return<void> iccIOForAppResponse(const RadioResponseInfo& info, const IccIoResult& iccIo);
+ Return<void> iccIOForAppResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const IccIoResult& iccIo);
- Return<void> sendUssdResponse(const RadioResponseInfo& info);
+ Return<void> sendUssdResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> cancelPendingUssdResponse(const RadioResponseInfo& info);
+ Return<void> cancelPendingUssdResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> getClirResponse(const RadioResponseInfo& info, int32_t n, int32_t m);
+ Return<void> getClirResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ int32_t n, int32_t m);
- Return<void> setClirResponse(const RadioResponseInfo& info);
+ Return<void> setClirResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
Return<void> getCallForwardStatusResponse(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::hidl_vec<CallForwardInfo>& call_forwardInfos);
- Return<void> setCallForwardResponse(const RadioResponseInfo& info);
+ Return<void> setCallForwardResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> getCallWaitingResponse(const RadioResponseInfo& info, bool enable,
- int32_t serviceClass);
+ Return<void> getCallWaitingResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info, bool enable,
+ int32_t serviceClass);
- Return<void> setCallWaitingResponse(const RadioResponseInfo& info);
+ Return<void> setCallWaitingResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> acknowledgeLastIncomingGsmSmsResponse(const RadioResponseInfo& info);
+ Return<void> acknowledgeLastIncomingGsmSmsResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> acceptCallResponse(const RadioResponseInfo& info);
+ Return<void> acceptCallResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> deactivateDataCallResponse(const RadioResponseInfo& info);
+ Return<void> deactivateDataCallResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> getFacilityLockForAppResponse(const RadioResponseInfo& info, int32_t response);
+ Return<void> getFacilityLockForAppResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info, int32_t response);
- Return<void> setFacilityLockForAppResponse(const RadioResponseInfo& info, int32_t retry);
+ Return<void> setFacilityLockForAppResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info, int32_t retry);
- Return<void> setBarringPasswordResponse(const RadioResponseInfo& info);
+ Return<void> setBarringPasswordResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> getNetworkSelectionModeResponse(const RadioResponseInfo& info, bool manual);
+ Return<void> getNetworkSelectionModeResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info, bool manual);
- Return<void> setNetworkSelectionModeAutomaticResponse(const RadioResponseInfo& info);
+ Return<void> setNetworkSelectionModeAutomaticResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> setNetworkSelectionModeManualResponse(const RadioResponseInfo& info);
+ Return<void> setNetworkSelectionModeManualResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
Return<void> getAvailableNetworksResponse(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::hidl_vec<OperatorInfo>& networkInfos);
- Return<void> startDtmfResponse(const RadioResponseInfo& info);
+ Return<void> startDtmfResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> stopDtmfResponse(const RadioResponseInfo& info);
+ Return<void> stopDtmfResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> getBasebandVersionResponse(const RadioResponseInfo& info,
- const ::android::hardware::hidl_string& version);
+ Return<void> getBasebandVersionResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const ::android::hardware::hidl_string& version);
- Return<void> separateConnectionResponse(const RadioResponseInfo& info);
+ Return<void> separateConnectionResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> setMuteResponse(const RadioResponseInfo& info);
+ Return<void> setMuteResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> getMuteResponse(const RadioResponseInfo& info, bool enable);
+ Return<void> getMuteResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ bool enable);
- Return<void> getClipResponse(const RadioResponseInfo& info, ClipStatus status);
+ Return<void> getClipResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ ClipStatus status);
Return<void> getDataCallListResponse(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::hidl_vec<
android::hardware::radio::V1_0::SetupDataCallResult>& dcResponse);
- Return<void> sendOemRilRequestRawResponse(const RadioResponseInfo& info,
- const ::android::hardware::hidl_vec<uint8_t>& data);
+ Return<void> sendOemRilRequestRawResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const ::android::hardware::hidl_vec<uint8_t>& data);
Return<void> sendOemRilRequestStringsResponse(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& data);
- Return<void> setSuppServiceNotificationsResponse(const RadioResponseInfo& info);
+ Return<void> setSuppServiceNotificationsResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> writeSmsToSimResponse(const RadioResponseInfo& info, int32_t index);
+ Return<void> writeSmsToSimResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info, int32_t index);
- Return<void> deleteSmsOnSimResponse(const RadioResponseInfo& info);
+ Return<void> deleteSmsOnSimResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> setBandModeResponse(const RadioResponseInfo& info);
+ Return<void> setBandModeResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
Return<void> getAvailableBandModesResponse(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::hidl_vec<RadioBandMode>& bandModes);
- Return<void> sendEnvelopeResponse(const RadioResponseInfo& info,
- const ::android::hardware::hidl_string& commandResponse);
+ Return<void> sendEnvelopeResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const ::android::hardware::hidl_string& commandResponse);
- Return<void> sendTerminalResponseToSimResponse(const RadioResponseInfo& info);
+ Return<void> sendTerminalResponseToSimResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> handleStkCallSetupRequestFromSimResponse(const RadioResponseInfo& info);
+ Return<void> handleStkCallSetupRequestFromSimResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> explicitCallTransferResponse(const RadioResponseInfo& info);
+ Return<void> explicitCallTransferResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> setPreferredNetworkTypeResponse(const RadioResponseInfo& info);
+ Return<void> setPreferredNetworkTypeResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> getPreferredNetworkTypeResponse(const RadioResponseInfo& info,
- PreferredNetworkType nwType);
+ Return<void> getPreferredNetworkTypeResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ PreferredNetworkType nwType);
Return<void> getNeighboringCidsResponse(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::hidl_vec<NeighboringCell>& cells);
- Return<void> setLocationUpdatesResponse(const RadioResponseInfo& info);
+ Return<void> setLocationUpdatesResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> setCdmaSubscriptionSourceResponse(const RadioResponseInfo& info);
+ Return<void> setCdmaSubscriptionSourceResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> setCdmaRoamingPreferenceResponse(const RadioResponseInfo& info);
+ Return<void> setCdmaRoamingPreferenceResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> getCdmaRoamingPreferenceResponse(const RadioResponseInfo& info,
- CdmaRoamingType type);
+ Return<void> getCdmaRoamingPreferenceResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info, CdmaRoamingType type);
- Return<void> setTTYModeResponse(const RadioResponseInfo& info);
+ Return<void> setTTYModeResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> getTTYModeResponse(const RadioResponseInfo& info, TtyMode mode);
+ Return<void> getTTYModeResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ TtyMode mode);
- Return<void> setPreferredVoicePrivacyResponse(const RadioResponseInfo& info);
+ Return<void> setPreferredVoicePrivacyResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> getPreferredVoicePrivacyResponse(const RadioResponseInfo& info, bool enable);
+ Return<void> getPreferredVoicePrivacyResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info, bool enable);
- Return<void> sendCDMAFeatureCodeResponse(const RadioResponseInfo& info);
+ Return<void> sendCDMAFeatureCodeResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> sendBurstDtmfResponse(const RadioResponseInfo& info);
+ Return<void> sendBurstDtmfResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> sendCdmaSmsResponse(const RadioResponseInfo& info, const SendSmsResult& sms);
+ Return<void> sendCdmaSmsResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const SendSmsResult& sms);
- Return<void> acknowledgeLastIncomingCdmaSmsResponse(const RadioResponseInfo& info);
+ Return<void> acknowledgeLastIncomingCdmaSmsResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
Return<void> getGsmBroadcastConfigResponse(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::hidl_vec<GsmBroadcastSmsConfigInfo>& configs);
- Return<void> setGsmBroadcastConfigResponse(const RadioResponseInfo& info);
+ Return<void> setGsmBroadcastConfigResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> setGsmBroadcastActivationResponse(const RadioResponseInfo& info);
+ Return<void> setGsmBroadcastActivationResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
Return<void> getCdmaBroadcastConfigResponse(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::hidl_vec<CdmaBroadcastSmsConfigInfo>& configs);
- Return<void> setCdmaBroadcastConfigResponse(const RadioResponseInfo& info);
+ Return<void> setCdmaBroadcastConfigResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> setCdmaBroadcastActivationResponse(const RadioResponseInfo& info);
+ Return<void> setCdmaBroadcastActivationResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> getCDMASubscriptionResponse(const RadioResponseInfo& info,
- const ::android::hardware::hidl_string& mdn,
- const ::android::hardware::hidl_string& hSid,
- const ::android::hardware::hidl_string& hNid,
- const ::android::hardware::hidl_string& min,
- const ::android::hardware::hidl_string& prl);
+ Return<void> getCDMASubscriptionResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const ::android::hardware::hidl_string& mdn,
+ const ::android::hardware::hidl_string& hSid,
+ const ::android::hardware::hidl_string& hNid,
+ const ::android::hardware::hidl_string& min,
+ const ::android::hardware::hidl_string& prl);
- Return<void> writeSmsToRuimResponse(const RadioResponseInfo& info, uint32_t index);
+ Return<void> writeSmsToRuimResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info, uint32_t index);
- Return<void> deleteSmsOnRuimResponse(const RadioResponseInfo& info);
+ Return<void> deleteSmsOnRuimResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> getDeviceIdentityResponse(const RadioResponseInfo& info,
- const ::android::hardware::hidl_string& imei,
- const ::android::hardware::hidl_string& imeisv,
- const ::android::hardware::hidl_string& esn,
- const ::android::hardware::hidl_string& meid);
+ Return<void> getDeviceIdentityResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const ::android::hardware::hidl_string& imei,
+ const ::android::hardware::hidl_string& imeisv,
+ const ::android::hardware::hidl_string& esn,
+ const ::android::hardware::hidl_string& meid);
- Return<void> exitEmergencyCallbackModeResponse(const RadioResponseInfo& info);
+ Return<void> exitEmergencyCallbackModeResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> getSmscAddressResponse(const RadioResponseInfo& info,
- const ::android::hardware::hidl_string& smsc);
+ Return<void> getSmscAddressResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const ::android::hardware::hidl_string& smsc);
- Return<void> setSmscAddressResponse(const RadioResponseInfo& info);
+ Return<void> setSmscAddressResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> reportSmsMemoryStatusResponse(const RadioResponseInfo& info);
+ Return<void> reportSmsMemoryStatusResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> reportStkServiceIsRunningResponse(const RadioResponseInfo& info);
+ Return<void> reportStkServiceIsRunningResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> getCdmaSubscriptionSourceResponse(const RadioResponseInfo& info,
- CdmaSubscriptionSource source);
+ Return<void> getCdmaSubscriptionSourceResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ CdmaSubscriptionSource source);
Return<void> requestIsimAuthenticationResponse(
- const RadioResponseInfo& info, const ::android::hardware::hidl_string& response);
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const ::android::hardware::hidl_string& response);
- Return<void> acknowledgeIncomingGsmSmsWithPduResponse(const RadioResponseInfo& info);
+ Return<void> acknowledgeIncomingGsmSmsWithPduResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> sendEnvelopeWithStatusResponse(const RadioResponseInfo& info,
- const IccIoResult& iccIo);
+ Return<void> sendEnvelopeWithStatusResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const IccIoResult& iccIo);
Return<void> getVoiceRadioTechnologyResponse(
- const RadioResponseInfo& info, ::android::hardware::radio::V1_0::RadioTechnology rat);
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ ::android::hardware::radio::V1_0::RadioTechnology rat);
Return<void> getCellInfoListResponse(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::hidl_vec<::android::hardware::radio::V1_0::CellInfo>&
cellInfo);
- Return<void> setCellInfoListRateResponse(const RadioResponseInfo& info);
+ Return<void> setCellInfoListRateResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> setInitialAttachApnResponse(const RadioResponseInfo& info);
+ Return<void> setInitialAttachApnResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> getImsRegistrationStateResponse(const RadioResponseInfo& info, bool isRegistered,
- RadioTechnologyFamily ratFamily);
+ Return<void> getImsRegistrationStateResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info, bool isRegistered,
+ RadioTechnologyFamily ratFamily);
- Return<void> sendImsSmsResponse(const RadioResponseInfo& info, const SendSmsResult& sms);
+ Return<void> sendImsSmsResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const SendSmsResult& sms);
- Return<void> iccTransmitApduBasicChannelResponse(const RadioResponseInfo& info,
- const IccIoResult& result);
+ Return<void> iccTransmitApduBasicChannelResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const IccIoResult& result);
Return<void> iccOpenLogicalChannelResponse(
- const RadioResponseInfo& info, int32_t channelId,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info, int32_t channelId,
const ::android::hardware::hidl_vec<int8_t>& selectResponse);
- Return<void> iccCloseLogicalChannelResponse(const RadioResponseInfo& info);
+ Return<void> iccCloseLogicalChannelResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> iccTransmitApduLogicalChannelResponse(const RadioResponseInfo& info,
- const IccIoResult& result);
+ Return<void> iccTransmitApduLogicalChannelResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const IccIoResult& result);
- Return<void> nvReadItemResponse(const RadioResponseInfo& info,
+ Return<void> nvReadItemResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::hidl_string& result);
- Return<void> nvWriteItemResponse(const RadioResponseInfo& info);
+ Return<void> nvWriteItemResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> nvWriteCdmaPrlResponse(const RadioResponseInfo& info);
+ Return<void> nvWriteCdmaPrlResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> nvResetConfigResponse(const RadioResponseInfo& info);
+ Return<void> nvResetConfigResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> setUiccSubscriptionResponse(const RadioResponseInfo& info);
+ Return<void> setUiccSubscriptionResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> setDataAllowedResponse(const RadioResponseInfo& info);
+ Return<void> setDataAllowedResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
Return<void> getHardwareConfigResponse(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::hidl_vec<HardwareConfig>& config);
- Return<void> requestIccSimAuthenticationResponse(const RadioResponseInfo& info,
- const IccIoResult& result);
+ Return<void> requestIccSimAuthenticationResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const IccIoResult& result);
- Return<void> setDataProfileResponse(const RadioResponseInfo& info);
+ Return<void> setDataProfileResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> requestShutdownResponse(const RadioResponseInfo& info);
+ Return<void> requestShutdownResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
Return<void> getRadioCapabilityResponse(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const android::hardware::radio::V1_0::RadioCapability& rc);
Return<void> setRadioCapabilityResponse(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const android::hardware::radio::V1_0::RadioCapability& rc);
- Return<void> startLceServiceResponse(const RadioResponseInfo& info,
- const LceStatusInfo& statusInfo);
+ Return<void> startLceServiceResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const LceStatusInfo& statusInfo);
- Return<void> stopLceServiceResponse(const RadioResponseInfo& info,
- const LceStatusInfo& statusInfo);
+ Return<void> stopLceServiceResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const LceStatusInfo& statusInfo);
- Return<void> pullLceDataResponse(const RadioResponseInfo& info, const LceDataInfo& lceInfo);
+ Return<void> pullLceDataResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const LceDataInfo& lceInfo);
- Return<void> getModemActivityInfoResponse(const RadioResponseInfo& info,
- const ActivityStatsInfo& activityInfo);
+ Return<void> getModemActivityInfoResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const ActivityStatsInfo& activityInfo);
- Return<void> setAllowedCarriersResponse(const RadioResponseInfo& info, int32_t numAllowed);
+ Return<void> setAllowedCarriersResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info, int32_t numAllowed);
- Return<void> getAllowedCarriersResponse(const RadioResponseInfo& info, bool allAllowed,
- const CarrierRestrictions& carriers);
+ Return<void> getAllowedCarriersResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info, bool allAllowed,
+ const CarrierRestrictions& carriers);
- Return<void> sendDeviceStateResponse(const RadioResponseInfo& info);
+ Return<void> sendDeviceStateResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> setIndicationFilterResponse(const RadioResponseInfo& info);
+ Return<void> setIndicationFilterResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> setSimCardPowerResponse(const RadioResponseInfo& info);
+ Return<void> setSimCardPowerResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
Return<void> acknowledgeRequest(int32_t serial);
/* 1.1 Api */
- Return<void> setCarrierInfoForImsiEncryptionResponse(const RadioResponseInfo& info);
+ Return<void> setCarrierInfoForImsiEncryptionResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> setSimCardPowerResponse_1_1(const RadioResponseInfo& info);
+ Return<void> setSimCardPowerResponse_1_1(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> startNetworkScanResponse(const RadioResponseInfo& info);
+ Return<void> startNetworkScanResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> stopNetworkScanResponse(const RadioResponseInfo& info);
+ Return<void> stopNetworkScanResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> startKeepaliveResponse(const RadioResponseInfo& info,
- const KeepaliveStatus& status);
+ Return<void> startKeepaliveResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const KeepaliveStatus& status);
- Return<void> stopKeepaliveResponse(const RadioResponseInfo& info);
+ Return<void> stopKeepaliveResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
/* 1.2 Api */
- Return<void> setSignalStrengthReportingCriteriaResponse(const RadioResponseInfo& info);
+ Return<void> setSignalStrengthReportingCriteriaResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> setLinkCapacityReportingCriteriaResponse(const RadioResponseInfo& info);
+ Return<void> setLinkCapacityReportingCriteriaResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
Return<void> getIccCardStatusResponse_1_2(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::radio::V1_2::CardStatus& card_status);
Return<void> getCurrentCallsResponse_1_2(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::hidl_vec<::android::hardware::radio::V1_2::Call>& calls);
Return<void> getSignalStrengthResponse_1_2(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::radio::V1_2::SignalStrength& sig_strength);
Return<void> getSignalStrengthResponse_1_4(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::radio::V1_4::SignalStrength& sig_strength);
Return<void> getCellInfoListResponse_1_2(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::hidl_vec<::android::hardware::radio::V1_2::CellInfo>&
cellInfo);
Return<void> getVoiceRegistrationStateResponse_1_2(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::radio::V1_2::VoiceRegStateResult& voiceRegResponse);
Return<void> getDataRegistrationStateResponse_1_2(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::radio::V1_2::DataRegStateResult& dataRegResponse);
/* 1.3 Api */
- Return<void> setSystemSelectionChannelsResponse(const RadioResponseInfo& info);
+ Return<void> setSystemSelectionChannelsResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> enableModemResponse(const RadioResponseInfo& info);
+ Return<void> enableModemResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> getModemStackStatusResponse(const RadioResponseInfo& info, const bool enabled);
+ Return<void> getModemStackStatusResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const bool enabled);
/* 1.4 Api */
- Return<void> emergencyDialResponse(const RadioResponseInfo& info);
+ Return<void> emergencyDialResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> startNetworkScanResponse_1_4(const RadioResponseInfo& info);
+ Return<void> startNetworkScanResponse_1_4(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
Return<void> getCellInfoListResponse_1_4(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::hidl_vec<::android::hardware::radio::V1_4::CellInfo>&
cellInfo);
Return<void> getDataRegistrationStateResponse_1_4(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::radio::V1_4::DataRegStateResult& dataRegResponse);
Return<void> getIccCardStatusResponse_1_4(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::radio::V1_4::CardStatus& card_status);
Return<void> getPreferredNetworkTypeBitmapResponse(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::hidl_bitfield<
::android::hardware::radio::V1_4::RadioAccessFamily>
networkTypeBitmap);
- Return<void> setPreferredNetworkTypeBitmapResponse(const RadioResponseInfo& info);
+ Return<void> setPreferredNetworkTypeBitmapResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
Return<void> getDataCallListResponse_1_4(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::hidl_vec<
::android::hardware::radio::V1_4::SetupDataCallResult>& dcResponse);
Return<void> setupDataCallResponse_1_4(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const android::hardware::radio::V1_4::SetupDataCallResult& dcResponse);
- Return<void> setAllowedCarriersResponse_1_4(const RadioResponseInfo& info);
+ Return<void> setAllowedCarriersResponse_1_4(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> getAllowedCarriersResponse_1_4(const RadioResponseInfo& info,
- const CarrierRestrictionsWithPriority& carriers,
- SimLockMultiSimPolicy multiSimPolicy);
+ Return<void> getAllowedCarriersResponse_1_4(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const CarrierRestrictionsWithPriority& carriers, SimLockMultiSimPolicy multiSimPolicy);
/* 1.5 Api */
- Return<void> setSignalStrengthReportingCriteriaResponse_1_5(const RadioResponseInfo& info);
+ Return<void> setSignalStrengthReportingCriteriaResponse_1_5(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> setLinkCapacityReportingCriteriaResponse_1_5(const RadioResponseInfo& info);
+ Return<void> setLinkCapacityReportingCriteriaResponse_1_5(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> enableUiccApplicationsResponse(const RadioResponseInfo& info);
+ Return<void> enableUiccApplicationsResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> areUiccApplicationsEnabledResponse(const RadioResponseInfo& info, bool enabled);
+ Return<void> areUiccApplicationsEnabledResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info, bool enabled);
- Return<void> canToggleUiccApplicationsEnablementResponse(const RadioResponseInfo& info,
- bool canToggle);
+ Return<void> canToggleUiccApplicationsEnablementResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info, bool canToggle);
- Return<void> setSystemSelectionChannelsResponse_1_5(const RadioResponseInfo& info);
+ Return<void> setSystemSelectionChannelsResponse_1_5(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> startNetworkScanResponse_1_5(const RadioResponseInfo& info);
+ Return<void> startNetworkScanResponse_1_5(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
Return<void> setupDataCallResponse_1_5(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const android::hardware::radio::V1_5::SetupDataCallResult& dcResponse);
Return<void> getDataCallListResponse_1_5(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const hidl_vec<::android::hardware::radio::V1_5::SetupDataCallResult>& dcResponse);
- Return<void> setInitialAttachApnResponse_1_5(const RadioResponseInfo& info);
+ Return<void> setInitialAttachApnResponse_1_5(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> setDataProfileResponse_1_5(const RadioResponseInfo& info);
+ Return<void> setDataProfileResponse_1_5(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> setRadioPowerResponse_1_5(const RadioResponseInfo& info);
+ Return<void> setRadioPowerResponse_1_5(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> setIndicationFilterResponse_1_5(const RadioResponseInfo& info);
+ Return<void> setIndicationFilterResponse_1_5(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
Return<void> getBarringInfoResponse(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::radio::V1_5::CellIdentity& cellIdentity,
const ::android::hardware::hidl_vec<::android::hardware::radio::V1_5::BarringInfo>&
barringInfos);
Return<void> getVoiceRegistrationStateResponse_1_5(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::radio::V1_5::RegStateResult& regResponse);
Return<void> getDataRegistrationStateResponse_1_5(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::radio::V1_5::RegStateResult& regResponse);
Return<void> getCellInfoListResponse_1_5(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::hidl_vec<::android::hardware::radio::V1_5::CellInfo>&
cellInfo);
- Return<void> setNetworkSelectionModeManualResponse_1_5(const RadioResponseInfo& info);
+ Return<void> setNetworkSelectionModeManualResponse_1_5(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info);
- Return<void> sendCdmaSmsExpectMoreResponse(const RadioResponseInfo& info,
- const SendSmsResult& sms);
+ Return<void> sendCdmaSmsExpectMoreResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const SendSmsResult& sms);
Return<void> supplySimDepersonalizationResponse(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
::android::hardware::radio::V1_5::PersoSubstate persoType, int32_t remainingRetries);
Return<void> getIccCardStatusResponse_1_5(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::radio::V1_5::CardStatus& card_status);
/* 1.6 Api */
+ Return<void> setRadioPowerResponse_1_6(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info);
+
Return<void> setupDataCallResponse_1_6(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
const android::hardware::radio::V1_6::SetupDataCallResult& dcResponse);
Return<void> getDataCallListResponse_1_6(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
const hidl_vec<::android::hardware::radio::V1_6::SetupDataCallResult>& dcResponse);
+
+ Return<void> sendSmsResponse_1_6(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
+ const SendSmsResult& sms);
+
+ Return<void> sendSMSExpectMoreResponse_1_6(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
+ const SendSmsResult& sms);
+
+ Return<void> sendCdmaSmsResponse_1_6(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
+ const SendSmsResult& sms);
+
+ Return<void> sendCdmaSmsExpectMoreResponse_1_6(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
+ const SendSmsResult& sms);
+
+ Return<void> enableNrDualConnectivityResponse(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info);
+ Return<void> isNrDualConnectivityEnabledResponse(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info, bool isEnabled);
};
/* Callback class for radio indication */
@@ -843,6 +1005,9 @@
/* Clear Potential Established Calls */
void clearPotentialEstablishedCalls();
+ /* Update Sim Card Status */
+ void updateSimCardStatus();
+
/* Get current data call list */
void getDataCallList();
diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp
index f53e199..ffa384e 100644
--- a/radio/1.6/vts/functional/radio_response.cpp
+++ b/radio/1.6/vts/functional/radio_response.cpp
@@ -22,435 +22,478 @@
/* 1.0 Apis */
Return<void> RadioResponse_v1_6::getIccCardStatusResponse(
- const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::radio::V1_0::CardStatus& /*card_status*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::supplyIccPinForAppResponse(const RadioResponseInfo& /*info*/,
- int32_t /*remainingRetries*/) {
+Return<void> RadioResponse_v1_6::supplyIccPinForAppResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ int32_t /*remainingRetries*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::supplyIccPukForAppResponse(const RadioResponseInfo& /*info*/,
- int32_t /*remainingRetries*/) {
+Return<void> RadioResponse_v1_6::supplyIccPukForAppResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ int32_t /*remainingRetries*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::supplyIccPin2ForAppResponse(const RadioResponseInfo& /*info*/,
- int32_t /*remainingRetries*/) {
+Return<void> RadioResponse_v1_6::supplyIccPin2ForAppResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ int32_t /*remainingRetries*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::supplyIccPuk2ForAppResponse(const RadioResponseInfo& /*info*/,
- int32_t /*remainingRetries*/) {
+Return<void> RadioResponse_v1_6::supplyIccPuk2ForAppResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ int32_t /*remainingRetries*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::changeIccPinForAppResponse(const RadioResponseInfo& /*info*/,
- int32_t /*remainingRetries*/) {
+Return<void> RadioResponse_v1_6::changeIccPinForAppResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ int32_t /*remainingRetries*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::changeIccPin2ForAppResponse(const RadioResponseInfo& /*info*/,
- int32_t /*remainingRetries*/) {
+Return<void> RadioResponse_v1_6::changeIccPin2ForAppResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ int32_t /*remainingRetries*/) {
return Void();
}
Return<void> RadioResponse_v1_6::supplyNetworkDepersonalizationResponse(
- const RadioResponseInfo& /*info*/, int32_t /*remainingRetries*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ int32_t /*remainingRetries*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getCurrentCallsResponse(
- const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::hidl_vec<::android::hardware::radio::V1_0::Call>& /*calls*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::dialResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::dialResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getIMSIForAppResponse(
- const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*imsi*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_string& /*imsi*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::hangupConnectionResponse(const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+Return<void> RadioResponse_v1_6::hangupConnectionResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::hangupWaitingOrBackgroundResponse(
- const RadioResponseInfo& /*info*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::hangupForegroundResumeBackgroundResponse(
- const RadioResponseInfo& /*info*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::switchWaitingOrHoldingAndActiveResponse(
- const RadioResponseInfo& /*info*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::conferenceResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::conferenceResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::rejectCallResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::rejectCallResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getLastCallFailCauseResponse(
- const RadioResponseInfo& /*info*/, const LastCallFailCauseInfo& /*failCauseInfo*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const LastCallFailCauseInfo& /*failCauseInfo*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getSignalStrengthResponse(
- const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::radio::V1_0::SignalStrength& /*sig_strength*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getVoiceRegistrationStateResponse(
- const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::radio::V1_0::VoiceRegStateResult& /*voiceRegResponse*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getDataRegistrationStateResponse(
- const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::radio::V1_0::DataRegStateResult& /*dataRegResponse*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getOperatorResponse(
- const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*longName*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_string& /*longName*/,
const ::android::hardware::hidl_string& /*shortName*/,
const ::android::hardware::hidl_string& /*numeric*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setRadioPowerResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::setRadioPowerResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::sendDtmfResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::sendDtmfResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::sendSmsResponse(const RadioResponseInfo& /*info*/,
- const SendSmsResult& /*sms*/) {
+Return<void> RadioResponse_v1_6::sendSmsResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const SendSmsResult& /*sms*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::sendSMSExpectMoreResponse(const RadioResponseInfo& /*info*/,
- const SendSmsResult& /*sms*/) {
+Return<void> RadioResponse_v1_6::sendSMSExpectMoreResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const SendSmsResult& /*sms*/) {
return Void();
}
Return<void> RadioResponse_v1_6::setupDataCallResponse(
- const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const android::hardware::radio::V1_0::SetupDataCallResult& /*dcResponse*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::iccIOForAppResponse(const RadioResponseInfo& /*info*/,
- const IccIoResult& /*iccIo*/) {
+Return<void> RadioResponse_v1_6::iccIOForAppResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const IccIoResult& /*iccIo*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::sendUssdResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::sendUssdResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::cancelPendingUssdResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::cancelPendingUssdResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::getClirResponse(const RadioResponseInfo& /*info*/, int32_t /*n*/,
- int32_t /*m*/) {
+Return<void> RadioResponse_v1_6::getClirResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, int32_t /*n*/,
+ int32_t /*m*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setClirResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::setClirResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getCallForwardStatusResponse(
- const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_vec<CallForwardInfo>&
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_vec<CallForwardInfo>&
/*callForwardInfos*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setCallForwardResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::setCallForwardResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::getCallWaitingResponse(const RadioResponseInfo& /*info*/,
- bool /*enable*/, int32_t /*serviceClass*/) {
+Return<void> RadioResponse_v1_6::getCallWaitingResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, bool /*enable*/,
+ int32_t /*serviceClass*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setCallWaitingResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::setCallWaitingResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::acknowledgeLastIncomingGsmSmsResponse(
- const RadioResponseInfo& /*info*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::acceptCallResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::acceptCallResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::deactivateDataCallResponse(const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+Return<void> RadioResponse_v1_6::deactivateDataCallResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::getFacilityLockForAppResponse(const RadioResponseInfo& /*info*/,
- int32_t /*response*/) {
+Return<void> RadioResponse_v1_6::getFacilityLockForAppResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, int32_t /*response*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setFacilityLockForAppResponse(const RadioResponseInfo& /*info*/,
- int32_t /*retry*/) {
+Return<void> RadioResponse_v1_6::setFacilityLockForAppResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, int32_t /*retry*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setBarringPasswordResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::setBarringPasswordResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::getNetworkSelectionModeResponse(const RadioResponseInfo& /*info*/,
- bool /*manual*/) {
+Return<void> RadioResponse_v1_6::getNetworkSelectionModeResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, bool /*manual*/) {
return Void();
}
Return<void> RadioResponse_v1_6::setNetworkSelectionModeAutomaticResponse(
- const RadioResponseInfo& /*info*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::setNetworkSelectionModeManualResponse(
- const RadioResponseInfo& /*info*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getAvailableNetworksResponse(
- const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::hidl_vec<OperatorInfo>& /*networkInfos*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::startDtmfResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::startDtmfResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::stopDtmfResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::stopDtmfResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getBasebandVersionResponse(
- const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*version*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_string& /*version*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::separateConnectionResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::separateConnectionResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setMuteResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::setMuteResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::getMuteResponse(const RadioResponseInfo& /*info*/,
- bool /*enable*/) {
+Return<void> RadioResponse_v1_6::getMuteResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, bool /*enable*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::getClipResponse(const RadioResponseInfo& /*info*/,
- ClipStatus /*status*/) {
+Return<void> RadioResponse_v1_6::getClipResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ ClipStatus /*status*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getDataCallListResponse(
- const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::hidl_vec<android::hardware::radio::V1_0::SetupDataCallResult>&
/*dcResponse*/) {
return Void();
}
Return<void> RadioResponse_v1_6::sendOemRilRequestRawResponse(
- const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_vec<uint8_t>& /*data*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_vec<uint8_t>& /*data*/) {
return Void();
}
Return<void> RadioResponse_v1_6::sendOemRilRequestStringsResponse(
- const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& /*data*/) {
return Void();
}
Return<void> RadioResponse_v1_6::setSuppServiceNotificationsResponse(
- const RadioResponseInfo& /*info*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::writeSmsToSimResponse(const RadioResponseInfo& /*info*/,
- int32_t /*index*/) {
+Return<void> RadioResponse_v1_6::writeSmsToSimResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, int32_t /*index*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::deleteSmsOnSimResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::deleteSmsOnSimResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setBandModeResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::setBandModeResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getAvailableBandModesResponse(
- const RadioResponseInfo& info,
- const ::android::hardware::hidl_vec<RadioBandMode>& bandModes) {
- rspInfo = info;
- radioBandModes = bandModes;
- parent_v1_6.notify(info.serial);
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_vec<RadioBandMode>& /*bandModes*/) {
return Void();
}
Return<void> RadioResponse_v1_6::sendEnvelopeResponse(
- const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::hidl_string& /*commandResponse*/) {
return Void();
}
Return<void> RadioResponse_v1_6::sendTerminalResponseToSimResponse(
- const RadioResponseInfo& /*info*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::handleStkCallSetupRequestFromSimResponse(
- const RadioResponseInfo& /*info*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::explicitCallTransferResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::explicitCallTransferResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::setPreferredNetworkTypeResponse(
- const RadioResponseInfo& /*info*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::getPreferredNetworkTypeResponse(const RadioResponseInfo& /*info*/,
- PreferredNetworkType /*nw_type*/) {
+Return<void> RadioResponse_v1_6::getPreferredNetworkTypeResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ PreferredNetworkType /*nw_type*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getNeighboringCidsResponse(
- const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::hidl_vec<NeighboringCell>& /*cells*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setLocationUpdatesResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::setLocationUpdatesResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::setCdmaSubscriptionSourceResponse(
- const RadioResponseInfo& /*info*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::setCdmaRoamingPreferenceResponse(
- const RadioResponseInfo& /*info*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::getCdmaRoamingPreferenceResponse(const RadioResponseInfo& /*info*/,
- CdmaRoamingType /*type*/) {
+Return<void> RadioResponse_v1_6::getCdmaRoamingPreferenceResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ CdmaRoamingType /*type*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setTTYModeResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::setTTYModeResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::getTTYModeResponse(const RadioResponseInfo& /*info*/,
- TtyMode /*mode*/) {
+Return<void> RadioResponse_v1_6::getTTYModeResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, TtyMode /*mode*/) {
return Void();
}
Return<void> RadioResponse_v1_6::setPreferredVoicePrivacyResponse(
- const RadioResponseInfo& /*info*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::getPreferredVoicePrivacyResponse(const RadioResponseInfo& /*info*/,
- bool /*enable*/) {
+Return<void> RadioResponse_v1_6::getPreferredVoicePrivacyResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, bool /*enable*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::sendCDMAFeatureCodeResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::sendCDMAFeatureCodeResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::sendBurstDtmfResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::sendBurstDtmfResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::sendCdmaSmsResponse(const RadioResponseInfo& /*info*/,
- const SendSmsResult& /*sms*/) {
+Return<void> RadioResponse_v1_6::sendCdmaSmsResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const SendSmsResult& /*sms*/) {
return Void();
}
Return<void> RadioResponse_v1_6::acknowledgeLastIncomingCdmaSmsResponse(
- const RadioResponseInfo& /*info*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getGsmBroadcastConfigResponse(
- const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::hidl_vec<GsmBroadcastSmsConfigInfo>& /*configs*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setGsmBroadcastConfigResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::setGsmBroadcastConfigResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::setGsmBroadcastActivationResponse(
- const RadioResponseInfo& /*info*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getCdmaBroadcastConfigResponse(
- const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::hidl_vec<CdmaBroadcastSmsConfigInfo>& /*configs*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setCdmaBroadcastConfigResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::setCdmaBroadcastConfigResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::setCdmaBroadcastActivationResponse(
- const RadioResponseInfo& /*info*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getCDMASubscriptionResponse(
- const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*mdn*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_string& /*mdn*/,
const ::android::hardware::hidl_string& /*hSid*/,
const ::android::hardware::hidl_string& /*hNid*/,
const ::android::hardware::hidl_string& /*min*/,
@@ -458,17 +501,19 @@
return Void();
}
-Return<void> RadioResponse_v1_6::writeSmsToRuimResponse(const RadioResponseInfo& /*info*/,
- uint32_t /*index*/) {
+Return<void> RadioResponse_v1_6::writeSmsToRuimResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, uint32_t /*index*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::deleteSmsOnRuimResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::deleteSmsOnRuimResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getDeviceIdentityResponse(
- const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*imei*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_string& /*imei*/,
const ::android::hardware::hidl_string& /*imeisv*/,
const ::android::hardware::hidl_string& /*esn*/,
const ::android::hardware::hidl_string& /*meid*/) {
@@ -476,202 +521,225 @@
}
Return<void> RadioResponse_v1_6::exitEmergencyCallbackModeResponse(
- const RadioResponseInfo& /*info*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getSmscAddressResponse(
- const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*smsc*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_string& /*smsc*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setSmscAddressResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::setSmscAddressResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::reportSmsMemoryStatusResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::reportSmsMemoryStatusResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::reportStkServiceIsRunningResponse(
- const RadioResponseInfo& /*info*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getCdmaSubscriptionSourceResponse(
- const RadioResponseInfo& /*info*/, CdmaSubscriptionSource /*source*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ CdmaSubscriptionSource /*source*/) {
return Void();
}
Return<void> RadioResponse_v1_6::requestIsimAuthenticationResponse(
- const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*response*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_string& /*response*/) {
return Void();
}
Return<void> RadioResponse_v1_6::acknowledgeIncomingGsmSmsWithPduResponse(
- const RadioResponseInfo& /*info*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::sendEnvelopeWithStatusResponse(const RadioResponseInfo& /*info*/,
- const IccIoResult& /*iccIo*/) {
+Return<void> RadioResponse_v1_6::sendEnvelopeWithStatusResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const IccIoResult& /*iccIo*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getVoiceRadioTechnologyResponse(
- const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
::android::hardware::radio::V1_0::RadioTechnology /*rat*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getCellInfoListResponse(
- const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::hidl_vec<
::android::hardware::radio::V1_0::CellInfo>& /*cellInfo*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setCellInfoListRateResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::setCellInfoListRateResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setInitialAttachApnResponse(const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+Return<void> RadioResponse_v1_6::setInitialAttachApnResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getImsRegistrationStateResponse(
- const RadioResponseInfo& /*info*/, bool /*isRegistered*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, bool /*isRegistered*/,
RadioTechnologyFamily /*ratFamily*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::sendImsSmsResponse(const RadioResponseInfo& /*info*/,
- const SendSmsResult& /*sms*/) {
+Return<void> RadioResponse_v1_6::sendImsSmsResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const SendSmsResult& /*sms*/) {
return Void();
}
Return<void> RadioResponse_v1_6::iccTransmitApduBasicChannelResponse(
- const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const IccIoResult& /*result*/) {
return Void();
}
Return<void> RadioResponse_v1_6::iccOpenLogicalChannelResponse(
- const RadioResponseInfo& /*info*/, int32_t /*channelId*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, int32_t /*channelId*/,
const ::android::hardware::hidl_vec<int8_t>& /*selectResponse*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::iccCloseLogicalChannelResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::iccCloseLogicalChannelResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::iccTransmitApduLogicalChannelResponse(
- const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const IccIoResult& /*result*/) {
return Void();
}
Return<void> RadioResponse_v1_6::nvReadItemResponse(
- const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*result*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_string& /*result*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::nvWriteItemResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::nvWriteItemResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::nvWriteCdmaPrlResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::nvWriteCdmaPrlResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::nvResetConfigResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::nvResetConfigResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setUiccSubscriptionResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::setUiccSubscriptionResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setDataAllowedResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::setDataAllowedResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getHardwareConfigResponse(
- const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::hidl_vec<HardwareConfig>& /*config*/) {
return Void();
}
Return<void> RadioResponse_v1_6::requestIccSimAuthenticationResponse(
- const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const IccIoResult& /*result*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setDataProfileResponse(const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+Return<void> RadioResponse_v1_6::setDataProfileResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::requestShutdownResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::requestShutdownResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getRadioCapabilityResponse(
- const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const android::hardware::radio::V1_0::RadioCapability& /*rc*/) {
return Void();
}
Return<void> RadioResponse_v1_6::setRadioCapabilityResponse(
- const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const android::hardware::radio::V1_0::RadioCapability& /*rc*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::startLceServiceResponse(const RadioResponseInfo& /*info*/,
- const LceStatusInfo& /*statusInfo*/) {
+Return<void> RadioResponse_v1_6::startLceServiceResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const LceStatusInfo& /*statusInfo*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::stopLceServiceResponse(const RadioResponseInfo& /*info*/,
- const LceStatusInfo& /*statusInfo*/) {
+Return<void> RadioResponse_v1_6::stopLceServiceResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const LceStatusInfo& /*statusInfo*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::pullLceDataResponse(const RadioResponseInfo& /*info*/,
- const LceDataInfo& /*lceInfo*/) {
+Return<void> RadioResponse_v1_6::pullLceDataResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const LceDataInfo& /*lceInfo*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getModemActivityInfoResponse(
- const RadioResponseInfo& /*info*/, const ActivityStatsInfo& /*activityInfo*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const ActivityStatsInfo& /*activityInfo*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setAllowedCarriersResponse(const RadioResponseInfo& /*info*/,
- int32_t /*numAllowed*/) {
+Return<void> RadioResponse_v1_6::setAllowedCarriersResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ int32_t /*numAllowed*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getAllowedCarriersResponse(
- const RadioResponseInfo& /*info*/, bool /*allAllowed*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, bool /*allAllowed*/,
const CarrierRestrictions& /*carriers*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::sendDeviceStateResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::sendDeviceStateResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setIndicationFilterResponse(const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+Return<void> RadioResponse_v1_6::setIndicationFilterResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setSimCardPowerResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::setSimCardPowerResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
@@ -681,378 +749,367 @@
/* 1.1 Apis */
Return<void> RadioResponse_v1_6::setCarrierInfoForImsiEncryptionResponse(
- const RadioResponseInfo& /*info*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setSimCardPowerResponse_1_1(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::setSimCardPowerResponse_1_1(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::startNetworkScanResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::startNetworkScanResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::stopNetworkScanResponse(const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+Return<void> RadioResponse_v1_6::stopNetworkScanResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::startKeepaliveResponse(const RadioResponseInfo& /*info*/,
- const KeepaliveStatus& /*status*/) {
+Return<void> RadioResponse_v1_6::startKeepaliveResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const KeepaliveStatus& /*status*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::stopKeepaliveResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_6::stopKeepaliveResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
/* 1.2 Apis */
Return<void> RadioResponse_v1_6::setSignalStrengthReportingCriteriaResponse(
- const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::setLinkCapacityReportingCriteriaResponse(
- const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getIccCardStatusResponse_1_2(
- const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::radio::V1_2::CardStatus& /*card_status*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getCurrentCallsResponse_1_2(
- const RadioResponseInfo& info,
- const ::android::hardware::hidl_vec<::android::hardware::radio::V1_2::Call>& calls) {
- rspInfo = info;
- currentCalls = calls;
- parent_v1_6.notify(info.serial);
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_vec<::android::hardware::radio::V1_2::Call>& /*calls*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getSignalStrengthResponse_1_2(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::radio::V1_2::SignalStrength& /*sig_strength*/) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
return Void();
}
Return<void> RadioResponse_v1_6::getSignalStrengthResponse_1_4(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::radio::V1_4::SignalStrength& /*sig_strength*/) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
return Void();
}
Return<void> RadioResponse_v1_6::getCellInfoListResponse_1_2(
- const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::hidl_vec<
::android::hardware::radio::V1_2::CellInfo>& /*cellInfo*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getVoiceRegistrationStateResponse_1_2(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::radio::V1_2::VoiceRegStateResult& /*voiceRegResponse*/) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
return Void();
}
Return<void> RadioResponse_v1_6::getDataRegistrationStateResponse_1_2(
- const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::radio::V1_2::DataRegStateResult& /*dataRegResponse*/) {
return Void();
}
/* 1.3 Apis */
-Return<void> RadioResponse_v1_6::setSystemSelectionChannelsResponse(const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+Return<void> RadioResponse_v1_6::setSystemSelectionChannelsResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::enableModemResponse(const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+Return<void> RadioResponse_v1_6::enableModemResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::getModemStackStatusResponse(const RadioResponseInfo& info,
- const bool enabled) {
- rspInfo = info;
- isModemEnabled = enabled;
- parent_v1_6.notify(info.serial);
+Return<void> RadioResponse_v1_6::getModemStackStatusResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const bool /*enabled*/) {
return Void();
}
/* 1.4 Apis */
-Return<void> RadioResponse_v1_6::emergencyDialResponse(const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+Return<void> RadioResponse_v1_6::emergencyDialResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::startNetworkScanResponse_1_4(const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+Return<void> RadioResponse_v1_6::startNetworkScanResponse_1_4(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getDataRegistrationStateResponse_1_4(
- const RadioResponseInfo& info,
- const ::android::hardware::radio::V1_4::DataRegStateResult& dataRegResponse) {
- rspInfo = info;
- dataRegResp = dataRegResponse;
- parent_v1_6.notify(info.serial);
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_4::DataRegStateResult& /*dataRegResponse*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getCellInfoListResponse_1_4(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::hidl_vec<
::android::hardware::radio::V1_4::CellInfo>& /*cellInfo*/) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
return Void();
}
Return<void> RadioResponse_v1_6::getIccCardStatusResponse_1_4(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::radio::V1_4::CardStatus& /*card_status*/) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
return Void();
}
Return<void> RadioResponse_v1_6::getPreferredNetworkTypeBitmapResponse(
- const RadioResponseInfo& info, const ::android::hardware::hidl_bitfield<
- ::android::hardware::radio::V1_4::RadioAccessFamily>
- networkTypeBitmap) {
- rspInfo = info;
- networkTypeBitmapResponse = networkTypeBitmap;
- parent_v1_6.notify(info.serial);
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_bitfield<
+ ::android::hardware::radio::V1_4::RadioAccessFamily>
+ /*networkTypeBitmap*/) {
return Void();
}
Return<void> RadioResponse_v1_6::setPreferredNetworkTypeBitmapResponse(
- const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getDataCallListResponse_1_4(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::hidl_vec<::android::hardware::radio::V1_4::SetupDataCallResult>&
/*dcResponse*/) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
return Void();
}
Return<void> RadioResponse_v1_6::setupDataCallResponse_1_4(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const android::hardware::radio::V1_4::SetupDataCallResult& /*dcResponse*/) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
return Void();
}
-Return<void> RadioResponse_v1_6::setAllowedCarriersResponse_1_4(const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+Return<void> RadioResponse_v1_6::setAllowedCarriersResponse_1_4(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getAllowedCarriersResponse_1_4(
- const RadioResponseInfo& info, const CarrierRestrictionsWithPriority& carriers,
- SimLockMultiSimPolicy multiSimPolicy) {
- rspInfo = info;
- carrierRestrictionsResp = carriers;
- multiSimPolicyResp = multiSimPolicy;
- parent_v1_6.notify(info.serial);
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const CarrierRestrictionsWithPriority& /*carriers*/,
+ SimLockMultiSimPolicy /*multiSimPolicy*/) {
return Void();
}
/* 1.5 Apis */
Return<void> RadioResponse_v1_6::setSignalStrengthReportingCriteriaResponse_1_5(
- const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::setLinkCapacityReportingCriteriaResponse_1_5(
- const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::enableUiccApplicationsResponse(const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+Return<void> RadioResponse_v1_6::enableUiccApplicationsResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::areUiccApplicationsEnabledResponse(const RadioResponseInfo& info,
- bool enabled) {
- rspInfo = info;
- areUiccApplicationsEnabled = enabled;
- parent_v1_6.notify(info.serial);
+Return<void> RadioResponse_v1_6::areUiccApplicationsEnabledResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, bool /*enabled*/) {
return Void();
}
Return<void> RadioResponse_v1_6::canToggleUiccApplicationsEnablementResponse(
- const RadioResponseInfo& info, bool canToggle) {
- rspInfo = info;
- canToggleUiccApplicationsEnablement = canToggle;
- parent_v1_6.notify(info.serial);
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, bool /*canToggle*/) {
return Void();
}
Return<void> RadioResponse_v1_6::setSystemSelectionChannelsResponse_1_5(
- const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::startNetworkScanResponse_1_5(const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+Return<void> RadioResponse_v1_6::startNetworkScanResponse_1_5(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::setupDataCallResponse_1_5(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const android::hardware::radio::V1_5::SetupDataCallResult& /* dcResponse */) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
return Void();
}
Return<void> RadioResponse_v1_6::getDataCallListResponse_1_5(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const hidl_vec<::android::hardware::radio::V1_5::SetupDataCallResult>& /* dcResponse */) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
return Void();
}
-Return<void> RadioResponse_v1_6::setInitialAttachApnResponse_1_5(const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+Return<void> RadioResponse_v1_6::setInitialAttachApnResponse_1_5(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setDataProfileResponse_1_5(const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+Return<void> RadioResponse_v1_6::setDataProfileResponse_1_5(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setRadioPowerResponse_1_5(const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+Return<void> RadioResponse_v1_6::setRadioPowerResponse_1_5(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::setIndicationFilterResponse_1_5(const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+Return<void> RadioResponse_v1_6::setIndicationFilterResponse_1_5(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getBarringInfoResponse(
- const RadioResponseInfo& info,
- const ::android::hardware::radio::V1_5::CellIdentity& cellIdentity,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_5::CellIdentity& /*cellIdentity*/,
const ::android::hardware::hidl_vec<::android::hardware::radio::V1_5::BarringInfo>&
- barringInfos) {
- this->barringCellIdentity = cellIdentity;
- this->barringInfos = barringInfos;
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+ /*barringInfos*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getVoiceRegistrationStateResponse_1_5(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::radio::V1_5::RegStateResult& /*regResponse*/) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
return Void();
}
Return<void> RadioResponse_v1_6::getDataRegistrationStateResponse_1_5(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::radio::V1_5::RegStateResult& /*regResponse*/) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
return Void();
}
Return<void> RadioResponse_v1_6::getCellInfoListResponse_1_5(
- const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::hidl_vec<
::android::hardware::radio::V1_5::CellInfo>& /*cellInfo*/) {
return Void();
}
Return<void> RadioResponse_v1_6::setNetworkSelectionModeManualResponse_1_5(
- const RadioResponseInfo& info) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) {
return Void();
}
-Return<void> RadioResponse_v1_6::sendCdmaSmsExpectMoreResponse(const RadioResponseInfo& info,
- const SendSmsResult& /*sms*/) {
- rspInfo = info;
- parent_v1_6.notify(info.serial);
+Return<void> RadioResponse_v1_6::sendCdmaSmsExpectMoreResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
+ const SendSmsResult& /*sms*/) {
return Void();
}
Return<void> RadioResponse_v1_6::supplySimDepersonalizationResponse(
- const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
::android::hardware::radio::V1_5::PersoSubstate /*persoType*/,
int32_t /*remainingRetries*/) {
return Void();
}
Return<void> RadioResponse_v1_6::getIccCardStatusResponse_1_5(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::radio::V1_5::CardStatus& card_status) {
- rspInfo = info;
+ rspInfo_v1_0 = info;
cardStatus = card_status;
parent_v1_6.notify(info.serial);
return Void();
}
/* 1.6 Apis */
+Return<void> RadioResponse_v1_6::setRadioPowerResponse_1_6(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_6.notify(info.serial);
+ return Void();
+}
+
Return<void> RadioResponse_v1_6::setupDataCallResponse_1_6(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
const android::hardware::radio::V1_6::SetupDataCallResult& /* dcResponse */) {
rspInfo = info;
parent_v1_6.notify(info.serial);
return Void();
}
+Return<void> RadioResponse_v1_6::enableNrDualConnectivityResponse(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_6.notify(info.serial);
+ return Void();
+}
Return<void> RadioResponse_v1_6::getDataCallListResponse_1_6(
- const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
const hidl_vec<::android::hardware::radio::V1_6::SetupDataCallResult>& /* dcResponse */) {
rspInfo = info;
parent_v1_6.notify(info.serial);
return Void();
}
+
+Return<void> RadioResponse_v1_6::sendSmsResponse_1_6(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
+ const SendSmsResult& sms) {
+ rspInfo = info;
+ sendSmsResult = sms;
+ parent_v1_6.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_6::sendSMSExpectMoreResponse_1_6(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
+ const SendSmsResult& sms) {
+ rspInfo = info;
+ sendSmsResult = sms;
+ parent_v1_6.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_6::sendCdmaSmsResponse_1_6(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
+ const SendSmsResult& sms) {
+ rspInfo = info;
+ sendSmsResult = sms;
+ parent_v1_6.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_6::sendCdmaSmsExpectMoreResponse_1_6(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
+ const SendSmsResult& sms) {
+ rspInfo = info;
+ sendSmsResult = sms;
+ parent_v1_6.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_6::isNrDualConnectivityEnabledResponse(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info, bool isEnabled) {
+ rspInfo = info;
+ isNRDualConnectivityEnabled = isEnabled;
+ parent_v1_6.notify(info.serial);
+ return Void();
+}
diff --git a/radio/1.6/vts/functional/vts_test_util_v1_6.cpp b/radio/1.6/vts/functional/vts_test_util_v1_6.cpp
new file mode 100644
index 0000000..2653865
--- /dev/null
+++ b/radio/1.6/vts/functional/vts_test_util_v1_6.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "RadioTest"
+
+#include <vts_test_util_v1_6.h>
+#include <iostream>
+#include "VtsCoreUtil.h"
+
+::testing::AssertionResult CheckAnyOfErrors(
+ ::android::hardware::radio::V1_6::RadioError err,
+ std::vector<::android::hardware::radio::V1_6::RadioError> errors, CheckFlag flag) {
+ const static vector<::android::hardware::radio::V1_6::RadioError> generalErrors = {
+ ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE,
+ ::android::hardware::radio::V1_6::RadioError::NO_MEMORY,
+ ::android::hardware::radio::V1_6::RadioError::INTERNAL_ERR,
+ ::android::hardware::radio::V1_6::RadioError::SYSTEM_ERR,
+ ::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED,
+ ::android::hardware::radio::V1_6::RadioError::CANCELLED};
+ if (flag == CHECK_GENERAL_ERROR || flag == CHECK_OEM_AND_GENERAL_ERROR) {
+ for (size_t i = 0; i < generalErrors.size(); i++) {
+ if (err == generalErrors[i]) {
+ return testing::AssertionSuccess();
+ }
+ }
+ }
+ if (flag == CHECK_OEM_ERROR || flag == CHECK_OEM_AND_GENERAL_ERROR) {
+ if (err >= ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_1 &&
+ err <= ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_25) {
+ return testing::AssertionSuccess();
+ }
+ }
+ for (size_t i = 0; i < errors.size(); i++) {
+ if (err == errors[i]) {
+ return testing::AssertionSuccess();
+ }
+ }
+ return testing::AssertionFailure() << "RadioError:" + toString(err) + " is returned";
+}
diff --git a/radio/1.6/vts/functional/vts_test_util_v1_6.h b/radio/1.6/vts/functional/vts_test_util_v1_6.h
new file mode 100644
index 0000000..e04d201
--- /dev/null
+++ b/radio/1.6/vts/functional/vts_test_util_v1_6.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/hardware/radio/1.6/types.h>
+
+#include "vts_test_util.h"
+
+/*
+ * Check multiple radio error codes which are possibly returned because of the different
+ * vendor/devices implementations. It allows optional checks for general errors or/and oem errors.
+ */
+::testing::AssertionResult CheckAnyOfErrors(
+ ::android::hardware::radio::V1_6::RadioError err,
+ std::vector<::android::hardware::radio::V1_6::RadioError> generalError,
+ CheckFlag flag = CHECK_DEFAULT);
diff --git a/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h b/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h
index 2e5aca4..e674ddb 100644
--- a/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h
+++ b/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h
@@ -226,6 +226,7 @@
void activateAllSensors(bool enable);
std::vector<SensorInfoType> getNonOneShotSensors();
std::vector<SensorInfoType> getNonOneShotAndNonSpecialSensors();
+ std::vector<SensorInfoType> getNonOneShotAndNonOnChangeAndNonSpecialSensors();
std::vector<SensorInfoType> getOneShotSensors();
std::vector<SensorInfoType> getInjectEventSensors();
int32_t getInvalidSensorHandle();
@@ -326,6 +327,19 @@
return sensors;
}
+std::vector<SensorInfoType> SensorsHidlTest::getNonOneShotAndNonOnChangeAndNonSpecialSensors() {
+ std::vector<SensorInfoType> sensors;
+ for (const SensorInfoType& info : getSensorsList()) {
+ SensorFlagBits reportMode = extractReportMode(info.flags);
+ if (reportMode != SensorFlagBits::ONE_SHOT_MODE &&
+ reportMode != SensorFlagBits::ON_CHANGE_MODE &&
+ reportMode != SensorFlagBits::SPECIAL_REPORTING_MODE) {
+ sensors.push_back(info);
+ }
+ }
+ return sensors;
+}
+
std::vector<SensorInfoType> SensorsHidlTest::getOneShotSensors() {
std::vector<SensorInfoType> sensors;
for (const SensorInfoType& info : getSensorsList()) {
@@ -726,8 +740,8 @@
EventCallback callback;
getEnvironment()->registerCallback(&callback);
- // This test is not valid for one-shot or special-report-mode sensors
- const std::vector<SensorInfoType> sensors = getNonOneShotAndNonSpecialSensors();
+ // This test is not valid for one-shot, on-change or special-report-mode sensors
+ const std::vector<SensorInfoType> sensors = getNonOneShotAndNonOnChangeAndNonSpecialSensors();
milliseconds maxMinDelay(0);
for (const SensorInfoType& sensor : sensors) {
milliseconds minDelay = duration_cast<milliseconds>(microseconds(sensor.minDelay));
@@ -750,10 +764,7 @@
<< " handle=0x" << std::hex << std::setw(8) << std::setfill('0')
<< sensor.sensorHandle << std::dec << " type=" << static_cast<int>(sensor.type)
<< " name=" << sensor.name);
- // Some on-change sensors may not report an event without stimulus
- if (extractReportMode(sensor.flags) != SensorFlagBits::ON_CHANGE_MODE) {
- ASSERT_GE(callback.getEvents(sensor.sensorHandle).size(), 1);
- }
+
if (callback.getEvents(sensor.sensorHandle).size() >= 1) {
lastEventTimestampMap[sensor.sensorHandle] =
callback.getEvents(sensor.sensorHandle).back().timestamp;
@@ -779,10 +790,7 @@
if (lastEventTimestampMap.find(sensor.sensorHandle) == lastEventTimestampMap.end()) {
continue;
}
- // Skip on-change sensors that do not consistently report an initial event
- if (callback.getEvents(sensor.sensorHandle).size() < 1) {
- continue;
- }
+
// Ensure that the first event received is not stale by ensuring that its timestamp is
// sufficiently different from the previous event
const EventType newEvent = callback.getEvents(sensor.sensorHandle).front();
diff --git a/tests/baz/1.0/IBaz.hal b/tests/baz/1.0/IBaz.hal
index 7855446..8be1d61 100644
--- a/tests/baz/1.0/IBaz.hal
+++ b/tests/baz/1.0/IBaz.hal
@@ -94,7 +94,7 @@
int8_t[7] array;
string oneString;
vec<string> vectorOfStrings;
- IBase dummy;
+ interface iface;
};
oneway doThis(float param);
diff --git a/tests/msgq/1.0/default/Android.bp b/tests/msgq/1.0/default/Android.bp
index a5ba23d..6e7cd44 100644
--- a/tests/msgq/1.0/default/Android.bp
+++ b/tests/msgq/1.0/default/Android.bp
@@ -79,7 +79,11 @@
suffix: "64",
},
},
- test_suites: ["device-tests"],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+ auto_gen_config: false,
// Allow dlsym'ing self for statically linked passthrough implementations
ldflags: ["-rdynamic"],
@@ -89,7 +93,7 @@
static_libs: [
"android.hardware.tests.msgq@1.0",
"android.fmq.test-ndk_platform",
- "android.hardware.common-unstable-ndk_platform",
+ "android.hardware.common.fmq-unstable-ndk_platform",
],
whole_static_libs: [
"android.hardware.tests.msgq@1.0-impl",
diff --git a/tests/safeunion/1.0/Android.bp b/tests/safeunion/1.0/Android.bp
index 2937832..f1ec267 100644
--- a/tests/safeunion/1.0/Android.bp
+++ b/tests/safeunion/1.0/Android.bp
@@ -4,7 +4,6 @@
name: "android.hardware.tests.safeunion@1.0",
root: "android.hardware",
srcs: [
- "IOtherInterface.hal",
"ISafeUnion.hal",
],
interfaces: [
diff --git a/tests/safeunion/1.0/ISafeUnion.hal b/tests/safeunion/1.0/ISafeUnion.hal
index 58c08c6..01e1727 100644
--- a/tests/safeunion/1.0/ISafeUnion.hal
+++ b/tests/safeunion/1.0/ISafeUnion.hal
@@ -16,8 +16,6 @@
package android.hardware.tests.safeunion@1.0;
-import IOtherInterface;
-
import android.hidl.safe_union@1.0::Monostate;
interface ISafeUnion {
@@ -73,7 +71,7 @@
uint32_t a;
int8_t[7] b;
- IOtherInterface c;
+ interface c;
string d;
vec<string> e;
handle f;
@@ -107,7 +105,7 @@
newInterfaceTypeSafeUnion() generates (InterfaceTypeSafeUnion myUnion);
setInterfaceA(InterfaceTypeSafeUnion myUnion, uint32_t a) generates (InterfaceTypeSafeUnion myUnion);
setInterfaceB(InterfaceTypeSafeUnion myUnion, int8_t[7] b) generates (InterfaceTypeSafeUnion myUnion);
- setInterfaceC(InterfaceTypeSafeUnion myUnion, IOtherInterface c) generates (InterfaceTypeSafeUnion myUnion);
+ setInterfaceC(InterfaceTypeSafeUnion myUnion, interface c) generates (InterfaceTypeSafeUnion myUnion);
setInterfaceD(InterfaceTypeSafeUnion myUnion, string d) generates (InterfaceTypeSafeUnion myUnion);
setInterfaceE(InterfaceTypeSafeUnion myUnion, vec<string> e) generates (InterfaceTypeSafeUnion myUnion);
setInterfaceF(InterfaceTypeSafeUnion myUnion, handle f) generates (InterfaceTypeSafeUnion myUnion);
diff --git a/tests/safeunion/1.0/default/SafeUnion.cpp b/tests/safeunion/1.0/default/SafeUnion.cpp
index 4fb0974..667da6e 100644
--- a/tests/safeunion/1.0/default/SafeUnion.cpp
+++ b/tests/safeunion/1.0/default/SafeUnion.cpp
@@ -202,7 +202,9 @@
return Void();
}
-Return<void> SafeUnion::setInterfaceC(const InterfaceTypeSafeUnion& myUnion, const sp<::android::hardware::tests::safeunion::V1_0::IOtherInterface>& c, setInterfaceC_cb _hidl_cb) {
+Return<void> SafeUnion::setInterfaceC(const InterfaceTypeSafeUnion& myUnion,
+ const sp<::android::hidl::base::V1_0::IBase>& c,
+ setInterfaceC_cb _hidl_cb) {
LOG(INFO) << "SERVER(SafeUnion) setInterfaceC(myUnion, " << toString(c) << ")";
InterfaceTypeSafeUnion myNewUnion = myUnion;
diff --git a/tests/safeunion/1.0/default/SafeUnion.h b/tests/safeunion/1.0/default/SafeUnion.h
index ee3a954..b10575c 100644
--- a/tests/safeunion/1.0/default/SafeUnion.h
+++ b/tests/safeunion/1.0/default/SafeUnion.h
@@ -54,7 +54,9 @@
Return<void> newInterfaceTypeSafeUnion(newInterfaceTypeSafeUnion_cb _hidl_cb) override;
Return<void> setInterfaceA(const InterfaceTypeSafeUnion& myUnion, uint32_t a, setInterfaceA_cb _hidl_cb) override;
Return<void> setInterfaceB(const InterfaceTypeSafeUnion& myUnion, const hidl_array<int8_t, 7>& b, setInterfaceB_cb _hidl_cb) override;
- Return<void> setInterfaceC(const InterfaceTypeSafeUnion& myUnion, const sp<::android::hardware::tests::safeunion::V1_0::IOtherInterface>& c, setInterfaceC_cb _hidl_cb) override;
+ Return<void> setInterfaceC(const InterfaceTypeSafeUnion& myUnion,
+ const sp<::android::hidl::base::V1_0::IBase>& c,
+ setInterfaceC_cb _hidl_cb) override;
Return<void> setInterfaceD(const InterfaceTypeSafeUnion& myUnion, const hidl_string& d, setInterfaceD_cb _hidl_cb) override;
Return<void> setInterfaceE(const InterfaceTypeSafeUnion& myUnion, const hidl_vec<hidl_string>& e, setInterfaceE_cb _hidl_cb) override;
Return<void> setInterfaceF(const InterfaceTypeSafeUnion& myUnion, const hidl_handle& f,
diff --git a/tv/tuner/1.1/Android.bp b/tv/tuner/1.1/Android.bp
index 6cf47f5..daa3683 100644
--- a/tv/tuner/1.1/Android.bp
+++ b/tv/tuner/1.1/Android.bp
@@ -7,6 +7,7 @@
"IFilter.hal",
"IFrontend.hal",
"IFilterCallback.hal",
+ "IFrontendCallback.hal",
"ITuner.hal",
"types.hal",
],
diff --git a/tv/tuner/1.1/IFilter.hal b/tv/tuner/1.1/IFilter.hal
index 2ba9bb7..df736aa 100644
--- a/tv/tuner/1.1/IFilter.hal
+++ b/tv/tuner/1.1/IFilter.hal
@@ -70,4 +70,32 @@
* memory is not initialized.
*/
getAvSharedHandle() generates (Result result, handle avMemory, uint64_t avMemSize);
+
+ /**
+ * Configure A/V filter’s stream type. This API only applies to A/V filters.
+ *
+ * @param avStreamType the stream type for A/V.
+ * @return return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if configure can't be applied,
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ configureAvStreamType(AvStreamType avStreamType) generates (Result result);
+
+ /**
+ * Configure the filter to monitor specific Scrambling Status.
+ *
+ * Scrambling Status should be sent through the filer callback at the following two scenarios:
+ * 1. When this method is called, the first detected scrambling status should be sent.
+ * 2. When the filter transits into the monitored statuses configured through this method,
+ * event should be sent.
+ *
+ * @param statuses Scrambling Statuses to monitor. Set corresponding bit to monitor. Reset to
+ * stop monitoring.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if configure can't be applied,
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ configureScramblingEvent(bitfield<ScramblingStatus> statuses) generates (Result result);
};
diff --git a/tv/tuner/1.1/IFrontend.hal b/tv/tuner/1.1/IFrontend.hal
index 9858d4b..63f0655 100644
--- a/tv/tuner/1.1/IFrontend.hal
+++ b/tv/tuner/1.1/IFrontend.hal
@@ -37,7 +37,7 @@
*
* @param settings Signal delivery information the frontend uses to
* search and lock the signal.
- * @param settingsExt Extended information that would be used in the 1.1 Frontend to
+ * @param settingsExt1_1 v1_1 Extended information that would be used in the 1.1 Frontend to
* search and lock the signal in a better way.
*
* @return result Result status of the operation.
@@ -45,7 +45,7 @@
* INVALID_STATE if tuning can't be applied at current stage,
* UNKNOWN_ERROR if tuning failed for other reasons.
*/
- tune_1_1(FrontendSettings settings, FrontendSettingsExt settingsExt)
+ tune_1_1(FrontendSettings settings, FrontendSettingsExt1_1 settingsExt1_1)
generates (Result result);
/**
@@ -59,15 +59,15 @@
* @param settings Signal delivery information which the frontend uses to
* scan the signal.
* @param type the type which the frontend uses to scan the signal.
- * @param settingsExt Extended information that would be used in the 1.1 Frontend to
+ * @param settingsExt1_1 v1_1 Extended information that would be used in the 1.1 Frontend to
* search and lock the signal in a better way.
* @return result Result status of the operation.
* SUCCESS if successful,
* INVALID_STATE if tuning can't be applied at current stage,
* UNKNOWN_ERROR if tuning failed for other reasons.
*/
- scan_1_1(FrontendSettings settings, FrontendScanType type, FrontendSettingsExt settingsExt)
- generates (Result result);
+ scan_1_1(FrontendSettings settings, FrontendScanType type,
+ FrontendSettingsExt1_1 settingsExt1_1) generates (Result result);
/**
* Link Conditional Access Modules (CAM) to Frontend support Common Interface (CI) bypass mode.
@@ -77,9 +77,36 @@
* directly from the frontend.
*
* @param ciCamId specify CI-CAM Id to link.
+ * @return ltsId Local Transport Stream Id.
* @return result Result status of the operation.
* SUCCESS if successful,
* UNKNOWN_ERROR if failed for other reasons.
*/
- linkCiCam(uint32_t ciCamId) generates (Result result);
+ linkCiCam(uint32_t ciCamId) generates (Result result, uint32_t ltsId);
+
+ /**
+ * Unlink Conditional Access Modules (CAM) to Frontend.
+ *
+ * @param ciCamId specify CI-CAM Id to unlink.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ unlinkCiCam(uint32_t ciCamId) generates (Result result);
+
+ /**
+ * Get the v1_1 extended statuses of the frontend.
+ *
+ * This retrieve the extended statuses of the frontend for given extended status types.
+ *
+ * @param statusTypes an array of the extended status types which the caller request.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if tuning can't be applied at current stage,
+ * UNKNOWN_ERROR if tuning failed for other reasons.
+ * @return statuses an array of extended statuses the caller requests for.
+ */
+ getStatusExt1_1(vec<FrontendStatusTypeExt1_1> statusTypes)
+ generates (Result result, vec<FrontendStatusExt1_1> statuses);
};
diff --git a/tv/tuner/1.1/IFrontendCallback.hal b/tv/tuner/1.1/IFrontendCallback.hal
new file mode 100644
index 0000000..e148b1e
--- /dev/null
+++ b/tv/tuner/1.1/IFrontendCallback.hal
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.tuner@1.1;
+
+import @1.0::IFrontendCallback;
+import FrontendScanMessageExt1_1;
+import FrontendScanMessageTypeExt1_1;
+
+interface IFrontendCallback extends @1.0::IFrontendCallback {
+ /**
+ * The callback function that must be called by HAL implementation to notify
+ * the client of the v1_1 extended scan messages.
+ *
+ * @param type the type of v1_1 extended scan message.
+ * @param message the v1_1 extended scan message sent by HAL to the client.
+ */
+ onScanMessageExt1_1(FrontendScanMessageTypeExt1_1 type, FrontendScanMessageExt1_1 messageExt);
+};
diff --git a/tv/tuner/1.1/ITuner.hal b/tv/tuner/1.1/ITuner.hal
index 915fb85..d59c425 100644
--- a/tv/tuner/1.1/ITuner.hal
+++ b/tv/tuner/1.1/ITuner.hal
@@ -16,6 +16,7 @@
package android.hardware.tv.tuner@1.1;
+import @1.0::FrontendId;
import @1.0::ITuner;
import @1.0::Result;
@@ -23,4 +24,10 @@
* Top level interface to manage Frontend, Demux and Decrambler hardware
* resources which are needed for Android TV.
*/
-interface ITuner extends @1.0::ITuner {};
+interface ITuner extends @1.0::ITuner {
+ /**
+ * Get Dtmb Frontend Capabilities. If no dtmb exists, Result::UNAVAILABLE would be returned.
+ */
+ getFrontendDtmbCapabilities(FrontendId frontendId)
+ generates (Result result, FrontendDtmbCapabilities caps);
+};
diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp
index c69beca..4c37729 100644
--- a/tv/tuner/1.1/default/Filter.cpp
+++ b/tv/tuner/1.1/default/Filter.cpp
@@ -228,6 +228,49 @@
return Void();
}
+Return<Result> Filter::configureAvStreamType(const V1_1::AvStreamType& avStreamType) {
+ ALOGV("%s", __FUNCTION__);
+
+ if (!mIsMediaFilter) {
+ return Result::UNAVAILABLE;
+ }
+
+ switch (avStreamType.getDiscriminator()) {
+ case V1_1::AvStreamType::hidl_discriminator::audio:
+ mAudioStreamType = static_cast<uint32_t>(avStreamType.audio());
+ break;
+ case V1_1::AvStreamType::hidl_discriminator::video:
+ mVideoStreamType = static_cast<uint32_t>(avStreamType.video());
+ break;
+ default:
+ break;
+ }
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Filter::configureScramblingEvent(uint32_t statuses) {
+ ALOGV("%s", __FUNCTION__);
+
+ mStatuses = statuses;
+ if (mCallback_1_1 != nullptr) {
+ // Assuming current status is always NOT_SCRAMBLED
+ V1_1::DemuxFilterEventExt filterEventExt;
+ V1_1::DemuxFilterEventExt::Event event;
+ event.scramblingStatus(V1_1::ScramblingStatus::NOT_SCRAMBLED);
+ int size = filterEventExt.events.size();
+ filterEventExt.events.resize(size + 1);
+ filterEventExt.events[size] = event;
+ DemuxFilterEvent emptyFilterEvent;
+
+ mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, filterEventExt);
+ mFilterEventExt.events.resize(0);
+ } else {
+ return Result::INVALID_STATE;
+ }
+ return Result::SUCCESS;
+}
+
bool Filter::createFilterMQ() {
ALOGV("%s", __FUNCTION__);
@@ -319,17 +362,17 @@
while (mFilterThreadRunning) {
std::lock_guard<std::mutex> lock(mFilterEventLock);
- if (mFilterEvent.events.size() == 0) {
+ if (mFilterEvent.events.size() == 0 && mFilterEventExt.events.size() == 0) {
continue;
}
// After successfully write, send a callback and wait for the read to be done
- if (mCallback != nullptr) {
- mCallback->onFilterEvent(mFilterEvent);
- mFilterEvent.events.resize(0);
- } else if (mCallback_1_1 != nullptr) {
+ if (mCallback_1_1 != nullptr) {
mCallback_1_1->onFilterEvent_1_1(mFilterEvent, mFilterEventExt);
mFilterEventExt.events.resize(0);
+ } else if (mCallback != nullptr) {
+ mCallback->onFilterEvent(mFilterEvent);
}
+ mFilterEvent.events.resize(0);
break;
}
// We do not wait for the last read to be done
@@ -638,6 +681,8 @@
V1_1::DemuxFilterRecordEventExt recordEventExt;
recordEventExt = {
.pts = (mPts == 0) ? time(NULL) * 900000 : mPts,
+ .firstMbInSlice = 0, // random address
+ .mpuSequenceNumber = 1, // random sequence number
};
int size;
diff --git a/tv/tuner/1.1/default/Filter.h b/tv/tuner/1.1/default/Filter.h
index f677666..522db35 100644
--- a/tv/tuner/1.1/default/Filter.h
+++ b/tv/tuner/1.1/default/Filter.h
@@ -82,6 +82,10 @@
virtual Return<void> getAvSharedHandle(getAvSharedHandle_cb _hidl_cb) override;
+ virtual Return<Result> configureAvStreamType(const V1_1::AvStreamType& avStreamType) override;
+
+ virtual Return<Result> configureScramblingEvent(uint32_t statuses) override;
+
/**
* To create a FilterMQ and its Event Flag.
*
@@ -225,6 +229,12 @@
hidl_handle mSharedAvMemHandle;
bool mUsingSharedAvMem = true;
uint32_t mSharedAvMemOffset = 0;
+
+ uint32_t mAudioStreamType;
+ uint32_t mVideoStreamType;
+
+ // Scrambling status to be monitored
+ uint32_t mStatuses = 0;
};
} // namespace implementation
diff --git a/tv/tuner/1.1/default/Frontend.cpp b/tv/tuner/1.1/default/Frontend.cpp
index 467d547..6956f30 100644
--- a/tv/tuner/1.1/default/Frontend.cpp
+++ b/tv/tuner/1.1/default/Frontend.cpp
@@ -17,7 +17,7 @@
#define LOG_TAG "android.hardware.tv.tuner@1.1-Frontend"
#include "Frontend.h"
-#include <android/hardware/tv/tuner/1.0/IFrontendCallback.h>
+#include <android/hardware/tv/tuner/1.1/IFrontendCallback.h>
#include <utils/Log.h>
namespace android {
@@ -72,7 +72,7 @@
}
Return<Result> Frontend::tune_1_1(const FrontendSettings& settings,
- const V1_1::FrontendSettingsExt& /*settingsExt*/) {
+ const V1_1::FrontendSettingsExt1_1& /*settingsExt1_1*/) {
ALOGV("%s", __FUNCTION__);
return tune(settings);
}
@@ -118,11 +118,25 @@
mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg);
mIsLocked = true;
+ sp<V1_1::IFrontendCallback> frontendCallback_v1_1 =
+ V1_1::IFrontendCallback::castFrom(mCallback);
+ if (frontendCallback_v1_1 != NULL) {
+ V1_1::FrontendScanMessageExt1_1 msg;
+ msg.modulation().dvbc(FrontendDvbcModulation::MOD_16QAM);
+ frontendCallback_v1_1->onScanMessageExt1_1(V1_1::FrontendScanMessageTypeExt1_1::MODULATION,
+ msg);
+ msg.isHighPriority(true);
+ frontendCallback_v1_1->onScanMessageExt1_1(
+ V1_1::FrontendScanMessageTypeExt1_1::HIGH_PRIORITY, msg);
+ } else {
+ ALOGD("[Filter] Couldn't cast to V1_1 IFrontendCallback");
+ }
+
return Result::SUCCESS;
}
Return<Result> Frontend::scan_1_1(const FrontendSettings& settings, FrontendScanType type,
- const V1_1::FrontendSettingsExt& /*settingsExt*/) {
+ const V1_1::FrontendSettingsExt1_1& /*settingsExt1_1*/) {
ALOGV("%s", __FUNCTION__);
return scan(settings, type);
}
@@ -259,6 +273,107 @@
return Void();
}
+Return<void> Frontend::getStatusExt1_1(const hidl_vec<V1_1::FrontendStatusTypeExt1_1>& statusTypes,
+ V1_1::IFrontend::getStatusExt1_1_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ vector<V1_1::FrontendStatusExt1_1> statuses;
+ for (int i = 0; i < statusTypes.size(); i++) {
+ V1_1::FrontendStatusTypeExt1_1 type = statusTypes[i];
+ V1_1::FrontendStatusExt1_1 status;
+ // assign randomly selected values for testing.
+ switch (type) {
+ case V1_1::FrontendStatusTypeExt1_1::MODULATIONS: {
+ vector<V1_1::FrontendModulation> modulations;
+ V1_1::FrontendModulation modulation;
+ modulation.isdbt(FrontendIsdbtModulation::MOD_16QAM); // value = 1 << 3
+ modulations.push_back(modulation);
+ status.modulations(modulations);
+ break;
+ }
+ case V1_1::FrontendStatusTypeExt1_1::BERS: {
+ vector<uint32_t> bers = {1};
+ status.bers(bers);
+ break;
+ }
+ case V1_1::FrontendStatusTypeExt1_1::CODERATES: {
+ // value = 1 << 39
+ vector<V1_1::FrontendInnerFec> codeRates = {V1_1::FrontendInnerFec::FEC_6_15};
+ status.codeRates(codeRates);
+ break;
+ }
+ case V1_1::FrontendStatusTypeExt1_1::BANDWIDTH: {
+ V1_1::FrontendBandwidth bandwidth;
+ bandwidth.dvbt(FrontendDvbtBandwidth::BANDWIDTH_8MHZ);
+ status.bandwidth(bandwidth);
+ break;
+ }
+ case V1_1::FrontendStatusTypeExt1_1::GUARD_INTERVAL: {
+ V1_1::FrontendGuardInterval interval;
+ interval.dvbt(FrontendDvbtGuardInterval::INTERVAL_1_32); // value = 1 << 1
+ status.interval(interval);
+ break;
+ }
+ case V1_1::FrontendStatusTypeExt1_1::TRANSMISSION_MODE: {
+ V1_1::FrontendTransmissionMode transMode;
+ transMode.dvbt(V1_1::FrontendDvbtTransmissionMode::AUTO); // value = 1 << 0
+ status.transmissionMode(transMode);
+ break;
+ }
+ case V1_1::FrontendStatusTypeExt1_1::UEC: {
+ status.uec(4);
+ break;
+ }
+ case V1_1::FrontendStatusTypeExt1_1::T2_SYSTEM_ID: {
+ status.systemId(5);
+ break;
+ }
+ case V1_1::FrontendStatusTypeExt1_1::INTERLEAVINGS: {
+ V1_1::FrontendInterleaveMode interleave;
+ interleave.atsc3(FrontendAtsc3TimeInterleaveMode::AUTO);
+ vector<V1_1::FrontendInterleaveMode> interleaving = {interleave};
+ status.interleaving(interleaving);
+ break;
+ }
+ case V1_1::FrontendStatusTypeExt1_1::ISDBT_SEGMENTS: {
+ vector<uint8_t> segments = {2, 3};
+ status.isdbtSegment(segments);
+ break;
+ }
+ case V1_1::FrontendStatusTypeExt1_1::TS_DATA_RATES: {
+ vector<uint32_t> dataRates = {4, 5};
+ status.tsDataRate(dataRates);
+ break;
+ }
+ case V1_1::FrontendStatusTypeExt1_1::ROLL_OFF: {
+ V1_1::FrontendRollOff rollOff;
+ rollOff.dvbs(FrontendDvbsRolloff::ROLLOFF_0_35);
+ status.rollOff(rollOff);
+ break;
+ }
+ case V1_1::FrontendStatusTypeExt1_1::IS_MISO: {
+ status.isMiso(true);
+ break;
+ }
+ case V1_1::FrontendStatusTypeExt1_1::IS_LINEAR: {
+ status.isLinear(true);
+ break;
+ }
+ case V1_1::FrontendStatusTypeExt1_1::IS_SHORT_FRAMES: {
+ status.isShortFrames(true);
+ break;
+ }
+ default: {
+ continue;
+ }
+ }
+ statuses.push_back(status);
+ }
+ _hidl_cb(Result::SUCCESS, statuses);
+
+ return Void();
+}
+
Return<Result> Frontend::setLna(bool /* bEnable */) {
ALOGV("%s", __FUNCTION__);
@@ -273,10 +388,19 @@
return Result::SUCCESS;
}
-Return<Result> Frontend::linkCiCam(uint32_t ciCamId) {
+Return<void> Frontend::linkCiCam(uint32_t ciCamId, linkCiCam_cb _hidl_cb) {
ALOGV("%s", __FUNCTION__);
mCiCamId = ciCamId;
+ _hidl_cb(Result::SUCCESS, 0 /*ltsId*/);
+
+ return Void();
+}
+
+Return<Result> Frontend::unlinkCiCam(uint32_t /*ciCamId*/) {
+ ALOGV("%s", __FUNCTION__);
+
+ mCiCamId = -1;
return Result::SUCCESS;
}
diff --git a/tv/tuner/1.1/default/Frontend.h b/tv/tuner/1.1/default/Frontend.h
index 6a80232..a28fb64 100644
--- a/tv/tuner/1.1/default/Frontend.h
+++ b/tv/tuner/1.1/default/Frontend.h
@@ -44,25 +44,31 @@
virtual Return<Result> tune(const FrontendSettings& settings) override;
virtual Return<Result> tune_1_1(const FrontendSettings& settings,
- const V1_1::FrontendSettingsExt& settingsExt) override;
+ const V1_1::FrontendSettingsExt1_1& settingsExt1_1) override;
virtual Return<Result> stopTune() override;
virtual Return<Result> scan(const FrontendSettings& settings, FrontendScanType type) override;
virtual Return<Result> scan_1_1(const FrontendSettings& settings, FrontendScanType type,
- const V1_1::FrontendSettingsExt& settingsExt) override;
+ const V1_1::FrontendSettingsExt1_1& settingsExt1_1) override;
virtual Return<Result> stopScan() override;
virtual Return<void> getStatus(const hidl_vec<FrontendStatusType>& statusTypes,
getStatus_cb _hidl_cb) override;
+ virtual Return<void> getStatusExt1_1(
+ const hidl_vec<V1_1::FrontendStatusTypeExt1_1>& statusTypes,
+ V1_1::IFrontend::getStatusExt1_1_cb _hidl_cb) override;
+
virtual Return<Result> setLna(bool bEnable) override;
virtual Return<Result> setLnb(uint32_t lnb) override;
- virtual Return<Result> linkCiCam(uint32_t ciCamId) override;
+ virtual Return<void> linkCiCam(uint32_t ciCamId, linkCiCam_cb _hidl_cb) override;
+
+ virtual Return<Result> unlinkCiCam(uint32_t ciCamId) override;
FrontendType getFrontendType();
diff --git a/tv/tuner/1.1/default/Tuner.cpp b/tv/tuner/1.1/default/Tuner.cpp
index 87a4d36..c3dcd1d 100644
--- a/tv/tuner/1.1/default/Tuner.cpp
+++ b/tv/tuner/1.1/default/Tuner.cpp
@@ -33,7 +33,7 @@
Tuner::Tuner() {
// Static Frontends array to maintain local frontends information
// Array index matches their FrontendId in the default impl
- mFrontendSize = 8;
+ mFrontendSize = 9;
mFrontends[0] = new Frontend(FrontendType::DVBT, 0, this);
mFrontends[1] = new Frontend(FrontendType::ATSC, 1, this);
mFrontends[2] = new Frontend(FrontendType::DVBC, 2, this);
@@ -42,6 +42,8 @@
mFrontends[5] = new Frontend(FrontendType::ISDBT, 5, this);
mFrontends[6] = new Frontend(FrontendType::ANALOG, 6, this);
mFrontends[7] = new Frontend(FrontendType::ATSC, 7, this);
+ mFrontends[8] =
+ new Frontend(static_cast<V1_0::FrontendType>(V1_1::FrontendType::DTMB), 8, this);
FrontendInfo::FrontendCapabilities caps;
caps = FrontendInfo::FrontendCapabilities();
@@ -224,6 +226,20 @@
return Void();
}
+Return<void> Tuner::getFrontendDtmbCapabilities(uint32_t frontendId,
+ getFrontendDtmbCapabilities_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ if (mFrontends[frontendId] != nullptr &&
+ (mFrontends[frontendId]->getFrontendType() ==
+ static_cast<V1_0::FrontendType>(V1_1::FrontendType::DTMB))) {
+ _hidl_cb(Result::SUCCESS, mDtmbCaps);
+ } else {
+ _hidl_cb(Result::UNAVAILABLE, mDtmbCaps);
+ }
+ return Void();
+}
+
void Tuner::setFrontendAsDemuxSource(uint32_t frontendId, uint32_t demuxId) {
mFrontendToDemux[frontendId] = demuxId;
if (mFrontends[frontendId] != nullptr && mFrontends[frontendId]->isLocked()) {
diff --git a/tv/tuner/1.1/default/Tuner.h b/tv/tuner/1.1/default/Tuner.h
index 3b1574b..fda3636 100644
--- a/tv/tuner/1.1/default/Tuner.h
+++ b/tv/tuner/1.1/default/Tuner.h
@@ -62,6 +62,9 @@
virtual Return<void> openLnbByName(const hidl_string& lnbName,
openLnbByName_cb _hidl_cb) override;
+ virtual Return<void> getFrontendDtmbCapabilities(
+ uint32_t frontendId, getFrontendDtmbCapabilities_cb _hidl_cb) override;
+
sp<Frontend> getFrontendById(uint32_t frontendId);
void setFrontendAsDemuxSource(uint32_t frontendId, uint32_t demuxId);
@@ -76,6 +79,7 @@
// Static mFrontends array to maintain local frontends information
map<uint32_t, sp<Frontend>> mFrontends;
map<uint32_t, FrontendInfo::FrontendCapabilities> mFrontendCaps;
+ V1_1::FrontendDtmbCapabilities mDtmbCaps;
map<uint32_t, uint32_t> mFrontendToDemux;
map<uint32_t, sp<Demux>> mDemuxes;
// To maintain how many Frontends we have
diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal
index af8d628..defc99b 100644
--- a/tv/tuner/1.1/types.hal
+++ b/tv/tuner/1.1/types.hal
@@ -19,19 +19,46 @@
import @1.0::Constant;
import @1.0::DemuxFilterMmtpRecordEvent;
import @1.0::DemuxFilterTsRecordEvent;
+import @1.0::DemuxScIndex;
+import @1.0::FrontendIsdbs3Rolloff;
+import @1.0::FrontendAtsc3Bandwidth;
+import @1.0::FrontendAtsc3Modulation;
+import @1.0::FrontendAtsc3TimeInterleaveMode;
+import @1.0::FrontendIsdbsRolloff;
+import @1.0::FrontendAtscModulation;
+import @1.0::FrontendDvbcAnnex;
+import @1.0::FrontendDvbcModulation;
import @1.0::FrontendDvbcSpectralInversion;
+import @1.0::FrontendDvbsModulation;
+import @1.0::FrontendDvbsRolloff;
+import @1.0::FrontendDvbtBandwidth;
import @1.0::FrontendDvbtConstellation;
import @1.0::FrontendDvbtTransmissionMode;
+import @1.0::FrontendDvbtGuardInterval;
+import @1.0::FrontendInnerFec;
+import @1.0::FrontendIsdbs3Modulation;
+import @1.0::FrontendIsdbsModulation;
+import @1.0::FrontendIsdbtBandwidth;
+import @1.0::FrontendIsdbtGuardInterval;
+import @1.0::FrontendIsdbtMode;
+import @1.0::FrontendIsdbtModulation;
+import @1.0::FrontendScanMessageType;
+import @1.0::FrontendStatusType;
+import @1.0::FrontendType;
import android.hidl.safe_union@1.0;
import android.hidl.safe_union@1.0::Monostate;
@export
enum Constant : @1.0::Constant {
/**
- * An invalid mpuSequenceNumber in DemuxFilterMmtpRecordEvent.
+ * An invalid mpuSequenceNumber in DemuxFilterRecordEventExt.
*/
INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM = 0xFFFFFFFF,
/**
+ * An invalid first macroblock address in DemuxFilterRecordEventExt.
+ */
+ INVALID_FIRST_MACROBLOCK_IN_SLICE = 0xFFFFFFFF,
+ /**
* An invalid frenquency that can be used as the default value of the frontend setting.
*/
INVALID_FRONTEND_SETTING_FREQUENCY = 0xFFFFFFFF,
@@ -40,6 +67,11 @@
* be used to reset the configured ip context id.
*/
INVALID_IP_FILTER_CONTEXT_ID = 0xFFFFFFFF,
+ /**
+ * An invalid local transport stream id used as the return value on a failed operation of
+ * IFrontend.linkCiCam.
+ */
+ INVALID_LTS_ID = 0xFFFFFFFF,
};
@export
@@ -53,7 +85,7 @@
*/
INVALID_AV_SYNC_ID_64BIT = 0xFFFFFFFFFFFFFFFF,
/**
- * An invalid pts in the DemuxFilterTsRecordEvent or DemuxFilterMmtpRecordEvent.
+ * An invalid pts.
*/
INVALID_PRESENTATION_TIME_STAMP = 0xFFFFFFFFFFFFFFFF,
};
@@ -64,8 +96,7 @@
struct DemuxFilterRecordEventExt {
/**
* The Presentation Time Stamp(PTS) for the audio or video frame. It is based on 90KHz
- * and has the same format as the PTS in ISO/IEC 13818-1. It is used only for the SC and
- * the SC_HEVC.
+ * and has the same format as the PTS in ISO/IEC 13818-1.
*/
uint64_t pts;
@@ -73,6 +104,11 @@
* MPU sequence number of the filtered data. This is only used for MMTP.
*/
uint32_t mpuSequenceNumber;
+
+ /**
+ * Specifies the address of the first macroblock in the slice defined in ITU-T Rec. H.264.
+ */
+ uint32_t firstMbInSlice;
};
/**
@@ -89,6 +125,8 @@
DemuxFilterRecordEventExt tsRecord;
DemuxFilterRecordEventExt mmtpRecord;
+
+ ScramblingStatus scramblingStatus;
};
/**
@@ -97,6 +135,25 @@
vec<Event> events;
};
+/**
+ * Scrambling Status Type.
+ */
+@export
+enum ScramblingStatus : uint32_t {
+ /**
+ * Content’s scrambling status is unknown
+ */
+ UNKNOWN = 1 << 0,
+ /**
+ * Content is not scrambled.
+ */
+ NOT_SCRAMBLED = 1 << 1,
+ /**
+ * Content is scrambled.
+ */
+ SCRAMBLED = 1 << 2,
+};
+
typedef FrontendDvbcSpectralInversion FrontendSpectralInversion;
/**
@@ -122,6 +179,24 @@
};
/**
+ * Time Interleave Mode for DVBC Frontend.
+ */
+@export
+enum FrontendCableTimeInterleaveMode : uint32_t {
+ UNDEFINED = 0,
+ AUTO = 1 << 0,
+ INTERLEAVING_128_1_0 = 1 << 1,
+ INTERLEAVING_128_1_1 = 1 << 2,
+ INTERLEAVING_64_2 = 1 << 3,
+ INTERLEAVING_32_4 = 1 << 4,
+ INTERLEAVING_16_8 = 1 << 5,
+ INTERLEAVING_8_16 = 1 << 6,
+ INTERLEAVING_128_2 = 1 << 7,
+ INTERLEAVING_128_3 = 1 << 8,
+ INTERLEAVING_128_4 = 1 << 9,
+};
+
+/**
* Extended Transmission Mode for DVBT.
*/
@export
@@ -145,14 +220,16 @@
/**
* Extended Signal Settings for a DVBS Frontend.
*/
-struct FrontendDvbsSettingsExt {
+struct FrontendDvbsSettingsExt1_1 {
FrontendDvbsScanType scanType;
+
+ bool isDiseqcRxMessage;
};
/**
* Extended Signal Settings for a DVBT Frontend.
*/
-struct FrontendDvbtSettingsExt {
+struct FrontendDvbtSettingsExt1_1 {
FrontendDvbtConstellation constellation;
FrontendDvbtTransmissionMode transmissionMode;
@@ -161,14 +238,23 @@
/**
* Extended Signal Settings for an Analog Frontend.
*/
-struct FrontendAnalogSettingsExt {
+struct FrontendAnalogSettingsExt1_1 {
FrontendAnalogAftFlag aftFlag;
};
/**
+ * Extended Signal Settings for DVBC Frontend.
+ */
+struct FrontendDvbcSettingsExt1_1 {
+ FrontendCableTimeInterleaveMode interleaveMode;
+
+ FrontendDvbcBandwidth bandwidth;
+};
+
+/**
* Extended Signal Settings for Frontend.
*/
-struct FrontendSettingsExt {
+struct FrontendSettingsExt1_1 {
uint32_t endFrequency;
FrontendSpectralInversion inversion;
@@ -176,10 +262,557 @@
safe_union SettingsExt {
Monostate noinit;
- FrontendAnalogSettingsExt analog;
+ FrontendAnalogSettingsExt1_1 analog;
- FrontendDvbsSettingsExt dvbs;
+ FrontendDvbcSettingsExt1_1 dvbc;
- FrontendDvbtSettingsExt dvbt;
+ FrontendDvbsSettingsExt1_1 dvbs;
+
+ FrontendDvbtSettingsExt1_1 dvbt;
+
+ FrontendDtmbSettings dtmb;
} settingExt;
};
+
+/**
+ * Extended Frontend Type.
+ */
+@export
+enum FrontendType : @1.0::FrontendType {
+ /**
+ * DTMB (Digital Terrestrial Multimedia Broadcast) standard.
+ */
+ DTMB,
+};
+
+/**
+ * Bandwidth Type for Cable Frontend.
+ */
+@export
+enum FrontendDvbcBandwidth : uint32_t {
+ UNDEFINED = 0,
+ BANDWIDTH_5MHZ = 1 << 0,
+ BANDWIDTH_6MHZ = 1 << 1,
+ BANDWIDTH_7MHZ = 1 << 2,
+ BANDWIDTH_8MHZ = 1 << 3,
+};
+
+/**
+ * Bandwidth Type for DTMB.
+ */
+@export
+enum FrontendDtmbBandwidth : uint32_t {
+ UNDEFINED = 0,
+ /**
+ * hardware is able to detect and set Bandwidth automatically
+ */
+ AUTO = 1 << 0,
+ BANDWIDTH_8MHZ = 1 << 1,
+ BANDWIDTH_6MHZ = 1 << 2,
+};
+
+/**
+ * TimeInterleaveMode Type for DTMB.
+ */
+@export
+enum FrontendDtmbTimeInterleaveMode : uint32_t {
+ UNDEFINED = 0,
+ /**
+ * hardware is able to detect and set time interleave mode automatically
+ */
+ AUTO = 1 << 0,
+ TIMER_INT_240 = 1 << 1,
+ TIMER_INT_720 = 1 << 2,
+};
+
+/**
+ * FrontendDtmbModulation Type for DTMB.
+ */
+@export
+enum FrontendDtmbModulation : uint32_t {
+ UNDEFINED = 0,
+ /**
+ * hardware is able to detect and set Constellation automatically
+ */
+ AUTO = 1 << 0,
+ CONSTELLATION_4QAM = 1 << 1,
+ CONSTELLATION_4QAM_NR = 1 << 2,
+ CONSTELLATION_16QAM = 1 << 3,
+ CONSTELLATION_32QAM = 1 << 4,
+ CONSTELLATION_64QAM = 1 << 5,
+};
+
+/**
+ * CODERATE Type for DTMB.
+ */
+@export
+enum FrontendDtmbCodeRate : uint32_t {
+ UNDEFINED = 0,
+ /**
+ * hardware is able to detect and set code rate automatically
+ */
+ AUTO = 1 << 0,
+ CODERATE_2_5 = 1 << 1,
+ CODERATE_3_5 = 1 << 2,
+ CODERATE_4_5 = 1 << 3,
+};
+
+/**
+ * Guard Interval Type for DTMB.
+ */
+@export
+enum FrontendDtmbGuardInterval : uint32_t {
+ UNDEFINED = 0,
+ /**
+ * hardware is able to detect and set Guard Interval automatically
+ */
+ AUTO = 1 << 0,
+ PN_420_VARIOUS = 1 << 1,
+ PN_595_CONST = 1 << 2,
+ PN_945_VARIOUS = 1 << 3,
+ PN_420_CONST = 1 << 4,
+ PN_945_CONST = 1 << 5,
+ PN_RESERVED = 1 << 6,
+};
+
+/**
+ * Transmission Mode for DTMB.
+ */
+@export
+enum FrontendDtmbTransmissionMode : uint32_t {
+ UNDEFINED = 0,
+ /**
+ * hardware is able to detect and set Transmission Mode automatically
+ */
+ AUTO = 1 << 0,
+ C1 = 1 << 1,
+ C3780 = 1 << 2,
+};
+
+/**
+ * Signal Setting for DTMB Frontend.
+ */
+struct FrontendDtmbSettings {
+ uint32_t frequency;
+
+ FrontendDtmbTransmissionMode transmissionMode;
+
+ FrontendDtmbBandwidth bandwidth;
+
+ FrontendDtmbModulation modulation;
+
+ FrontendDtmbCodeRate codeRate;
+
+ FrontendDtmbGuardInterval guardInterval;
+
+ FrontendDtmbTimeInterleaveMode interleaveMode;
+};
+
+/**
+ * Capabilities for DTMB Frontend.
+ */
+struct FrontendDtmbCapabilities {
+ bitfield<FrontendDtmbTransmissionMode> transmissionModeCap;
+
+ bitfield<FrontendDtmbBandwidth> bandwidthCap;
+
+ bitfield<FrontendDtmbModulation> modulationCap;
+
+ bitfield<FrontendDtmbCodeRate> codeRateCap;
+
+ bitfield<FrontendDtmbGuardInterval> guardIntervalCap;
+
+ bitfield<FrontendDtmbTimeInterleaveMode> interleaveModeCap;
+};
+
+safe_union FrontendModulation {
+ @1.0::FrontendDvbcModulation dvbc;
+
+ @1.0::FrontendDvbsModulation dvbs;
+
+ FrontendDvbtConstellation dvbt;
+
+ @1.0::FrontendIsdbsModulation isdbs;
+
+ @1.0::FrontendIsdbs3Modulation isdbs3;
+
+ @1.0::FrontendIsdbtModulation isdbt;
+
+ @1.0::FrontendAtscModulation atsc;
+
+ @1.0::FrontendAtsc3Modulation atsc3;
+
+ FrontendDtmbModulation dtmb;
+};
+
+safe_union FrontendInterleaveMode {
+ @1.0::FrontendAtsc3TimeInterleaveMode atsc3;
+
+ FrontendCableTimeInterleaveMode dvbc;
+
+ FrontendDtmbTimeInterleaveMode dtmb;
+};
+
+@export
+enum FrontendInnerFec : @1.0::FrontendInnerFec {
+ FEC_2_15 = 1 << 36,
+ FEC_3_15 = 1 << 37,
+ FEC_5_15 = 1 << 38,
+ FEC_6_15 = 1 << 39,
+ FEC_9_15 = 1 << 40,
+ FEC_10_15 = 1 << 41,
+ FEC_12_15 = 1 << 42,
+ FEC_13_15 = 1 << 43,
+ FEC_18_30 = 1 << 44,
+ FEC_20_30 = 1 << 45,
+ FEC_90_180 = 1 << 46,
+ FEC_96_180 = 1 << 47,
+ FEC_104_180 = 1 << 48,
+ FEC_128_180 = 1 << 49,
+ FEC_132_180 = 1 << 50,
+ FEC_135_180 = 1 << 51,
+ FEC_140_180 = 1 << 52,
+};
+
+safe_union FrontendBandwidth {
+ @1.0::FrontendAtsc3Bandwidth atsc3;
+
+ FrontendDvbcBandwidth dvbc;
+
+ @1.0::FrontendDvbtBandwidth dvbt;
+
+ @1.0::FrontendIsdbtBandwidth isdbt;
+
+ FrontendDtmbBandwidth dtmb;
+};
+
+safe_union FrontendGuardInterval {
+ @1.0::FrontendDvbtGuardInterval dvbt;
+
+ @1.0::FrontendIsdbtGuardInterval isdbt;
+
+ FrontendDtmbGuardInterval dtmb;
+};
+
+safe_union FrontendTransmissionMode {
+ FrontendDvbtTransmissionMode dvbt;
+
+ @1.0::FrontendIsdbtMode isdbt;
+
+ FrontendDtmbTransmissionMode dtmb;
+};
+
+safe_union FrontendRollOff {
+ @1.0::FrontendDvbsRolloff dvbs;
+
+ @1.0::FrontendIsdbsRolloff isdbs;
+
+ @1.0::FrontendIsdbs3Rolloff isdbs3;
+};
+
+@export
+enum FrontendStatusTypeExt1_1 : uint32_t {
+ /**
+ * Modulation Types.
+ */
+ MODULATIONS = @1.0::FrontendStatusType:ATSC3_PLP_INFO + 1,
+ /**
+ * Bit Error Ratios.
+ */
+ BERS,
+ /**
+ * Code Rates.
+ */
+ CODERATES,
+ /**
+ * Extended Bandwidth.
+ */
+ BANDWIDTH,
+ /**
+ * Extended Guard Intervals.
+ */
+ GUARD_INTERVAL,
+ /**
+ * Extended Transmission Mode.
+ */
+ TRANSMISSION_MODE,
+ /**
+ * Uncorrectable Error Counts of the frontend's Physical Layer Pipe (PLP)
+ * since the last tune operation.
+ */
+ UEC,
+ /**
+ * DVB-T2 System Id.
+ */
+ T2_SYSTEM_ID,
+ /**
+ * Frontend Interleaving Modes.
+ */
+ INTERLEAVINGS,
+ /**
+ * Segments in ISDB-T Specification of all the channels.
+ */
+ ISDBT_SEGMENTS,
+ /**
+ * Transport Stream Data Rate in BPS of the current channel.
+ */
+ TS_DATA_RATES,
+ /**
+ * Roll Off Type status of the frontend.
+ */
+ ROLL_OFF,
+ /**
+ * If the frontend currently supports MISO or not.
+ */
+ IS_MISO,
+ /**
+ * If the frontend code rate is linear or not.
+ */
+ IS_LINEAR,
+ /**
+ * If short frames is enabled or not.
+ */
+ IS_SHORT_FRAMES,
+};
+
+safe_union FrontendStatusExt1_1 {
+ /**
+ * Extended modulation status.
+ */
+ vec<FrontendModulation> modulations;
+
+ /**
+ * Extended bit error ratio status.
+ */
+ vec<uint32_t> bers;
+
+ /**
+ * Extended code rate status.
+ */
+ vec<FrontendInnerFec> codeRates;
+
+ /**
+ * Extended bandwidth status.
+ */
+ FrontendBandwidth bandwidth;
+
+ /**
+ * Extended guard interval status.
+ */
+ FrontendGuardInterval interval;
+
+ /**
+ * Extended transmission mode status.
+ */
+ FrontendTransmissionMode transmissionMode;
+
+ /**
+ * Uncorrectable Error Counts of the frontend's Physical Layer Pipe (PLP)
+ * since the last tune operation.
+ */
+ uint32_t uec;
+
+ /**
+ * The current DVB-T2 system id status.
+ */
+ uint16_t systemId;
+
+ /**
+ * Frontend Interleaving Modes.
+ */
+ vec<FrontendInterleaveMode> interleaving;
+
+ /**
+ * Segments in ISDB-T Specification of all the channels.
+ */
+ vec<uint8_t> isdbtSegment;
+
+ /**
+ * Transport Stream Data Rate in BPS of the current channel.
+ */
+ vec<uint32_t> tsDataRate;
+ /**
+ * Roll Off Type status of the frontend.
+ */
+ FrontendRollOff rollOff;
+ /**
+ * If the frontend currently supports MISO or not.
+ */
+ bool isMiso;
+ /**
+ * If the frontend code rate is linear or not.
+ */
+ bool isLinear;
+ /**
+ * If short frames is enabled or not.
+ */
+ bool isShortFrames;
+};
+
+enum FrontendScanMessageTypeExt1_1 : uint32_t {
+ MODULATION = @1.0::FrontendScanMessageType:ATSC3_PLP_INFO + 1,
+ DVBC_ANNEX,
+ HIGH_PRIORITY,
+};
+
+safe_union FrontendScanMessageExt1_1 {
+ FrontendModulation modulation;
+
+ @1.0::FrontendDvbcAnnex annex;
+
+ bool isHighPriority;
+};
+
+@export
+enum VideoStreamType : uint32_t {
+ UNDEFINED,
+ /*
+ * ITU-T | ISO/IEC Reserved
+ */
+ RESERVED,
+ /*
+ * ISO/IEC 11172
+ */
+ MPEG1,
+ /*
+ * ITU-T Rec.H.262 and ISO/IEC 13818-2
+ */
+ MPEG2,
+ /*
+ * ISO/IEC 14496-2 (MPEG-4 H.263 based video)
+ */
+ MPEG4P2,
+ /*
+ * ITU-T Rec.H.264 and ISO/IEC 14496-10
+ */
+ AVC,
+ /*
+ * ITU-T Rec. H.265 and ISO/IEC 23008-2
+ */
+ HEVC,
+ /*
+ * Microsoft VC.1
+ */
+ VC1,
+ /*
+ * Google VP8
+ */
+ VP8,
+ /*
+ * Google VP9
+ */
+ VP9,
+ /*
+ * AOMedia Video 1
+ */
+ AV1,
+ /*
+ * Chinese Standard
+ */
+ AVS,
+ /*
+ * New Chinese Standard
+ */
+ AVS2,
+};
+
+@export
+enum AudioStreamType : uint32_t {
+ UNDEFINED,
+ /*
+ * Uncompressed Audio
+ */
+ PCM,
+ /*
+ * MPEG Audio Layer III versions
+ */
+ MP3,
+ /*
+ * ISO/IEC 11172 Audio
+ */
+ MPEG1,
+ /*
+ * ISO/IEC 13818-3
+ */
+ MPEG2,
+ /*
+ * ISO/IEC 23008-3 (MPEG-H Part 3)
+ */
+ MPEGH,
+ /*
+ * ISO/IEC 14496-3
+ */
+ AAC,
+ /*
+ * Dolby Digital
+ */
+ AC3,
+ /*
+ * Dolby Digital Plus
+ */
+ EAC3,
+ /*
+ * Dolby AC-4
+ */
+ AC4,
+ /*
+ * Basic DTS
+ */
+ DTS,
+ /*
+ * High Resolution DTS
+ */
+ DTS_HD,
+ /*
+ * Windows Media Audio
+ */
+ WMA,
+ /*
+ * Opus Interactive Audio Codec
+ */
+ OPUS,
+ /*
+ * VORBIS Interactive Audio Codec
+ */
+ VORBIS,
+ /*
+ * SJ/T 11368-2006
+ */
+ DRA,
+};
+
+/**
+ * Stream type for A/V filter.
+ */
+safe_union AvStreamType {
+ VideoStreamType video;
+
+ AudioStreamType audio;
+};
+
+/**
+ * Indexes can be tagged by start point of slice groups according to ISO/IEC 14496-10.
+ */
+@export
+enum DemuxScIndex : @1.0::DemuxScIndex {
+ /**
+ * All blocks are coded as I blocks.
+ */
+ I_SLICE = 1 << 4,
+ /**
+ * Blocks are coded as I or P blocks.
+ */
+ P_SLICE = 1 << 5,
+ /**
+ * Blocks are coded as I, P or B blocks.
+ */
+ B_SLICE = 1 << 6,
+ /**
+ * A so-called switching I slice that is coded.
+ */
+ SI_SLICE = 1 << 7,
+ /**
+ * A so-called switching P slice that is coded.
+ */
+ SP_SLICE = 1 << 8,
+};
diff --git a/tv/tuner/1.1/vts/functional/DvrTests.cpp b/tv/tuner/1.1/vts/functional/DvrTests.cpp
index 0dfc032..1e478f5 100644
--- a/tv/tuner/1.1/vts/functional/DvrTests.cpp
+++ b/tv/tuner/1.1/vts/functional/DvrTests.cpp
@@ -192,9 +192,10 @@
bool DvrCallback::readRecordFMQ() {
android::Mutex::Autolock autoLock(mMsgLock);
bool result = false;
+ int readSize = mRecordMQ->availableToRead();
mDataOutputBuffer.clear();
- mDataOutputBuffer.resize(mRecordMQ->availableToRead());
- result = mRecordMQ->read(mDataOutputBuffer.data(), mRecordMQ->availableToRead());
+ mDataOutputBuffer.resize(readSize);
+ result = mRecordMQ->read(mDataOutputBuffer.data(), readSize);
EXPECT_TRUE(result) << "can't read from Record MQ";
mMsgCondition.signal();
return result;
diff --git a/tv/tuner/1.1/vts/functional/FilterTests.cpp b/tv/tuner/1.1/vts/functional/FilterTests.cpp
index 5a8985d..f114a66 100644
--- a/tv/tuner/1.1/vts/functional/FilterTests.cpp
+++ b/tv/tuner/1.1/vts/functional/FilterTests.cpp
@@ -28,6 +28,18 @@
ALOGW("[vts] pass and stop");
}
+void FilterCallback::testFilterScramblingEvent() {
+ android::Mutex::Autolock autoLock(mMsgLock);
+ while (mScramblingStatusEvent < 1) {
+ if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+ EXPECT_TRUE(false) << "scrambling event does not output within timeout";
+ return;
+ }
+ }
+ mScramblingStatusEvent = 0;
+ ALOGW("[vts] pass and stop");
+}
+
void FilterCallback::readFilterEventData() {
ALOGW("[vts] reading filter event");
// todo separate filter handlers
@@ -47,8 +59,17 @@
auto eventExt = mFilterEventExt.events[i];
switch (eventExt.getDiscriminator()) {
case DemuxFilterEventExt::Event::hidl_discriminator::tsRecord:
- ALOGD("[vts] Extended TS record filter event, pts=%" PRIu64 ".",
- eventExt.tsRecord().pts);
+ ALOGD("[vts] Extended TS record filter event, pts=%" PRIu64 ", firstMbInSlice=%d",
+ eventExt.tsRecord().pts, eventExt.tsRecord().firstMbInSlice);
+ break;
+ case DemuxFilterEventExt::Event::hidl_discriminator::mmtpRecord:
+ ALOGD("[vts] Extended MMTP record filter event, pts=%" PRIu64
+ ", firstMbInSlice=%d, mpuSequenceNumber=%d",
+ eventExt.mmtpRecord().pts, eventExt.mmtpRecord().firstMbInSlice,
+ eventExt.mmtpRecord().mpuSequenceNumber);
+ break;
+ case DemuxFilterEventExt::Event::hidl_discriminator::scramblingStatus:
+ mScramblingStatusEvent++;
break;
default:
break;
@@ -164,6 +185,20 @@
return AssertionResult(status == Result::SUCCESS);
}
+AssertionResult FilterTests::configAvFilterStreamType(AvStreamType type, uint64_t filterId) {
+ Result status;
+ EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+ sp<android::hardware::tv::tuner::V1_1::IFilter> filter_v1_1 =
+ android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilters[filterId]);
+ if (filter_v1_1 != NULL) {
+ status = filter_v1_1->configureAvStreamType(type);
+ } else {
+ ALOGW("[vts] Can't cast IFilter into v1_1.");
+ return failure();
+ }
+ return AssertionResult(status == Result::SUCCESS);
+}
+
AssertionResult FilterTests::configIpFilterCid(uint32_t ipCid, uint64_t filterId) {
Result status;
EXPECT_TRUE(mFilters[filterId]) << "Open Ip filter first.";
@@ -220,3 +255,19 @@
}
return AssertionResult(status == Result::SUCCESS);
}
+
+AssertionResult FilterTests::configureScramblingEvent(uint64_t filterId, uint32_t statuses) {
+ EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+ Result status;
+
+ sp<android::hardware::tv::tuner::V1_1::IFilter> filter_v1_1 =
+ android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilters[filterId]);
+ if (filter_v1_1 != NULL) {
+ status = filter_v1_1->configureScramblingEvent(statuses);
+ mFilterCallbacks[filterId]->testFilterScramblingEvent();
+ } else {
+ ALOGW("[vts] Can't cast IFilter into v1_1.");
+ return failure();
+ }
+ return AssertionResult(status == Result::SUCCESS);
+}
diff --git a/tv/tuner/1.1/vts/functional/FilterTests.h b/tv/tuner/1.1/vts/functional/FilterTests.h
index bc6db86..d88f171 100644
--- a/tv/tuner/1.1/vts/functional/FilterTests.h
+++ b/tv/tuner/1.1/vts/functional/FilterTests.h
@@ -54,6 +54,7 @@
using android::hardware::tv::tuner::V1_0::IDemux;
using android::hardware::tv::tuner::V1_0::IFilter;
using android::hardware::tv::tuner::V1_0::Result;
+using android::hardware::tv::tuner::V1_1::AvStreamType;
using android::hardware::tv::tuner::V1_1::DemuxFilterEventExt;
using android::hardware::tv::tuner::V1_1::IFilterCallback;
using android::hardware::tv::tuner::V1_1::ITuner;
@@ -116,6 +117,7 @@
void setMemSize(uint64_t size) { mAvSharedMemSize = size; }
void testFilterDataOutput();
+ void testFilterScramblingEvent();
void readFilterEventData();
bool dumpAvData(DemuxFilterMediaEvent event);
@@ -135,6 +137,7 @@
android::Condition mMsgCondition;
int mPidFilterOutputCount = 0;
+ int mScramblingStatusEvent = 0;
};
class FilterTests {
@@ -150,7 +153,9 @@
AssertionResult getSharedAvMemoryHandle(uint64_t filterId);
AssertionResult releaseShareAvHandle(uint64_t filterId);
AssertionResult configFilter(DemuxFilterSettings setting, uint64_t filterId);
+ AssertionResult configAvFilterStreamType(AvStreamType type, uint64_t filterId);
AssertionResult configIpFilterCid(uint32_t ipCid, uint64_t filterId);
+ AssertionResult configureScramblingEvent(uint64_t filterId, uint32_t statuses);
AssertionResult getFilterMQDescriptor(uint64_t filterId);
AssertionResult startFilter(uint64_t filterId);
AssertionResult stopFilter(uint64_t filterId);
diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.cpp b/tv/tuner/1.1/vts/functional/FrontendTests.cpp
index 5e2b288..0948f74 100644
--- a/tv/tuner/1.1/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/1.1/vts/functional/FrontendTests.cpp
@@ -47,8 +47,59 @@
return Void();
}
+Return<void> FrontendCallback::onScanMessageExt1_1(FrontendScanMessageTypeExt1_1 type,
+ const FrontendScanMessageExt1_1& message) {
+ android::Mutex::Autolock autoLock(mMsgLock);
+ ALOGD("[vts] frontend ext1_1 scan message. Type: %d", type);
+ switch (message.getDiscriminator()) {
+ case FrontendScanMessageExt1_1::hidl_discriminator::modulation:
+ readFrontendScanMessageExt1_1Modulation(message.modulation());
+ break;
+ case FrontendScanMessageExt1_1::hidl_discriminator::isHighPriority:
+ ALOGD("[vts] frontend ext1_1 scan message high priority: %d", message.isHighPriority());
+ break;
+ case FrontendScanMessageExt1_1::hidl_discriminator::annex:
+ ALOGD("[vts] frontend ext1_1 scan message dvbc annex: %hhu", message.annex());
+ break;
+ default:
+ break;
+ }
+ return Void();
+}
+
+void FrontendCallback::readFrontendScanMessageExt1_1Modulation(FrontendModulation modulation) {
+ switch (modulation.getDiscriminator()) {
+ case FrontendModulation::hidl_discriminator::dvbc:
+ ALOGD("[vts] frontend ext1_1 scan message modulation dvbc: %d", modulation.dvbc());
+ break;
+ case FrontendModulation::hidl_discriminator::dvbs:
+ ALOGD("[vts] frontend ext1_1 scan message modulation dvbs: %d", modulation.dvbs());
+ break;
+ case FrontendModulation::hidl_discriminator::isdbs:
+ ALOGD("[vts] frontend ext1_1 scan message modulation isdbs: %d", modulation.isdbs());
+ break;
+ case FrontendModulation::hidl_discriminator::isdbs3:
+ ALOGD("[vts] frontend ext1_1 scan message modulation isdbs3: %d", modulation.isdbs3());
+ break;
+ case FrontendModulation::hidl_discriminator::isdbt:
+ ALOGD("[vts] frontend ext1_1 scan message modulation isdbt: %d", modulation.isdbt());
+ break;
+ case FrontendModulation::hidl_discriminator::atsc:
+ ALOGD("[vts] frontend ext1_1 scan message modulation atsc: %d", modulation.atsc());
+ break;
+ case FrontendModulation::hidl_discriminator::atsc3:
+ ALOGD("[vts] frontend ext1_1 scan message modulation atsc3: %d", modulation.atsc3());
+ break;
+ case FrontendModulation::hidl_discriminator::dvbt:
+ ALOGD("[vts] frontend ext1_1 scan message modulation dvbt: %d", modulation.dvbt());
+ break;
+ default:
+ break;
+ }
+}
+
void FrontendCallback::tuneTestOnLock(sp<IFrontend>& frontend, FrontendSettings settings,
- FrontendSettingsExt settingsExt) {
+ FrontendSettingsExt1_1 settingsExt1_1) {
sp<android::hardware::tv::tuner::V1_1::IFrontend> frontend_1_1;
frontend_1_1 = android::hardware::tv::tuner::V1_1::IFrontend::castFrom(frontend);
if (frontend_1_1 == nullptr) {
@@ -56,7 +107,7 @@
return;
}
- Result result = frontend_1_1->tune_1_1(settings, settingsExt);
+ Result result = frontend_1_1->tune_1_1(settings, settingsExt1_1);
EXPECT_TRUE(result == Result::SUCCESS);
android::Mutex::Autolock autoLock(mMsgLock);
@@ -88,7 +139,7 @@
resetBlindScanStartingFrequency(config, targetFrequency - 100);
}
- Result result = frontend_1_1->scan_1_1(config.settings, type, config.settingsExt);
+ Result result = frontend_1_1->scan_1_1(config.settings, type, config.settingsExt1_1);
EXPECT_TRUE(result == Result::SUCCESS);
bool scanMsgLockedReceived = false;
@@ -108,7 +159,7 @@
if (mScanMessageType != FrontendScanMessageType::END) {
if (mScanMessageType == FrontendScanMessageType::LOCKED) {
scanMsgLockedReceived = true;
- Result result = frontend_1_1->scan_1_1(config.settings, type, config.settingsExt);
+ Result result = frontend_1_1->scan_1_1(config.settings, type, config.settingsExt1_1);
EXPECT_TRUE(result == Result::SUCCESS);
}
@@ -243,118 +294,108 @@
EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
Result status;
status = mFrontend->stopScan();
+
return AssertionResult(status == Result::SUCCESS);
}
-void FrontendTests::verifyFrontendStatus(vector<FrontendStatusType> statusTypes,
- vector<FrontendStatus> expectStatuses) {
+AssertionResult FrontendTests::getFrontendDtmbCaps(uint32_t id) {
+ Result status;
+ mService->getFrontendDtmbCapabilities(
+ id, [&](Result result, const FrontendDtmbCapabilities& /*caps*/) { status = result; });
+ return AssertionResult(status == Result::SUCCESS);
+}
+
+void FrontendTests::verifyFrontendStatusExt1_1(vector<FrontendStatusTypeExt1_1> statusTypes,
+ vector<FrontendStatusExt1_1> expectStatuses) {
ASSERT_TRUE(mFrontend) << "Frontend is not opened yet.";
Result status;
- vector<FrontendStatus> realStatuses;
+ vector<FrontendStatusExt1_1> realStatuses;
- mFrontend->getStatus(statusTypes, [&](Result result, const hidl_vec<FrontendStatus>& statuses) {
- status = result;
- realStatuses = statuses;
- });
+ sp<android::hardware::tv::tuner::V1_1::IFrontend> frontend_1_1;
+ frontend_1_1 = android::hardware::tv::tuner::V1_1::IFrontend::castFrom(mFrontend);
+ if (frontend_1_1 == nullptr) {
+ EXPECT_TRUE(false) << "Couldn't get 1.1 IFrontend from the Hal implementation.";
+ return;
+ }
+
+ frontend_1_1->getStatusExt1_1(
+ statusTypes, [&](Result result, const hidl_vec<FrontendStatusExt1_1>& statuses) {
+ status = result;
+ realStatuses = statuses;
+ });
ASSERT_TRUE(realStatuses.size() == statusTypes.size());
for (int i = 0; i < statusTypes.size(); i++) {
- FrontendStatusType type = statusTypes[i];
+ FrontendStatusTypeExt1_1 type = statusTypes[i];
switch (type) {
- case FrontendStatusType::DEMOD_LOCK: {
- ASSERT_TRUE(realStatuses[i].isDemodLocked() == expectStatuses[i].isDemodLocked());
+ case FrontendStatusTypeExt1_1::MODULATIONS: {
+ // TODO: verify modulations
break;
}
- case FrontendStatusType::SNR: {
- ASSERT_TRUE(realStatuses[i].snr() == expectStatuses[i].snr());
+ case FrontendStatusTypeExt1_1::BERS: {
+ ASSERT_TRUE(std::equal(realStatuses[i].bers().begin(), realStatuses[i].bers().end(),
+ expectStatuses[i].bers().begin()));
break;
}
- case FrontendStatusType::BER: {
- ASSERT_TRUE(realStatuses[i].ber() == expectStatuses[i].ber());
+ case FrontendStatusTypeExt1_1::CODERATES: {
+ ASSERT_TRUE(std::equal(realStatuses[i].codeRates().begin(),
+ realStatuses[i].codeRates().end(),
+ expectStatuses[i].codeRates().begin()));
break;
}
- case FrontendStatusType::PER: {
- ASSERT_TRUE(realStatuses[i].per() == expectStatuses[i].per());
+ case FrontendStatusTypeExt1_1::GUARD_INTERVAL: {
+ // TODO: verify interval
break;
}
- case FrontendStatusType::PRE_BER: {
- ASSERT_TRUE(realStatuses[i].preBer() == expectStatuses[i].preBer());
+ case FrontendStatusTypeExt1_1::TRANSMISSION_MODE: {
+ // TODO: verify tranmission mode
break;
}
- case FrontendStatusType::SIGNAL_QUALITY: {
- ASSERT_TRUE(realStatuses[i].signalQuality() == expectStatuses[i].signalQuality());
+ case FrontendStatusTypeExt1_1::UEC: {
+ ASSERT_TRUE(realStatuses[i].uec() == expectStatuses[i].uec());
break;
}
- case FrontendStatusType::SIGNAL_STRENGTH: {
- ASSERT_TRUE(realStatuses[i].signalStrength() == expectStatuses[i].signalStrength());
+ case FrontendStatusTypeExt1_1::T2_SYSTEM_ID: {
+ ASSERT_TRUE(realStatuses[i].systemId() == expectStatuses[i].systemId());
break;
}
- case FrontendStatusType::SYMBOL_RATE: {
- ASSERT_TRUE(realStatuses[i].symbolRate() == expectStatuses[i].symbolRate());
+ case FrontendStatusTypeExt1_1::INTERLEAVINGS: {
+ ASSERT_TRUE(std::equal(realStatuses[i].interleaving().begin(),
+ realStatuses[i].interleaving().end(),
+ expectStatuses[i].interleaving().begin()));
break;
}
- case FrontendStatusType::FEC: {
- ASSERT_TRUE(realStatuses[i].innerFec() == expectStatuses[i].innerFec());
+ case FrontendStatusTypeExt1_1::ISDBT_SEGMENTS: {
+ ASSERT_TRUE(std::equal(realStatuses[i].isdbtSegment().begin(),
+ realStatuses[i].isdbtSegment().end(),
+ expectStatuses[i].isdbtSegment().begin()));
break;
}
- case FrontendStatusType::MODULATION: {
- // TODO: check modulation status
+ case FrontendStatusTypeExt1_1::TS_DATA_RATES: {
+ ASSERT_TRUE(std::equal(realStatuses[i].tsDataRate().begin(),
+ realStatuses[i].tsDataRate().end(),
+ expectStatuses[i].tsDataRate().begin()));
break;
}
- case FrontendStatusType::SPECTRAL: {
- ASSERT_TRUE(realStatuses[i].inversion() == expectStatuses[i].inversion());
+ case FrontendStatusTypeExt1_1::ROLL_OFF: {
+ // TODO: verify roll off
break;
}
- case FrontendStatusType::LNB_VOLTAGE: {
- ASSERT_TRUE(realStatuses[i].lnbVoltage() == expectStatuses[i].lnbVoltage());
+ case FrontendStatusTypeExt1_1::IS_MISO: {
+ ASSERT_TRUE(realStatuses[i].isMiso() == expectStatuses[i].isMiso());
break;
}
- case FrontendStatusType::PLP_ID: {
- ASSERT_TRUE(realStatuses[i].plpId() == expectStatuses[i].plpId());
+ case FrontendStatusTypeExt1_1::IS_LINEAR: {
+ ASSERT_TRUE(realStatuses[i].isLinear() == expectStatuses[i].isLinear());
break;
}
- case FrontendStatusType::EWBS: {
- ASSERT_TRUE(realStatuses[i].isEWBS() == expectStatuses[i].isEWBS());
+ case FrontendStatusTypeExt1_1::IS_SHORT_FRAMES: {
+ ASSERT_TRUE(realStatuses[i].isShortFrames() == expectStatuses[i].isShortFrames());
break;
}
- case FrontendStatusType::AGC: {
- ASSERT_TRUE(realStatuses[i].agc() == expectStatuses[i].agc());
- break;
- }
- case FrontendStatusType::LNA: {
- ASSERT_TRUE(realStatuses[i].isLnaOn() == expectStatuses[i].isLnaOn());
- break;
- }
- case FrontendStatusType::LAYER_ERROR: {
- vector<bool> realLayberError = realStatuses[i].isLayerError();
- vector<bool> expectLayerError = expectStatuses[i].isLayerError();
- ASSERT_TRUE(realLayberError.size() == expectLayerError.size());
- for (int i = 0; i < realLayberError.size(); i++) {
- ASSERT_TRUE(realLayberError[i] == expectLayerError[i]);
- }
- break;
- }
- case FrontendStatusType::MER: {
- ASSERT_TRUE(realStatuses[i].mer() == expectStatuses[i].mer());
- break;
- }
- case FrontendStatusType::FREQ_OFFSET: {
- ASSERT_TRUE(realStatuses[i].freqOffset() == expectStatuses[i].freqOffset());
- break;
- }
- case FrontendStatusType::HIERARCHY: {
- ASSERT_TRUE(realStatuses[i].hierarchy() == expectStatuses[i].hierarchy());
- break;
- }
- case FrontendStatusType::RF_LOCK: {
- ASSERT_TRUE(realStatuses[i].isRfLocked() == expectStatuses[i].isRfLocked());
- break;
- }
- case FrontendStatusType::ATSC3_PLP_INFO:
- // TODO: verify plpinfo
- break;
- default:
+ default: {
continue;
+ }
}
}
ASSERT_TRUE(status == Result::SUCCESS);
@@ -380,7 +421,7 @@
return failure();
}
}
- mFrontendCallback->tuneTestOnLock(mFrontend, config.settings, config.settingsExt);
+ mFrontendCallback->tuneTestOnLock(mFrontend, config.settings, config.settingsExt1_1);
return AssertionResult(true);
}
@@ -425,7 +466,7 @@
ASSERT_TRUE(openFrontendById(feId));
ASSERT_TRUE(setFrontendCallback());
ASSERT_TRUE(tuneFrontend(frontendConf, false /*testWithDemux*/));
- verifyFrontendStatus(frontendConf.tuneStatusTypes, frontendConf.expectTuneStatuses);
+ verifyFrontendStatusExt1_1(frontendConf.tuneStatusTypes, frontendConf.expectTuneStatuses);
ASSERT_TRUE(stopTuneFrontend(false /*testWithDemux*/));
ASSERT_TRUE(closeFrontend());
}
@@ -440,3 +481,14 @@
ASSERT_TRUE(stopScanFrontend());
ASSERT_TRUE(closeFrontend());
}
+
+void FrontendTests::getFrontendDtmbCapsTest() {
+ uint32_t feId;
+ getFrontendIdByType(
+ static_cast<FrontendType>(android::hardware::tv::tuner::V1_1::FrontendType::DTMB),
+ feId);
+ if (feId != INVALID_ID) {
+ ALOGD("[vts] Found DTMB Frontend");
+ ASSERT_TRUE(getFrontendDtmbCaps(feId));
+ }
+}
diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.h b/tv/tuner/1.1/vts/functional/FrontendTests.h
index 8986d81..243d9de 100644
--- a/tv/tuner/1.1/vts/functional/FrontendTests.h
+++ b/tv/tuner/1.1/vts/functional/FrontendTests.h
@@ -15,9 +15,9 @@
*/
#include <android-base/logging.h>
-#include <android/hardware/tv/tuner/1.0/IFrontendCallback.h>
#include <android/hardware/tv/tuner/1.0/types.h>
#include <android/hardware/tv/tuner/1.1/IFrontend.h>
+#include <android/hardware/tv/tuner/1.1/IFrontendCallback.h>
#include <android/hardware/tv/tuner/1.1/ITuner.h>
#include <binder/MemoryDealer.h>
#include <gtest/gtest.h>
@@ -54,8 +54,12 @@
using android::hardware::tv::tuner::V1_0::FrontendScanMessageType;
using android::hardware::tv::tuner::V1_0::FrontendScanType;
using android::hardware::tv::tuner::V1_0::IFrontend;
-using android::hardware::tv::tuner::V1_0::IFrontendCallback;
using android::hardware::tv::tuner::V1_0::Result;
+using android::hardware::tv::tuner::V1_1::FrontendDtmbCapabilities;
+using android::hardware::tv::tuner::V1_1::FrontendModulation;
+using android::hardware::tv::tuner::V1_1::FrontendScanMessageExt1_1;
+using android::hardware::tv::tuner::V1_1::FrontendScanMessageTypeExt1_1;
+using android::hardware::tv::tuner::V1_1::IFrontendCallback;
using android::hardware::tv::tuner::V1_1::ITuner;
using ::testing::AssertionResult;
@@ -70,9 +74,11 @@
virtual Return<void> onEvent(FrontendEventType frontendEventType) override;
virtual Return<void> onScanMessage(FrontendScanMessageType type,
const FrontendScanMessage& message) override;
+ virtual Return<void> onScanMessageExt1_1(FrontendScanMessageTypeExt1_1 type,
+ const FrontendScanMessageExt1_1& message) override;
void tuneTestOnLock(sp<IFrontend>& frontend, FrontendSettings settings,
- FrontendSettingsExt settingsExt);
+ FrontendSettingsExt1_1 settingsExt1_1);
void scanTest(sp<IFrontend>& frontend, FrontendConfig config, FrontendScanType type);
// Helper methods
@@ -80,6 +86,8 @@
void resetBlindScanStartingFrequency(FrontendConfig& config, uint32_t resetingFreq);
private:
+ void readFrontendScanMessageExt1_1Modulation(FrontendModulation modulation);
+
bool mEventReceived = false;
bool mScanMessageReceived = false;
bool mLockMsgReceived = false;
@@ -109,14 +117,16 @@
AssertionResult scanFrontend(FrontendConfig config, FrontendScanType type);
AssertionResult stopScanFrontend();
AssertionResult tuneFrontend(FrontendConfig config, bool testWithDemux);
- void verifyFrontendStatus(vector<FrontendStatusType> statusTypes,
- vector<FrontendStatus> expectStatuses);
+ void verifyFrontendStatusExt1_1(vector<FrontendStatusTypeExt1_1> statusTypes,
+ vector<FrontendStatusExt1_1> expectStatuses);
AssertionResult stopTuneFrontend(bool testWithDemux);
AssertionResult closeFrontend();
+ AssertionResult getFrontendDtmbCaps(uint32_t);
void getFrontendIdByType(FrontendType feType, uint32_t& feId);
void tuneTest(FrontendConfig frontendConf);
void scanTest(FrontendConfig frontend, FrontendScanType type);
+ void getFrontendDtmbCapsTest();
void setDvrTests(DvrTests dvrTests) { mDvrTests = dvrTests; }
void setDemux(sp<IDemux> demux) { mDvrTests.setDemux(demux); }
diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
index f87fa3c..17abf49 100644
--- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
+++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
@@ -22,6 +22,10 @@
return filterDataOutputTestBase(mFilterTests);
}
+AssertionResult TunerRecordHidlTest::filterDataOutputTest() {
+ return filterDataOutputTestBase(mFilterTests);
+}
+
void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf,
FrontendConfig frontendConf) {
uint32_t feId;
@@ -42,6 +46,9 @@
if (filterConf.type.mainType == DemuxFilterMainType::IP) {
ASSERT_TRUE(mFilterTests.configIpFilterCid(filterConf.ipCid, filterId));
}
+ if (filterConf.statuses > 0) {
+ ASSERT_TRUE(mFilterTests.configureScramblingEvent(filterId, filterConf.statuses));
+ }
ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
ASSERT_TRUE(mFilterTests.startFilter(filterId));
ASSERT_TRUE(mFilterTests.stopFilter(filterId));
@@ -69,6 +76,7 @@
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId));
ASSERT_TRUE(mFilterTests.getSharedAvMemoryHandle(filterId));
ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
+ ASSERT_TRUE(mFilterTests.configAvFilterStreamType(filterConf.streamType, filterId));
ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
ASSERT_TRUE(mFilterTests.startFilter(filterId));
// tune test
@@ -114,6 +122,7 @@
ASSERT_TRUE(mFilterTests.startFilter(filterId));
ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
mDvrTests.testRecordOutput();
+ ASSERT_TRUE(filterDataOutputTest());
mDvrTests.stopRecordThread();
ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
ASSERT_TRUE(mFilterTests.stopFilter(filterId));
@@ -142,13 +151,13 @@
recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[DVBT], dvrArray[DVR_RECORD0]);
}
-TEST_P(TunerFrontendHidlTest, TuneFrontendWithFrontendSettingsExt) {
- description("Tune one Frontend with specific setting and check Lock event");
+TEST_P(TunerFrontendHidlTest, TuneFrontendWithFrontendSettingsExt1_1) {
+ description("Tune one Frontend with v1_1 extended setting and check Lock event");
mFrontendTests.tuneTest(frontendArray[DVBT]);
}
TEST_P(TunerFrontendHidlTest, BlindScanFrontendWithEndFrequency) {
- description("Run an blind frontend scan with specific setting and check lock scanMessage");
+ description("Run an blind frontend scan with v1_1 extended setting and check lock scanMessage");
mFrontendTests.scanTest(frontendScanArray[SCAN_DVBT], FrontendScanType::SCAN_BLIND);
}
@@ -157,6 +166,11 @@
mediaFilterUsingSharedMemoryTest(filterArray[TS_VIDEO0], frontendArray[DVBT]);
}
+TEST_P(TunerFrontendHidlTest, GetFrontendDtmbCaps) {
+ description("Test to query Dtmb frontend caps if exists");
+ mFrontendTests.getFrontendDtmbCapsTest();
+}
+
INSTANTIATE_TEST_SUITE_P(
PerInstance, TunerBroadcastHidlTest,
testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)),
diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h
index f77a740..773224e 100644
--- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h
+++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h
@@ -87,6 +87,7 @@
void recordSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf,
DvrConfig dvrConf);
+ AssertionResult filterDataOutputTest();
sp<ITuner> mService;
FrontendTests mFrontendTests;
diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h
index 36b4bd2..76bf765 100644
--- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h
+++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h
@@ -43,12 +43,15 @@
using android::hardware::tv::tuner::V1_0::FrontendDvbtStandard;
using android::hardware::tv::tuner::V1_0::FrontendDvbtTransmissionMode;
using android::hardware::tv::tuner::V1_0::FrontendSettings;
-using android::hardware::tv::tuner::V1_0::FrontendStatus;
-using android::hardware::tv::tuner::V1_0::FrontendStatusType;
using android::hardware::tv::tuner::V1_0::FrontendType;
using android::hardware::tv::tuner::V1_0::PlaybackSettings;
using android::hardware::tv::tuner::V1_0::RecordSettings;
-using android::hardware::tv::tuner::V1_1::FrontendSettingsExt;
+using android::hardware::tv::tuner::V1_1::AudioStreamType;
+using android::hardware::tv::tuner::V1_1::AvStreamType;
+using android::hardware::tv::tuner::V1_1::FrontendSettingsExt1_1;
+using android::hardware::tv::tuner::V1_1::FrontendStatusExt1_1;
+using android::hardware::tv::tuner::V1_1::FrontendStatusTypeExt1_1;
+using android::hardware::tv::tuner::V1_1::VideoStreamType;
using namespace std;
@@ -91,7 +94,9 @@
uint32_t bufferSize;
DemuxFilterType type;
DemuxFilterSettings settings;
+ AvStreamType streamType;
uint32_t ipCid;
+ uint32_t statuses;
bool operator<(const FilterConfig& /*c*/) const { return false; }
};
@@ -100,9 +105,9 @@
bool isSoftwareFe;
FrontendType type;
FrontendSettings settings;
- FrontendSettingsExt settingsExt;
- vector<FrontendStatusType> tuneStatusTypes;
- vector<FrontendStatus> expectTuneStatuses;
+ FrontendSettingsExt1_1 settingsExt1_1;
+ vector<FrontendStatusTypeExt1_1> tuneStatusTypes;
+ vector<FrontendStatusExt1_1> expectTuneStatuses;
};
struct DvrConfig {
@@ -132,16 +137,20 @@
.standard = FrontendDvbtStandard::T,
};
frontendArray[DVBT].type = FrontendType::DVBT, frontendArray[DVBT].settings.dvbt(dvbtSettings);
- vector<FrontendStatusType> types;
- types.push_back(FrontendStatusType::DEMOD_LOCK);
- FrontendStatus status;
- status.isDemodLocked(true);
- vector<FrontendStatus> statuses;
+ vector<FrontendStatusTypeExt1_1> types;
+ types.push_back(FrontendStatusTypeExt1_1::UEC);
+ types.push_back(FrontendStatusTypeExt1_1::IS_MISO);
+ vector<FrontendStatusExt1_1> statuses;
+ FrontendStatusExt1_1 status;
+ status.uec(4);
statuses.push_back(status);
+ status.isMiso(true);
+ statuses.push_back(status);
+
frontendArray[DVBT].tuneStatusTypes = types;
frontendArray[DVBT].expectTuneStatuses = statuses;
frontendArray[DVBT].isSoftwareFe = true;
- frontendArray[DVBT].settingsExt.settingExt.dvbt({
+ frontendArray[DVBT].settingsExt1_1.settingExt.dvbt({
.transmissionMode =
android::hardware::tv::tuner::V1_1::FrontendDvbtTransmissionMode::MODE_8K_E,
});
@@ -164,8 +173,8 @@
.isHighPriority = true,
.standard = FrontendDvbtStandard::T,
});
- frontendScanArray[SCAN_DVBT].settingsExt.endFrequency = 800000;
- frontendScanArray[SCAN_DVBT].settingsExt.settingExt.dvbt({
+ frontendScanArray[SCAN_DVBT].settingsExt1_1.endFrequency = 800000;
+ frontendScanArray[SCAN_DVBT].settingsExt1_1.settingExt.dvbt({
.transmissionMode =
android::hardware::tv::tuner::V1_1::FrontendDvbtTransmissionMode::MODE_8K_E,
});
@@ -179,11 +188,13 @@
filterArray[TS_VIDEO0].bufferSize = FMQ_SIZE_16M;
filterArray[TS_VIDEO0].settings.ts().tpid = 256;
filterArray[TS_VIDEO0].settings.ts().filterSettings.av({.isPassthrough = false});
+ filterArray[TS_VIDEO0].statuses = 1;
filterArray[TS_VIDEO1].type.mainType = DemuxFilterMainType::TS;
filterArray[TS_VIDEO1].type.subType.tsFilterType(DemuxTsFilterType::VIDEO);
filterArray[TS_VIDEO1].bufferSize = FMQ_SIZE_16M;
filterArray[TS_VIDEO1].settings.ts().tpid = 256;
filterArray[TS_VIDEO1].settings.ts().filterSettings.av({.isPassthrough = false});
+ filterArray[TS_VIDEO1].streamType.video(VideoStreamType::MPEG1);
// TS AUDIO filter setting
filterArray[TS_AUDIO0].type.mainType = DemuxFilterMainType::TS;
filterArray[TS_AUDIO0].type.subType.tsFilterType(DemuxTsFilterType::AUDIO);
@@ -195,6 +206,7 @@
filterArray[TS_AUDIO1].bufferSize = FMQ_SIZE_16M;
filterArray[TS_AUDIO1].settings.ts().tpid = 257;
filterArray[TS_AUDIO1].settings.ts().filterSettings.av({.isPassthrough = false});
+ filterArray[TS_VIDEO1].streamType.audio(AudioStreamType::MP3);
// TS PES filter setting
filterArray[TS_PES0].type.mainType = DemuxFilterMainType::TS;
filterArray[TS_PES0].type.subType.tsFilterType(DemuxTsFilterType::PES);
diff --git a/tv/tuner/README.md b/tv/tuner/README.md
index aa1f62d..2a358f5 100644
--- a/tv/tuner/README.md
+++ b/tv/tuner/README.md
@@ -5,8 +5,3 @@
TV specific tuners.
See 1.0/ITuner.hal for an overview.
-
-*** note
-**Warning:** The HALs are not (yet) frozen, as the HAL definition is
-expected to evolve between Android releases.
-***
diff --git a/update-base-files.sh b/update-base-files.sh
index daaa530..d01847d 100755
--- a/update-base-files.sh
+++ b/update-base-files.sh
@@ -42,8 +42,11 @@
# system/media
hidl-gen $options \
+ -o $ANDROID_BUILD_TOP/system/media/audio/include/system/audio_common-base.h \
+ android.hardware.audio.common@7.0
+hidl-gen $options \
-o $ANDROID_BUILD_TOP/system/media/audio/include/system/audio-base.h \
- android.hardware.audio.common@2.0
+ android.hardware.audio@7.0
hidl-gen $options \
-o $ANDROID_BUILD_TOP/system/media/audio/include/system/audio_effect-base.h \
- android.hardware.audio.effect@2.0
+ android.hardware.audio.effect@7.0
diff --git a/wifi/1.0/vts/functional/Android.bp b/wifi/1.0/vts/functional/Android.bp
index cad54fe..30512a9 100644
--- a/wifi/1.0/vts/functional/Android.bp
+++ b/wifi/1.0/vts/functional/Android.bp
@@ -73,6 +73,11 @@
static_libs: [
"VtsHalWifiV1_0TargetTestUtil",
"android.hardware.wifi@1.0",
+ "android.hardware.wifi@1.1",
+ "android.hardware.wifi@1.2",
+ "android.hardware.wifi@1.3",
+ "android.hardware.wifi@1.4",
+ "android.hardware.wifi@1.5",
"libwifi-system-iface",
],
test_suites: [
diff --git a/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp
index 17abbd7..a74987c 100644
--- a/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp
+++ b/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp
@@ -20,6 +20,7 @@
#include <android/hardware/wifi/1.0/IWifi.h>
#include <android/hardware/wifi/1.0/IWifiNanIface.h>
#include <android/hardware/wifi/1.0/IWifiNanIfaceEventCallback.h>
+#include <android/hardware/wifi/1.5/IWifiNanIface.h>
#include <gtest/gtest.h>
#include <hidl/GtestPrinter.h>
#include <hidl/ServiceManagement.h>
@@ -483,6 +484,16 @@
TEST_P(WifiNanIfaceHidlTest, getCapabilitiesRequest) {
uint16_t inputCmdId = 10;
callbackType = INVALID;
+ sp<::android::hardware::wifi::V1_5::IWifiNanIface> iface_converted =
+ ::android::hardware::wifi::V1_5::IWifiNanIface::castFrom(iwifiNanIface);
+ if (iface_converted != nullptr) {
+ ASSERT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED,
+ HIDL_INVOKE(iwifiNanIface, getCapabilitiesRequest, inputCmdId)
+ .code);
+ // Skip this test since this API is deprecated in this newer HAL version
+ return;
+ }
+
ASSERT_EQ(
WifiStatusCode::SUCCESS,
HIDL_INVOKE(iwifiNanIface, getCapabilitiesRequest, inputCmdId).code);
diff --git a/wifi/1.4/vts/functional/Android.bp b/wifi/1.4/vts/functional/Android.bp
index 59a35e0..0051d27 100644
--- a/wifi/1.4/vts/functional/Android.bp
+++ b/wifi/1.4/vts/functional/Android.bp
@@ -52,6 +52,7 @@
"android.hardware.wifi@1.2",
"android.hardware.wifi@1.3",
"android.hardware.wifi@1.4",
+ "android.hardware.wifi@1.5",
"libwifi-system-iface",
],
test_suites: [
diff --git a/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp
index 9b69f57..3ac047d 100644
--- a/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp
+++ b/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp
@@ -20,6 +20,7 @@
#include <android/hardware/wifi/1.2/IWifiNanIfaceEventCallback.h>
#include <android/hardware/wifi/1.4/IWifi.h>
#include <android/hardware/wifi/1.4/IWifiNanIface.h>
+#include <android/hardware/wifi/1.5/IWifiNanIface.h>
#include <gtest/gtest.h>
#include <hidl/GtestPrinter.h>
#include <hidl/ServiceManagement.h>
@@ -488,6 +489,17 @@
callbackType = INVALID;
::android::hardware::wifi::V1_4::NanEnableRequest nanEnableRequest = {};
NanConfigRequestSupplemental nanConfigRequestSupp = {};
+
+ sp<::android::hardware::wifi::V1_5::IWifiNanIface> iface_converted =
+ ::android::hardware::wifi::V1_5::IWifiNanIface::castFrom(iwifiNanIface);
+ if (iface_converted != nullptr) {
+ ASSERT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED,
+ HIDL_INVOKE(iwifiNanIface, enableRequest_1_4, inputCmdId,
+ nanEnableRequest, nanConfigRequestSupp)
+ .code);
+ // Skip this test since this API is deprecated in this newer HAL version
+ return;
+ }
ASSERT_EQ(WifiStatusCode::SUCCESS,
HIDL_INVOKE(iwifiNanIface, enableRequest_1_4, inputCmdId,
nanEnableRequest, nanConfigRequestSupp)
@@ -509,6 +521,17 @@
nanEnableRequest.configParams.numberOfPublishServiceIdsInBeacon =
128; // must be <= 127
NanConfigRequestSupplemental nanConfigRequestSupp = {};
+
+ sp<::android::hardware::wifi::V1_5::IWifiNanIface> iface_converted =
+ ::android::hardware::wifi::V1_5::IWifiNanIface::castFrom(iwifiNanIface);
+ if (iface_converted != nullptr) {
+ ASSERT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED,
+ HIDL_INVOKE(iwifiNanIface, enableRequest_1_4, inputCmdId,
+ nanEnableRequest, nanConfigRequestSupp)
+ .code);
+ // Skip this test since this API is deprecated in this newer HAL version
+ return;
+ }
ASSERT_EQ(WifiStatusCode::ERROR_INVALID_ARGS,
HIDL_INVOKE(iwifiNanIface, enableRequest_1_4, inputCmdId,
nanEnableRequest, nanConfigRequestSupp)
@@ -523,6 +546,17 @@
callbackType = INVALID;
::android::hardware::wifi::V1_4::NanConfigRequest nanConfigRequest = {};
NanConfigRequestSupplemental nanConfigRequestSupp = {};
+
+ sp<::android::hardware::wifi::V1_5::IWifiNanIface> iface_converted =
+ ::android::hardware::wifi::V1_5::IWifiNanIface::castFrom(iwifiNanIface);
+ if (iface_converted != nullptr) {
+ ASSERT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED,
+ HIDL_INVOKE(iwifiNanIface, configRequest_1_4, inputCmdId,
+ nanConfigRequest, nanConfigRequestSupp)
+ .code);
+ // Skip this test since this API is deprecated in this newer HAL version
+ return;
+ }
ASSERT_EQ(WifiStatusCode::SUCCESS,
HIDL_INVOKE(iwifiNanIface, configRequest_1_4, inputCmdId,
nanConfigRequest, nanConfigRequestSupp)
@@ -543,6 +577,18 @@
::android::hardware::wifi::V1_4::NanConfigRequest nanConfigRequest = {};
nanConfigRequest.numberOfPublishServiceIdsInBeacon = 128; // must be <= 127
NanConfigRequestSupplemental nanConfigRequestSupp = {};
+
+ sp<::android::hardware::wifi::V1_5::IWifiNanIface> iface_converted =
+ ::android::hardware::wifi::V1_5::IWifiNanIface::castFrom(iwifiNanIface);
+ if (iface_converted != nullptr) {
+ ASSERT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED,
+ HIDL_INVOKE(iwifiNanIface, configRequest_1_4, inputCmdId,
+ nanConfigRequest, nanConfigRequestSupp)
+ .code);
+ // Skip this test since this API is deprecated in this newer HAL version
+ return;
+ }
+
ASSERT_EQ(WifiStatusCode::ERROR_INVALID_ARGS,
HIDL_INVOKE(iwifiNanIface, configRequest_1_4, inputCmdId,
nanConfigRequest, nanConfigRequestSupp)
diff --git a/wifi/1.5/Android.bp b/wifi/1.5/Android.bp
index 5304760..ecb0a35 100644
--- a/wifi/1.5/Android.bp
+++ b/wifi/1.5/Android.bp
@@ -7,6 +7,8 @@
"types.hal",
"IWifi.hal",
"IWifiChip.hal",
+ "IWifiNanIface.hal",
+ "IWifiNanIfaceEventCallback.hal",
],
interfaces: [
"android.hardware.wifi@1.0",
diff --git a/wifi/1.5/IWifiNanIface.hal b/wifi/1.5/IWifiNanIface.hal
new file mode 100644
index 0000000..93257b5
--- /dev/null
+++ b/wifi/1.5/IWifiNanIface.hal
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi@1.5;
+
+import @1.0::CommandIdShort;
+import @1.0::WifiStatus;
+import @1.4::IWifiNanIface;
+import @1.4::NanConfigRequest;
+import @1.4::NanEnableRequest;
+import IWifiNanIfaceEventCallback;
+import NanConfigRequestSupplemental;
+
+/**
+ * Interface used to represent a single NAN (Neighbour Aware Network) iface.
+ *
+ * References to "NAN Spec" are to the Wi-Fi Alliance "Wi-Fi Neighbor Awareness
+ * Networking (NAN) Technical Specification".
+ */
+interface IWifiNanIface extends @1.4::IWifiNanIface {
+ /**
+ * Enable NAN: configures and activates NAN clustering (does not start
+ * a discovery session or set up data-interfaces or data-paths). Use the
+ * |IWifiNanIface.configureRequest| method to change the configuration of an already enabled
+ * NAN interface.
+ * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyEnableResponse|.
+ *
+ * Note: supersedes the @1.4::IWifiNanIface.enableRequest() method which is deprecated as of
+ * HAL version 1.5.
+ *
+ * @param cmdId command Id to use for this invocation.
+ * @param msg1 Instance of |NanEnableRequest|.
+ * @param msg2 Instance of |NanConfigRequestSupplemental|.
+ * @return status WifiStatus of the operation.
+ * Possible status codes:
+ * |WifiStatusCode.SUCCESS|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_INVALID_ARGS|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ enableRequest_1_5(CommandIdShort cmdId, NanEnableRequest msg1,
+ NanConfigRequestSupplemental msg2) generates (WifiStatus status);
+
+ /**
+ * Configure NAN: configures an existing NAN functionality (i.e. assumes
+ * |IWifiNanIface.enableRequest| already submitted and succeeded).
+ * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyConfigResponse|.
+ *
+ * Note: supersedes the @1.4::IWifiNanIface.configRequest() method which is deprecated as of
+ * HAL version 1.5.
+ *
+ * @param cmdId command Id to use for this invocation.
+ * @param msg1 Instance of |NanConfigRequest|.
+ * @param msg2 Instance of |NanConfigRequestSupplemental|.
+ * @return status WifiStatus of the operation.
+ * Possible status codes:
+ * |WifiStatusCode.SUCCESS|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_INVALID_ARGS|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ configRequest_1_5(CommandIdShort cmdId, NanConfigRequest msg1,
+ NanConfigRequestSupplemental msg2) generates (WifiStatus status);
+
+ /**
+ * Requests notifications of significant events on this iface. Multiple calls
+ * to this must register multiple callbacks each of which must receive all
+ * events.
+ *
+ * Note: supersedes the @1.2::IWifiNanIface.registerEventCallback() method which is deprecated
+ * as of HAL version 1.5.
+ *
+ * @param callback An instance of the |IWifiNanIfaceEventCallback| HIDL interface
+ * object.
+ * @return status WifiStatus of the operation.
+ * Possible status codes:
+ * |WifiStatusCode.SUCCESS|,
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|
+ */
+ registerEventCallback_1_5(IWifiNanIfaceEventCallback callback)
+ generates (WifiStatus status);
+
+ /**
+ * Get NAN capabilities. Asynchronous response is with
+ * |IWifiNanIfaceEventCallback.notifyCapabilitiesResponse|.
+
+ * Note: supersedes the @1.0::IWifiNanIface.getCapabilitiesRequest() method which is deprecated
+ * as of HAL version 1.5.
+ *
+ * @param cmdId command Id to use for this invocation.
+ * @return status WifiStatus of the operation.
+ * Possible status codes:
+ * |WifiStatusCode.SUCCESS|,
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ getCapabilitiesRequest_1_5(CommandIdShort cmdId) generates (WifiStatus status);
+};
\ No newline at end of file
diff --git a/wifi/1.5/IWifiNanIfaceEventCallback.hal b/wifi/1.5/IWifiNanIfaceEventCallback.hal
new file mode 100644
index 0000000..867c03c
--- /dev/null
+++ b/wifi/1.5/IWifiNanIfaceEventCallback.hal
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi@1.5;
+
+import @1.0::CommandIdShort;
+import @1.0::WifiNanStatus;
+import @1.2::IWifiNanIfaceEventCallback;
+
+/**
+ * NAN Response and Asynchronous Event Callbacks.
+ *
+ * References to "NAN Spec" are to the Wi-Fi Alliance "Wi-Fi Neighbor Awareness
+ * Networking (NAN) Technical Specification".
+ */
+interface IWifiNanIfaceEventCallback extends @1.2::IWifiNanIfaceEventCallback {
+ /**
+ * Asynchronous callback invoked in response to a capability request
+ * |IWifiNanIface.getCapabilitiesRequest|.
+ *
+ * Note: supersedes the @1.2::IWifiNanIfaceEventCallback.notifyCapabilitiesResponse() method
+ * which is deprecated as of HAL version 1.5.
+ *
+ * @param cmdId command Id corresponding to the original request.
+ * @param status WifiNanStatus of the operation. Possible status codes are:
+ * |NanStatusType.SUCCESS|
+ * @param capabilities Capability data.
+ */
+ oneway notifyCapabilitiesResponse_1_5(CommandIdShort id, WifiNanStatus status,
+ NanCapabilities capabilities);
+};
\ No newline at end of file
diff --git a/wifi/1.5/default/hidl_struct_util.cpp b/wifi/1.5/default/hidl_struct_util.cpp
index 91a82a7..578f3e2 100644
--- a/wifi/1.5/default/hidl_struct_util.cpp
+++ b/wifi/1.5/default/hidl_struct_util.cpp
@@ -1280,7 +1280,7 @@
bool convertHidlNanEnableRequest_1_4ToLegacy(
const V1_4::NanEnableRequest& hidl_request1,
- const V1_2::NanConfigRequestSupplemental& hidl_request2,
+ const NanConfigRequestSupplemental& hidl_request2,
legacy_hal::NanEnableRequest* legacy_request) {
if (!legacy_request) {
LOG(ERROR)
@@ -1295,14 +1295,60 @@
legacy_request->config_discovery_beacon_int = 1;
legacy_request->discovery_beacon_interval =
- hidl_request2.discoveryBeaconIntervalMs;
+ hidl_request2.V1_2.discoveryBeaconIntervalMs;
legacy_request->config_nss = 1;
- legacy_request->nss = hidl_request2.numberOfSpatialStreamsInDiscovery;
+ legacy_request->nss = hidl_request2.V1_2.numberOfSpatialStreamsInDiscovery;
legacy_request->config_dw_early_termination = 1;
legacy_request->enable_dw_termination =
- hidl_request2.enableDiscoveryWindowEarlyTermination;
+ hidl_request2.V1_2.enableDiscoveryWindowEarlyTermination;
legacy_request->config_enable_ranging = 1;
- legacy_request->enable_ranging = hidl_request2.enableRanging;
+ legacy_request->enable_ranging = hidl_request2.V1_2.enableRanging;
+
+ return true;
+}
+
+bool convertHidlNanEnableRequest_1_5ToLegacy(
+ const V1_4::NanEnableRequest& hidl_request1,
+ const NanConfigRequestSupplemental& hidl_request2,
+ legacy_hal::NanEnableRequest* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR)
+ << "convertHidlNanEnableRequest_1_5ToLegacy: null legacy_request";
+ return false;
+ }
+
+ *legacy_request = {};
+ if (!convertHidlNanEnableRequest_1_4ToLegacy(hidl_request1, hidl_request2,
+ legacy_request)) {
+ return false;
+ }
+
+ legacy_request->config_enable_instant_mode = 1;
+ legacy_request->enable_instant_mode =
+ hidl_request2.enableInstantCommunicationMode;
+
+ return true;
+}
+
+bool convertHidlNanConfigRequest_1_5ToLegacy(
+ const V1_4::NanConfigRequest& hidl_request1,
+ const NanConfigRequestSupplemental& hidl_request2,
+ legacy_hal::NanConfigRequest* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR)
+ << "convertHidlNanConfigRequest_1_5ToLegacy: null legacy_request";
+ return false;
+ }
+
+ *legacy_request = {};
+ if (!convertHidlNanConfigRequest_1_4ToLegacy(hidl_request1, hidl_request2,
+ legacy_request)) {
+ return false;
+ }
+
+ legacy_request->config_enable_instant_mode = 1;
+ legacy_request->enable_instant_mode =
+ hidl_request2.enableInstantCommunicationMode;
return true;
}
@@ -1794,7 +1840,7 @@
bool convertHidlNanConfigRequest_1_4ToLegacy(
const V1_4::NanConfigRequest& hidl_request1,
- const V1_2::NanConfigRequestSupplemental& hidl_request2,
+ const NanConfigRequestSupplemental& hidl_request2,
legacy_hal::NanConfigRequest* legacy_request) {
if (!legacy_request) {
LOG(ERROR) << "convertHidlNanConfigRequest_1_4ToLegacy: legacy_request "
@@ -1809,14 +1855,14 @@
legacy_request->config_discovery_beacon_int = 1;
legacy_request->discovery_beacon_interval =
- hidl_request2.discoveryBeaconIntervalMs;
+ hidl_request2.V1_2.discoveryBeaconIntervalMs;
legacy_request->config_nss = 1;
- legacy_request->nss = hidl_request2.numberOfSpatialStreamsInDiscovery;
+ legacy_request->nss = hidl_request2.V1_2.numberOfSpatialStreamsInDiscovery;
legacy_request->config_dw_early_termination = 1;
legacy_request->enable_dw_termination =
- hidl_request2.enableDiscoveryWindowEarlyTermination;
+ hidl_request2.V1_2.enableDiscoveryWindowEarlyTermination;
legacy_request->config_enable_ranging = 1;
- legacy_request->enable_ranging = hidl_request2.enableRanging;
+ legacy_request->enable_ranging = hidl_request2.V1_2.enableRanging;
return true;
}
@@ -2023,27 +2069,31 @@
}
*hidl_response = {};
- hidl_response->maxConcurrentClusters =
+ hidl_response->V1_0.maxConcurrentClusters =
legacy_response.max_concurrent_nan_clusters;
- hidl_response->maxPublishes = legacy_response.max_publishes;
- hidl_response->maxSubscribes = legacy_response.max_subscribes;
- hidl_response->maxServiceNameLen = legacy_response.max_service_name_len;
- hidl_response->maxMatchFilterLen = legacy_response.max_match_filter_len;
- hidl_response->maxTotalMatchFilterLen =
+ hidl_response->V1_0.maxPublishes = legacy_response.max_publishes;
+ hidl_response->V1_0.maxSubscribes = legacy_response.max_subscribes;
+ hidl_response->V1_0.maxServiceNameLen =
+ legacy_response.max_service_name_len;
+ hidl_response->V1_0.maxMatchFilterLen =
+ legacy_response.max_match_filter_len;
+ hidl_response->V1_0.maxTotalMatchFilterLen =
legacy_response.max_total_match_filter_len;
- hidl_response->maxServiceSpecificInfoLen =
+ hidl_response->V1_0.maxServiceSpecificInfoLen =
legacy_response.max_service_specific_info_len;
- hidl_response->maxExtendedServiceSpecificInfoLen =
+ hidl_response->V1_0.maxExtendedServiceSpecificInfoLen =
legacy_response.max_sdea_service_specific_info_len;
- hidl_response->maxNdiInterfaces = legacy_response.max_ndi_interfaces;
- hidl_response->maxNdpSessions = legacy_response.max_ndp_sessions;
- hidl_response->maxAppInfoLen = legacy_response.max_app_info_len;
- hidl_response->maxQueuedTransmitFollowupMsgs =
+ hidl_response->V1_0.maxNdiInterfaces = legacy_response.max_ndi_interfaces;
+ hidl_response->V1_0.maxNdpSessions = legacy_response.max_ndp_sessions;
+ hidl_response->V1_0.maxAppInfoLen = legacy_response.max_app_info_len;
+ hidl_response->V1_0.maxQueuedTransmitFollowupMsgs =
legacy_response.max_queued_transmit_followup_msgs;
- hidl_response->maxSubscribeInterfaceAddresses =
+ hidl_response->V1_0.maxSubscribeInterfaceAddresses =
legacy_response.max_subscribe_address;
- hidl_response->supportedCipherSuites =
+ hidl_response->V1_0.supportedCipherSuites =
legacy_response.cipher_suites_supported;
+ hidl_response->instantCommunicationModeSupportFlag =
+ legacy_response.is_instant_mode_supported;
return true;
}
diff --git a/wifi/1.5/default/hidl_struct_util.h b/wifi/1.5/default/hidl_struct_util.h
index c6dc692..b0b1d22 100644
--- a/wifi/1.5/default/hidl_struct_util.h
+++ b/wifi/1.5/default/hidl_struct_util.h
@@ -26,6 +26,7 @@
#include <android/hardware/wifi/1.4/IWifiChipEventCallback.h>
#include <android/hardware/wifi/1.4/types.h>
#include <android/hardware/wifi/1.5/IWifiChip.h>
+#include <android/hardware/wifi/1.5/types.h>
#include "wifi_legacy_hal.h"
@@ -122,11 +123,19 @@
legacy_hal::NanConfigRequest* legacy_request);
bool convertHidlNanEnableRequest_1_4ToLegacy(
const V1_4::NanEnableRequest& hidl_request1,
- const V1_2::NanConfigRequestSupplemental& hidl_request2,
+ const NanConfigRequestSupplemental& hidl_request2,
legacy_hal::NanEnableRequest* legacy_request);
bool convertHidlNanConfigRequest_1_4ToLegacy(
const V1_4::NanConfigRequest& hidl_request1,
- const V1_2::NanConfigRequestSupplemental& hidl_request2,
+ const NanConfigRequestSupplemental& hidl_request2,
+ legacy_hal::NanConfigRequest* legacy_request);
+bool convertHidlNanEnableRequest_1_5ToLegacy(
+ const V1_4::NanEnableRequest& hidl_request1,
+ const NanConfigRequestSupplemental& hidl_request2,
+ legacy_hal::NanEnableRequest* legacy_request);
+bool convertHidlNanConfigRequest_1_5ToLegacy(
+ const V1_4::NanConfigRequest& hidl_request1,
+ const NanConfigRequestSupplemental& hidl_request2,
legacy_hal::NanConfigRequest* legacy_request);
bool convertHidlNanPublishRequestToLegacy(
const NanPublishRequest& hidl_request,
diff --git a/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp b/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp
index 411190b..52f0c2b 100644
--- a/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp
+++ b/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp
@@ -41,7 +41,6 @@
namespace V1_5 {
namespace implementation {
-using android::hardware::wifi::V1_2::IWifiNanIfaceEventCallback;
using android::hardware::wifi::V1_2::NanDataPathConfirmInd;
bool CaptureIfaceEventHandlers(
@@ -56,9 +55,10 @@
public:
MockNanIfaceEventCallback() = default;
- MOCK_METHOD3(notifyCapabilitiesResponse,
- Return<void>(uint16_t, const WifiNanStatus&,
- const NanCapabilities&));
+ MOCK_METHOD3(
+ notifyCapabilitiesResponse,
+ Return<void>(uint16_t, const WifiNanStatus&,
+ const android::hardware::wifi::V1_0::NanCapabilities&));
MOCK_METHOD2(notifyEnableResponse,
Return<void>(uint16_t, const WifiNanStatus&));
MOCK_METHOD2(notifyConfigResponse,
@@ -108,6 +108,9 @@
Return<void>(const NanDataPathConfirmInd&));
MOCK_METHOD1(eventDataPathScheduleUpdate,
Return<void>(const NanDataPathScheduleUpdateInd&));
+ MOCK_METHOD3(notifyCapabilitiesResponse_1_5,
+ Return<void>(uint16_t, const WifiNanStatus&,
+ const NanCapabilities&));
};
class WifiNanIfaceTest : public Test {
diff --git a/wifi/1.5/default/wifi_nan_iface.cpp b/wifi/1.5/default/wifi_nan_iface.cpp
index e2b0332..0cc6cd5 100644
--- a/wifi/1.5/default/wifi_nan_iface.cpp
+++ b/wifi/1.5/default/wifi_nan_iface.cpp
@@ -166,10 +166,10 @@
return;
}
for (const auto& callback :
- shared_ptr_this->getEventCallbacks()) {
+ shared_ptr_this->getEventCallbacks_1_5()) {
if (!callback
- ->notifyCapabilitiesResponse(id, wifiNanStatus,
- hidl_struct)
+ ->notifyCapabilitiesResponse_1_5(id, wifiNanStatus,
+ hidl_struct)
.isOk()) {
LOG(ERROR) << "Failed to invoke the callback";
}
@@ -545,6 +545,7 @@
legacy_hal_.reset();
event_cb_handler_.invalidate();
event_cb_handler_1_2_.invalidate();
+ event_cb_handler_1_5_.invalidate();
is_valid_ = false;
if (is_dedicated_iface_) {
// If using a dedicated iface, set the iface down.
@@ -566,6 +567,10 @@
return event_cb_handler_1_2_.getCallbacks();
}
+std::set<sp<IWifiNanIfaceEventCallback>> WifiNanIface::getEventCallbacks_1_5() {
+ return event_cb_handler_1_5_.getCallbacks();
+}
+
Return<void> WifiNanIface::getName(getName_cb hidl_status_cb) {
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
&WifiNanIface::getNameInternal, hidl_status_cb);
@@ -738,6 +743,39 @@
hidl_status_cb, cmd_id, msg1, msg2);
}
+Return<void> WifiNanIface::registerEventCallback_1_5(
+ const sp<IWifiNanIfaceEventCallback>& callback,
+ registerEventCallback_1_5_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::registerEventCallback_1_5Internal,
+ hidl_status_cb, callback);
+}
+
+Return<void> WifiNanIface::enableRequest_1_5(
+ uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
+ const NanConfigRequestSupplemental& msg2,
+ enableRequest_1_5_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::enableRequest_1_5Internal,
+ hidl_status_cb, cmd_id, msg1, msg2);
+}
+
+Return<void> WifiNanIface::configRequest_1_5(
+ uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
+ const NanConfigRequestSupplemental& msg2,
+ configRequest_1_5_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::configRequest_1_5Internal,
+ hidl_status_cb, cmd_id, msg1, msg2);
+}
+
+Return<void> WifiNanIface::getCapabilitiesRequest_1_5(
+ uint16_t cmd_id, getCapabilitiesRequest_1_5_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::getCapabilitiesRequest_1_5Internal,
+ hidl_status_cb, cmd_id);
+}
+
std::pair<WifiStatus, std::string> WifiNanIface::getNameInternal() {
return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_};
}
@@ -754,10 +792,8 @@
return createWifiStatus(WifiStatusCode::SUCCESS);
}
-WifiStatus WifiNanIface::getCapabilitiesRequestInternal(uint16_t cmd_id) {
- legacy_hal::wifi_error legacy_status =
- legacy_hal_.lock()->nanGetCapabilities(ifname_, cmd_id);
- return createWifiStatusFromLegacyError(legacy_status);
+WifiStatus WifiNanIface::getCapabilitiesRequestInternal(uint16_t /* cmd_id */) {
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
}
WifiStatus WifiNanIface::enableRequestInternal(
@@ -890,7 +926,7 @@
WifiStatus WifiNanIface::enableRequest_1_2Internal(
uint16_t /* cmd_id */, const V1_0::NanEnableRequest& /* msg1 */,
- const V1_2::NanConfigRequestSupplemental& /*msg2 */) {
+ const V1_2::NanConfigRequestSupplemental& /* msg2 */) {
return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
}
@@ -901,10 +937,44 @@
}
WifiStatus WifiNanIface::enableRequest_1_4Internal(
+ uint16_t /* cmd_id */, const V1_4::NanEnableRequest& /* msg1 */,
+ const V1_2::NanConfigRequestSupplemental& /* msg2 */) {
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiNanIface::configRequest_1_4Internal(
+ uint16_t /* cmd_id */, const V1_4::NanConfigRequest& /* msg1 */,
+ const V1_2::NanConfigRequestSupplemental& /* msg2 */) {
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiNanIface::registerEventCallback_1_5Internal(
+ const sp<IWifiNanIfaceEventCallback>& callback) {
+ sp<V1_0::IWifiNanIfaceEventCallback> callback_1_0 = callback;
+ if (!event_cb_handler_.addCallback(callback_1_0)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ sp<V1_2::IWifiNanIfaceEventCallback> callback_1_2 = callback;
+ if (!event_cb_handler_1_2_.addCallback(callback_1_2)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ if (!event_cb_handler_1_5_.addCallback(callback)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+WifiStatus WifiNanIface::getCapabilitiesRequest_1_5Internal(uint16_t cmd_id) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanGetCapabilities(ifname_, cmd_id);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiNanIface::enableRequest_1_5Internal(
uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
- const V1_2::NanConfigRequestSupplemental& msg2) {
+ const NanConfigRequestSupplemental& msg2) {
legacy_hal::NanEnableRequest legacy_msg;
- if (!hidl_struct_util::convertHidlNanEnableRequest_1_4ToLegacy(
+ if (!hidl_struct_util::convertHidlNanEnableRequest_1_5ToLegacy(
msg1, msg2, &legacy_msg)) {
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
}
@@ -913,11 +983,11 @@
return createWifiStatusFromLegacyError(legacy_status);
}
-WifiStatus WifiNanIface::configRequest_1_4Internal(
+WifiStatus WifiNanIface::configRequest_1_5Internal(
uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
- const V1_2::NanConfigRequestSupplemental& msg2) {
+ const NanConfigRequestSupplemental& msg2) {
legacy_hal::NanConfigRequest legacy_msg;
- if (!hidl_struct_util::convertHidlNanConfigRequest_1_4ToLegacy(
+ if (!hidl_struct_util::convertHidlNanConfigRequest_1_5ToLegacy(
msg1, msg2, &legacy_msg)) {
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
}
diff --git a/wifi/1.5/default/wifi_nan_iface.h b/wifi/1.5/default/wifi_nan_iface.h
index efdb2da..fb9c047 100644
--- a/wifi/1.5/default/wifi_nan_iface.h
+++ b/wifi/1.5/default/wifi_nan_iface.h
@@ -18,8 +18,8 @@
#define WIFI_NAN_IFACE_H_
#include <android-base/macros.h>
-#include <android/hardware/wifi/1.0/IWifiNanIfaceEventCallback.h>
-#include <android/hardware/wifi/1.4/IWifiNanIface.h>
+#include <android/hardware/wifi/1.5/IWifiNanIface.h>
+#include <android/hardware/wifi/1.5/IWifiNanIfaceEventCallback.h>
#include "hidl_callback_util.h"
#include "wifi_iface_util.h"
@@ -36,7 +36,7 @@
/**
* HIDL interface object used to control a NAN Iface instance.
*/
-class WifiNanIface : public V1_4::IWifiNanIface {
+class WifiNanIface : public V1_5::IWifiNanIface {
public:
WifiNanIface(const std::string& ifname, bool is_dedicated_iface,
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
@@ -112,6 +112,19 @@
uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
const V1_2::NanConfigRequestSupplemental& msg2,
configRequest_1_4_cb hidl_status_cb) override;
+ Return<void> registerEventCallback_1_5(
+ const sp<IWifiNanIfaceEventCallback>& callback,
+ registerEventCallback_1_5_cb hidl_status_cb) override;
+ Return<void> enableRequest_1_5(
+ uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
+ const NanConfigRequestSupplemental& msg2,
+ enableRequest_1_4_cb hidl_status_cb) override;
+ Return<void> configRequest_1_5(
+ uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
+ const NanConfigRequestSupplemental& msg2,
+ configRequest_1_4_cb hidl_status_cb) override;
+ Return<void> getCapabilitiesRequest_1_5(
+ uint16_t cmd_id, getCapabilitiesRequest_cb hidl_status_cb) override;
private:
// Corresponding worker functions for the HIDL methods.
@@ -158,11 +171,22 @@
WifiStatus configRequest_1_4Internal(
uint16_t cmd_id, const V1_4::NanConfigRequest& msg,
const V1_2::NanConfigRequestSupplemental& msg2);
+ WifiStatus registerEventCallback_1_5Internal(
+ const sp<IWifiNanIfaceEventCallback>& callback);
+ WifiStatus enableRequest_1_5Internal(
+ uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
+ const NanConfigRequestSupplemental& msg2);
+ WifiStatus configRequest_1_5Internal(
+ uint16_t cmd_id, const V1_4::NanConfigRequest& msg,
+ const NanConfigRequestSupplemental& msg2);
+ WifiStatus getCapabilitiesRequest_1_5Internal(uint16_t cmd_id);
// all 1_0 and descendant callbacks
std::set<sp<V1_0::IWifiNanIfaceEventCallback>> getEventCallbacks();
// all 1_2 and descendant callbacks
std::set<sp<V1_2::IWifiNanIfaceEventCallback>> getEventCallbacks_1_2();
+ // all 1_5 and descendant callbacks
+ std::set<sp<IWifiNanIfaceEventCallback>> getEventCallbacks_1_5();
std::string ifname_;
bool is_dedicated_iface_;
@@ -173,6 +197,8 @@
event_cb_handler_;
hidl_callback_util::HidlCallbackHandler<V1_2::IWifiNanIfaceEventCallback>
event_cb_handler_1_2_;
+ hidl_callback_util::HidlCallbackHandler<IWifiNanIfaceEventCallback>
+ event_cb_handler_1_5_;
DISALLOW_COPY_AND_ASSIGN(WifiNanIface);
};
diff --git a/wifi/1.5/types.hal b/wifi/1.5/types.hal
index 71f0679..5873f79 100644
--- a/wifi/1.5/types.hal
+++ b/wifi/1.5/types.hal
@@ -17,6 +17,9 @@
package android.hardware.wifi@1.5;
import @1.0::WifiBand;
+import @1.0::NanCipherSuiteType;
+import @1.0::NanCapabilities;
+import @1.2::NanConfigRequestSupplemental;
/**
* Wifi bands defined in 80211 spec.
@@ -35,3 +38,32 @@
*/
BAND_24GHZ_5GHZ_WITH_DFS_6GHZ_60GHZ = 31,
};
+
+/**
+ * NAN configuration request parameters added in the 1.2 HAL. These are supplemental to previous
+ * versions.
+ */
+struct NanConfigRequestSupplemental {
+ /**
+ * Baseline information as defined in HAL 1.2.
+ */
+ @1.2::NanConfigRequestSupplemental V1_2;
+ /**
+ * Controls whether NAN instant communication mode is enabled.
+ */
+ bool enableInstantCommunicationMode;
+};
+
+/**
+ * NDP Capabilities response.
+ */
+struct NanCapabilities {
+ /**
+ * Baseline information as defined in HAL 1.0.
+ */
+ @1.0::NanCapabilities V1_0;
+ /**
+ * Flag to indicate id instant communication mode is supported.
+ */
+ bool instantCommunicationModeSupportFlag;
+};
\ No newline at end of file
diff --git a/wifi/1.5/vts/OWNERS b/wifi/1.5/vts/OWNERS
new file mode 100644
index 0000000..8bfb148
--- /dev/null
+++ b/wifi/1.5/vts/OWNERS
@@ -0,0 +1,2 @@
+rpius@google.com
+etancohen@google.com
diff --git a/wifi/1.5/vts/functional/Android.bp b/wifi/1.5/vts/functional/Android.bp
new file mode 100644
index 0000000..a7ba498
--- /dev/null
+++ b/wifi/1.5/vts/functional/Android.bp
@@ -0,0 +1,39 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// These tests are split out so that they can be conditioned on presence of the
+// "android.hardware.wifi.aware" feature.
+cc_test {
+ name: "VtsHalWifiNanV1_5TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: [
+ "wifi_nan_iface_hidl_test.cpp",
+ ],
+ static_libs: [
+ "VtsHalWifiV1_0TargetTestUtil",
+ "android.hardware.wifi@1.0",
+ "android.hardware.wifi@1.1",
+ "android.hardware.wifi@1.2",
+ "android.hardware.wifi@1.3",
+ "android.hardware.wifi@1.4",
+ "android.hardware.wifi@1.5",
+ "libwifi-system-iface",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
diff --git a/wifi/1.5/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.5/vts/functional/wifi_nan_iface_hidl_test.cpp
new file mode 100644
index 0000000..803d39d
--- /dev/null
+++ b/wifi/1.5/vts/functional/wifi_nan_iface_hidl_test.cpp
@@ -0,0 +1,628 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Nanache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <android-base/logging.h>
+
+#include <VtsCoreUtil.h>
+#include <android/hardware/wifi/1.5/IWifi.h>
+#include <android/hardware/wifi/1.5/IWifiNanIface.h>
+#include <android/hardware/wifi/1.5/IWifiNanIfaceEventCallback.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+
+#include "wifi_hidl_call_util.h"
+#include "wifi_hidl_test_utils.h"
+
+using namespace ::android::hardware::wifi::V1_0;
+using namespace ::android::hardware::wifi::V1_2;
+using namespace ::android::hardware::wifi::V1_4;
+using namespace ::android::hardware::wifi::V1_5;
+
+using ::android::sp;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+#define TIMEOUT_PERIOD 10
+
+android::sp<android::hardware::wifi::V1_5::IWifiNanIface> getWifiNanIface_1_5(
+ const std::string& instance_name) {
+ return android::hardware::wifi::V1_5::IWifiNanIface::castFrom(
+ getWifiNanIface(instance_name));
+}
+
+/**
+ * Fixture to use for all NAN Iface HIDL interface tests.
+ */
+class WifiNanIfaceHidlTest : public ::testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ if (!::testing::deviceSupportsFeature("android.hardware.wifi.aware"))
+ GTEST_SKIP() << "Skipping this test since NAN is not supported.";
+ // Make sure to start with a clean state
+ stopWifi(GetInstanceName());
+
+ iwifiNanIface = getWifiNanIface_1_5(GetInstanceName());
+ ASSERT_NE(nullptr, iwifiNanIface.get());
+ ASSERT_EQ(WifiStatusCode::SUCCESS,
+ HIDL_INVOKE(iwifiNanIface, registerEventCallback_1_5,
+ new WifiNanIfaceEventCallback(*this))
+ .code);
+ }
+
+ virtual void TearDown() override { stopWifi(GetInstanceName()); }
+
+ /* Used as a mechanism to inform the test about data/event callback */
+ inline void notify() {
+ std::unique_lock<std::mutex> lock(mtx_);
+ count_++;
+ cv_.notify_one();
+ }
+
+ enum CallbackType {
+ INVALID = -2,
+ ANY_CALLBACK = -1,
+
+ NOTIFY_CAPABILITIES_RESPONSE = 0,
+ NOTIFY_ENABLE_RESPONSE,
+ NOTIFY_CONFIG_RESPONSE,
+ NOTIFY_DISABLE_RESPONSE,
+ NOTIFY_START_PUBLISH_RESPONSE,
+ NOTIFY_STOP_PUBLISH_RESPONSE,
+ NOTIFY_START_SUBSCRIBE_RESPONSE,
+ NOTIFY_STOP_SUBSCRIBE_RESPONSE,
+ NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE,
+ NOTIFY_CREATE_DATA_INTERFACE_RESPONSE,
+ NOTIFY_DELETE_DATA_INTERFACE_RESPONSE,
+ NOTIFY_INITIATE_DATA_PATH_RESPONSE,
+ NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE,
+ NOTIFY_TERMINATE_DATA_PATH_RESPONSE,
+ NOTIFY_CAPABILITIES_RESPONSE_1_5,
+
+ EVENT_CLUSTER_EVENT,
+ EVENT_DISABLED,
+ EVENT_PUBLISH_TERMINATED,
+ EVENT_SUBSCRIBE_TERMINATED,
+ EVENT_MATCH,
+ EVENT_MATCH_EXPIRED,
+ EVENT_FOLLOWUP_RECEIVED,
+ EVENT_TRANSMIT_FOLLOWUP,
+ EVENT_DATA_PATH_REQUEST,
+ EVENT_DATA_PATH_CONFIRM,
+ EVENT_DATA_PATH_TERMINATED,
+ EVENT_DATA_PATH_CONFIRM_1_2,
+ EVENT_DATA_PATH_SCHEDULE_UPDATE
+ };
+
+ /* Test code calls this function to wait for data/event callback */
+ /* Must set callbackType = INVALID before call this function */
+ inline std::cv_status wait(CallbackType waitForCallbackType) {
+ std::unique_lock<std::mutex> lock(mtx_);
+
+ EXPECT_NE(INVALID, waitForCallbackType); // can't ASSERT in a
+ // non-void-returning method
+
+ std::cv_status status = std::cv_status::no_timeout;
+ auto now = std::chrono::system_clock::now();
+ while (count_ == 0) {
+ status = cv_.wait_until(lock,
+ now + std::chrono::seconds(TIMEOUT_PERIOD));
+ if (status == std::cv_status::timeout) return status;
+ if (waitForCallbackType != ANY_CALLBACK &&
+ callbackType != INVALID &&
+ callbackType != waitForCallbackType) {
+ count_--;
+ }
+ }
+ count_--;
+ return status;
+ }
+
+ class WifiNanIfaceEventCallback
+ : public ::android::hardware::wifi::V1_5::IWifiNanIfaceEventCallback {
+ WifiNanIfaceHidlTest& parent_;
+
+ public:
+ WifiNanIfaceEventCallback(WifiNanIfaceHidlTest& parent)
+ : parent_(parent){};
+
+ virtual ~WifiNanIfaceEventCallback() = default;
+
+ Return<void> notifyCapabilitiesResponse(
+ uint16_t id, const WifiNanStatus& status,
+ const ::android::hardware::wifi::V1_0::NanCapabilities&
+ capabilities) override {
+ parent_.callbackType = NOTIFY_CAPABILITIES_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+ parent_.capabilities = capabilities;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyCapabilitiesResponse_1_5(
+ uint16_t id, const WifiNanStatus& status,
+ const ::android::hardware::wifi::V1_5::NanCapabilities&
+ capabilities) override {
+ parent_.callbackType = NOTIFY_CAPABILITIES_RESPONSE_1_5;
+
+ parent_.id = id;
+ parent_.status = status;
+ parent_.capabilities_1_5 = capabilities;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyEnableResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_ENABLE_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyConfigResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_CONFIG_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyDisableResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_DISABLE_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyStartPublishResponse(uint16_t id,
+ const WifiNanStatus& status,
+ uint8_t sessionId) override {
+ parent_.callbackType = NOTIFY_START_PUBLISH_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+ parent_.sessionId = sessionId;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyStopPublishResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_STOP_PUBLISH_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyStartSubscribeResponse(uint16_t id,
+ const WifiNanStatus& status,
+ uint8_t sessionId) override {
+ parent_.callbackType = NOTIFY_START_SUBSCRIBE_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+ parent_.sessionId = sessionId;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyStopSubscribeResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_STOP_SUBSCRIBE_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyTransmitFollowupResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyCreateDataInterfaceResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_CREATE_DATA_INTERFACE_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyDeleteDataInterfaceResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_DELETE_DATA_INTERFACE_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyInitiateDataPathResponse(
+ uint16_t id, const WifiNanStatus& status,
+ uint32_t ndpInstanceId) override {
+ parent_.callbackType = NOTIFY_INITIATE_DATA_PATH_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+ parent_.ndpInstanceId = ndpInstanceId;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyRespondToDataPathIndicationResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType =
+ NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyTerminateDataPathResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_TERMINATE_DATA_PATH_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventClusterEvent(
+ const NanClusterEventInd& event) override {
+ parent_.callbackType = EVENT_CLUSTER_EVENT;
+
+ parent_.nanClusterEventInd = event;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventDisabled(const WifiNanStatus& status) override {
+ parent_.callbackType = EVENT_DISABLED;
+
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventPublishTerminated(
+ uint8_t sessionId, const WifiNanStatus& status) override {
+ parent_.callbackType = EVENT_PUBLISH_TERMINATED;
+
+ parent_.sessionId = sessionId;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventSubscribeTerminated(
+ uint8_t sessionId, const WifiNanStatus& status) override {
+ parent_.callbackType = EVENT_SUBSCRIBE_TERMINATED;
+
+ parent_.sessionId = sessionId;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventMatch(const NanMatchInd& event) override {
+ parent_.callbackType = EVENT_MATCH;
+
+ parent_.nanMatchInd = event;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventMatchExpired(uint8_t discoverySessionId,
+ uint32_t peerId) override {
+ parent_.callbackType = EVENT_MATCH_EXPIRED;
+
+ parent_.sessionId = discoverySessionId;
+ parent_.peerId = peerId;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventFollowupReceived(
+ const NanFollowupReceivedInd& event) override {
+ parent_.callbackType = EVENT_FOLLOWUP_RECEIVED;
+
+ parent_.nanFollowupReceivedInd = event;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventTransmitFollowup(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = EVENT_TRANSMIT_FOLLOWUP;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventDataPathRequest(
+ const NanDataPathRequestInd& event) override {
+ parent_.callbackType = EVENT_DATA_PATH_REQUEST;
+
+ parent_.nanDataPathRequestInd = event;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventDataPathConfirm(
+ const ::android::hardware::wifi::V1_0::NanDataPathConfirmInd& event)
+ override {
+ parent_.callbackType = EVENT_DATA_PATH_CONFIRM;
+
+ parent_.nanDataPathConfirmInd = event;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventDataPathTerminated(uint32_t ndpInstanceId) override {
+ parent_.callbackType = EVENT_DATA_PATH_TERMINATED;
+
+ parent_.ndpInstanceId = ndpInstanceId;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventDataPathConfirm_1_2(
+ const ::android::hardware::wifi::V1_2::NanDataPathConfirmInd& event)
+ override {
+ parent_.callbackType = EVENT_DATA_PATH_CONFIRM_1_2;
+
+ parent_.nanDataPathConfirmInd_1_2 = event;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventDataPathScheduleUpdate(
+ const NanDataPathScheduleUpdateInd& event) override {
+ parent_.callbackType = EVENT_DATA_PATH_SCHEDULE_UPDATE;
+
+ parent_.nanDataPathScheduleUpdateInd = event;
+
+ parent_.notify();
+ return Void();
+ }
+ };
+
+ private:
+ // synchronization objects
+ std::mutex mtx_;
+ std::condition_variable cv_;
+ int count_ = 0;
+
+ protected:
+ android::sp<::android::hardware::wifi::V1_5::IWifiNanIface> iwifiNanIface;
+
+ // Data from IWifiNanIfaceEventCallback callbacks: this is the collection of
+ // all arguments to all callbacks. They are set by the callback
+ // (notifications or events) and can be retrieved by tests.
+ CallbackType callbackType;
+ uint16_t id;
+ WifiNanStatus status;
+ uint8_t sessionId;
+ uint32_t ndpInstanceId;
+ NanClusterEventInd nanClusterEventInd;
+ NanMatchInd nanMatchInd;
+ uint32_t peerId;
+ NanFollowupReceivedInd nanFollowupReceivedInd;
+ NanDataPathRequestInd nanDataPathRequestInd;
+ ::android::hardware::wifi::V1_0::NanCapabilities capabilities;
+ ::android::hardware::wifi::V1_5::NanCapabilities capabilities_1_5;
+ ::android::hardware::wifi::V1_0::NanDataPathConfirmInd
+ nanDataPathConfirmInd;
+ ::android::hardware::wifi::V1_2::NanDataPathConfirmInd
+ nanDataPathConfirmInd_1_2;
+ NanDataPathScheduleUpdateInd nanDataPathScheduleUpdateInd;
+
+ std::string GetInstanceName() { return GetParam(); }
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifiNanIface proxy object is
+ * successfully created.
+ */
+TEST_P(WifiNanIfaceHidlTest, Create) {
+ // The creation of a proxy object is tested as part of SetUp method.
+}
+
+/*
+ * enableRequest_1_5InvalidArgs: validate that fails with invalid arguments
+ */
+TEST_P(WifiNanIfaceHidlTest, enableRequest_1_5InvalidArgs) {
+ uint16_t inputCmdId = 10;
+ callbackType = INVALID;
+ ::android::hardware::wifi::V1_4::NanEnableRequest nanEnableRequest = {};
+ ::android::hardware::wifi::V1_5::NanConfigRequestSupplemental
+ nanConfigRequestSupp = {};
+ const auto& halStatus =
+ HIDL_INVOKE(iwifiNanIface, enableRequest_1_5, inputCmdId,
+ nanEnableRequest, nanConfigRequestSupp);
+ if (halStatus.code != WifiStatusCode::ERROR_NOT_SUPPORTED) {
+ ASSERT_EQ(WifiStatusCode::SUCCESS, halStatus.code);
+
+ // wait for a callback
+ ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_ENABLE_RESPONSE));
+ ASSERT_EQ(NOTIFY_ENABLE_RESPONSE, callbackType);
+ ASSERT_EQ(id, inputCmdId);
+ ASSERT_EQ(status.status, NanStatusType::INVALID_ARGS);
+ }
+}
+
+/*
+ * enableRequest_1_5ShimInvalidArgs: validate that fails with invalid arguments
+ * to the shim
+ */
+TEST_P(WifiNanIfaceHidlTest, enableRequest_1_5ShimInvalidArgs) {
+ uint16_t inputCmdId = 10;
+ ::android::hardware::wifi::V1_4::NanEnableRequest nanEnableRequest = {};
+ nanEnableRequest.configParams.numberOfPublishServiceIdsInBeacon =
+ 128; // must be <= 127
+ ::android::hardware::wifi::V1_5::NanConfigRequestSupplemental
+ nanConfigRequestSupp = {};
+ const auto& halStatus =
+ HIDL_INVOKE(iwifiNanIface, enableRequest_1_5, inputCmdId,
+ nanEnableRequest, nanConfigRequestSupp);
+ if (halStatus.code != WifiStatusCode::ERROR_NOT_SUPPORTED) {
+ ASSERT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, halStatus.code);
+ }
+}
+
+/*
+ * configRequest_1_5InvalidArgs: validate that fails with invalid arguments
+ */
+TEST_P(WifiNanIfaceHidlTest, configRequest_1_5InvalidArgs) {
+ uint16_t inputCmdId = 10;
+ callbackType = INVALID;
+ ::android::hardware::wifi::V1_4::NanConfigRequest nanConfigRequest = {};
+ ::android::hardware::wifi::V1_5::NanConfigRequestSupplemental
+ nanConfigRequestSupp = {};
+ const auto& halStatus =
+ HIDL_INVOKE(iwifiNanIface, configRequest_1_5, inputCmdId,
+ nanConfigRequest, nanConfigRequestSupp);
+
+ if (halStatus.code != WifiStatusCode::ERROR_NOT_SUPPORTED) {
+ ASSERT_EQ(WifiStatusCode::SUCCESS, halStatus.code);
+
+ // wait for a callback
+ ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_CONFIG_RESPONSE));
+ ASSERT_EQ(NOTIFY_CONFIG_RESPONSE, callbackType);
+ ASSERT_EQ(id, inputCmdId);
+ ASSERT_EQ(status.status, NanStatusType::INVALID_ARGS);
+ }
+}
+
+/*
+ * configRequest_1_5ShimInvalidArgs: validate that fails with invalid arguments
+ * to the shim
+ */
+TEST_P(WifiNanIfaceHidlTest, configRequest_1_5ShimInvalidArgs) {
+ uint16_t inputCmdId = 10;
+ ::android::hardware::wifi::V1_4::NanConfigRequest nanConfigRequest = {};
+ nanConfigRequest.numberOfPublishServiceIdsInBeacon = 128; // must be <= 127
+ ::android::hardware::wifi::V1_5::NanConfigRequestSupplemental
+ nanConfigRequestSupp = {};
+ const auto& halStatus =
+ HIDL_INVOKE(iwifiNanIface, configRequest_1_5, inputCmdId,
+ nanConfigRequest, nanConfigRequestSupp);
+ if (halStatus.code != WifiStatusCode::ERROR_NOT_SUPPORTED) {
+ ASSERT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, halStatus.code);
+ }
+}
+
+/*
+ * getCapabilitiesRequest: validate that returns capabilities.
+ */
+TEST_P(WifiNanIfaceHidlTest, getCapabilitiesRequest_1_5) {
+ uint16_t inputCmdId = 10;
+ callbackType = INVALID;
+ const auto& halStatus =
+ HIDL_INVOKE(iwifiNanIface, getCapabilitiesRequest_1_5, inputCmdId).code;
+ ASSERT_EQ(WifiStatusCode::SUCCESS, halStatus);
+ // wait for a callback
+ ASSERT_EQ(std::cv_status::no_timeout,
+ wait(NOTIFY_CAPABILITIES_RESPONSE_1_5));
+ ASSERT_EQ(NOTIFY_CAPABILITIES_RESPONSE_1_5, callbackType);
+ ASSERT_EQ(id, inputCmdId);
+
+ // check for reasonable capability values
+ EXPECT_GT(capabilities_1_5.V1_0.maxConcurrentClusters, (unsigned int)0);
+ EXPECT_GT(capabilities_1_5.V1_0.maxPublishes, (unsigned int)0);
+ EXPECT_GT(capabilities_1_5.V1_0.maxSubscribes, (unsigned int)0);
+ EXPECT_EQ(capabilities_1_5.V1_0.maxServiceNameLen, (unsigned int)255);
+ EXPECT_EQ(capabilities_1_5.V1_0.maxMatchFilterLen, (unsigned int)255);
+ EXPECT_GT(capabilities_1_5.V1_0.maxTotalMatchFilterLen, (unsigned int)255);
+ EXPECT_EQ(capabilities_1_5.V1_0.maxServiceSpecificInfoLen,
+ (unsigned int)255);
+ EXPECT_GE(capabilities_1_5.V1_0.maxExtendedServiceSpecificInfoLen,
+ (unsigned int)255);
+ EXPECT_GT(capabilities_1_5.V1_0.maxNdiInterfaces, (unsigned int)0);
+ EXPECT_GT(capabilities_1_5.V1_0.maxNdpSessions, (unsigned int)0);
+ EXPECT_GT(capabilities_1_5.V1_0.maxAppInfoLen, (unsigned int)0);
+ EXPECT_GT(capabilities_1_5.V1_0.maxQueuedTransmitFollowupMsgs,
+ (unsigned int)0);
+ EXPECT_GT(capabilities_1_5.V1_0.maxSubscribeInterfaceAddresses,
+ (unsigned int)0);
+ EXPECT_NE(capabilities_1_5.V1_0.supportedCipherSuites, (unsigned int)0);
+ EXPECT_TRUE(capabilities_1_5.instantCommunicationModeSupportFlag ||
+ !capabilities_1_5.instantCommunicationModeSupportFlag);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiNanIfaceHidlTest);
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, WifiNanIfaceHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ::android::hardware::wifi::V1_5::IWifi::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/wifi/hostapd/1.2/vts/functional/Android.bp b/wifi/hostapd/1.2/vts/functional/Android.bp
index cec1782..577174b 100644
--- a/wifi/hostapd/1.2/vts/functional/Android.bp
+++ b/wifi/hostapd/1.2/vts/functional/Android.bp
@@ -25,12 +25,15 @@
"VtsHalWifiHostapdV1_0TargetTestUtil",
"android.hardware.wifi.hostapd@1.0",
"android.hardware.wifi.hostapd@1.1",
- "android.hardware.wifi.hostapd@1.2",
+ "android.hardware.wifi.hostapd@1.2",
+ "android.hardware.wifi.hostapd@1.3",
"android.hardware.wifi@1.0",
"libgmock",
"libwifi-system",
"libwifi-system-iface",
],
- test_suites: ["general-tests", "vts"],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
}
-
diff --git a/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp
index 99784a4..c40c582 100644
--- a/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp
+++ b/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp
@@ -25,6 +25,7 @@
#include <android/hardware/wifi/1.0/IWifi.h>
#include <android/hardware/wifi/hostapd/1.2/IHostapd.h>
+#include <android/hardware/wifi/hostapd/1.3/IHostapd.h>
#include "hostapd_hidl_call_util.h"
#include "hostapd_hidl_test_utils.h"
@@ -216,12 +217,20 @@
std::string hostapd_instance_name_;
};
+bool is_1_3(const sp<IHostapd>& hostapd) {
+ sp<::android::hardware::wifi::hostapd::V1_3::IHostapd> hostapd_1_3 =
+ ::android::hardware::wifi::hostapd::V1_3::IHostapd::castFrom(hostapd);
+ return hostapd_1_3.get() != nullptr;
+}
+
/**
* Adds an access point with PSK network config & ACS enabled.
* Access point creation should pass.
*/
TEST_P(HostapdHidlTest, AddPskAccessPointWithAcs) {
if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithAcs(), getPskNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
@@ -233,6 +242,8 @@
*/
TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndFreqRange) {
if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status =
HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithAcsAndFreqRange(), getPskNwParams());
@@ -245,6 +256,8 @@
*/
TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndInvalidFreqRange) {
if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithAcsAndInvalidFreqRange(),
getPskNwParams());
@@ -257,6 +270,8 @@
*/
TEST_P(HostapdHidlTest, AddOpenAccessPointWithAcs) {
if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithAcs(), getOpenNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
@@ -267,6 +282,8 @@
* Access point creation should pass.
*/
TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcs) {
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithoutAcs(), getPskNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
@@ -277,6 +294,8 @@
* Access point creation should pass.
*/
TEST_P(HostapdHidlTest, AddOpenAccessPointWithoutAcs) {
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithoutAcs(), getOpenNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
@@ -288,6 +307,8 @@
*/
TEST_P(HostapdHidlTest, AddSaeTransitionAccessPointWithoutAcs) {
if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status =
HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
getSaeTransitionNwParams());
@@ -300,6 +321,8 @@
*/
TEST_P(HostapdHidlTest, AddSAEAccessPointWithoutAcs) {
if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithoutAcs(), getSaeNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
@@ -311,6 +334,8 @@
*/
TEST_P(HostapdHidlTest, RemoveAccessPointWithAcs) {
if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithAcs(), getPskNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code);
@@ -326,6 +351,8 @@
* Access point creation & removal should pass.
*/
TEST_P(HostapdHidlTest, RemoveAccessPointWithoutAcs) {
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithoutAcs(), getPskNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code);
@@ -341,6 +368,8 @@
* Access point creation should fail.
*/
TEST_P(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) {
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status =
HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithInvalidChannel(), getPskNwParams());
@@ -352,6 +381,8 @@
* Access point creation should fail.
*/
TEST_P(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) {
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status =
HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
getInvalidPskNwParams());
@@ -364,6 +395,8 @@
*/
TEST_P(HostapdHidlTest, AddInvalidSaeTransitionAccessPointWithoutAcs) {
if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status =
HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
getInvalidSaeTransitionNwParams());
@@ -376,6 +409,8 @@
*/
TEST_P(HostapdHidlTest, AddInvalidSaeAccessPointWithoutAcs) {
if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status =
HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
getInvalidSaeNwParams());
@@ -398,6 +433,8 @@
* when hotspot interface available.
*/
TEST_P(HostapdHidlTest, DisconnectClientWhenIfacAvailable) {
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status_1_2 =
HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
getOpenNwParams());
diff --git a/wifi/hostapd/1.3/vts/OWNERS b/wifi/hostapd/1.3/vts/OWNERS
new file mode 100644
index 0000000..8bfb148
--- /dev/null
+++ b/wifi/hostapd/1.3/vts/OWNERS
@@ -0,0 +1,2 @@
+rpius@google.com
+etancohen@google.com
diff --git a/wifi/hostapd/1.3/vts/functional/Android.bp b/wifi/hostapd/1.3/vts/functional/Android.bp
new file mode 100644
index 0000000..07cebb0
--- /dev/null
+++ b/wifi/hostapd/1.3/vts/functional/Android.bp
@@ -0,0 +1,39 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+ name: "VtsHalWifiHostapdV1_3TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: [
+ "hostapd_hidl_test.cpp",
+ ],
+ static_libs: [
+ "VtsHalWifiV1_0TargetTestUtil",
+ "VtsHalWifiHostapdV1_0TargetTestUtil",
+ "android.hardware.wifi.hostapd@1.0",
+ "android.hardware.wifi.hostapd@1.1",
+ "android.hardware.wifi.hostapd@1.2",
+ "android.hardware.wifi.hostapd@1.3",
+ "android.hardware.wifi@1.0",
+ "libgmock",
+ "libwifi-system",
+ "libwifi-system-iface",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
diff --git a/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp
new file mode 100644
index 0000000..d6c750f
--- /dev/null
+++ b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp
@@ -0,0 +1,433 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <VtsCoreUtil.h>
+
+#include <android-base/logging.h>
+#include <cutils/properties.h>
+
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+#include <android/hardware/wifi/1.0/IWifi.h>
+#include <android/hardware/wifi/hostapd/1.3/IHostapd.h>
+
+#include "hostapd_hidl_call_util.h"
+#include "hostapd_hidl_test_utils.h"
+
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::wifi::hostapd::V1_2::DebugLevel;
+using ::android::hardware::wifi::hostapd::V1_2::HostapdStatusCode;
+using ::android::hardware::wifi::hostapd::V1_2::Ieee80211ReasonCode;
+using ::android::hardware::wifi::hostapd::V1_3::IHostapd;
+using ::android::hardware::wifi::V1_0::IWifi;
+
+namespace {
+constexpr unsigned char kNwSsid[] = {'t', 'e', 's', 't', '1',
+ '2', '3', '4', '5'};
+constexpr char kNwPassphrase[] = "test12345";
+constexpr char kInvalidMaxPskNwPassphrase[] =
+ "0123456789012345678901234567890123456789012345678901234567890123456789";
+constexpr char kInvalidMinPskNwPassphrase[] = "test";
+constexpr int kIfaceChannel = 6;
+constexpr int kIfaceInvalidChannel = 567;
+constexpr uint8_t kTestZeroMacAddr[] = {[0 ... 5] = 0x0};
+constexpr Ieee80211ReasonCode kTestDisconnectReasonCode =
+ Ieee80211ReasonCode::WLAN_REASON_UNSPECIFIED;
+} // namespace
+
+class HostapdHidlTest
+ : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
+ public:
+ virtual void SetUp() override {
+ wifi_instance_name_ = std::get<0>(GetParam());
+ hostapd_instance_name_ = std::get<1>(GetParam());
+ stopSupplicantIfNeeded(wifi_instance_name_);
+ startHostapdAndWaitForHidlService(wifi_instance_name_,
+ hostapd_instance_name_);
+ hostapd_ = IHostapd::getService(hostapd_instance_name_);
+ ASSERT_NE(hostapd_.get(), nullptr);
+ HIDL_INVOKE(hostapd_, setDebugParams, DebugLevel::EXCESSIVE);
+ isAcsSupport_ = testing::checkSubstringInCommandOutput(
+ "/system/bin/cmd wifi get-softap-supported-features",
+ "wifi_softap_acs_supported");
+ isWpa3SaeSupport_ = testing::checkSubstringInCommandOutput(
+ "/system/bin/cmd wifi get-softap-supported-features",
+ "wifi_softap_wpa3_sae_supported");
+ }
+
+ virtual void TearDown() override {
+ HIDL_INVOKE_VOID_WITHOUT_ARGUMENTS(hostapd_, terminate);
+ stopHostapd(wifi_instance_name_);
+ }
+
+ protected:
+ bool isWpa3SaeSupport_ = false;
+ bool isAcsSupport_ = false;
+ std::string getPrimaryWlanIfaceName() {
+ std::array<char, PROPERTY_VALUE_MAX> buffer;
+ auto res = property_get("ro.vendor.wifi.sap.interface", buffer.data(),
+ nullptr);
+ if (res > 0) return buffer.data();
+ property_get("wifi.interface", buffer.data(), "wlan0");
+ return buffer.data();
+ }
+
+ IHostapd::IfaceParams getIfaceParamsWithoutAcs() {
+ ::android::hardware::wifi::hostapd::V1_0::IHostapd::IfaceParams
+ iface_params;
+ ::android::hardware::wifi::hostapd::V1_1::IHostapd::IfaceParams
+ iface_params_1_1;
+ IHostapd::IfaceParams iface_params_1_2;
+
+ iface_params.ifaceName = getPrimaryWlanIfaceName();
+ iface_params.hwModeParams.enable80211N = true;
+ iface_params.hwModeParams.enable80211AC = false;
+ iface_params.channelParams.enableAcs = false;
+ iface_params.channelParams.acsShouldExcludeDfs = false;
+ iface_params.channelParams.channel = kIfaceChannel;
+ iface_params_1_1.V1_0 = iface_params;
+ iface_params_1_2.V1_1 = iface_params_1_1;
+ // Newly added attributes in V1_2
+ iface_params_1_2.hwModeParams.enable80211AX = false;
+ iface_params_1_2.hwModeParams.enable6GhzBand = false;
+ iface_params_1_2.channelParams.bandMask = 0;
+ iface_params_1_2.channelParams.bandMask |=
+ IHostapd::BandMask::BAND_2_GHZ;
+ return iface_params_1_2;
+ }
+
+ IHostapd::IfaceParams getIfaceParamsWithAcs() {
+ // First get the settings for WithoutAcs and then make changes
+ IHostapd::IfaceParams iface_params_1_2 = getIfaceParamsWithoutAcs();
+ iface_params_1_2.V1_1.V1_0.channelParams.enableAcs = true;
+ iface_params_1_2.V1_1.V1_0.channelParams.acsShouldExcludeDfs = true;
+ iface_params_1_2.V1_1.V1_0.channelParams.channel = 0;
+ iface_params_1_2.channelParams.bandMask |=
+ IHostapd::BandMask::BAND_5_GHZ;
+
+ return iface_params_1_2;
+ }
+
+ IHostapd::IfaceParams getIfaceParamsWithAcsAndFreqRange() {
+ IHostapd::IfaceParams iface_params_1_2 = getIfaceParamsWithAcs();
+ ::android::hardware::wifi::hostapd::V1_2::IHostapd::AcsFrequencyRange
+ acsFrequencyRange;
+ acsFrequencyRange.start = 2412;
+ acsFrequencyRange.end = 2462;
+ std::vector<::android::hardware::wifi::hostapd::V1_2::IHostapd::
+ AcsFrequencyRange>
+ vec_acsFrequencyRange;
+ vec_acsFrequencyRange.push_back(acsFrequencyRange);
+ iface_params_1_2.channelParams.acsChannelFreqRangesMhz =
+ vec_acsFrequencyRange;
+ return iface_params_1_2;
+ }
+
+ IHostapd::IfaceParams getIfaceParamsWithAcsAndInvalidFreqRange() {
+ IHostapd::IfaceParams iface_params_1_2 =
+ getIfaceParamsWithAcsAndFreqRange();
+ iface_params_1_2.channelParams.acsChannelFreqRangesMhz[0].start = 222;
+ iface_params_1_2.channelParams.acsChannelFreqRangesMhz[0].end = 999;
+ return iface_params_1_2;
+ }
+
+ IHostapd::NetworkParams getOpenNwParams() {
+ IHostapd::NetworkParams nw_params_1_3;
+ ::android::hardware::wifi::hostapd::V1_2::IHostapd::NetworkParams
+ nw_params_1_2;
+ ::android::hardware::wifi::hostapd::V1_0::IHostapd::NetworkParams
+ nw_params_1_0;
+ nw_params_1_0.ssid =
+ std::vector<uint8_t>(kNwSsid, kNwSsid + sizeof(kNwSsid));
+ nw_params_1_0.isHidden = false;
+ nw_params_1_2.V1_0 = nw_params_1_0;
+ nw_params_1_2.encryptionType = IHostapd::EncryptionType::NONE;
+ nw_params_1_3.V1_2 = nw_params_1_2;
+ nw_params_1_3.isMetered = true;
+ return nw_params_1_3;
+ }
+
+ IHostapd::NetworkParams getPskNwParamsWithNonMetered() {
+ IHostapd::NetworkParams nw_params_1_3 = getOpenNwParams();
+ nw_params_1_3.V1_2.encryptionType = IHostapd::EncryptionType::WPA2;
+ nw_params_1_3.V1_2.passphrase = kNwPassphrase;
+ nw_params_1_3.isMetered = false;
+ return nw_params_1_3;
+ }
+
+ IHostapd::NetworkParams getPskNwParams() {
+ IHostapd::NetworkParams nw_params_1_3 = getOpenNwParams();
+ nw_params_1_3.V1_2.encryptionType = IHostapd::EncryptionType::WPA2;
+ nw_params_1_3.V1_2.passphrase = kNwPassphrase;
+ return nw_params_1_3;
+ }
+
+ IHostapd::NetworkParams getInvalidPskNwParams() {
+ IHostapd::NetworkParams nw_params_1_3 = getOpenNwParams();
+ nw_params_1_3.V1_2.encryptionType = IHostapd::EncryptionType::WPA2;
+ nw_params_1_3.V1_2.passphrase = kInvalidMaxPskNwPassphrase;
+
+ return nw_params_1_3;
+ }
+
+ IHostapd::NetworkParams getSaeTransitionNwParams() {
+ IHostapd::NetworkParams nw_params_1_3 = getOpenNwParams();
+ nw_params_1_3.V1_2.encryptionType =
+ IHostapd::EncryptionType::WPA3_SAE_TRANSITION;
+ nw_params_1_3.V1_2.passphrase = kNwPassphrase;
+ return nw_params_1_3;
+ }
+
+ IHostapd::NetworkParams getInvalidSaeTransitionNwParams() {
+ IHostapd::NetworkParams nw_params_1_3 = getOpenNwParams();
+ nw_params_1_3.V1_2.encryptionType = IHostapd::EncryptionType::WPA2;
+ nw_params_1_3.V1_2.passphrase = kInvalidMinPskNwPassphrase;
+ return nw_params_1_3;
+ }
+
+ IHostapd::NetworkParams getSaeNwParams() {
+ IHostapd::NetworkParams nw_params_1_3 = getOpenNwParams();
+ nw_params_1_3.V1_2.encryptionType = IHostapd::EncryptionType::WPA3_SAE;
+ nw_params_1_3.V1_2.passphrase = kNwPassphrase;
+ return nw_params_1_3;
+ }
+
+ IHostapd::NetworkParams getInvalidSaeNwParams() {
+ IHostapd::NetworkParams nw_params_1_3 = getOpenNwParams();
+ nw_params_1_3.V1_2.encryptionType = IHostapd::EncryptionType::WPA3_SAE;
+ nw_params_1_3.V1_2.passphrase = "";
+ return nw_params_1_3;
+ }
+
+ IHostapd::IfaceParams getIfaceParamsWithInvalidChannel() {
+ IHostapd::IfaceParams iface_params_1_2 = getIfaceParamsWithoutAcs();
+ iface_params_1_2.V1_1.V1_0.channelParams.channel = kIfaceInvalidChannel;
+ return iface_params_1_2;
+ }
+
+ // IHostapd object used for all tests in this fixture.
+ sp<IHostapd> hostapd_;
+ std::string wifi_instance_name_;
+ std::string hostapd_instance_name_;
+};
+
+/**
+ * Adds an access point with PSK network config & ACS enabled.
+ * Access point creation should pass.
+ */
+TEST_P(HostapdHidlTest, AddPskAccessPointWithAcs) {
+ if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
+ auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithAcs(), getPskNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with PSK network config, ACS enabled & frequency Range.
+ * Access point creation should pass.
+ */
+TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndFreqRange) {
+ if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
+ auto status =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithAcsAndFreqRange(), getPskNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with invalid channel range.
+ * Access point creation should fail.
+ */
+TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndInvalidFreqRange) {
+ if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
+ auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithAcsAndInvalidFreqRange(),
+ getPskNwParams());
+ EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with Open network config & ACS enabled.
+ * Access point creation should pass.
+ */
+TEST_P(HostapdHidlTest, AddOpenAccessPointWithAcs) {
+ if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
+ auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithAcs(), getOpenNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with PSK network config & ACS disabled.
+ * Access point creation should pass.
+ */
+TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcs) {
+ auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithoutAcs(), getPskNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with PSK network config, ACS disabled & Non metered.
+ * Access point creation should pass.
+ */
+TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcsAndNonMetered) {
+ auto status =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(),
+ getPskNwParamsWithNonMetered());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with Open network config & ACS disabled.
+ * Access point creation should pass.
+ */
+TEST_P(HostapdHidlTest, AddOpenAccessPointWithoutAcs) {
+ auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithoutAcs(), getOpenNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with SAE Transition network config & ACS disabled.
+ * Access point creation should pass.
+ */
+TEST_P(HostapdHidlTest, AddSaeTransitionAccessPointWithoutAcs) {
+ if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
+ auto status =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(),
+ getSaeTransitionNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with SAE network config & ACS disabled.
+ * Access point creation should pass.
+ */
+TEST_P(HostapdHidlTest, AddSAEAccessPointWithoutAcs) {
+ if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
+ auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithoutAcs(), getSaeNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds & then removes an access point with PSK network config & ACS enabled.
+ * Access point creation & removal should pass.
+ */
+TEST_P(HostapdHidlTest, RemoveAccessPointWithAcs) {
+ if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
+ auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithAcs(), getPskNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code);
+ auto status =
+ HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName());
+ EXPECT_EQ(
+ android::hardware::wifi::hostapd::V1_0::HostapdStatusCode::SUCCESS,
+ status.code);
+}
+
+/**
+ * Adds & then removes an access point with PSK network config & ACS disabled.
+ * Access point creation & removal should pass.
+ */
+TEST_P(HostapdHidlTest, RemoveAccessPointWithoutAcs) {
+ auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithoutAcs(), getPskNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code);
+ auto status =
+ HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName());
+ EXPECT_EQ(
+ android::hardware::wifi::hostapd::V1_0::HostapdStatusCode::SUCCESS,
+ status.code);
+}
+
+/**
+ * Adds an access point with invalid channel.
+ * Access point creation should fail.
+ */
+TEST_P(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) {
+ auto status =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithInvalidChannel(), getPskNwParams());
+ EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with invalid PSK network config.
+ * Access point creation should fail.
+ */
+TEST_P(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) {
+ auto status =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(),
+ getInvalidPskNwParams());
+ EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with invalid SAE transition network config.
+ * Access point creation should fail.
+ */
+TEST_P(HostapdHidlTest, AddInvalidSaeTransitionAccessPointWithoutAcs) {
+ if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
+ auto status =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(),
+ getInvalidSaeTransitionNwParams());
+ EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with invalid SAE network config.
+ * Access point creation should fail.
+ */
+TEST_P(HostapdHidlTest, AddInvalidSaeAccessPointWithoutAcs) {
+ if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
+ auto status =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(),
+ getInvalidSaeNwParams());
+ EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * forceClientDisconnect should return FAILURE_CLIENT_UNKNOWN
+ * when hotspot interface available.
+ */
+TEST_P(HostapdHidlTest, DisconnectClientWhenIfacAvailable) {
+ auto status_1_2 =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(),
+ getOpenNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code);
+
+ status_1_2 =
+ HIDL_INVOKE(hostapd_, forceClientDisconnect, getPrimaryWlanIfaceName(),
+ kTestZeroMacAddr, kTestDisconnectReasonCode);
+ EXPECT_EQ(HostapdStatusCode::FAILURE_CLIENT_UNKNOWN, status_1_2.code);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HostapdHidlTest);
+INSTANTIATE_TEST_CASE_P(
+ PerInstance, HostapdHidlTest,
+ testing::Combine(
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ android::hardware::wifi::hostapd::V1_2::IHostapd::descriptor))),
+ android::hardware::PrintInstanceTupleNameToString<>);
diff --git a/wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantP2pV1_0TargetTest.cpp b/wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantP2pV1_0TargetTest.cpp
index 01840e2..b2bdaf1 100644
--- a/wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantP2pV1_0TargetTest.cpp
+++ b/wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantP2pV1_0TargetTest.cpp
@@ -18,9 +18,6 @@
#include "supplicant_hidl_test_utils.h"
int main(int argc, char** argv) {
- if (!::testing::deviceSupportsFeature("android.hardware.wifi.direct"))
- return 0;
-
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp
index e74fd59..325f355 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp
@@ -282,8 +282,17 @@
mac_addr_, ISupplicantP2pIface::WpsProvisionMethod::PBC,
kTestConnectPin, false, false, kTestConnectGoIntent,
[](const SupplicantStatus& status, const hidl_string& /* pin */) {
- // After enabling auto-join, it will succeed always.
- EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ /*
+ * Before R, auto-join is not enabled and it is not going to work
+ * with fake values. After enabling auto-join, it will succeed
+ * always.
+ */
+ LOG(INFO) << "ISupplicantP2pIface::connect() ret: "
+ << toString(status);
+ if (SupplicantStatusCode::FAILURE_UNKNOWN != status.code &&
+ SupplicantStatusCode::SUCCESS != status.code) {
+ FAIL();
+ }
});
}
@@ -295,12 +304,26 @@
mac_addr_, ISupplicantP2pIface::WpsProvisionMethod::PBC,
kTestConnectPin, false, false, kTestConnectGoIntent,
[](const SupplicantStatus& status, const hidl_string& /* pin */) {
- // After enabling auto-join, it will succeed always.
- EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ /*
+ * Before R, auto-join is not enabled and it is not going to work
+ * with fake values. After enabling auto-join, it will succeed
+ * always.
+ */
+ LOG(INFO) << "ISupplicantP2pIface::connect() ret: "
+ << toString(status);
+ if (SupplicantStatusCode::FAILURE_UNKNOWN != status.code &&
+ SupplicantStatusCode::SUCCESS != status.code) {
+ FAIL();
+ }
});
p2p_iface_->cancelConnect([](const SupplicantStatus& status) {
- EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ LOG(INFO) << "ISupplicantP2pIface::cancelConnect() ret: "
+ << toString(status);
+ if (SupplicantStatusCode::FAILURE_UNKNOWN != status.code &&
+ SupplicantStatusCode::SUCCESS != status.code) {
+ FAIL();
+ }
});
}
diff --git a/wifi/supplicant/1.4/Android.bp b/wifi/supplicant/1.4/Android.bp
index df0b23a..0a039de 100644
--- a/wifi/supplicant/1.4/Android.bp
+++ b/wifi/supplicant/1.4/Android.bp
@@ -6,8 +6,10 @@
srcs: [
"types.hal",
"ISupplicant.hal",
+ "ISupplicantP2pIface.hal",
"ISupplicantStaIface.hal",
"ISupplicantStaNetwork.hal",
+ "ISupplicantStaNetworkCallback.hal",
],
interfaces: [
"android.hardware.wifi.supplicant@1.0",
diff --git a/wifi/supplicant/1.4/ISupplicantP2pIface.hal b/wifi/supplicant/1.4/ISupplicantP2pIface.hal
new file mode 100644
index 0000000..7c41d1c
--- /dev/null
+++ b/wifi/supplicant/1.4/ISupplicantP2pIface.hal
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant@1.4;
+
+import @1.2::ISupplicantP2pIface;
+import @1.0::SupplicantStatus;
+
+/**
+ * Interface exposed by the supplicant for each P2P mode network
+ * interface (e.g p2p0) it controls.
+ * To use 1.4 features you must cast specific interfaces returned from the
+ * 1.4 HAL. For example V1_4::ISupplicant::addIface() adds V1_4::ISupplicantIface,
+ * which can be cast to V1_4::ISupplicantP2pIface.
+ */
+interface ISupplicantP2pIface extends @1.2::ISupplicantP2pIface {
+ /**
+ * Set whether to enable EDMG(802.11ay). Only allowed if hw mode is |HOSTAPD_MODE_IEEE80211AD|
+ *
+ * @param enable true to set, false otherwise.
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+ */
+ setEdmg(bool enable) generates (SupplicantStatus status);
+
+ /**
+ * Get whether EDMG(802.11ay) is enabled for this network.
+ *
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+ * @return enabled true if set, false otherwise.
+ */
+ getEdmg() generates (SupplicantStatus status, bool enabled);
+};
diff --git a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal
index 7b043d0..0cc62c0 100644
--- a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal
+++ b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal
@@ -17,6 +17,7 @@
package android.hardware.wifi.supplicant@1.4;
import @1.3::ISupplicantStaNetwork;
+import @1.4::ISupplicantStaNetworkCallback;
import @1.0::SupplicantStatus;
/**
@@ -123,4 +124,41 @@
* @return enabled true if set, false otherwise.
*/
getEdmg() generates (SupplicantStatus status, bool enabled);
+
+ /**
+ * Register for callbacks from this network.
+ *
+ * These callbacks are invoked for events that are specific to this network.
+ * Registration of multiple callback objects is supported. These objects must
+ * be automatically deleted when the corresponding client process is dead or
+ * if this network is removed.
+ *
+ * @param callback An instance of the |ISupplicantStaNetworkCallback| HIDL
+ * interface object.
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+ */
+ registerCallback_1_4(ISupplicantStaNetworkCallback callback)
+ generates (SupplicantStatus status);
+
+ /**
+ * Set whether to enable SAE H2E (Hash-to-Element) only mode.
+ *
+ * When enabled, only SAE H2E network is allowed; othewise
+ * H&P (Hunting and Pecking) and H2E are both allowed.
+ * H&P only mode is not supported.
+ * If this API is not called before connecting to a SAE
+ * network, the behavior is undefined.
+ *
+ * @param enable true to set, false otherwise.
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+ */
+ enableSaeH2eOnlyMode(bool enable) generates (SupplicantStatus status);
};
diff --git a/wifi/supplicant/1.4/ISupplicantStaNetworkCallback.hal b/wifi/supplicant/1.4/ISupplicantStaNetworkCallback.hal
new file mode 100644
index 0000000..38cdcf9
--- /dev/null
+++ b/wifi/supplicant/1.4/ISupplicantStaNetworkCallback.hal
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant@1.4;
+
+import @1.0::ISupplicantStaNetworkCallback;
+
+/**
+ * Callback Interface exposed by the supplicant service
+ * for each network (ISupplicantStaNetwork).
+ *
+ * Clients need to host an instance of this HIDL interface object and
+ * pass a reference of the object to the supplicant via the
+ * corresponding |ISupplicantStaNetwork.registerCallback_1_4| method.
+ */
+interface ISupplicantStaNetworkCallback extends @1.0::ISupplicantStaNetworkCallback {
+ /**
+ * WPA3™ Specification Addendum for WPA3 R3 - Table 3.
+ * Transition Disable Indication filled in the third
+ * 4-way handshake message.
+ */
+ enum TransitionDisableIndication : uint32_t {
+ USE_WPA3_PERSONAL = 1 << 0,
+ USE_SAE_PK = 1 << 1,
+ USE_WPA3_ENTERPRISE = 1 << 2,
+ USE_ENHANCED_OPEN = 1 << 3,
+ };
+
+ /**
+ * Used to notify WPA3 transition disable.
+ */
+ oneway onTransitionDisable(bitfield<TransitionDisableIndication> ind);
+};
diff --git a/wifi/supplicant/1.4/vts/functional/Android.bp b/wifi/supplicant/1.4/vts/functional/Android.bp
index 7f2ba70..d6af0a0 100644
--- a/wifi/supplicant/1.4/vts/functional/Android.bp
+++ b/wifi/supplicant/1.4/vts/functional/Android.bp
@@ -44,6 +44,38 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: [
"supplicant_sta_iface_hidl_test.cpp",
+ "supplicant_sta_network_hidl_test.cpp",
+ ],
+ static_libs: [
+ "VtsHalWifiV1_0TargetTestUtil",
+ "VtsHalWifiSupplicantV1_0TargetTestUtil",
+ "VtsHalWifiSupplicantV1_1TargetTestUtil",
+ "VtsHalWifiSupplicantV1_2TargetTestUtil",
+ "VtsHalWifiSupplicantV1_3TargetTestUtil",
+ "VtsHalWifiSupplicantV1_4TargetTestUtil",
+ "android.hardware.wifi.supplicant@1.0",
+ "android.hardware.wifi.supplicant@1.1",
+ "android.hardware.wifi.supplicant@1.2",
+ "android.hardware.wifi.supplicant@1.3",
+ "android.hardware.wifi.supplicant@1.4",
+ "android.hardware.wifi@1.0",
+ "android.hardware.wifi@1.1",
+ "libgmock",
+ "libwifi-system",
+ "libwifi-system-iface",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+ disable_framework: true,
+}
+
+cc_test {
+ name: "VtsHalWifiSupplicantP2pV1_4TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: [
+ "supplicant_p2p_iface_hidl_test.cpp",
],
static_libs: [
"VtsHalWifiV1_0TargetTestUtil",
diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.cpp
index 3a59bd6..7e7a465 100644
--- a/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.cpp
+++ b/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.cpp
@@ -21,6 +21,7 @@
using ::android::sp;
using ::android::hardware::wifi::supplicant::V1_4::ISupplicant;
+using ::android::hardware::wifi::supplicant::V1_4::ISupplicantP2pIface;
using ::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIface;
sp<ISupplicantStaIface> getSupplicantStaIface_1_4(
@@ -29,6 +30,12 @@
return ISupplicantStaIface::castFrom(getSupplicantStaIface(supplicant));
}
+sp<ISupplicantP2pIface> getSupplicantP2pIface_1_4(
+ const android::sp<android::hardware::wifi::supplicant::V1_4::ISupplicant>&
+ supplicant) {
+ return ISupplicantP2pIface::castFrom(getSupplicantP2pIface(supplicant));
+}
+
sp<ISupplicant> getSupplicant_1_4(const std::string& supplicant_instance_name,
bool isP2pOn) {
return ISupplicant::castFrom(
diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.h b/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.h
index 60fe1dc..b3b6990 100644
--- a/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.h
+++ b/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.h
@@ -18,12 +18,17 @@
#define SUPPLICANT_HIDL_TEST_UTILS_1_4_H
#include <android/hardware/wifi/supplicant/1.4/ISupplicant.h>
+#include <android/hardware/wifi/supplicant/1.4/ISupplicantP2pIface.h>
#include <android/hardware/wifi/supplicant/1.4/ISupplicantStaIface.h>
android::sp<android::hardware::wifi::supplicant::V1_4::ISupplicantStaIface>
getSupplicantStaIface_1_4(
const android::sp<android::hardware::wifi::supplicant::V1_4::ISupplicant>&
supplicant);
+android::sp<android::hardware::wifi::supplicant::V1_4::ISupplicantP2pIface>
+getSupplicantP2pIface_1_4(
+ const android::sp<android::hardware::wifi::supplicant::V1_4::ISupplicant>&
+ supplicant);
android::sp<android::hardware::wifi::supplicant::V1_4::ISupplicant>
getSupplicant_1_4(const std::string& supplicant_instance_name, bool isP2pOn);
diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_p2p_iface_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_p2p_iface_hidl_test.cpp
new file mode 100644
index 0000000..17e1b9f
--- /dev/null
+++ b/wifi/supplicant/1.4/vts/functional/supplicant_p2p_iface_hidl_test.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <VtsCoreUtil.h>
+#include <android/hardware/wifi/1.1/IWifi.h>
+#include <android/hardware/wifi/supplicant/1.4/ISupplicant.h>
+#include <android/hardware/wifi/supplicant/1.4/ISupplicantP2pIface.h>
+#include <android/hardware/wifi/supplicant/1.4/types.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/ServiceManagement.h>
+
+#include "supplicant_hidl_test_utils.h"
+#include "supplicant_hidl_test_utils_1_4.h"
+
+using ::android::sp;
+using ::android::hardware::Void;
+using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
+using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
+using ::android::hardware::wifi::supplicant::V1_4::ISupplicantP2pIface;
+
+class SupplicantP2pIfaceHidlTest : public SupplicantHidlTestBaseV1_4 {
+ public:
+ virtual void SetUp() override {
+ SupplicantHidlTestBaseV1_4::SetUp();
+ p2p_iface_ = getSupplicantP2pIface_1_4(supplicant_);
+ ASSERT_NE(p2p_iface_.get(), nullptr);
+ }
+
+ protected:
+ // ISupplicantP2pIface object used for all tests in this fixture.
+ sp<ISupplicantP2pIface> p2p_iface_;
+};
+
+/*
+ * SetGetEdmg
+ */
+TEST_P(SupplicantP2pIfaceHidlTest, SetGetEdmg) {
+ p2p_iface_->setEdmg(true, [&](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ p2p_iface_->getEdmg([&](const SupplicantStatus& status, bool enable) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(true, enable);
+ });
+ p2p_iface_->setEdmg(false, [&](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ p2p_iface_->getEdmg([&](const SupplicantStatus& status, bool enable) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(false, enable);
+ });
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantP2pIfaceHidlTest);
+INSTANTIATE_TEST_CASE_P(
+ PerInstance, SupplicantP2pIfaceHidlTest,
+ testing::Combine(
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ android::hardware::wifi::V1_0::IWifi::descriptor)),
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ android::hardware::wifi::supplicant::V1_4::ISupplicant::
+ descriptor))),
+ android::hardware::PrintInstanceTupleNameToString<>);
diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp
new file mode 100644
index 0000000..aaaccfc
--- /dev/null
+++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#include <VtsCoreUtil.h>
+#include <android/hardware/wifi/1.0/IWifi.h>
+#include <android/hardware/wifi/supplicant/1.0/ISupplicantStaNetwork.h>
+#include <android/hardware/wifi/supplicant/1.4/ISupplicantStaNetwork.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+#include "supplicant_hidl_test_utils.h"
+#include "supplicant_hidl_test_utils_1_4.h"
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::wifi::supplicant::V1_0::IfaceType;
+using ::android::hardware::wifi::supplicant::V1_0::ISupplicant;
+using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaIface;
+using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork;
+using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
+using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
+using ::android::hardware::wifi::supplicant::V1_4::
+ ISupplicantStaNetworkCallback;
+using ::android::hardware::wifi::V1_0::IWifi;
+
+class SupplicantStaNetworkHidlTest : public SupplicantHidlTestBaseV1_4 {
+ public:
+ virtual void SetUp() override {
+ SupplicantHidlTestBaseV1_4::SetUp();
+ sta_network_ = createSupplicantStaNetwork(supplicant_);
+ ASSERT_NE(sta_network_.get(), nullptr);
+ /* variable used to check if the underlying HAL version is 1.4 or
+ * higher. This is to skip tests which are using deprecated methods.
+ */
+ v1_4 = ::android::hardware::wifi::supplicant::V1_4::
+ ISupplicantStaNetwork::castFrom(sta_network_);
+ }
+
+ protected:
+ sp<::android::hardware::wifi::supplicant::V1_4::ISupplicantStaNetwork>
+ v1_4 = nullptr;
+ // ISupplicantStaNetwork object used for all tests in this fixture.
+ sp<ISupplicantStaNetwork> sta_network_;
+};
+
+class NetworkCallback : public ISupplicantStaNetworkCallback {
+ Return<void> onNetworkEapSimGsmAuthRequest(
+ const ISupplicantStaNetworkCallback::NetworkRequestEapSimGsmAuthParams&
+ /* params */) override {
+ return Void();
+ }
+ Return<void> onNetworkEapSimUmtsAuthRequest(
+ const ISupplicantStaNetworkCallback::NetworkRequestEapSimUmtsAuthParams&
+ /* params */) override {
+ return Void();
+ }
+ Return<void> onNetworkEapIdentityRequest() override { return Void(); }
+ Return<void> onTransitionDisable(uint32_t /* params */) override {
+ return Void();
+ }
+};
+
+/*
+ * RegisterCallback
+ */
+TEST_P(SupplicantStaNetworkHidlTest, RegisterCallback_1_4) {
+ v1_4->registerCallback_1_4(
+ new NetworkCallback(), [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+/*
+ * enable SAE H2E (Hash-to-Element) only mode
+ */
+TEST_P(SupplicantStaNetworkHidlTest, EnableSaeH2eOnlyMode) {
+ v1_4->enableSaeH2eOnlyMode(true, [&](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ v1_4->enableSaeH2eOnlyMode(false, [&](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaNetworkHidlTest);
+INSTANTIATE_TEST_CASE_P(
+ PerInstance, SupplicantStaNetworkHidlTest,
+ testing::Combine(
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ISupplicant::descriptor))),
+ android::hardware::PrintInstanceTupleNameToString<>);