Merge "Add portMode configuration test" into oc-mr1-dev
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 5b31d1e..dd4cee0 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -61,3 +61,5 @@
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/android.hardware.automotive*)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/init/android.hardware.automotive*)
$(call add-clean-step, find $(PRODUCT_OUT)/system $(PRODUCT_OUT)/vendor -type f -name "android\.hardware\.configstore\@1\.1*" -print0 | xargs -0 rm -f)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/android.hardware.tests*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/vndk/android.hardware.tests*)
diff --git a/audio/2.0/config/audio_policy_configuration.xsd b/audio/2.0/config/audio_policy_configuration.xsd
index c94da80..eb59152 100644
--- a/audio/2.0/config/audio_policy_configuration.xsd
+++ b/audio/2.0/config/audio_policy_configuration.xsd
@@ -365,10 +365,10 @@
</xs:restriction>
</xs:simpleType>
<xs:complexType name="profile">
- <xs:attribute name="name" type="xs:token" use="required"/>
- <xs:attribute name="format" type="audioFormat" use="required"/>
- <xs:attribute name="samplingRates" type="samplingRates" use="required"/>
- <xs:attribute name="channelMasks" type="channelMask" use="required"/>
+ <xs:attribute name="name" type="xs:token" use="optional"/>
+ <xs:attribute name="format" type="audioFormat" use="optional"/>
+ <xs:attribute name="samplingRates" type="samplingRates" use="optional"/>
+ <xs:attribute name="channelMasks" type="channelMask" use="optional"/>
</xs:complexType>
<xs:simpleType name="gainMode">
<xs:restriction base="xs:string">
diff --git a/audio/2.0/vts/functional/ValidateAudioConfiguration.cpp b/audio/2.0/vts/functional/ValidateAudioConfiguration.cpp
index 5fc1b3d..ee49023 100644
--- a/audio/2.0/vts/functional/ValidateAudioConfiguration.cpp
+++ b/audio/2.0/vts/functional/ValidateAudioConfiguration.cpp
@@ -24,13 +24,9 @@
const char* possibleConfigLocations[] = {"/odm/etc", "/vendor/etc", "/system/etc"};
const char* configSchemaPath = "/data/local/tmp/audio_policy_configuration.xsd";
- bool found = false;
for (std::string folder : possibleConfigLocations) {
const auto configPath = folder + '/' + configName;
if (access(configPath.c_str(), R_OK) == 0) {
- ASSERT_FALSE(found) << "Multiple " << configName << " found in "
- << ::testing::PrintToString(possibleConfigLocations);
- found = true;
ASSERT_VALID_XML(configPath.c_str(), configSchemaPath);
}
}
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
index 385f03d..6bc0522 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
@@ -162,12 +162,29 @@
return StatusCode::OK;
}
+static bool isDiagnosticProperty(VehiclePropConfig propConfig) {
+ switch (propConfig.prop) {
+ case OBD2_LIVE_FRAME:
+ case OBD2_FREEZE_FRAME:
+ case OBD2_FREEZE_FRAME_CLEAR:
+ case OBD2_FREEZE_FRAME_INFO:
+ return true;
+ }
+ return false;
+}
+
// Parse supported properties list and generate vector of property values to hold current values.
void EmulatedVehicleHal::onCreate() {
for (auto& it : kVehicleProperties) {
VehiclePropConfig cfg = it.config;
int32_t supportedAreas = cfg.supportedAreas;
+ if (isDiagnosticProperty(cfg)) {
+ // do not write an initial empty value for the diagnostic properties
+ // as we will initialize those separately.
+ continue;
+ }
+
// A global property will have supportedAreas = 0
if (isGlobalProp(cfg.prop)) {
supportedAreas = 0;
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index 12b92dd..7c08b4a 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -785,7 +785,8 @@
* requested by Android side. The focus has both per stream characteristics
* and global characteristics.
*
- * Focus request (get of this property) must take the following form:
+ * Focus request (get of this property) must take the following form with indices defined
+ * by VehicleAudioFocusIndex:
* int32Values[0]: VehicleAudioFocusRequest type
* int32Values[1]: bit flags of streams requested by this focus request.
* There can be up to 32 streams.
@@ -803,7 +804,7 @@
* REQUEST_RELEASE). In that case, audio module must
* maintain mute state until user's explicit action to
* play some media.
- * int32Values[3]: Currently active audio contexts. Use combination of
+ * int32Values[3]: Audio contexts wishing to be active. Use combination of
* flags from VehicleAudioContextFlag.
* This can be used as a hint to adjust audio policy or
* other policy decision.
@@ -818,7 +819,7 @@
* request.
*
* Focus response (set and subscription callback for this property) must
- * take the following form:
+ * take the following form with indices defined by VehicleAudioFocusIndex:
* int32Values[0]: VehicleAudioFocusState type
* int32Values[1]: bit flags of streams allowed.
* int32Values[2]: External focus state: bit flags of currently active
@@ -847,9 +848,10 @@
* side is playing something permanent.
* LOSS_TRANSIENT: must always be
* VehicleAudioExtFocusFlag#PERMANENT_FLAG
- * int32Values[3]: context requested by android side when responding to
- * focus request. When car side is taking focus away,
- * this must be zero.
+ * int32Values[3]: Audio context(s) allowed to be active. When responding positively to a
+ * focus request from Android, the request's original context must be
+ * repeated here. When taking focus away, or denying a request, the
+ * rejected or stopped context would have its corresponding bit cleared.
*
* A focus response must be sent per each focus request even if there is
* no change in focus state. This can happen in case like focus request
@@ -890,8 +892,8 @@
*
* VehiclePropConfig
* configArray[0] : bit flags of all supported audio contexts from
- * VehicleAudioContextFlag. If this is 0, audio volume is
- * controlled per physical stream.
+ * VehicleAudioContextFlag. If this is 0, audio volume
+ * is controlled per physical stream.
* configArray[1] : flags defined in VehicleAudioVolumeCapabilityFlag to
* represent audio module's capability.
* configArray[2..3] : reserved
@@ -901,7 +903,7 @@
* indicates mute state.
*
* Data type looks like:
- * int32Values[0] : stream context as defined in VehicleAudioContextFlag.
+ * int32Values[0] : audio context as defined in VehicleAudioContextFlag.
* If only physical stream is supported
* (configArray[0] == 0), this must represent physical
* stream number.
@@ -909,8 +911,8 @@
* defined in the config.
* int32Values[2] : One of VehicleAudioVolumeState.
*
- * This property requires per stream based get. HAL implementation must
- * check stream number in get call to return the right volume.
+ * HAL implementations must check the incoming value of audio context
+ * field in get call to return the right volume.
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
* @access VehiclePropertyAccess:READ_WRITE
@@ -949,18 +951,18 @@
* to represent audio module's capability.
*
* Data type looks like:
- * int32Values[0] : stream context as defined in VehicleAudioContextFlag.
+ * int32Values[0] : audio context as defined in VehicleAudioContextFlag.
* If only physical stream is supported
* (configArray[0] == 0), this must represent physical
* stream number.
* int32Values[1] : maximum volume set to the stream. If there is no
- * restriction, this value must be bigger than
+ * restriction, this value must be equal to
* AUDIO_VOLUME's max value.
*
* If car does not support this feature, this property must not be
* populated by HAL.
- * This property requires per stream based get. HAL implementation must
- * check stream number in get call to return the right volume.
+ * HAL implementations must check the incoming value of audio context
+ * field in get call to return the right volume.
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
* @access VehiclePropertyAccess:READ_WRITE
@@ -974,10 +976,8 @@
/**
* Property to share audio routing policy of android side. This property is
- * set at the beginning to pass audio policy in android side down to
+ * set at startup to pass audio policy in android side down to
* vehicle HAL and car audio module.
- * This can be used as a hint to adjust audio policy or other policy
- * decision.
*
* int32Values[0] : audio stream where the audio for the application
* context must be routed by default. Note that this is
@@ -1001,11 +1001,11 @@
| VehicleArea:GLOBAL),
/**
- * Property to return audio H/W variant type used in this car. This allows
- * android side to support different audio policy based on H/W variant used.
- * Note that other components like CarService may need overlay update to
- * support additional variants. If this property does not
- * exist, default audio policy must be used.
+ * Property to return audio H/W variant type used in this car. This is a
+ * zero based index into the set of audio routing policies defined in
+ * R.array.audioRoutingPolicy on CarService, which may be overlaid to
+ * support multiple variants. If this property does not exist, the default
+ * audio policy must be used.
*
* @change_mode VehiclePropertyChangeMode:STATIC
* @access VehiclePropertyAccess:READ
@@ -2224,6 +2224,9 @@
/** Ext source is played. This is for tagging generic ext sources. */
EXT_SOURCE_FLAG = 0x1000,
+
+ /** The phone ring tone is played */
+ RINGTONE_FLAG = 0x2000
};
/**
@@ -2232,23 +2235,23 @@
*/
enum VehicleAudioVolumeCapabilityFlag : int32_t {
/**
- * External audio module or vehicle hal has persistent storage
- * to keep the volume level. This must be set only when per context
- * volume level is supported. When this is set, audio volume level per
- * each context will be retrieved from the property when system starts up.
+ * External audio module or vehicle hal has persistent storage to keep the
+ * volume level. When this is set, the audio volume level for each context
+ * will be retrieved from the property when the system starts up.
* And external audio module is also expected to adjust volume automatically
* whenever there is an audio context change.
* When this flag is not set, android side will assume that there is no
- * persistent storage and stored value in android side will be used to
- * initialize the volume level. And android side will set volume level
- * of each physical streams whenever there is an audio context change.
+ * persistent storage and the value stored in the android side will be used to
+ * initialize the volume level, and android side will set volume level
+ * of each physical stream whenever there is an audio context change.
*/
PERSISTENT_STORAGE = 0x1,
/**
+ * [DEPRECATED]
* When this flag is set, the H/W can support only single master volume for
- * all streams.
- * There is no way to set volume level differently per each stream or context.
+ * all streams. There is no way to set volume level differently for each stream
+ * or context.
*/
MASTER_VOLUME_ONLY = 0x2,
};
@@ -2264,16 +2267,16 @@
* VehicleProperty#AUDIO_VOLUME_LIMIT and user's request to increase volume
* further is not allowed.
*/
- LIMIT_REACHED = 1,
+ STATE_LIMIT_REACHED = 1,
};
/**
* Index in int32Values for VehicleProperty#AUDIO_VOLUME property.
*/
enum VehicleAudioVolumeIndex : int32_t {
- INDEX_STREAM = 0,
- INDEX_VOLUME = 1,
- INDEX_STATE = 2,
+ STREAM = 0,
+ VOLUME = 1,
+ STATE = 2,
};
/**
diff --git a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
index fb53366..6c9aa18 100644
--- a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
+++ b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
@@ -464,8 +464,9 @@
// Return the number of completed packets reported by the controller.
int BluetoothHidlTest::wait_for_completed_packets_event(uint16_t handle) {
- EXPECT_TRUE(bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived)
- .no_timeout);
+ if (!bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived).no_timeout) {
+ ALOGW("%s: WaitForCallback timed out.", __func__);
+ }
int packets_processed = 0;
while (event_queue.size() > 0) {
hidl_vec<uint8_t> event = event_queue.front();
@@ -604,20 +605,24 @@
// This should work, but breaks on some current platforms. Figure out how to
// grandfather older devices but test new ones.
- int sco_packets_sent = 0;
if (0 && sco_connection_handles.size() > 0) {
sendAndCheckSCO(1, max_sco_data_packet_length, sco_connection_handles[0]);
- sco_packets_sent = 1;
- EXPECT_EQ(sco_packets_sent,
- wait_for_completed_packets_event(sco_connection_handles[0]));
+ int sco_packets_sent = 1;
+ int completed_packets = wait_for_completed_packets_event(sco_connection_handles[0]);
+ if (sco_packets_sent != completed_packets) {
+ ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__, sco_packets_sent,
+ completed_packets);
+ }
}
- int acl_packets_sent = 0;
if (acl_connection_handles.size() > 0) {
sendAndCheckACL(1, max_acl_data_packet_length, acl_connection_handles[0]);
- acl_packets_sent = 1;
- EXPECT_EQ(acl_packets_sent,
- wait_for_completed_packets_event(acl_connection_handles[0]));
+ int acl_packets_sent = 1;
+ int completed_packets = wait_for_completed_packets_event(acl_connection_handles[0]);
+ if (acl_packets_sent != completed_packets) {
+ ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__, acl_packets_sent,
+ completed_packets);
+ }
}
}
@@ -633,22 +638,26 @@
// This should work, but breaks on some current platforms. Figure out how to
// grandfather older devices but test new ones.
- int sco_packets_sent = 0;
if (0 && sco_connection_handles.size() > 0) {
sendAndCheckSCO(NUM_SCO_PACKETS_BANDWIDTH, max_sco_data_packet_length,
sco_connection_handles[0]);
- sco_packets_sent = NUM_SCO_PACKETS_BANDWIDTH;
- EXPECT_EQ(sco_packets_sent,
- wait_for_completed_packets_event(sco_connection_handles[0]));
+ int sco_packets_sent = NUM_SCO_PACKETS_BANDWIDTH;
+ int completed_packets = wait_for_completed_packets_event(sco_connection_handles[0]);
+ if (sco_packets_sent != completed_packets) {
+ ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__, sco_packets_sent,
+ completed_packets);
+ }
}
- int acl_packets_sent = 0;
if (acl_connection_handles.size() > 0) {
sendAndCheckACL(NUM_ACL_PACKETS_BANDWIDTH, max_acl_data_packet_length,
acl_connection_handles[0]);
- acl_packets_sent = NUM_ACL_PACKETS_BANDWIDTH;
- EXPECT_EQ(acl_packets_sent,
- wait_for_completed_packets_event(acl_connection_handles[0]));
+ int acl_packets_sent = NUM_ACL_PACKETS_BANDWIDTH;
+ int completed_packets = wait_for_completed_packets_event(acl_connection_handles[0]);
+ if (acl_packets_sent != completed_packets) {
+ ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__, acl_packets_sent,
+ completed_packets);
+ }
}
}
diff --git a/compatibility_matrix.26.xml b/compatibility_matrix.26.xml
index c9b68a8..5c81f26 100644
--- a/compatibility_matrix.26.xml
+++ b/compatibility_matrix.26.xml
@@ -57,7 +57,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.broadcastradio</name>
- <version>1.0</version>
+ <version>1.0-1</version>
<interface>
<name>IBroadcastRadioFactory</name>
<instance>default</instance>
@@ -71,6 +71,14 @@
<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="false">
<name>android.hardware.configstore</name>
<version>1.0</version>
@@ -204,16 +212,24 @@
</interface>
</hal>
<hal format="hidl" optional="true">
- <name>android.hardware.power</name>
+ <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</version>
+ <version>1.0-1</version>
<interface>
<name>IRadio</name>
<instance>slot1</instance>
@@ -256,9 +272,25 @@
</interface>
</hal>
<hal format="hidl" optional="true">
- <name>android.hardware.thermal</name>
+ <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>
@@ -281,7 +313,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.usb</name>
- <version>1.0</version>
+ <version>1.0-1</version>
<interface>
<name>IUsb</name>
<instance>default</instance>
@@ -289,7 +321,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.vibrator</name>
- <version>1.0</version>
+ <version>1.0-1</version>
<interface>
<name>IVibrator</name>
<instance>default</instance>
@@ -304,14 +336,30 @@
</interface>
</hal>
<hal format="hidl" optional="true">
- <name>android.hardware.wifi</name>
+ <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>
diff --git a/compatibility_matrix.27.xml b/compatibility_matrix.27.xml
new file mode 100644
index 0000000..5c81f26
--- /dev/null
+++ b/compatibility_matrix.27.xml
@@ -0,0 +1,370 @@
+<compatibility-matrix version="1.0" type="framework">
+ <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="false">
+ <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>
+ </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_matrix.current.xml b/compatibility_matrix.current.xml
index 8d50325..5c81f26 100644
--- a/compatibility_matrix.current.xml
+++ b/compatibility_matrix.current.xml
@@ -57,7 +57,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.broadcastradio</name>
- <version>1.0</version>
+ <version>1.0-1</version>
<interface>
<name>IBroadcastRadioFactory</name>
<instance>default</instance>
@@ -71,6 +71,14 @@
<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="false">
<name>android.hardware.configstore</name>
<version>1.0</version>
@@ -206,10 +214,14 @@
<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</version>
+ <version>1.0-1</version>
<interface>
<name>IPower</name>
<instance>default</instance>
@@ -217,7 +229,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.radio</name>
- <version>1.0</version>
+ <version>1.0-1</version>
<interface>
<name>IRadio</name>
<instance>slot1</instance>
@@ -260,9 +272,25 @@
</interface>
</hal>
<hal format="hidl" optional="true">
- <name>android.hardware.thermal</name>
+ <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>
@@ -285,7 +313,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.usb</name>
- <version>1.0</version>
+ <version>1.0-1</version>
<interface>
<name>IUsb</name>
<instance>default</instance>
@@ -293,7 +321,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.vibrator</name>
- <version>1.0</version>
+ <version>1.0-1</version>
<interface>
<name>IVibrator</name>
<instance>default</instance>
@@ -310,16 +338,28 @@
<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</version>
+ <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>
diff --git a/compatibility_matrix.legacy.xml b/compatibility_matrix.legacy.xml
index ad6d4b9..5655fb9 100644
--- a/compatibility_matrix.legacy.xml
+++ b/compatibility_matrix.legacy.xml
@@ -57,7 +57,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.broadcastradio</name>
- <version>1.0</version>
+ <version>1.0-1</version>
<interface>
<name>IBroadcastRadioFactory</name>
<instance>default</instance>
@@ -71,6 +71,14 @@
<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="false">
<name>android.hardware.configstore</name>
<version>1.0</version>
@@ -204,16 +212,24 @@
</interface>
</hal>
<hal format="hidl" optional="true">
- <name>android.hardware.power</name>
+ <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</version>
+ <version>1.0-1</version>
<interface>
<name>IRadio</name>
<instance>slot1</instance>
@@ -256,9 +272,25 @@
</interface>
</hal>
<hal format="hidl" optional="true">
- <name>android.hardware.thermal</name>
+ <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>
@@ -281,7 +313,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.usb</name>
- <version>1.0</version>
+ <version>1.0-1</version>
<interface>
<name>IUsb</name>
<instance>default</instance>
@@ -289,7 +321,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.vibrator</name>
- <version>1.0</version>
+ <version>1.0-1</version>
<interface>
<name>IVibrator</name>
<instance>default</instance>
@@ -304,14 +336,30 @@
</interface>
</hal>
<hal format="hidl" optional="true">
- <name>android.hardware.wifi</name>
+ <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>
diff --git a/current.txt b/current.txt
index c0dd0fa..f045fd8 100644
--- a/current.txt
+++ b/current.txt
@@ -189,7 +189,7 @@
# ABI preserving changes to HALs during Android O MR1 (Initial Set)
-05e0edf31db5b3ae19047d87059545cc2f836023edf8f9d969319e15e3485158 android.hardware.automotive.vehicle@2.0::types
+26a4dd19a71f3a28249100af29be470f80e08355165fe6a7173aaa1ef264640d android.hardware.automotive.vehicle@2.0::types
150a338ce11fcec70757c9675d83cf6a5d7b40d0c812741b91671fecce59eac9 android.hardware.broadcastradio@1.0::types
dc7e6d4f537b9943e27edc4f86c5a03bb643b18f18f866f8c3c71c0ac4ea8cbc android.hardware.broadcastradio@1.0::types
760485232f6cce07f8bb05e3475509956996b702f77415ee5bff05e2ec5a5bcc android.hardware.dumpstate@1.0::IDumpstateDevice
diff --git a/graphics/composer/2.1/default/IComposerCommandBuffer.h b/graphics/composer/2.1/default/IComposerCommandBuffer.h
index 9ee5f4f..058709c 100644
--- a/graphics/composer/2.1/default/IComposerCommandBuffer.h
+++ b/graphics/composer/2.1/default/IComposerCommandBuffer.h
@@ -92,6 +92,23 @@
bool writeQueue(bool* outQueueChanged, uint32_t* outCommandLength,
hidl_vec<hidl_handle>* outCommandHandles)
{
+ // After data are written to the queue, it may not be read by the
+ // remote reader when
+ //
+ // - the writer does not send them (because of other errors)
+ // - the hwbinder transaction fails
+ // - the reader does not read them (because of other errors)
+ //
+ // Discard the stale data here.
+ size_t staleDataSize = mQueue ? mQueue->availableToRead() : 0;
+ if (staleDataSize > 0) {
+ ALOGW("discarding stale data from message queue");
+ CommandQueueType::MemTransaction tx;
+ if (mQueue->beginRead(staleDataSize, &tx)) {
+ mQueue->commitRead(staleDataSize);
+ }
+ }
+
// write data to queue, optionally resizing it
if (mQueue && (mDataMaxSize <= mQueue->getQuantumCount())) {
if (!mQueue->write(mData.get(), mDataWritten)) {
diff --git a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
index 18955da..9a749d7 100644
--- a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
+++ b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
@@ -23,6 +23,7 @@
#include "VtsHalGraphicsMapperTestUtils.h"
#include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
#include <unistd.h>
#include <algorithm>
@@ -703,10 +704,11 @@
} // namespace android
int main(int argc, char** argv) {
- ::testing::InitGoogleTest(&argc, argv);
-
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
-
- return status;
+ using android::hardware::graphics::composer::V2_1::tests::GraphicsComposerHidlEnvironment;
+ ::testing::AddGlobalTestEnvironment(GraphicsComposerHidlEnvironment::Instance());
+ ::testing::InitGoogleTest(&argc, argv);
+ GraphicsComposerHidlEnvironment::Instance()->init(&argc, argv);
+ int status = RUN_ALL_TESTS();
+ ALOGI("Test result = %d", status);
+ return status;
}
diff --git a/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioDecTest.cpp b/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioDecTest.cpp
index 6790ebf..8520757 100644
--- a/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioDecTest.cpp
+++ b/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioDecTest.cpp
@@ -765,13 +765,13 @@
int bytesCount = 0;
uint32_t flags = 0;
uint32_t timestamp = 0;
- timestampDevTest = true;
+ timestampDevTest = false;
while (1) {
if (!(eleInfo >> bytesCount)) break;
eleInfo >> flags;
eleInfo >> timestamp;
Info.push_back({bytesCount, flags, timestamp});
- if (flags != OMX_BUFFERFLAG_CODECCONFIG)
+ if (timestampDevTest && (flags != OMX_BUFFERFLAG_CODECCONFIG))
timestampUslist.push_back(timestamp);
}
eleInfo.close();
@@ -813,7 +813,7 @@
packedArgs audioArgs = {eEncoding, compName};
testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, nullptr,
portReconfiguration, kPortIndexInput, kPortIndexOutput, &audioArgs);
- EXPECT_EQ(timestampUslist.empty(), true);
+ if (timestampDevTest) EXPECT_EQ(timestampUslist.empty(), true);
// set state to idle
changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
// set state to executing
diff --git a/media/omx/1.0/vts/functional/component/VtsHalMediaOmxV1_0TargetComponentTest.cpp b/media/omx/1.0/vts/functional/component/VtsHalMediaOmxV1_0TargetComponentTest.cpp
index 37d9956..2ec86b2 100644
--- a/media/omx/1.0/vts/functional/component/VtsHalMediaOmxV1_0TargetComponentTest.cpp
+++ b/media/omx/1.0/vts/functional/component/VtsHalMediaOmxV1_0TargetComponentTest.cpp
@@ -371,7 +371,7 @@
kPortIndexOutput = kPortIndexInput + 1;
}
- for (size_t i = kPortIndexInput; i < kPortIndexOutput; i++) {
+ for (size_t i = kPortIndexInput; i <= kPortIndexOutput; i++) {
OMX_PARAM_PORTDEFINITIONTYPE portDef;
status =
getPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef);
@@ -406,10 +406,32 @@
setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &mirror);
portDef = mirror;
- portDef.nBufferSize >>= 1;
+ OMX_U32 nBufferSize = portDef.nBufferSize >> 1;
+ if (nBufferSize != 0) {
+ if (!strncmp(gEnv->getComponent().c_str(), "OMX.google.", 11)) {
+ portDef.nBufferSize = nBufferSize;
+ } else {
+ // Probable alignment requirements of vendor component
+ portDef.nBufferSize = ALIGN_POWER_OF_TWO(nBufferSize, 12);
+ nBufferSize = portDef.nBufferSize;
+ }
+ } else {
+ ASSERT_TRUE(false) << "Unexpected buffer size";
+ }
setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef);
getPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef);
- EXPECT_EQ(portDef.nBufferSize, mirror.nBufferSize);
+ // SPECIAL CASE: For video decoder, allow configuration of input
+ // buffer size even if it is less than minimum requirement and
+ // similarly for encoder allow configuration of output port buffer
+ // size.
+ if ((compClass == video_encoder && i == kPortIndexOutput) ||
+ (compClass == video_decoder && i == kPortIndexInput)) {
+ double dev = (portDef.nBufferSize / (double)nBufferSize);
+ dev -= 1;
+ if (dev < 0 || dev > 0.1) EXPECT_TRUE(false);
+ } else {
+ EXPECT_EQ(portDef.nBufferSize, mirror.nBufferSize);
+ }
setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &mirror);
portDef = mirror;
@@ -467,6 +489,11 @@
portBase = params.nStartPortNumber;
}
+ // set state to idle
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+ OMX_StateIdle);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
OMX_PARAM_PORTDEFINITIONTYPE portDef;
status =
getPortParam(omxNode, OMX_IndexParamPortDefinition, portBase, &portDef);
diff --git a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp
index c75bd7c..1d4fd67 100644
--- a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp
+++ b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp
@@ -498,6 +498,21 @@
ASSERT_EQ(msg.data.eventData.data1, kPortIndexOutput);
if (msg.data.eventData.data2 == OMX_IndexParamPortDefinition ||
msg.data.eventData.data2 == 0) {
+ // Components can send various kinds of port settings changed events
+ // all at once. Before committing to a full port reconfiguration,
+ // defer any events waiting in the queue to be addressed to a later
+ // point.
+ android::List<Message> msgQueueDefer;
+ while (1) {
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
+ iBuffer, oBuffer);
+ if (status !=
+ android::hardware::media::omx::V1_0::Status::TIMED_OUT) {
+ msgQueueDefer.push_back(msg);
+ continue;
+ } else
+ break;
+ }
status = omxNode->sendCommand(
toRawCommandType(OMX_CommandPortDisable), kPortIndexOutput);
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
@@ -577,6 +592,16 @@
ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
+ // Push back deferred messages to the list
+ android::List<Message>::iterator it = msgQueueDefer.begin();
+ while (it != msgQueueDefer.end()) {
+ status = omxNode->dispatchMessage(*it);
+ ASSERT_EQ(
+ status,
+ ::android::hardware::media::omx::V1_0::Status::OK);
+ it++;
+ }
+
// dispatch output buffers
for (size_t i = 0; i < oBuffer->size(); i++) {
dispatchOutputBuffer(omxNode, oBuffer, i, oPortMode);
@@ -906,7 +931,7 @@
eleInfo >> flags;
eleInfo >> timestamp;
Info.push_back({bytesCount, flags, timestamp});
- if (flags != OMX_BUFFERFLAG_CODECCONFIG)
+ if (timestampDevTest && (flags != OMX_BUFFERFLAG_CODECCONFIG))
timestampUslist.push_back(timestamp);
if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
}
@@ -980,7 +1005,7 @@
kPortIndexInput, kPortIndexOutput, portMode[1]);
testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode,
portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
- EXPECT_EQ(timestampUslist.empty(), true);
+ if (timestampDevTest) EXPECT_EQ(timestampUslist.empty(), true);
// set state to idle
changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
// set state to executing
diff --git a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
index f4a4e9b..23f051d 100644
--- a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
+++ b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
@@ -1300,7 +1300,7 @@
eleStream.close();
waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer);
testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag);
- EXPECT_EQ(timestampUslist.empty(), true);
+ if (timestampDevTest) EXPECT_EQ(timestampUslist.empty(), true);
// set state to idle
changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
diff --git a/neuralnetworks/1.0/Android.bp b/neuralnetworks/1.0/Android.bp
index b5603a2..d7c3bbb 100644
--- a/neuralnetworks/1.0/Android.bp
+++ b/neuralnetworks/1.0/Android.bp
@@ -5,6 +5,7 @@
srcs: [
"types.hal",
"IDevice.hal",
+ "IEvent.hal",
"IPreparedModel.hal",
],
}
@@ -19,6 +20,7 @@
out: [
"android/hardware/neuralnetworks/1.0/types.cpp",
"android/hardware/neuralnetworks/1.0/DeviceAll.cpp",
+ "android/hardware/neuralnetworks/1.0/EventAll.cpp",
"android/hardware/neuralnetworks/1.0/PreparedModelAll.cpp",
],
}
@@ -38,6 +40,11 @@
"android/hardware/neuralnetworks/1.0/BnHwDevice.h",
"android/hardware/neuralnetworks/1.0/BpHwDevice.h",
"android/hardware/neuralnetworks/1.0/BsDevice.h",
+ "android/hardware/neuralnetworks/1.0/IEvent.h",
+ "android/hardware/neuralnetworks/1.0/IHwEvent.h",
+ "android/hardware/neuralnetworks/1.0/BnHwEvent.h",
+ "android/hardware/neuralnetworks/1.0/BpHwEvent.h",
+ "android/hardware/neuralnetworks/1.0/BsEvent.h",
"android/hardware/neuralnetworks/1.0/IPreparedModel.h",
"android/hardware/neuralnetworks/1.0/IHwPreparedModel.h",
"android/hardware/neuralnetworks/1.0/BnHwPreparedModel.h",
diff --git a/neuralnetworks/1.0/IEvent.hal b/neuralnetworks/1.0/IEvent.hal
new file mode 100644
index 0000000..63afeaf
--- /dev/null
+++ b/neuralnetworks/1.0/IEvent.hal
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* This HAL is a work in progress */
+
+package android.hardware.neuralnetworks@1.0;
+
+/**
+ * The IEvent interface is a callback object passed by the
+ * Neuralnetworks runtime to the vendor service. It is used as a
+ * synchronization primitive between one or more runtime threads and a
+ * single asynchronous vendor thread. An event object is passed as an
+ * argument to a HIDL call that is expected to take a non-trivial
+ * amount of time. When the asynchronous execution thread has
+ * completed its computation, it must call "notify" on the event to
+ * indicate to the Neuralnetworks runtime whether the computation was
+ * successful or not, and that the corresponding output is ready to be
+ * consumed if the execution was successful.
+ *
+ * TODO: Mention that "notify" is also called by a runtime thread
+ * during CPU fallback execution? Depends on whether the HIDL comments
+ * are strictly for vendors or not.
+ */
+interface IEvent {
+
+ /**
+ * IEvent::notify is called by the server thread (i.e. the thread doing the
+ * work) to mark the event as completed so that any threads requiring the
+ * corresponding resources can continue executing.
+ *
+ * @param status Status of the execution associated with the Event.
+ * Should be SUCCESS or ERROR.
+ */
+ oneway notify(Status status);
+
+};
diff --git a/neuralnetworks/1.0/IPreparedModel.hal b/neuralnetworks/1.0/IPreparedModel.hal
index 566d6ac..428ddc7 100644
--- a/neuralnetworks/1.0/IPreparedModel.hal
+++ b/neuralnetworks/1.0/IPreparedModel.hal
@@ -18,8 +18,9 @@
package android.hardware.neuralnetworks@1.0;
+import IEvent;
+
interface IPreparedModel {
- // TODO: The execution is synchronous. Change that to have a callback on completion.
// Multiple threads can call this execute function concurrently.
- execute(Request request) generates(bool success);
+ execute(Request request, IEvent event) generates(bool success);
};
diff --git a/neuralnetworks/1.0/types.hal b/neuralnetworks/1.0/types.hal
index 959506a..844c44c 100644
--- a/neuralnetworks/1.0/types.hal
+++ b/neuralnetworks/1.0/types.hal
@@ -32,7 +32,8 @@
UINT32 = 7,
TENSOR_FLOAT16 = 8,
TENSOR_FLOAT32 = 9,
- TENSOR_QUANT8_ASYMM = 10,
+ TENSOR_INT32 = 10,
+ TENSOR_QUANT8_ASYMM = 11,
};
// The type of operations. Unlike the operation types found in
@@ -42,50 +43,60 @@
// When modifying, be sure to update HAL_NUM_OPERATION_TYPES in HalIntefaces.h.
enum OperationType : uint32_t {
OEM_OPERATION = 0,
- AVERAGE_POOL = 1,
- CONCATENATION = 2,
- CONV = 3,
- DEPTHWISE_CONV = 4,
- MAX_POOL = 5,
- L2_POOL = 6,
- DEPTH_TO_SPACE = 7,
- SPACE_TO_DEPTH = 8,
- LOCAL_RESPONSE_NORMALIZATION = 9,
- SOFTMAX = 10,
- RESHAPE = 11,
- SPLIT = 12,
- FAKE_QUANT = 13,
- ADD = 14,
- FULLY_CONNECTED = 15,
- CAST = 16,
- MUL = 17,
- L2_NORMALIZATION = 18,
- LOGISTIC = 19,
- RELU = 20,
- RELU6 = 21,
+ ADD = 1,
+ AVERAGE_POOL_2D = 2,
+ CONCATENATION = 3,
+ CONV_2D = 4,
+ DEPTHWISE_CONV_2D = 5,
+ DEPTH_TO_SPACE = 6,
+ DEQUANTIZE = 7,
+ EMBEDDING_LOOKUP = 8,
+ FAKE_QUANT = 9,
+ FLOOR = 10,
+ FULLY_CONNECTED = 11,
+ HASHTABLE_LOOKUP = 12,
+ L2_NORMALIZATION = 13,
+ L2_POOL_2D = 14,
+ LOCAL_RESPONSE_NORMALIZATION = 15,
+ LOGISTIC = 16,
+ LSH_PROJECTION = 17,
+ LSTM = 18,
+ MAX_POOL_2D = 19,
+ MUL = 20,
+ RELU = 21,
RELU1 = 22,
- TANH = 23,
- DEQUANTIZE = 24,
- FLOOR = 25,
- GATHER = 26,
- RESIZE_BILINEAR = 27,
- LSH_PROJECTION = 28,
- LSTM = 29,
- SVDF = 30,
- RNN = 31,
- N_GRAM = 32,
- EMBEDDING_LOOKUP = 33,
- HASHTABLE_LOOKUP = 34,
+ RELU6 = 23,
+ RESHAPE = 24,
+ RESIZE_BILINEAR = 25,
+ RNN = 26,
+ SOFTMAX = 27,
+ SPACE_TO_DEPTH = 28,
+ SVDF = 29,
+ TANH = 30,
};
-// Two special values that can be used instead of a regular poolIndex.
-enum LocationValues : uint32_t {
- // The location will be specified at runtime. It's either a temporary
- // variable, an input, or an output.
- LOCATION_AT_RUN_TIME = 0xFFFFFFFF,
- // The operand's value is stored in the
- // TODO: Only for old
- LOCATION_SAME_BLOCK = 0xFFFFFFFE
+// Fused activation functions
+enum FusedActivationFunc : int32_t {
+ NONE = 0,
+ RELU = 1,
+ RELU1 = 2,
+ RELU6 = 3,
+};
+
+// How an operand is used.
+enum OperandLifeTime : uint32_t {
+ // The operand is internal to the model. It's created by an operation
+ // and consumed by other operations.
+ TEMPORARY_VARIABLE,
+ // The operand is an input of the model. An operand can't be both
+ // input and output of a model.
+ MODEL_INPUT,
+ // The operand is an output of the model.
+ MODEL_OUTPUT,
+ // The operand is a constant found in Model.operandValues.
+ CONSTANT_COPY,
+ // The operand is a constant that was specified via a Memory object.
+ CONSTANT_REFERENCE
};
// Status of a device.
@@ -145,7 +156,20 @@
float scale;
int32_t zeroPoint;
+ // How the operand is used.
+ OperandLifeTime lifetime;
+
// Where to find the data for this operand.
+ // If the lifetime is TEMPORARY_VARIABLE, MODEL_INPUT, or MODEL_OUTPUT:
+ // - All the fields will be 0.
+ // If the lifetime is CONSTANT_COPY:
+ // - location.poolIndex is 0.
+ // - location.offset is the offset in bytes into Model.operandValues.
+ // - location.length is set.
+ // If the lifetime is CONSTANT_REFERENCE:
+ // - location.poolIndex is set.
+ // - location.offset is the offset in bytes into the specified pool.
+ // - location.length is set.
DataLocation location;
};
@@ -161,12 +185,6 @@
vec<uint32_t> outputs;
};
-struct InputOutputInfo {
- DataLocation location;
- // If dimensions.size() > 0, we have updated dimensions.
- vec<uint32_t> dimensions;
-};
-
struct Model {
vec<Operand> operands;
vec<Operation> operations;
@@ -176,8 +194,23 @@
vec<memory> pools;
};
+struct RequestArgument {
+ // The location within one of the memory pools
+ DataLocation location;
+ // If dimensions.size() > 0, dimension information was provided along with the
+ // argument. This can be the case for models that accept inputs of varying size.
+ // This can't change the rank, just the value of the dimensions that were
+ // unspecified in the model.
+ vec<uint32_t> dimensions;
+};
+
struct Request {
- vec<InputOutputInfo> inputs;
- vec<InputOutputInfo> outputs;
+ vec<RequestArgument> inputs;
+ vec<RequestArgument> outputs;
vec<memory> pools;
};
+
+enum Status : uint32_t {
+ SUCCESS,
+ ERROR,
+};
diff --git a/neuralnetworks/1.0/vts/functional/Android.bp b/neuralnetworks/1.0/vts/functional/Android.bp
index d76b2c3..1efff0e 100644
--- a/neuralnetworks/1.0/vts/functional/Android.bp
+++ b/neuralnetworks/1.0/vts/functional/Android.bp
@@ -16,7 +16,10 @@
cc_test {
name: "VtsHalNeuralnetworksV1_0TargetTest",
- srcs: ["VtsHalNeuralnetworksV1_0TargetTest.cpp"],
+ srcs: [
+ "Event.cpp",
+ "VtsHalNeuralnetworksV1_0TargetTest.cpp",
+ ],
defaults: ["VtsHalTargetTestDefaults"],
static_libs: [
"android.hardware.neuralnetworks@1.0",
diff --git a/neuralnetworks/1.0/vts/functional/Event.cpp b/neuralnetworks/1.0/vts/functional/Event.cpp
new file mode 100644
index 0000000..0fab86b
--- /dev/null
+++ b/neuralnetworks/1.0/vts/functional/Event.cpp
@@ -0,0 +1,76 @@
+#include "Event.h"
+#include <android-base/logging.h>
+
+namespace android {
+namespace hardware {
+namespace neuralnetworks {
+namespace V1_0 {
+namespace implementation {
+
+Event::Event() : mStatus(Status::WAITING) {}
+
+Event::~Event() {
+ if (mThread.joinable()) {
+ mThread.join();
+ }
+}
+
+Return<void> Event::notify(ReturnedStatus status) {
+ {
+ std::lock_guard<std::mutex> lock(mMutex);
+ mStatus = status == ReturnedStatus::SUCCESS ? Status::SUCCESS : Status::ERROR;
+ if (mStatus == Status::SUCCESS && mCallback != nullptr) {
+ bool success = mCallback();
+ if (!success) {
+ LOG(ERROR) << "Event::notify -- callback failed";
+ }
+ }
+ }
+ mCondition.notify_all();
+ return Void();
+}
+
+Event::Status Event::poll() {
+ std::lock_guard<std::mutex> lock(mMutex);
+ return mStatus;
+}
+
+Event::Status Event::wait() {
+ std::unique_lock<std::mutex> lock(mMutex);
+ mCondition.wait(lock, [this]{return mStatus != Status::WAITING;});
+ return mStatus;
+}
+
+bool Event::on_finish(std::function<bool(void)> callback) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ if (mCallback != nullptr) {
+ LOG(ERROR) << "Event::on_finish -- a callback has already been bound to this event";
+ return false;
+ }
+ if (callback == nullptr) {
+ LOG(ERROR) << "Event::on_finish -- the new callback is invalid";
+ return false;
+ }
+ mCallback = std::move(callback);
+ return true;
+}
+
+bool Event::bind_thread(std::thread&& asyncThread) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ if (mThread.joinable()) {
+ LOG(ERROR) << "Event::bind_thread -- a thread has already been bound to this event";
+ return false;
+ }
+ if (!asyncThread.joinable()) {
+ LOG(ERROR) << "Event::bind_thread -- the new thread is not joinable";
+ return false;
+ }
+ mThread = std::move(asyncThread);
+ return true;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace neuralnetworks
+} // namespace hardware
+} // namespace android
diff --git a/neuralnetworks/1.0/vts/functional/Event.h b/neuralnetworks/1.0/vts/functional/Event.h
new file mode 100644
index 0000000..2e19585
--- /dev/null
+++ b/neuralnetworks/1.0/vts/functional/Event.h
@@ -0,0 +1,192 @@
+#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_0_EVENT_H
+#define ANDROID_HARDWARE_NEURALNETWORKS_V1_0_EVENT_H
+
+#include <android/hardware/neuralnetworks/1.0/IEvent.h>
+#include <chrono>
+#include <condition_variable>
+#include <functional>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <mutex>
+#include <thread>
+
+namespace android {
+namespace hardware {
+namespace neuralnetworks {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+using ReturnedStatus = ::android::hardware::neuralnetworks::V1_0::Status;
+
+/**
+ * The Event class is used internally by the Neuralnetworks runtime to
+ * synchronize between different threads. An asynchronous task is launched
+ * paired with an event object. When a client thread requires the output being
+ * processed by the asynchronous task, the client thread can wait for the result
+ * and be blocked until it has completed or a timeout condition has been
+ * reached, or poll the result periodically. Both poll and wait* may safely be
+ * called concurrently, even on the same event. When the server thread has
+ * completed, it should immediately call "notify" to indicate the corresponding
+ * output has been produced and awaken any client threads waiting on the event.
+ *
+ * This class exists to enable synchronization across HIDL. When synchronization
+ * is only required in the same process, consider using std::future, std::mutex,
+ * std::condition_variable, or std::experimental::latch instead.
+ */
+struct Event : public IEvent {
+ Event();
+ ~Event() override;
+
+ /**
+ * Event::Status::WAITING -- The corresponding asynchronous execution has
+ * not yet finished.
+ * Event::Status::SUCCESS -- The corresponding asynchronous execution has
+ * succeeded and the output is ready to be
+ * consumed.
+ * Event::Status::TIMEOUT -- The calling thread has waited longer than the
+ * user has specified. This only applies to the
+ * methods Event::wait_for and Event::wait_until.
+ * Event::Status::ERROR -- The corresponding asynchronous execution has
+ * failed to properly execute.
+ */
+ enum class Status : uint32_t {
+ WAITING,
+ SUCCESS,
+ TIMEOUT,
+ ERROR,
+ };
+
+ /**
+ * IEvent::notify marks the event with the return status of the
+ * asynchronous call the event is paired with and enables all
+ * prior and future wait calls on the Event object to proceed. The
+ * call to IEvent::notify happens before any wait* calls on
+ * this event return (except in the case of TIMEOUT) and before
+ * any poll calls that see the resulting status. The asynchronous
+ * call the event is paired with must ensure that any update to
+ * state that should be visible to the caller of wait* or poll
+ * happens before the call to IEvent::notify.
+ *
+ * IEvent::notify can be called at most once on a given event.
+ *
+ * @param neuralnetworks::V1_0::Status SUCCESS or ERROR
+ */
+ Return<void> notify(ReturnedStatus status) override;
+
+ /**
+ * Event::poll returns the current status of the event.
+ *
+ * @return Status SUCCESS, ERROR, or WAITING
+ */
+ Event::Status poll();
+
+ /**
+ * Event::wait blocks until the event has been signaled.
+ *
+ * @return Status SUCCESS or ERROR
+ */
+ Event::Status wait();
+
+ /**
+ * Event::wait_for blocks until the event has been signaled or the time
+ * duration from the time the wait_for function was called has expired,
+ * whichever comes first.
+ *
+ * @return Status SUCCESS, ERROR, or TIMEOUT
+ */
+ template<class Rep, class Period>
+ Event::Status wait_for(const std::chrono::duration<Rep,Period>& timeout_duration);
+
+ /**
+ * Event::wait_until blocks until the event has been signaled or a certain
+ * time has been reached, whichever comes first.
+ *
+ * @return Status SUCCESS, ERROR, or TIMEOUT
+ */
+ template<class Clock, class Duration>
+ Event::Status wait_until(const std::chrono::time_point<Clock,Duration>& timeout_duration);
+
+ /**
+ * Event::on_finish binds a callback function to the event. The
+ * callback will be executed when IEvent::notify is called, before
+ * any calls to wait* return. (Note that wait_for or wait_until
+ * can return TIMEOUT before IEvent::notify is called for the
+ * first time, and hence before the callback is executed.)
+ *
+ * The callback function must not synchronize with or otherwise
+ * access the event object it is bound to.
+ *
+ * Event::on_finish can be called at most once on a given event.
+ *
+ * @param callback Function to be invoked the first time IEvent::notify is
+ * called. Must have a target -- i.e., must not compare equal
+ * to nullptr. Callback returns true if it successfully
+ * completes, false if it fails.
+ * @return bool True if the callback was successfully bound, false if
+ * unsuccessful.
+ *
+ * TODO: What if notify has already been called before on_finish?
+ * TODO: Why does the return value of the callback matter?
+ */
+ bool on_finish(std::function<bool(void)> callback);
+
+ /**
+ * Event::bind_thread binds a thread to the event ensuring that the thread
+ * has fully finished and cleaned its resources before the event is
+ * destroyed. The thread should be bound using std::move.
+ *
+ * The bound thread shall not call any Event method with the exception of
+ * IEvent::notify, which it will call when the thread has finished its
+ * computation.
+ *
+ * Event::bind_thread can be called at most once on a given event.
+ *
+ * @param asyncThread Thread to be bound to the event. The thread object
+ * must represent a thread of execution -- i.e.,
+ * asyncThread.joinable() must be true.
+ * @return bool True if successful, false if thread was not properly bound.
+ */
+ bool bind_thread(std::thread&& asyncThread);
+
+ private:
+ Status mStatus;
+ std::mutex mMutex;
+ std::condition_variable mCondition;
+ std::function<bool(void)> mCallback;
+ std::thread mThread;
+};
+
+
+// template function implementations
+
+template<class Rep, class Period>
+Event::Status Event::wait_for(const std::chrono::duration<Rep,Period>& timeout_duration) {
+ std::unique_lock<std::mutex> lock(mMutex);
+ std::cv_status status = mCondition.wait_for(lock, timeout_duration,
+ [this]{return mStatus != Status::WAITING;});
+ return status != std::cv_status::timeout ? mStatus : Status::TIMEOUT;
+}
+
+template<class Clock, class Duration>
+Event::Status Event::wait_until(const std::chrono::time_point<Clock,Duration>& timeout_time) {
+ std::unique_lock<std::mutex> lock(mMutex);
+ std::cv_status status = mCondition.wait_until(lock, timeout_time,
+ [this]{return mStatus != Status::WAITING;});
+ return status != std::cv_status::timeout ? mStatus : Status::TIMEOUT;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace neuralnetworks
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_0_EVENT_H
diff --git a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.cpp b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.cpp
index 84e67cb..90ccd06 100644
--- a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.cpp
+++ b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.cpp
@@ -16,6 +16,7 @@
#define LOG_TAG "neuralnetworks_hidl_hal_test"
+#include "Event.h"
#include "VtsHalNeuralnetworksV1_0TargetTest.h"
#include <android-base/logging.h>
#include <android/hidl/memory/1.0/IMemory.h>
@@ -29,9 +30,13 @@
namespace vts {
namespace functional {
+using ::android::hardware::neuralnetworks::V1_0::implementation::Event;
+
// A class for test environment setup
NeuralnetworksHidlEnvironment::NeuralnetworksHidlEnvironment() {}
+NeuralnetworksHidlEnvironment::~NeuralnetworksHidlEnvironment() {}
+
NeuralnetworksHidlEnvironment* NeuralnetworksHidlEnvironment::getInstance() {
// This has to return a "new" object because it is freed inside
// ::testing::AddGlobalTestEnvironment when the gtest is being torn down
@@ -44,6 +49,8 @@
}
// The main test class for NEURALNETWORK HIDL HAL.
+NeuralnetworksHidlTest::~NeuralnetworksHidlTest() {}
+
void NeuralnetworksHidlTest::SetUp() {
device = ::testing::VtsHalHidlTargetTestBase::getService<IDevice>(
NeuralnetworksHidlEnvironment::getInstance());
@@ -96,7 +103,8 @@
.numberOfConsumers = 1,
.scale = 0.0f,
.zeroPoint = 0,
- .location = {.poolIndex = static_cast<uint32_t>(LocationValues::LOCATION_AT_RUN_TIME),
+ .lifetime = OperandLifeTime::MODEL_INPUT,
+ .location = {.poolIndex = 0,
.offset = 0,
.length = 0},
},
@@ -106,7 +114,8 @@
.numberOfConsumers = 1,
.scale = 0.0f,
.zeroPoint = 0,
- .location = {.poolIndex = static_cast<uint32_t>(LocationValues::LOCATION_SAME_BLOCK),
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0,
.offset = 0,
.length = size},
},
@@ -116,7 +125,8 @@
.numberOfConsumers = 1,
.scale = 0.0f,
.zeroPoint = 0,
- .location = {.poolIndex = static_cast<uint32_t>(LocationValues::LOCATION_SAME_BLOCK),
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0,
.offset = size,
.length = sizeof(int32_t)},
},
@@ -126,7 +136,8 @@
.numberOfConsumers = 0,
.scale = 0.0f,
.zeroPoint = 0,
- .location = {.poolIndex = static_cast<uint32_t>(LocationValues::LOCATION_AT_RUN_TIME),
+ .lifetime = OperandLifeTime::MODEL_OUTPUT,
+ .location = {.poolIndex = 0,
.offset = 0,
.length = 0},
},
@@ -143,7 +154,7 @@
std::vector<uint8_t> operandValues(
reinterpret_cast<const uint8_t*>(operand2Data.data()),
reinterpret_cast<const uint8_t*>(operand2Data.data()) + size);
- int32_t activation[1] = {0};
+ int32_t activation[1] = {static_cast<int32_t>(FusedActivationFunc::NONE)};
operandValues.insert(operandValues.end(), reinterpret_cast<const uint8_t*>(&activation[0]),
reinterpret_cast<const uint8_t*>(&activation[1]));
@@ -206,10 +217,10 @@
// prepare inputs
uint32_t inputSize = static_cast<uint32_t>(inputData.size() * sizeof(float));
uint32_t outputSize = static_cast<uint32_t>(outputData.size() * sizeof(float));
- std::vector<InputOutputInfo> inputs = {{
+ std::vector<RequestArgument> inputs = {{
.location = {.poolIndex = INPUT, .offset = 0, .length = inputSize}, .dimensions = {},
}};
- std::vector<InputOutputInfo> outputs = {{
+ std::vector<RequestArgument> outputs = {{
.location = {.poolIndex = OUTPUT, .offset = 0, .length = outputSize}, .dimensions = {},
}};
std::vector<hidl_memory> pools = {allocateSharedMemory(inputSize),
@@ -226,21 +237,32 @@
float* outputPtr = reinterpret_cast<float*>(static_cast<void*>(outputMemory->getPointer()));
ASSERT_NE(nullptr, inputPtr);
ASSERT_NE(nullptr, outputPtr);
+ inputMemory->update();
+ outputMemory->update();
std::copy(inputData.begin(), inputData.end(), inputPtr);
std::copy(outputData.begin(), outputData.end(), outputPtr);
inputMemory->commit();
outputMemory->commit();
// execute request
- bool success = preparedModel->execute({.inputs = inputs, .outputs = outputs, .pools = pools});
+ sp<Event> event = sp<Event>(new Event());
+ ASSERT_NE(nullptr, event.get());
+ bool success = preparedModel->execute({.inputs = inputs, .outputs = outputs, .pools = pools},
+ event);
EXPECT_TRUE(success);
+ Event::Status status = event->wait();
+ EXPECT_EQ(Event::Status::SUCCESS, status);
// validate results { 1+5, 2+6, 3+7, 4+8 }
- outputMemory->update();
+ outputMemory->read();
std::copy(outputPtr, outputPtr + outputData.size(), outputData.begin());
+ outputMemory->commit();
EXPECT_EQ(expectedData, outputData);
}
+// TODO: Add tests for execution failure, or wait_for/wait_until timeout.
+// Discussion: https://googleplex-android-review.git.corp.google.com/#/c/platform/hardware/interfaces/+/2654636/5/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.cpp@222
+
} // namespace functional
} // namespace vts
} // namespace V1_0
diff --git a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.h b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.h
index bb0cdaa..9c56e6a 100644
--- a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.h
+++ b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.h
@@ -31,6 +31,7 @@
using ::android::hardware::neuralnetworks::V1_0::IPreparedModel;
using ::android::hardware::neuralnetworks::V1_0::Capabilities;
using ::android::hardware::neuralnetworks::V1_0::DeviceStatus;
+using ::android::hardware::neuralnetworks::V1_0::FusedActivationFunc;
using ::android::hardware::neuralnetworks::V1_0::Model;
using ::android::hardware::neuralnetworks::V1_0::OperationType;
using ::android::hardware::neuralnetworks::V1_0::PerformanceInfo;
@@ -59,15 +60,17 @@
NeuralnetworksHidlEnvironment& operator=(NeuralnetworksHidlEnvironment&&) = delete;
public:
+ ~NeuralnetworksHidlEnvironment() override;
static NeuralnetworksHidlEnvironment* getInstance();
- virtual void registerTestServices() override;
+ void registerTestServices() override;
};
// The main test class for NEURALNETWORKS HIDL HAL.
class NeuralnetworksHidlTest : public ::testing::VtsHalHidlTargetTestBase {
public:
- virtual void SetUp() override;
- virtual void TearDown() override;
+ ~NeuralnetworksHidlTest() override;
+ void SetUp() override;
+ void TearDown() override;
sp<IDevice> device;
};
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
index d93b176..795af86 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
@@ -70,7 +70,7 @@
TEST_F(RadioHidlTest, setRadioPower) {
int serial = GetRandomSerialNumber();
- radio->setRadioPower(serial, 0);
+ radio->setRadioPower(serial, 1);
EXPECT_EQ(std::cv_status::no_timeout, wait());
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
diff --git a/tests/bar/1.0/.hidl_for_test b/tests/bar/1.0/.hidl_for_test
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/bar/1.0/.hidl_for_test
diff --git a/tests/bar/1.0/Android.bp b/tests/bar/1.0/Android.bp
index 2dbfb0f..44ae7a5 100644
--- a/tests/bar/1.0/Android.bp
+++ b/tests/bar/1.0/Android.bp
@@ -67,7 +67,7 @@
],
}
-cc_library {
+cc_test_library {
name: "android.hardware.tests.bar@1.0",
defaults: ["hidl-module-defaults"],
generated_sources: ["android.hardware.tests.bar@1.0_genc++"],
diff --git a/tests/baz/1.0/.hidl_for_test b/tests/baz/1.0/.hidl_for_test
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/baz/1.0/.hidl_for_test
diff --git a/tests/baz/1.0/Android.bp b/tests/baz/1.0/Android.bp
index cec3039..7fa8b27 100644
--- a/tests/baz/1.0/Android.bp
+++ b/tests/baz/1.0/Android.bp
@@ -60,7 +60,7 @@
],
}
-cc_library {
+cc_test_library {
name: "android.hardware.tests.baz@1.0",
defaults: ["hidl-module-defaults"],
generated_sources: ["android.hardware.tests.baz@1.0_genc++"],
diff --git a/tests/expression/1.0/.hidl_for_test b/tests/expression/1.0/.hidl_for_test
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/expression/1.0/.hidl_for_test
diff --git a/tests/expression/1.0/Android.bp b/tests/expression/1.0/Android.bp
index 093b660..0ea0acf 100644
--- a/tests/expression/1.0/Android.bp
+++ b/tests/expression/1.0/Android.bp
@@ -42,7 +42,7 @@
],
}
-cc_library {
+cc_test_library {
name: "android.hardware.tests.expression@1.0",
defaults: ["hidl-module-defaults"],
generated_sources: ["android.hardware.tests.expression@1.0_genc++"],
diff --git a/tests/extension/light/2.0/.hidl_for_test b/tests/extension/light/2.0/.hidl_for_test
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/extension/light/2.0/.hidl_for_test
diff --git a/tests/extension/light/2.0/Android.bp b/tests/extension/light/2.0/Android.bp
index 52117b4..e8a5017 100644
--- a/tests/extension/light/2.0/Android.bp
+++ b/tests/extension/light/2.0/Android.bp
@@ -39,7 +39,7 @@
],
}
-cc_library {
+cc_test_library {
name: "android.hardware.tests.extension.light@2.0",
defaults: ["hidl-module-defaults"],
generated_sources: ["android.hardware.tests.extension.light@2.0_genc++"],
diff --git a/tests/foo/1.0/.hidl_for_test b/tests/foo/1.0/.hidl_for_test
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/foo/1.0/.hidl_for_test
diff --git a/tests/foo/1.0/Android.bp b/tests/foo/1.0/Android.bp
index d0038ab..b5de12e 100644
--- a/tests/foo/1.0/Android.bp
+++ b/tests/foo/1.0/Android.bp
@@ -67,7 +67,7 @@
],
}
-cc_library {
+cc_test_library {
name: "android.hardware.tests.foo@1.0",
defaults: ["hidl-module-defaults"],
generated_sources: ["android.hardware.tests.foo@1.0_genc++"],
diff --git a/tests/hash/1.0/.hidl_for_test b/tests/hash/1.0/.hidl_for_test
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/hash/1.0/.hidl_for_test
diff --git a/tests/hash/1.0/Android.bp b/tests/hash/1.0/Android.bp
index 336963e..d4d1d1a 100644
--- a/tests/hash/1.0/Android.bp
+++ b/tests/hash/1.0/Android.bp
@@ -35,7 +35,7 @@
],
}
-cc_library {
+cc_test_library {
name: "android.hardware.tests.hash@1.0",
defaults: ["hidl-module-defaults"],
generated_sources: ["android.hardware.tests.hash@1.0_genc++"],
diff --git a/tests/inheritance/1.0/.hidl_for_test b/tests/inheritance/1.0/.hidl_for_test
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/inheritance/1.0/.hidl_for_test
diff --git a/tests/inheritance/1.0/Android.bp b/tests/inheritance/1.0/Android.bp
index a8c0e6c..93a8ad5 100644
--- a/tests/inheritance/1.0/Android.bp
+++ b/tests/inheritance/1.0/Android.bp
@@ -56,7 +56,7 @@
],
}
-cc_library {
+cc_test_library {
name: "android.hardware.tests.inheritance@1.0",
defaults: ["hidl-module-defaults"],
generated_sources: ["android.hardware.tests.inheritance@1.0_genc++"],
diff --git a/tests/libhwbinder/1.0/.hidl_for_test b/tests/libhwbinder/1.0/.hidl_for_test
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/libhwbinder/1.0/.hidl_for_test
diff --git a/tests/libhwbinder/1.0/Android.bp b/tests/libhwbinder/1.0/Android.bp
index 6132628..4f3beb0 100644
--- a/tests/libhwbinder/1.0/Android.bp
+++ b/tests/libhwbinder/1.0/Android.bp
@@ -42,7 +42,7 @@
],
}
-cc_library {
+cc_test_library {
name: "android.hardware.tests.libhwbinder@1.0",
defaults: ["hidl-module-defaults"],
generated_sources: ["android.hardware.tests.libhwbinder@1.0_genc++"],
diff --git a/tests/libhwbinder/aidl/.hidl_for_test b/tests/libhwbinder/aidl/.hidl_for_test
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/libhwbinder/aidl/.hidl_for_test
diff --git a/tests/memory/1.0/.hidl_for_test b/tests/memory/1.0/.hidl_for_test
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/memory/1.0/.hidl_for_test
diff --git a/tests/memory/1.0/Android.bp b/tests/memory/1.0/Android.bp
index c5cc4a0..d39ba28 100644
--- a/tests/memory/1.0/Android.bp
+++ b/tests/memory/1.0/Android.bp
@@ -35,7 +35,7 @@
],
}
-cc_library {
+cc_test_library {
name: "android.hardware.tests.memory@1.0",
defaults: ["hidl-module-defaults"],
generated_sources: ["android.hardware.tests.memory@1.0_genc++"],
diff --git a/tests/msgq/1.0/.hidl_for_test b/tests/msgq/1.0/.hidl_for_test
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/msgq/1.0/.hidl_for_test
diff --git a/tests/msgq/1.0/Android.bp b/tests/msgq/1.0/Android.bp
index 017e0d4..7758ee8 100644
--- a/tests/msgq/1.0/Android.bp
+++ b/tests/msgq/1.0/Android.bp
@@ -42,7 +42,7 @@
],
}
-cc_library {
+cc_test_library {
name: "android.hardware.tests.msgq@1.0",
defaults: ["hidl-module-defaults"],
generated_sources: ["android.hardware.tests.msgq@1.0_genc++"],
diff --git a/tests/multithread/1.0/.hidl_for_test b/tests/multithread/1.0/.hidl_for_test
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/multithread/1.0/.hidl_for_test
diff --git a/tests/multithread/1.0/Android.bp b/tests/multithread/1.0/Android.bp
index 68c19aa..76ad2c1 100644
--- a/tests/multithread/1.0/Android.bp
+++ b/tests/multithread/1.0/Android.bp
@@ -35,7 +35,7 @@
],
}
-cc_library {
+cc_test_library {
name: "android.hardware.tests.multithread@1.0",
defaults: ["hidl-module-defaults"],
generated_sources: ["android.hardware.tests.multithread@1.0_genc++"],
diff --git a/tests/pointer/1.0/.hidl_for_test b/tests/pointer/1.0/.hidl_for_test
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/pointer/1.0/.hidl_for_test
diff --git a/tests/pointer/1.0/Android.bp b/tests/pointer/1.0/Android.bp
index 55598ca..178f165 100644
--- a/tests/pointer/1.0/Android.bp
+++ b/tests/pointer/1.0/Android.bp
@@ -42,7 +42,7 @@
],
}
-cc_library {
+cc_test_library {
name: "android.hardware.tests.pointer@1.0",
defaults: ["hidl-module-defaults"],
generated_sources: ["android.hardware.tests.pointer@1.0_genc++"],
diff --git a/thermal/1.1/Android.bp b/thermal/1.1/Android.bp
index 833f219..0985d94 100644
--- a/thermal/1.1/Android.bp
+++ b/thermal/1.1/Android.bp
@@ -42,13 +42,16 @@
],
}
-cc_library_shared {
+cc_library {
name: "android.hardware.thermal@1.1",
defaults: ["hidl-module-defaults"],
generated_sources: ["android.hardware.thermal@1.1_genc++"],
generated_headers: ["android.hardware.thermal@1.1_genc++_headers"],
export_generated_headers: ["android.hardware.thermal@1.1_genc++_headers"],
vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
shared_libs: [
"libhidlbase",
"libhidltransport",
diff --git a/thermal/1.1/vts/functional/Android.bp b/thermal/1.1/vts/functional/Android.bp
index cea5bf8..f5f01fa 100644
--- a/thermal/1.1/vts/functional/Android.bp
+++ b/thermal/1.1/vts/functional/Android.bp
@@ -16,20 +16,11 @@
cc_test {
name: "VtsHalThermalV1_1TargetTest",
- defaults: ["hidl_defaults"],
+ defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalThermalV1_1TargetTest.cpp"],
- shared_libs: [
- "liblog",
- "libhidlbase",
- "libhidltransport",
- "libutils",
+ static_libs: [
"android.hardware.thermal@1.0",
"android.hardware.thermal@1.1",
],
- static_libs: ["VtsHalHidlTargetTestBase"],
- cflags: [
- "-O0",
- "-g",
- ],
}
diff --git a/wifi/1.1/default/hidl_return_util.h b/wifi/1.1/default/hidl_return_util.h
index 2f95c23..f36c8bd 100644
--- a/wifi/1.1/default/hidl_return_util.h
+++ b/wifi/1.1/default/hidl_return_util.h
@@ -55,6 +55,25 @@
return Void();
}
+// Use for HIDL methods which return only an instance of WifiStatus.
+// This version passes the global lock acquired to the body of the method.
+// Note: Only used by IWifi::stop() currently.
+template <typename ObjT, typename WorkFuncT, typename... Args>
+Return<void> validateAndCallWithLock(
+ ObjT* obj,
+ WifiStatusCode status_code_if_invalid,
+ WorkFuncT&& work,
+ const std::function<void(const WifiStatus&)>& hidl_cb,
+ Args&&... args) {
+ auto lock = hidl_sync_util::acquireGlobalLock();
+ if (obj->isValid()) {
+ hidl_cb((obj->*work)(&lock, std::forward<Args>(args)...));
+ } else {
+ hidl_cb(createWifiStatus(status_code_if_invalid));
+ }
+ return Void();
+}
+
// Use for HIDL methods which return instance of WifiStatus and a single return
// value.
template <typename ObjT, typename WorkFuncT, typename ReturnT, typename... Args>
diff --git a/wifi/1.1/default/wifi.cpp b/wifi/1.1/default/wifi.cpp
index 8456b90..c46ef95 100644
--- a/wifi/1.1/default/wifi.cpp
+++ b/wifi/1.1/default/wifi.cpp
@@ -31,6 +31,7 @@
namespace V1_1 {
namespace implementation {
using hidl_return_util::validateAndCall;
+using hidl_return_util::validateAndCallWithLock;
Wifi::Wifi()
: legacy_hal_(new legacy_hal::WifiLegacyHal()),
@@ -64,8 +65,8 @@
}
Return<void> Wifi::stop(stop_cb hidl_status_cb) {
- return validateAndCall(
- this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::stopInternal, hidl_status_cb);
+ return validateAndCallWithLock(this, WifiStatusCode::ERROR_UNKNOWN,
+ &Wifi::stopInternal, hidl_status_cb);
}
Return<void> Wifi::getChipIds(getChipIds_cb hidl_status_cb) {
@@ -120,7 +121,8 @@
return wifi_status;
}
-WifiStatus Wifi::stopInternal() {
+WifiStatus Wifi::stopInternal(
+ /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) {
if (run_state_ == RunState::STOPPED) {
return createWifiStatus(WifiStatusCode::SUCCESS);
} else if (run_state_ == RunState::STOPPING) {
@@ -133,7 +135,7 @@
chip_->invalidate();
chip_.clear();
}
- WifiStatus wifi_status = stopLegacyHalAndDeinitializeModeController();
+ WifiStatus wifi_status = stopLegacyHalAndDeinitializeModeController(lock);
if (wifi_status.code == WifiStatusCode::SUCCESS) {
for (const auto& callback : event_cb_handler_.getCallbacks()) {
if (!callback->onStop().isOk()) {
@@ -180,11 +182,11 @@
return createWifiStatus(WifiStatusCode::SUCCESS);
}
-WifiStatus Wifi::stopLegacyHalAndDeinitializeModeController() {
+WifiStatus Wifi::stopLegacyHalAndDeinitializeModeController(
+ /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) {
run_state_ = RunState::STOPPING;
- const auto on_complete_callback_ = [&]() { run_state_ = RunState::STOPPED; };
legacy_hal::wifi_error legacy_status =
- legacy_hal_->stop(on_complete_callback_);
+ legacy_hal_->stop(lock, [&]() { run_state_ = RunState::STOPPED; });
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
LOG(ERROR) << "Failed to stop legacy HAL: "
<< legacyErrorToString(legacy_status);
diff --git a/wifi/1.1/default/wifi.h b/wifi/1.1/default/wifi.h
index 1ade2d8..3a64cbd 100644
--- a/wifi/1.1/default/wifi.h
+++ b/wifi/1.1/default/wifi.h
@@ -61,12 +61,13 @@
WifiStatus registerEventCallbackInternal(
const sp<IWifiEventCallback>& event_callback);
WifiStatus startInternal();
- WifiStatus stopInternal();
+ WifiStatus stopInternal(std::unique_lock<std::recursive_mutex>* lock);
std::pair<WifiStatus, std::vector<ChipId>> getChipIdsInternal();
std::pair<WifiStatus, sp<IWifiChip>> getChipInternal(ChipId chip_id);
WifiStatus initializeLegacyHal();
- WifiStatus stopLegacyHalAndDeinitializeModeController();
+ WifiStatus stopLegacyHalAndDeinitializeModeController(
+ std::unique_lock<std::recursive_mutex>* lock);
// Instance is created in this root level |IWifi| HIDL interface object
// and shared with all the child HIDL interface objects.
diff --git a/wifi/1.1/default/wifi_legacy_hal.cpp b/wifi/1.1/default/wifi_legacy_hal.cpp
index 151a600..a6f6971 100644
--- a/wifi/1.1/default/wifi_legacy_hal.cpp
+++ b/wifi/1.1/default/wifi_legacy_hal.cpp
@@ -15,6 +15,7 @@
*/
#include <array>
+#include <chrono>
#include <android-base/logging.h>
#include <cutils/properties.h>
@@ -34,6 +35,7 @@
static constexpr uint32_t kLinkLayerStatsDataMpduSizeThreshold = 128;
static constexpr uint32_t kMaxWakeReasonStatsArraySize = 32;
static constexpr uint32_t kMaxRingBuffers = 10;
+static constexpr uint32_t kMaxStopCompleteWaitMs = 50;
// Helper function to create a non-const char* for legacy Hal API's.
std::vector<char> makeCharVec(const std::string& str) {
@@ -53,7 +55,8 @@
// Legacy HAL functions accept "C" style function pointers, so use global
// functions to pass to the legacy HAL function and store the corresponding
// std::function methods to be invoked.
-// Callback to be invoked once |stop| is complete.
+//
+// Callback to be invoked once |stop| is complete
std::function<void(wifi_handle handle)> on_stop_complete_internal_callback;
void onAsyncStopComplete(wifi_handle handle) {
const auto lock = hidl_sync_util::acquireGlobalLock();
@@ -369,6 +372,7 @@
}
wifi_error WifiLegacyHal::stop(
+ /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
const std::function<void()>& on_stop_complete_user_callback) {
if (!is_started_) {
LOG(DEBUG) << "Legacy HAL already stopped";
@@ -376,19 +380,27 @@
return WIFI_SUCCESS;
}
LOG(DEBUG) << "Stopping legacy HAL";
- on_stop_complete_internal_callback = [on_stop_complete_user_callback,
- this](wifi_handle handle) {
+ on_stop_complete_internal_callback =
+ [on_stop_complete_user_callback, this](wifi_handle handle) {
CHECK_EQ(global_handle_, handle) << "Handle mismatch";
+ LOG(INFO) << "Legacy HAL stop complete callback received";
// Invalidate all the internal pointers now that the HAL is
// stopped.
invalidate();
iface_tool_.SetWifiUpState(false);
on_stop_complete_user_callback();
+ is_started_ = false;
};
awaiting_event_loop_termination_ = true;
global_func_table_.wifi_cleanup(global_handle_, onAsyncStopComplete);
+ const auto status = stop_wait_cv_.wait_for(
+ *lock, std::chrono::milliseconds(kMaxStopCompleteWaitMs),
+ [this] { return !awaiting_event_loop_termination_; });
+ if (!status) {
+ LOG(ERROR) << "Legacy HAL stop failed or timed out";
+ return WIFI_ERROR_UNKNOWN;
+ }
LOG(DEBUG) << "Legacy HAL stop complete";
- is_started_ = false;
return WIFI_SUCCESS;
}
@@ -1257,11 +1269,13 @@
void WifiLegacyHal::runEventLoop() {
LOG(DEBUG) << "Starting legacy HAL event loop";
global_func_table_.wifi_event_loop(global_handle_);
+ const auto lock = hidl_sync_util::acquireGlobalLock();
if (!awaiting_event_loop_termination_) {
LOG(FATAL) << "Legacy HAL event loop terminated, but HAL was not stopping";
}
LOG(DEBUG) << "Legacy HAL event loop terminated";
awaiting_event_loop_termination_ = false;
+ stop_wait_cv_.notify_one();
}
std::pair<wifi_error, std::vector<wifi_cached_scan_results>>
diff --git a/wifi/1.1/default/wifi_legacy_hal.h b/wifi/1.1/default/wifi_legacy_hal.h
index caa1bd5..5498803 100644
--- a/wifi/1.1/default/wifi_legacy_hal.h
+++ b/wifi/1.1/default/wifi_legacy_hal.h
@@ -20,6 +20,7 @@
#include <functional>
#include <thread>
#include <vector>
+#include <condition_variable>
#include <wifi_system/interface_tool.h>
@@ -149,8 +150,10 @@
wifi_error initialize();
// Start the legacy HAL and the event looper thread.
wifi_error start();
- // Deinitialize the legacy HAL and stop the event looper thread.
- wifi_error stop(const std::function<void()>& on_complete_callback);
+ // Deinitialize the legacy HAL and wait for the event loop thread to exit
+ // using a predefined timeout.
+ wifi_error stop(std::unique_lock<std::recursive_mutex>* lock,
+ const std::function<void()>& on_complete_callback);
// Wrappers for all the functions in the legacy HAL function table.
std::pair<wifi_error, std::string> getDriverVersion();
std::pair<wifi_error, std::string> getFirmwareVersion();
@@ -293,6 +296,7 @@
wifi_interface_handle wlan_interface_handle_;
// Flag to indicate if we have initiated the cleanup of legacy HAL.
std::atomic<bool> awaiting_event_loop_termination_;
+ std::condition_variable_any stop_wait_cv_;
// Flag to indicate if the legacy HAL has been started.
bool is_started_;
wifi_system::InterfaceTool iface_tool_;