Merge "wifi(implementation): API to flush HAL ringbuffer to files"
diff --git a/audio/5.0/Android.bp b/audio/5.0/Android.bp
index 27c1ef5..3586b8e 100644
--- a/audio/5.0/Android.bp
+++ b/audio/5.0/Android.bp
@@ -20,6 +20,7 @@
"android.hardware.audio.common@5.0",
"android.hardware.audio.effect@5.0",
"android.hidl.base@1.0",
+ "android.hidl.safe_union@1.0",
],
types: [
"AudioDrain",
@@ -28,18 +29,13 @@
"AudioMicrophoneCoordinate",
"AudioMicrophoneDirectionality",
"AudioMicrophoneLocation",
- "DeviceAddress",
"MessageQueueFlagBits",
"MicrophoneInfo",
"MmapBufferFlag",
"MmapBufferInfo",
"MmapPosition",
"ParameterValue",
- "PlaybackTrackMetadata",
- "RecordTrackMetadata",
"Result",
- "SinkMetadata",
- "SourceMetadata",
"TimeSpec",
],
gen_java: false,
diff --git a/audio/5.0/IDevice.hal b/audio/5.0/IDevice.hal
index afb4fad..9e45ba5 100644
--- a/audio/5.0/IDevice.hal
+++ b/audio/5.0/IDevice.hal
@@ -133,7 +133,7 @@
* @param config stream configuration.
* @param flags additional flags.
* @param sinkMetadata Description of the audio that is suggested by the client.
- * May be used by implementations to configure hardware effects.
+ * May be used by implementations to configure processing effects.
* @return retval operation completion status.
* @return inStream in case of success, created input stream.
* @return suggestedConfig in case of invalid parameters, suggested config.
diff --git a/audio/5.0/types.hal b/audio/5.0/types.hal
index 988f584..4932367 100644
--- a/audio/5.0/types.hal
+++ b/audio/5.0/types.hal
@@ -49,34 +49,11 @@
uint64_t tvNSec; // nanoseconds
};
-/**
- * IEEE 802 MAC address.
- */
-typedef uint8_t[6] MacAddress;
-
struct ParameterValue {
string key;
string value;
};
-/**
- * Specifies a device in case when several devices of the same type
- * can be connected (e.g. BT A2DP, USB).
- */
-struct DeviceAddress {
- AudioDevice device; // discriminator
- union Address {
- MacAddress mac; // used for BLUETOOTH_A2DP_*
- uint8_t[4] ipv4; // used for IP
- struct Alsa {
- int32_t card;
- int32_t device;
- } alsa; // used for USB_*
- } address;
- string busAddress; // used for BUS
- string rSubmixAddress; // used for REMOTE_SUBMIX
-};
-
enum MmapBufferFlag : uint32_t {
NONE = 0x0,
/**
diff --git a/audio/common/5.0/Android.bp b/audio/common/5.0/Android.bp
index 663f847..86d9354 100644
--- a/audio/common/5.0/Android.bp
+++ b/audio/common/5.0/Android.bp
@@ -9,6 +9,9 @@
srcs: [
"types.hal",
],
+ interfaces: [
+ "android.hidl.safe_union@1.0",
+ ],
types: [
"AudioChannelMask",
"AudioConfig",
@@ -38,7 +41,12 @@
"AudioSource",
"AudioStreamType",
"AudioUsage",
+ "DeviceAddress",
"FixedChannelCount",
+ "PlaybackTrackMetadata",
+ "RecordTrackMetadata",
+ "SinkMetadata",
+ "SourceMetadata",
"ThreadInfo",
"Uuid",
],
diff --git a/audio/common/5.0/types.hal b/audio/common/5.0/types.hal
index e5919cb..dab7464 100644
--- a/audio/common/5.0/types.hal
+++ b/audio/common/5.0/types.hal
@@ -16,6 +16,8 @@
package android.hardware.audio.common@5.0;
+import android.hidl.safe_union@1.0;
+
/*
*
* IDs and Handles
@@ -602,6 +604,29 @@
};
/**
+ * IEEE 802 MAC address.
+ */
+typedef uint8_t[6] MacAddress;
+
+/**
+ * Specifies a device address in case when several devices of the same type
+ * can be connected (e.g. BT A2DP, USB).
+ */
+struct DeviceAddress {
+ AudioDevice device; // discriminator
+ union Address {
+ MacAddress mac; // used for BLUETOOTH_A2DP_*
+ uint8_t[4] ipv4; // used for IP
+ struct Alsa {
+ int32_t card;
+ int32_t device;
+ } alsa; // used for USB_*
+ } address;
+ string busAddress; // used for BUS
+ string rSubmixAddress; // used for REMOTE_SUBMIX
+};
+
+/**
* The audio output flags serve two purposes:
*
* - when an AudioTrack is created they indicate a "wish" to be connected to an
@@ -748,9 +773,17 @@
* Must not be negative.
*/
float gain;
+ /**
+ * Indicates the destination of an input stream, can be left unspecified.
+ */
+ safe_union Destination {
+ Monostate unspecified;
+ DeviceAddress device;
+ };
+ Destination destination;
};
-/** Metadatas of the source of a StreamIn. */
+/** Metadatas of the sink of a StreamIn. */
struct SinkMetadata {
vec<RecordTrackMetadata> tracks;
};
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 9ab3ceb..022f75e 100644
--- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
@@ -64,7 +64,7 @@
config.sampleRateHz = 8000;
config.format = AudioFormat::PCM_16_BIT;
auto flags = hidl_bitfield<AudioInputFlag>(AudioInputFlag::NONE);
- const SinkMetadata initMetadata = {{{AudioSource::MIC, 1 /* gain */}}};
+ const SinkMetadata initMetadata = {{{.source = AudioSource::MIC, .gain = 1}}};
EventFlag* efGroup;
for (auto microphone : microphones) {
if (microphone.deviceAddress.device != AudioDevice::IN_BUILTIN_MIC) {
@@ -200,7 +200,7 @@
// Test all possible track configuration
for (AudioSource source : range) {
for (float volume : {0.0, 0.5, 1.0}) {
- const SinkMetadata metadata = {{{source, volume}}};
+ const SinkMetadata metadata = {{{.source = source, .gain = volume}}};
ASSERT_OK(stream->updateSinkMetadata(metadata))
<< "source=" << toString(source) << ", volume=" << volume;
}
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index 238b3d8..ec8041c 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -769,7 +769,7 @@
#if MAJOR_VERSION == 2
const AudioSource initMetadata = AudioSource::DEFAULT;
#elif MAJOR_VERSION >= 4
- const SinkMetadata initMetadata = {{{AudioSource::DEFAULT, 1 /* gain */}}};
+ const SinkMetadata initMetadata = {{{.source = AudioSource::DEFAULT, .gain = 1}}};
#endif
};
diff --git a/audio/effect/5.0/Android.bp b/audio/effect/5.0/Android.bp
index d60d94a..78b950e 100644
--- a/audio/effect/5.0/Android.bp
+++ b/audio/effect/5.0/Android.bp
@@ -26,6 +26,7 @@
interfaces: [
"android.hardware.audio.common@5.0",
"android.hidl.base@1.0",
+ "android.hidl.safe_union@1.0",
],
types: [
"AudioBuffer",
diff --git a/camera/metadata/3.3/types.hal b/camera/metadata/3.3/types.hal
index d21bb7c..27d82b9 100644
--- a/camera/metadata/3.3/types.hal
+++ b/camera/metadata/3.3/types.hal
@@ -154,7 +154,7 @@
ANDROID_INFO_END_3_3,
- /** android.logicalMultiCamera.physicalIds [static, byte[], hidden]
+ /** android.logicalMultiCamera.physicalIds [static, byte[], ndk_public]
*
* <p>String containing the ids of the underlying physical cameras.</p>
*/
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index ceb53be..d4c422d 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -202,7 +202,7 @@
</hal>
<hal format="hidl" optional="false">
<name>android.hardware.graphics.composer</name>
- <version>2.1</version>
+ <version>2.1-3</version>
<interface>
<name>IComposer</name>
<instance>default</instance>
diff --git a/current.txt b/current.txt
index 5d50629..3f124ae 100644
--- a/current.txt
+++ b/current.txt
@@ -389,7 +389,7 @@
8caf9104dc6885852c0b117d853dd93f6d4b61a0a365138295eb8bcd41b36423 android.hardware.camera.device@3.2::ICameraDeviceSession
684702a60deef03a1e8093961dc0a18c555c857ad5a77ba7340b0635ae01eb70 android.hardware.camera.device@3.4::ICameraDeviceSession
291638a1b6d4e63283e9e722ab5049d9351717ffa2b66162124f84d1aa7c2835 android.hardware.camera.metadata@3.2::types
-dd2436f251a90f3e5e7ed773b1aeae21e381b00ae26b10ebe3a1001c894e5980 android.hardware.camera.metadata@3.3::types
+8a075cf3a17fe99c6d23415a3e9a65612f1fee73ee052a3a8a0ca5b8877395a4 android.hardware.camera.metadata@3.3::types
da33234403ff5d60f3473711917b9948e6484a4260b5247acdafb111193a9de2 android.hardware.configstore@1.0::ISurfaceFlingerConfigs
21165b8e30c4b2d52980e4728f661420adc16e38bbe73476c06b2085be908f4c android.hardware.gnss@1.0::IGnssCallback
d702fb01dc2a0733aa820b7eb65435ee3334f75632ef880bafd2fb8803a20a58 android.hardware.gnss@1.0::IGnssMeasurementCallback
diff --git a/gnss/2.0/Android.bp b/gnss/2.0/Android.bp
index 6972e40..200671e 100644
--- a/gnss/2.0/Android.bp
+++ b/gnss/2.0/Android.bp
@@ -8,6 +8,8 @@
},
srcs: [
"types.hal",
+ "IAGnss.hal",
+ "IAGnssCallback.hal",
"IAGnssRil.hal",
"IGnss.hal",
"IGnssCallback.hal",
diff --git a/gnss/2.0/IAGnss.hal b/gnss/2.0/IAGnss.hal
new file mode 100644
index 0000000..d4e7d2f
--- /dev/null
+++ b/gnss/2.0/IAGnss.hal
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss@2.0;
+
+import IAGnssCallback;
+
+/**
+ * Extended interface for Assisted GNSS support.
+ */
+interface IAGnss {
+ enum ApnIpType : uint8_t {
+ INVALID = 0,
+ IPV4 = 1,
+ IPV6 = 2,
+ IPV4V6 = 3
+ };
+
+ /**
+ * Opens the AGNSS interface and provides the callback routines to the
+ * implementation of this interface.
+ *
+ * @param callback Handle to the AGNSS status callback interface.
+ */
+ setCallback(IAGnssCallback callback);
+
+ /**
+ * Notifies that the AGNSS data connection has been closed.
+ *
+ * @return success True if the operation is successful.
+ */
+ dataConnClosed() generates (bool success);
+
+ /**
+ * Notifies that a data connection is not available for AGNSS.
+ *
+ * @return success True if the operation is successful.
+ */
+ dataConnFailed() generates (bool success);
+
+ /**
+ * Sets the hostname and port for the AGNSS server.
+ *
+ * @param type Specifies if SUPL or C2K.
+ * @param hostname Hostname of the AGNSS server.
+ * @param port Port number associated with the server.
+ *
+ * @return success True if the operation is successful.
+ */
+ setServer(AGnssType type, string hostname, int32_t port)
+ generates (bool success);
+
+ /**
+ * Notifies GNSS that a data connection is available and sets the network handle,
+ * name of the APN, and its IP type to be used for SUPL connections.
+ *
+ * The HAL implementation must use the network handle to set the network for the
+ * SUPL connection sockets using the android_setsocknetwork function. This will ensure
+ * that there is a network path to the SUPL server. The network handle can also be used
+ * to get the IP address of SUPL FQDN using the android_getaddrinfofornetwork() function.
+ *
+ * @param networkHandle Handle representing the network for use with the NDK API.
+ * @param apn Access Point Name (follows regular APN naming convention).
+ * @param apnIpType Specifies IP type of APN.
+ *
+ * @return success True if the operation is successful.
+ */
+ dataConnOpen(net_handle_t networkHandle, string apn, ApnIpType apnIpType)
+ generates (bool success);
+};
\ No newline at end of file
diff --git a/gnss/2.0/IAGnssCallback.hal b/gnss/2.0/IAGnssCallback.hal
new file mode 100644
index 0000000..896be18
--- /dev/null
+++ b/gnss/2.0/IAGnssCallback.hal
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss@2.0;
+
+/** Callback structure for the AGNSS interface. */
+interface IAGnssCallback {
+ /** AGNSS service type **/
+ enum AGnssType : uint8_t {
+ SUPL = 1,
+ C2K = 2,
+ SUPL_EIMS = 3,
+ SUPL_IMS = 4,
+ };
+
+ enum AGnssStatusValue : uint8_t {
+ /** GNSS requests data connection for AGNSS. */
+ REQUEST_AGNSS_DATA_CONN = 1,
+ /** GNSS releases the AGNSS data connection. */
+ RELEASE_AGNSS_DATA_CONN = 2,
+ /** AGNSS data connection initiated */
+ AGNSS_DATA_CONNECTED = 3,
+ /** AGNSS data connection completed */
+ AGNSS_DATA_CONN_DONE = 4,
+ /** AGNSS data connection failed */
+ AGNSS_DATA_CONN_FAILED = 5
+ };
+
+ /**
+ * Callback with AGNSS status information.
+ *
+ * The GNSS HAL implementation must use this method to request the framework to setup
+ * network connection for the specified AGNSS service and to update the connection
+ * status so that the framework can release the resources.
+ *
+ * @param type Type of AGNSS service.
+ * @parama status Status of the data connection.
+ */
+ agnssStatusCb(AGnssType type, AGnssStatusValue status);
+};
\ No newline at end of file
diff --git a/gnss/2.0/IGnss.hal b/gnss/2.0/IGnss.hal
index 0799a60..fb8b040 100644
--- a/gnss/2.0/IGnss.hal
+++ b/gnss/2.0/IGnss.hal
@@ -21,6 +21,7 @@
import IGnssCallback;
import IGnssMeasurement;
+import IAGnss;
import IAGnssRil;
/** Represents the standard GNSS (Global Navigation Satellite System) interface. */
@@ -36,6 +37,16 @@
setCallback_2_0(IGnssCallback callback) generates (bool success);
/**
+ * This method returns the IAGnss Interface.
+ *
+ * The getExtensionAGnss() must return nullptr as the @1.0::IAGnss interface is
+ * deprecated.
+ *
+ * @return aGnssIface Handle to the IAGnss interface.
+ */
+ getExtensionAGnss_2_0() generates (IAGnss aGnssIface);
+
+ /**
* This method returns the IAGnssRil Interface.
*
* @return aGnssRilIface Handle to the IAGnssRil interface.
@@ -59,4 +70,4 @@
*/
getExtensionMeasurementCorrections()
generates (IMeasurementCorrections measurementCorrectionsIface);
-};
\ No newline at end of file
+};
diff --git a/gnss/2.0/default/AGnss.cpp b/gnss/2.0/default/AGnss.cpp
new file mode 100644
index 0000000..c8e8bf1
--- /dev/null
+++ b/gnss/2.0/default/AGnss.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AGnss"
+
+#include "AGnss.h"
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+// Methods from ::android::hardware::gnss::V2_0::IAGnss follow.
+Return<void> AGnss::setCallback(const sp<V2_0::IAGnssCallback>&) {
+ // TODO implement
+ return Void();
+}
+
+Return<bool> AGnss::dataConnClosed() {
+ // TODO implement
+ return bool{};
+}
+
+Return<bool> AGnss::dataConnFailed() {
+ // TODO implement
+ return bool{};
+}
+
+Return<bool> AGnss::setServer(V2_0::IAGnssCallback::AGnssType type, const hidl_string& hostname,
+ int32_t port) {
+ ALOGD("setServer: type: %s, hostname: %s, port: %d", toString(type).c_str(), hostname.c_str(),
+ port);
+ return true;
+}
+
+Return<bool> AGnss::dataConnOpen(uint64_t, const hidl_string&, V2_0::IAGnss::ApnIpType) {
+ // TODO implement
+ return bool{};
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/2.0/default/AGnss.h b/gnss/2.0/default/AGnss.h
new file mode 100644
index 0000000..244a2c6
--- /dev/null
+++ b/gnss/2.0/default/AGnss.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_AGNSS_H
+#define ANDROID_HARDWARE_GNSS_V2_0_AGNSS_H
+
+#include <android/hardware/gnss/2.0/IAGnss.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::sp;
+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;
+
+struct AGnss : public IAGnss {
+ // Methods from ::android::hardware::gnss::V2_0::IAGnss follow.
+ Return<void> setCallback(const sp<V2_0::IAGnssCallback>& callback) override;
+ Return<bool> dataConnClosed() override;
+ Return<bool> dataConnFailed() override;
+ Return<bool> setServer(V2_0::IAGnssCallback::AGnssType type, const hidl_string& hostname,
+ int32_t port) override;
+ Return<bool> dataConnOpen(uint64_t networkHandle, const hidl_string& apn,
+ V2_0::IAGnss::ApnIpType apnIpType) override;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_AGNSS_H
\ No newline at end of file
diff --git a/gnss/2.0/default/Android.bp b/gnss/2.0/default/Android.bp
index dcdebe8..9119ee4 100644
--- a/gnss/2.0/default/Android.bp
+++ b/gnss/2.0/default/Android.bp
@@ -21,6 +21,7 @@
vendor: true,
vintf_fragments: ["android.hardware.gnss@2.0-service.xml"],
srcs: [
+ "AGnss.cpp",
"AGnssRil.cpp",
"Gnss.cpp",
"GnssMeasurement.cpp",
diff --git a/gnss/2.0/default/Gnss.cpp b/gnss/2.0/default/Gnss.cpp
index 886a3a8..bde904f 100644
--- a/gnss/2.0/default/Gnss.cpp
+++ b/gnss/2.0/default/Gnss.cpp
@@ -18,9 +18,12 @@
#include "Gnss.h"
#include <log/log.h>
+#include "AGnss.h"
#include "AGnssRil.h"
#include "GnssMeasurement.h"
+using ::android::hardware::Status;
+
namespace android {
namespace hardware {
namespace gnss {
@@ -178,6 +181,10 @@
}
// Methods from V2_0::IGnss follow.
+Return<sp<V2_0::IAGnss>> Gnss::getExtensionAGnss_2_0() {
+ return new AGnss{};
+}
+
Return<sp<V2_0::IAGnssRil>> Gnss::getExtensionAGnssRil_2_0() {
return new AGnssRil{};
}
diff --git a/gnss/2.0/default/Gnss.h b/gnss/2.0/default/Gnss.h
index cd69a93..47792cf 100644
--- a/gnss/2.0/default/Gnss.h
+++ b/gnss/2.0/default/Gnss.h
@@ -72,6 +72,7 @@
Return<bool> injectBestLocation(const V1_0::GnssLocation& location) override;
// Methods from V2_0::IGnss follow.
+ Return<sp<V2_0::IAGnss>> getExtensionAGnss_2_0() override;
Return<sp<V2_0::IAGnssRil>> getExtensionAGnssRil_2_0() override;
Return<sp<V2_0::IGnssMeasurement>> getExtensionGnssMeasurement_2_0() override;
Return<bool> setCallback_2_0(const sp<V2_0::IGnssCallback>& callback) override;
@@ -89,4 +90,4 @@
} // namespace hardware
} // namespace android
-#endif // ANDROID_HARDWARE_GNSS_V2_0_GNSS_H
\ No newline at end of file
+#endif // ANDROID_HARDWARE_GNSS_V2_0_GNSS_H
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 c1f1393..ef232c9 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
@@ -25,6 +25,10 @@
using IGnssMeasurement_2_0 = android::hardware::gnss::V2_0::IGnssMeasurement;
using IGnssMeasurement_1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
using IGnssMeasurement_1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
+using IAGnssRil_2_0 = android::hardware::gnss::V2_0::IAGnssRil;
+using IAGnss_2_0 = android::hardware::gnss::V2_0::IAGnss;
+using IAGnss_1_0 = android::hardware::gnss::V1_0::IAGnss;
+using IAGnssCallback_2_0 = android::hardware::gnss::V2_0::IAGnssCallback;
/*
* SetupTeardownCreateCleanup:
@@ -60,7 +64,9 @@
* Gets the AGnssRilExtension and verifies that it returns an actual extension.
*
* The GNSS HAL 2.0 implementation must support @2.0::IAGnssRil interface due to the deprecation
- * of framework network API methods needed to support the @1::IAGnssRil interface.
+ * of framework network API methods needed to support the @1.0::IAGnssRil interface.
+ *
+ * TODO (b/121287858): Enforce gnss@2.0 HAL package is supported on devices launced with Q or later.
*/
TEST_F(GnssHalTest, TestAGnssRilExtension) {
auto agnssRil = gnss_hal_->getExtensionAGnssRil_2_0();
@@ -71,8 +77,8 @@
/*
* TestAGnssRilUpdateNetworkState_2_0:
- * 1. Update GNSS HAL that a network has connected.
- * 2. Update GNSS HAL that network has disconnected.
+ * 1. Updates GNSS HAL that a network has connected.
+ * 2. Updates GNSS HAL that network has disconnected.
*/
TEST_F(GnssHalTest, TestAGnssRilUpdateNetworkState_2_0) {
auto agnssRil = gnss_hal_->getExtensionAGnssRil_2_0();
@@ -80,7 +86,7 @@
sp<IAGnssRil_2_0> iAGnssRil = agnssRil;
ASSERT_NE(iAGnssRil, nullptr);
- // Update GNSS HAL that a network is connected.
+ // Update GNSS HAL that a network has connected.
IAGnssRil_2_0::NetworkAttributes networkAttributes = {
.networkHandle = static_cast<uint64_t>(7700664333),
.isConnected = true,
@@ -133,3 +139,38 @@
iGnssMeasurement->close();
}
+
+/*
+ * TestAGnssExtension:
+ * Gets the AGnssExtension and verifies that it supports @2.0::IAGnss interface by invoking
+ * a method.
+ *
+ * The GNSS HAL 2.0 implementation must support @2.0::IAGnss interface due to the deprecation
+ * of framework network API methods needed to support the @1.0::IAGnss interface.
+ *
+ * TODO (b/121287858): Enforce gnss@2.0 HAL package is supported on devices launced with Q or later.
+ */
+TEST_F(GnssHalTest, TestAGnssExtension) {
+ // Verify IAGnss 2.0 is supported.
+ auto agnss = gnss_hal_->getExtensionAGnss_2_0();
+ ASSERT_TRUE(agnss.isOk());
+ sp<IAGnss_2_0> iAGnss = agnss;
+ ASSERT_NE(iAGnss, nullptr);
+
+ // Set SUPL server host/port
+ auto result = iAGnss->setServer(IAGnssCallback_2_0::AGnssType::SUPL, "supl.google.com", 7275);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+}
+
+/*
+ * TestAGnssExtension_1_0_Deprecation:
+ * Gets the @1.0::IAGnss extension and verifies that it is a nullptr.
+ *
+ * TODO (b/121287858): Enforce gnss@2.0 HAL package is supported on devices launced with Q or later.
+ */
+TEST_F(GnssHalTest, TestAGnssExtension_1_0_Deprecation) {
+ // Verify IAGnss 1.0 is not supported.
+ auto agnss_1_0 = gnss_hal_->getExtensionAGnss();
+ ASSERT_TRUE(!agnss_1_0.isOk() || ((sp<IAGnss_1_0>)agnss_1_0) == nullptr);
+}
diff --git a/graphics/common/1.2/types.hal b/graphics/common/1.2/types.hal
index 15f2c14..392a12e 100644
--- a/graphics/common/1.2/types.hal
+++ b/graphics/common/1.2/types.hal
@@ -16,11 +16,20 @@
package android.hardware.graphics.common@1.2;
+import @1.0::Hdr;
import @1.1::BufferUsage;
import @1.1::ColorMode;
import @1.1::Dataspace;
import @1.1::PixelFormat;
+/**
+ * Hdr
+ */
+@export(name="android_hdr_v1_2_t", value_prefix="HAL_HDR_")
+enum Hdr : @1.0::Hdr {
+ HDR10_PLUS = 4,
+};
+
@export(name="android_dataspace_v1_2_t", value_prefix="HAL_DATASPACE_",
export_parent="false")
enum Dataspace : @1.1::Dataspace {
diff --git a/graphics/composer/2.1/utils/command-buffer/include/composer-command-buffer/2.1/ComposerCommandBuffer.h b/graphics/composer/2.1/utils/command-buffer/include/composer-command-buffer/2.1/ComposerCommandBuffer.h
index 2742207..ebac2e0 100644
--- a/graphics/composer/2.1/utils/command-buffer/include/composer-command-buffer/2.1/ComposerCommandBuffer.h
+++ b/graphics/composer/2.1/utils/command-buffer/include/composer-command-buffer/2.1/ComposerCommandBuffer.h
@@ -534,6 +534,9 @@
static constexpr uint16_t kMaxLength = std::numeric_limits<uint16_t>::max();
+ std::unique_ptr<uint32_t[]> mData;
+ uint32_t mDataWritten;
+
private:
void growData(uint32_t grow) {
uint32_t newWritten = mDataWritten + grow;
@@ -558,9 +561,6 @@
}
uint32_t mDataMaxSize;
- std::unique_ptr<uint32_t[]> mData;
-
- uint32_t mDataWritten;
// end offset of the current command
uint32_t mCommandEnd;
@@ -746,13 +746,14 @@
return fd;
}
+ std::unique_ptr<uint32_t[]> mData;
+ uint32_t mDataRead;
+
private:
std::unique_ptr<CommandQueueType> mQueue;
uint32_t mDataMaxSize;
- std::unique_ptr<uint32_t[]> mData;
uint32_t mDataSize;
- uint32_t mDataRead;
// begin/end offsets of the current command
uint32_t mCommandBegin;
diff --git a/graphics/composer/2.3/IComposerClient.hal b/graphics/composer/2.3/IComposerClient.hal
index e5ee3c5..cf78dea 100644
--- a/graphics/composer/2.3/IComposerClient.hal
+++ b/graphics/composer/2.3/IComposerClient.hal
@@ -20,6 +20,7 @@
import android.hardware.graphics.common@1.1::PixelFormat;
import android.hardware.graphics.common@1.2::ColorMode;
import android.hardware.graphics.common@1.2::Dataspace;
+import android.hardware.graphics.common@1.2::Hdr;
import android.hardware.graphics.composer@2.1::IComposerClient.Command;
import @2.2::IComposerClient;
import @2.1::Display;
@@ -27,7 +28,7 @@
interface IComposerClient extends @2.2::IComposerClient {
- // TODO: Move this enum to LLNDK after we decide where to put graphic types.
+ // Bug: Move this enum to LLNDK after we decide where to put graphic types.
/**
* Required capabilities which are supported by the display. The
* particular set of supported capabilities for a given display may be
@@ -63,6 +64,48 @@
DOZE = 2,
};
+ //Bug: Move this enum to LLNDK after we decide where to put graphic types.
+ /**
+ * PerFrameMetadataKey
+ *
+ * A set of PerFrameMetadataKey pertains specifically to blob-formatted
+ * metadata (as opposed to float-valued metadata).
+ * The list of keys that represent blobs are:
+ * 1. HDR10_PLUS_SEI
+ */
+ enum PerFrameMetadataKey : @2.2::IComposerClient.PerFrameMetadataKey {
+ /**HDR10+ metadata
+ * Specifies a metadata blob adhering to
+ * the ST2094-40 SEI message spec, Version 1.0
+ */
+ HDR10_PLUS_SEI,
+ };
+
+ /**
+ * PerFrameMetadata
+ * This struct encapsulates float-valued
+ * metadata - key must not be in the list
+ * of keys representing blob-formatted metadata
+ * (see PerFrameMetadataKey)
+ */
+ struct PerFrameMetadata {
+ PerFrameMetadataKey key;
+ float value;
+ };
+
+ /**
+ * PerFrameMetadataBlob
+ * This struct encapsulates blob
+ * metadata - key must be one of the list of keys
+ * associated with blob-type metadata key
+ * and the blob must adhere to the format specified by
+ * that key (See PerFrameMetadataKey).
+ */
+ struct PerFrameMetadataBlob {
+ PerFrameMetadataKey key;
+ vec<uint8_t> blob;
+ };
+
enum Command : @2.2::IComposerClient.Command {
/**
* SET_LAYER_COLOR_TRANSFORM has this pseudo prototype
@@ -106,6 +149,22 @@
* @param matrix is a 4x4 transform matrix (16 floats) as described above.
*/
SET_LAYER_COLOR_TRANSFORM = 0x40d << @2.1::IComposerClient.Command:OPCODE_SHIFT,
+
+ /* SET_LAYER_PER_FRAME_METADATA_BLOBS has this pseudo prototype
+ *
+ * setLayerPerFrameMetadataBlobs(Display display, Layer layer,
+ * vec<PerFrameMetadataBlob> metadata);
+ *
+ * This command sends metadata that may be used for tone-mapping the
+ * associated layer. The metadata structure follows a {key, blob}
+ * format (see the PerFrameMetadataBlob struct). All keys must be
+ * returned by a prior call to getPerFrameMetadataKeys and must
+ * be part of the list of keys associated with blob-type metadata
+ * (see PerFrameMetadataKey).
+ *
+ * This method may be called every frame.
+ */
+ SET_LAYER_PER_FRAME_METADATA_BLOBS = 0x304 << @2.1::IComposerClient.Command:OPCODE_SHIFT,
};
/**
@@ -399,4 +458,43 @@
getDisplayCapabilities(Display display)
generates (Error error,
vec<DisplayCapability> capabilities);
+
+ /**
+ * Returns the PerFrameMetadataKeys that are supported by this device.
+ *
+ * @param display is the display on which to create the layer.
+ * @return keys is the vector of PerFrameMetadataKey keys that are
+ * supported by this device.
+ * @return error is NONE upon success. Otherwise,
+ * UNSUPPORTED if not supported on underlying HAL
+ */
+ getPerFrameMetadataKeys_2_3(Display display)
+ generates (Error error,
+ vec<PerFrameMetadataKey> keys);
+
+ /**
+ * Returns the high dynamic range (HDR) capabilities of the given display,
+ * which are invariant with regard to the active configuration.
+ *
+ * Displays which are not HDR-capable must return no types.
+ *
+ * @param display is the display to query.
+ * @return error is NONE upon success. Otherwise,
+ * BAD_DISPLAY when an invalid display handle was passed in.
+ * @return types is an array of HDR types, may have 0 elements if the
+ * display is not HDR-capable.
+ * @return maxLuminance is the desired content maximum luminance for this
+ * display in cd/m^2.
+ * @return maxAverageLuminance - the desired content maximum frame-average
+ * luminance for this display in cd/m^2.
+ * @return minLuminance is the desired content minimum luminance for this
+ * display in cd/m^2.
+ */
+ @callflow(next="*")
+ getHdrCapabilities_2_3(Display display)
+ generates (Error error,
+ vec<Hdr> types,
+ float maxLuminance,
+ float maxAverageLuminance,
+ float minLuminance);
};
diff --git a/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h b/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
index 6c95a1f..11863fa 100644
--- a/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
+++ b/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
@@ -26,6 +26,7 @@
#include <android/hardware/graphics/composer/2.3/IComposer.h>
#include <android/hardware/graphics/composer/2.3/IComposerClient.h>
#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
+#include <limits>
namespace android {
namespace hardware {
@@ -44,6 +45,16 @@
// units of uint32_t's.
class CommandWriterBase : public V2_2::CommandWriterBase {
public:
+ void setLayerPerFrameMetadata(const hidl_vec<IComposerClient::PerFrameMetadata>& metadataVec) {
+ beginCommand_2_3(IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA,
+ metadataVec.size() * 2);
+ for (const auto& metadata : metadataVec) {
+ writeSigned(static_cast<int32_t>(metadata.key));
+ writeFloat(metadata.value);
+ }
+ endCommand();
+ }
+
void setLayerDataspace(Dataspace dataspace) {
setLayerDataspaceInternal(static_cast<int32_t>(dataspace));
}
@@ -66,11 +77,59 @@
endCommand();
}
+ void setLayerPerFrameMetadataBlobs(
+ const hidl_vec<IComposerClient::PerFrameMetadataBlob>& metadata) {
+ size_t commandLength = 0;
+
+ if (metadata.size() > std::numeric_limits<uint32_t>::max()) {
+ LOG_FATAL("too many metadata blobs - dynamic metadata size is too large");
+ return;
+ }
+
+ // number of blobs
+ commandLength += metadata.size();
+
+ for (auto metadataBlob : metadata) {
+ commandLength += sizeof(int32_t); // key of metadata blob
+ commandLength += 1; // size information of metadata blob
+
+ // metadata content size
+ size_t metadataSize = metadataBlob.blob.size() / sizeof(uint32_t);
+ commandLength += metadataSize;
+ commandLength +=
+ (metadataBlob.blob.size() - (metadataSize * sizeof(uint32_t)) > 0) ? 1 : 0;
+ }
+
+ if (commandLength > std::numeric_limits<uint16_t>::max()) {
+ LOG_FATAL("dynamic metadata size is too large");
+ return;
+ }
+
+ // Blobs are written as:
+ // {numElements, key1, size1, blob1, key2, size2, blob2, key3, size3...}
+ uint16_t length = static_cast<uint16_t>(commandLength);
+ beginCommand_2_3(IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA_BLOBS, length);
+ write(static_cast<uint32_t>(metadata.size()));
+ for (auto metadataBlob : metadata) {
+ writeSigned(static_cast<int32_t>(metadataBlob.key));
+ write(static_cast<uint32_t>(metadataBlob.blob.size()));
+ writeBlob(static_cast<uint32_t>(metadataBlob.blob.size()), metadataBlob.blob.data());
+ }
+ endCommand();
+ }
+
protected:
void beginCommand_2_3(IComposerClient::Command command, uint16_t length) {
V2_2::CommandWriterBase::beginCommand_2_2(
static_cast<V2_2::IComposerClient::Command>(static_cast<int32_t>(command)), length);
}
+
+ void writeBlob(uint32_t length, const unsigned char* blob) {
+ memcpy(&mData[mDataWritten], blob, length);
+ uint32_t numElements = length / 4;
+ mDataWritten += numElements;
+ mDataWritten += (length - (numElements * 4) > 0) ? 1 : 0;
+ }
};
// This class helps parse a command queue. Note that all sizes/lengths are in
diff --git a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h
index 69872d2..edc203e 100644
--- a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h
+++ b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h
@@ -21,6 +21,7 @@
#endif
#include <android/hardware/graphics/composer/2.3/IComposerClient.h>
+#include <composer-hal/2.2/ComposerResources.h>
#include <composer-hal/2.3/ComposerClient.h>
#include <composer-hal/2.3/ComposerCommandEngine.h>
#include <composer-hal/2.3/ComposerHal.h>
@@ -38,6 +39,14 @@
template <typename Interface, typename Hal>
class ComposerClientImpl : public V2_2::hal::detail::ComposerClientImpl<Interface, Hal> {
public:
+ Return<void> getPerFrameMetadataKeys_2_3(
+ Display display, IComposerClient::getPerFrameMetadataKeys_2_3_cb hidl_cb) override {
+ std::vector<IComposerClient::PerFrameMetadataKey> keys;
+ Error error = mHal->getPerFrameMetadataKeys_2_3(display, &keys);
+ hidl_cb(error, keys);
+ return Void();
+ }
+
Return<Error> setColorMode_2_3(Display display, ColorMode mode, RenderIntent intent) override {
return mHal->setColorMode_2_3(display, mode, intent);
}
@@ -67,6 +76,18 @@
return Void();
}
+ Return<void> getHdrCapabilities_2_3(
+ Display display, IComposerClient::getHdrCapabilities_2_3_cb hidl_cb) override {
+ hidl_vec<Hdr> types;
+ float max_lumi = 0.0f;
+ float max_avg_lumi = 0.0f;
+ float min_lumi = 0.0f;
+ Error err =
+ mHal->getHdrCapabilities_2_3(display, &types, &max_lumi, &max_avg_lumi, &min_lumi);
+ hidl_cb(err, types, max_lumi, max_avg_lumi, min_lumi);
+ return Void();
+ }
+
Return<Error> getClientTargetSupport_2_3(Display display, uint32_t width, uint32_t height,
PixelFormat format, Dataspace dataspace) override {
Error err = mHal->getClientTargetSupport_2_3(display, width, height, format, dataspace);
@@ -151,12 +172,19 @@
return Void();
}
+ protected:
+ std::unique_ptr<V2_1::hal::ComposerCommandEngine> createCommandEngine() override {
+ return std::make_unique<ComposerCommandEngine>(
+ mHal, static_cast<V2_2::hal::ComposerResources*>(mResources.get()));
+ }
+
private:
using BaseType2_2 = V2_2::hal::detail::ComposerClientImpl<Interface, Hal>;
using BaseType2_1 = V2_1::hal::detail::ComposerClientImpl<Interface, Hal>;
using BaseType2_1::mCommandEngine;
using BaseType2_1::mCommandEngineMutex;
using BaseType2_1::mHal;
+ using BaseType2_1::mResources;
};
} // namespace detail
diff --git a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerCommandEngine.h b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerCommandEngine.h
index c3dcbcd..1a40d96 100644
--- a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerCommandEngine.h
+++ b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerCommandEngine.h
@@ -43,6 +43,8 @@
switch (static_cast<IComposerClient::Command>(command)) {
case IComposerClient::Command::SET_LAYER_COLOR_TRANSFORM:
return executeSetLayerColorTransform(length);
+ case IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA_BLOBS:
+ return executeSetLayerPerFrameMetadataBlobs(length);
default:
return BaseType2_2::executeCommand(command, length);
}
@@ -65,6 +67,48 @@
return true;
}
+ bool executeSetLayerPerFrameMetadataBlobs(uint16_t length) {
+ // must have at least one metadata blob
+ // of at least size 1 in queue (i.e {/*numBlobs=*/1, key, size, blob})
+ if (length < 4) {
+ return false;
+ }
+
+ uint32_t numBlobs = read();
+ length--;
+
+ std::vector<IComposerClient::PerFrameMetadataBlob> metadata;
+
+ for (size_t i = 0; i < numBlobs; i++) {
+ IComposerClient::PerFrameMetadataKey key =
+ static_cast<IComposerClient::PerFrameMetadataKey>(readSigned());
+ uint32_t blobSize = read();
+
+ length -= 2;
+
+ if (length * sizeof(uint32_t) < blobSize) {
+ return false;
+ }
+
+ metadata.push_back({key, std::vector<uint8_t>()});
+ IComposerClient::PerFrameMetadataBlob& metadataBlob = metadata.back();
+ metadataBlob.blob.resize(blobSize);
+ readBlob(blobSize, metadataBlob.blob.data());
+ }
+ auto err = mHal->setLayerPerFrameMetadataBlobs(mCurrentDisplay, mCurrentLayer, metadata);
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+ return true;
+ }
+
+ void readBlob(uint32_t size, void* blob) {
+ memcpy(blob, &mData[mDataRead], size);
+ uint32_t numElements = size / sizeof(uint32_t);
+ mDataRead += numElements;
+ mDataRead += (size - numElements * sizeof(uint32_t) != 0) ? 1 : 0;
+ }
+
private:
using BaseType2_1 = V2_1::hal::ComposerCommandEngine;
using BaseType2_1::mWriter;
diff --git a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h
index c7de848..882621f 100644
--- a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h
+++ b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h
@@ -29,12 +29,19 @@
using common::V1_1::RenderIntent;
using common::V1_2::ColorMode;
using common::V1_2::Dataspace;
+using common::V1_2::Hdr;
using V2_1::Display;
using V2_1::Error;
using V2_1::Layer;
class ComposerHal : public V2_2::hal::ComposerHal {
public:
+ Error getPerFrameMetadataKeys(
+ Display display, std::vector<V2_2::IComposerClient::PerFrameMetadataKey>* outKeys) {
+ return getPerFrameMetadataKeys_2_3(
+ display, reinterpret_cast<std::vector<IComposerClient::PerFrameMetadataKey>*>(outKeys));
+ }
+
Error setColorMode_2_2(Display display, common::V1_1::ColorMode mode,
RenderIntent intent) override {
return setColorMode_2_3(display, static_cast<ColorMode>(mode), intent);
@@ -57,6 +64,24 @@
reinterpret_cast<Dataspace*>(outDataspace));
}
+ Error getHdrCapabilities(Display display, hidl_vec<common::V1_0::Hdr>* outTypes,
+ float* outMaxLuminance, float* outMaxAverageLuminance,
+ float* outMinLuminance) override {
+ return getHdrCapabilities_2_3(display, reinterpret_cast<hidl_vec<Hdr>*>(outTypes),
+ outMaxLuminance, outMaxAverageLuminance, outMinLuminance);
+ }
+
+ Error setLayerPerFrameMetadata(
+ Display display, Layer layer,
+ const std::vector<V2_2::IComposerClient::PerFrameMetadata>& metadata) override {
+ return setLayerPerFrameMetadata_2_3(
+ display, layer,
+ reinterpret_cast<const std::vector<IComposerClient::PerFrameMetadata>&>(metadata));
+ }
+
+ virtual Error getPerFrameMetadataKeys_2_3(
+ Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) = 0;
+
virtual Error setColorMode_2_3(Display display, ColorMode mode, RenderIntent intent) = 0;
virtual Error getRenderIntents_2_3(Display display, ColorMode mode,
@@ -68,7 +93,12 @@
PixelFormat format, Dataspace dataspace) = 0;
virtual Error getReadbackBufferAttributes_2_3(Display display, PixelFormat* outFormat,
Dataspace* outDataspace) = 0;
-
+ virtual Error getHdrCapabilities_2_3(Display display, hidl_vec<Hdr>* outTypes,
+ float* outMaxLuminance, float* outMaxAverageLuminance,
+ float* outMinLuminance) = 0;
+ virtual Error setLayerPerFrameMetadata_2_3(
+ Display display, Layer layer,
+ const std::vector<IComposerClient::PerFrameMetadata>& metadata) = 0;
virtual Error getDisplayIdentificationData(Display display, uint8_t* outPort,
std::vector<uint8_t>* outData) = 0;
virtual Error setLayerColorTransform(Display display, Layer layer, const float* matrix) = 0;
@@ -86,6 +116,9 @@
hidl_vec<uint64_t>& sampleComponent3) = 0;
virtual Error getDisplayCapabilities(
Display display, hidl_vec<IComposerClient::DisplayCapability>* outCapabilities) = 0;
+ virtual Error setLayerPerFrameMetadataBlobs(
+ Display display, Layer layer,
+ std::vector<IComposerClient::PerFrameMetadataBlob>& blobs) = 0;
};
} // namespace hal
diff --git a/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h b/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h
index f7ce7e8..9fb6d4b 100644
--- a/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h
+++ b/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h
@@ -38,6 +38,7 @@
using common::V1_1::RenderIntent;
using common::V1_2::ColorMode;
using common::V1_2::Dataspace;
+using common::V1_2::Hdr;
using V2_1::Display;
using V2_1::Error;
@@ -45,6 +46,29 @@
template <typename Hal>
class HwcHalImpl : public V2_2::passthrough::detail::HwcHalImpl<Hal> {
public:
+ Error getPerFrameMetadataKeys_2_3(
+ Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) override {
+ std::vector<V2_2::IComposerClient::PerFrameMetadataKey> castKeys;
+ Error error = getPerFrameMetadataKeys(display, &castKeys);
+ if (error != Error::NONE) {
+ return error;
+ }
+ outKeys->clear();
+ for (auto key : castKeys) {
+ outKeys->push_back(static_cast<IComposerClient::PerFrameMetadataKey>(key));
+ }
+ return Error::NONE;
+ }
+
+ Error setLayerPerFrameMetadata_2_3(
+ Display display, Layer layer,
+ const std::vector<IComposerClient::PerFrameMetadata>& metadata) override {
+ return setLayerPerFrameMetadata(
+ display, layer,
+ reinterpret_cast<const std::vector<V2_2::IComposerClient::PerFrameMetadata>&>(
+ metadata));
+ }
+
Error setColorMode_2_3(Display display, ColorMode mode, RenderIntent intent) override {
return setColorMode_2_2(display, static_cast<common::V1_1::ColorMode>(mode), intent);
}
@@ -59,6 +83,12 @@
reinterpret_cast<hidl_vec<common::V1_1::ColorMode>*>(outModes));
}
+ Error getHdrCapabilities_2_3(Display display, hidl_vec<Hdr>* outTypes, float* outMaxLuminance,
+ float* outMaxAverageLuminance, float* outMinLuminance) override {
+ return getHdrCapabilities(display, reinterpret_cast<hidl_vec<common::V1_0::Hdr>*>(outTypes),
+ outMaxLuminance, outMaxAverageLuminance, outMinLuminance);
+ }
+
Error getClientTargetSupport_2_3(Display display, uint32_t width, uint32_t height,
PixelFormat format, Dataspace dataspace) override {
return getClientTargetSupport_2_2(display, width, height, format,
@@ -186,6 +216,33 @@
return Error::NONE;
}
+ Error setLayerPerFrameMetadataBlobs(
+ Display display, Layer layer,
+ std::vector<IComposerClient::PerFrameMetadataBlob>& metadata) override {
+ if (!mDispatch.setLayerPerFrameMetadataBlobs) {
+ return Error::UNSUPPORTED;
+ }
+
+ std::vector<IComposerClient::PerFrameMetadataKey> keys;
+ std::vector<uint32_t> sizes;
+ std::vector<uint8_t> blobs;
+
+ for (auto metadataBlob : metadata) {
+ keys.push_back(metadataBlob.key);
+ sizes.push_back(metadataBlob.blob.size());
+
+ int writeIndex = blobs.size();
+ blobs.resize(blobs.size() + metadataBlob.blob.size());
+ memcpy(blobs.data() + writeIndex, metadataBlob.blob.data(), metadataBlob.blob.size());
+ }
+
+ int32_t err = mDispatch.setLayerPerFrameMetadataBlobs(
+ mDevice, display, layer, static_cast<uint32_t>(metadata.size()),
+ reinterpret_cast<int32_t*>(keys.data()), reinterpret_cast<uint32_t*>(sizes.data()),
+ blobs.data());
+ return static_cast<Error>(err);
+ }
+
protected:
bool initDispatch() override {
if (!BaseType2_2::initDispatch()) {
@@ -204,6 +261,8 @@
&mDispatch.getDisplayedContentSample);
this->initOptionalDispatch(HWC2_FUNCTION_GET_DISPLAY_CAPABILITIES,
&mDispatch.getDisplayCapabilities);
+ this->initOptionalDispatch(HWC2_FUNCTION_SET_LAYER_PER_FRAME_METADATA_BLOBS,
+ &mDispatch.setLayerPerFrameMetadataBlobs);
return true;
}
@@ -215,16 +274,20 @@
HWC2_PFN_SET_DISPLAYED_CONTENT_SAMPLING_ENABLED setDisplayedContentSamplingEnabled;
HWC2_PFN_GET_DISPLAYED_CONTENT_SAMPLE getDisplayedContentSample;
HWC2_PFN_GET_DISPLAY_CAPABILITIES getDisplayCapabilities;
+ HWC2_PFN_SET_LAYER_PER_FRAME_METADATA_BLOBS setLayerPerFrameMetadataBlobs;
} mDispatch = {};
using BaseType2_2 = V2_2::passthrough::detail::HwcHalImpl<Hal>;
using BaseType2_1 = V2_1::passthrough::detail::HwcHalImpl<Hal>;
+ using BaseType2_1::getHdrCapabilities;
using BaseType2_1::mDevice;
using BaseType2_2::getClientTargetSupport_2_2;
using BaseType2_2::getColorModes_2_2;
+ using BaseType2_2::getPerFrameMetadataKeys;
using BaseType2_2::getReadbackBufferAttributes;
using BaseType2_2::getRenderIntents;
using BaseType2_2::setColorMode_2_2;
+ using BaseType2_2::setLayerPerFrameMetadata;
};
} // namespace detail
diff --git a/graphics/composer/2.3/utils/vts/ComposerVts.cpp b/graphics/composer/2.3/utils/vts/ComposerVts.cpp
index c631c50..0e541ed 100644
--- a/graphics/composer/2.3/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.3/utils/vts/ComposerVts.cpp
@@ -108,6 +108,33 @@
return error == Error::NONE;
}
+std::vector<IComposerClient::PerFrameMetadataKey> ComposerClient::getPerFrameMetadataKeys_2_3(
+ Display display) {
+ std::vector<IComposerClient::PerFrameMetadataKey> keys;
+ mClient->getPerFrameMetadataKeys_2_3(display, [&](const auto& tmpError, const auto& tmpKeys) {
+ ASSERT_EQ(Error::NONE, tmpError) << "failed to get perFrameMetadataKeys";
+ keys = tmpKeys;
+ });
+ return keys;
+}
+
+std::vector<Hdr> ComposerClient::getHdrCapabilities_2_3(Display display, float* outMaxLuminance,
+ float* outMaxAverageLuminance,
+ float* outMinLuminance) {
+ std::vector<Hdr> types;
+ mClient->getHdrCapabilities_2_3(
+ display, [&](const auto& tmpError, const auto& tmpTypes, const auto& tmpMaxLuminance,
+ const auto& tmpMaxAverageLuminance, const auto& tmpMinLuminance) {
+ ASSERT_EQ(Error::NONE, tmpError) << "failed to get HDR capabilities";
+ types = tmpTypes;
+ *outMaxLuminance = tmpMaxLuminance;
+ *outMaxAverageLuminance = tmpMaxAverageLuminance;
+ *outMinLuminance = tmpMinLuminance;
+ });
+
+ return types;
+}
+
Error ComposerClient::getDisplayedContentSamplingAttributes(
uint64_t display, PixelFormat& format, Dataspace& dataspace,
hidl_bitfield<IComposerClient::FormatColorComponent>& componentMask) {
diff --git a/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h b/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
index d3aa779..7add322 100644
--- a/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
+++ b/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
@@ -36,6 +36,7 @@
using common::V1_1::RenderIntent;
using common::V1_2::ColorMode;
using common::V1_2::Dataspace;
+using common::V1_2::Hdr;
using V2_1::Display;
using V2_1::Error;
using V2_3::IComposer;
@@ -89,10 +90,15 @@
void getReadbackBufferAttributes_2_3(Display display, PixelFormat* outPixelFormat,
Dataspace* outDataspace);
+ std::vector<Hdr> getHdrCapabilities_2_3(Display display, float* outMaxLuminance,
+ float* outMaxAverageLuminance, float* outMinLuminance);
+
bool getClientTargetSupport_2_3(Display display, uint32_t width, uint32_t height,
PixelFormat format, Dataspace dataspace);
std::vector<IComposerClient::DisplayCapability> getDisplayCapabilities(Display display);
+ std::vector<IComposerClient::PerFrameMetadataKey> getPerFrameMetadataKeys_2_3(Display display);
+
private:
const sp<IComposerClient> mClient;
};
diff --git a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
index 6c5cb5d..535f847 100644
--- a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
+++ b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
@@ -20,10 +20,12 @@
#include <VtsHalHidlTargetTestBase.h>
#include <android-base/logging.h>
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
#include <composer-command-buffer/2.3/ComposerCommandBuffer.h>
#include <composer-vts/2.1/GraphicsComposerCallback.h>
#include <composer-vts/2.1/TestCommandReader.h>
#include <composer-vts/2.3/ComposerVts.h>
+#include <mapper-vts/2.0/MapperVts.h>
namespace android {
namespace hardware {
@@ -33,10 +35,13 @@
namespace vts {
namespace {
+using common::V1_0::BufferUsage;
using common::V1_1::PixelFormat;
using common::V1_1::RenderIntent;
using common::V1_2::ColorMode;
using common::V1_2::Dataspace;
+using mapper::V2_0::IMapper;
+using mapper::V2_0::vts::Gralloc;
// Test environment for graphics.composer
class GraphicsComposerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
@@ -80,6 +85,8 @@
}
void TearDown() override {
+ ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_EQ(0, mReader->mCompositionChanges.size());
if (mComposerCallback != nullptr) {
EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
@@ -131,6 +138,44 @@
}
};
+// Tests for IComposerClient::Command.
+class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest {
+ protected:
+ void SetUp() override {
+ ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::SetUp());
+
+ ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>());
+
+ mWriter = std::make_unique<CommandWriterBase>(1024);
+ mReader = std::make_unique<V2_1::vts::TestCommandReader>();
+ }
+
+ void TearDown() override {
+ ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown());
+ }
+
+ const native_handle_t* allocate() {
+ IMapper::BufferDescriptorInfo info{};
+ info.width = 64;
+ info.height = 64;
+ info.layerCount = 1;
+ info.format = static_cast<common::V1_0::PixelFormat>(PixelFormat::RGBA_8888);
+ info.usage =
+ static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
+
+ return mGralloc->allocate(info);
+ }
+
+ void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }
+
+ std::unique_ptr<CommandWriterBase> mWriter;
+ std::unique_ptr<V2_1::vts::TestCommandReader> mReader;
+
+ private:
+ std::unique_ptr<Gralloc> mGralloc;
+};
+
/**
* Test IComposerClient::getDisplayIdentificationData.
*
@@ -152,6 +197,57 @@
}
/**
+ * Test IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA.
+ */
+TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_PER_FRAME_METADATA) {
+ Layer layer;
+ ASSERT_NO_FATAL_FAILURE(layer =
+ mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+
+ /**
+ * DISPLAY_P3 is a color space that uses the DCI_P3 primaries,
+ * the D65 white point and the SRGB transfer functions.
+ * Rendering Intent: Colorimetric
+ * Primaries:
+ * x y
+ * green 0.265 0.690
+ * blue 0.150 0.060
+ * red 0.680 0.320
+ * white (D65) 0.3127 0.3290
+ */
+
+ std::vector<IComposerClient::PerFrameMetadata> hidlMetadata;
+ hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X, 0.680});
+ hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y, 0.320});
+ hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X, 0.265});
+ hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y, 0.690});
+ hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X, 0.150});
+ hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y, 0.060});
+ hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::WHITE_POINT_X, 0.3127});
+ hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::WHITE_POINT_Y, 0.3290});
+ hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::MAX_LUMINANCE, 100.0});
+ hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::MIN_LUMINANCE, 0.1});
+ hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL, 78.0});
+ hidlMetadata.push_back(
+ {IComposerClient::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL, 62.0});
+ mWriter->setLayerPerFrameMetadata(hidlMetadata);
+ execute();
+
+ if (mReader->mErrors.size() == 1 &&
+ static_cast<Error>(mReader->mErrors[0].second) == Error::UNSUPPORTED) {
+ mReader->mErrors.clear();
+ GTEST_SUCCEED() << "SetLayerPerFrameMetadata is not supported";
+ ASSERT_NO_FATAL_FAILURE(mComposerClient->destroyLayer(mPrimaryDisplay, layer));
+ return;
+ }
+
+ ASSERT_NO_FATAL_FAILURE(mComposerClient->destroyLayer(mPrimaryDisplay, layer));
+}
+
+/**
* TestIComposerClient::getReadbackBufferAttributes_2_3
*/
TEST_F(GraphicsComposerHidlTest, GetReadbackBufferAttributes_2_3) {
@@ -353,6 +449,13 @@
mWriter->setLayerColorTransform(matrix.data());
execute();
+
+ if (mReader->mErrors.size() == 1 &&
+ static_cast<Error>(mReader->mErrors[0].second) == Error::UNSUPPORTED) {
+ mReader->mErrors.clear();
+ GTEST_SUCCEED() << "setLayerColorTransform is not supported";
+ return;
+ }
}
TEST_F(GraphicsComposerHidlTest, GetDisplayedContentSamplingAttributes) {
@@ -444,6 +547,29 @@
[&](const auto& tmpError, const auto&) { EXPECT_EQ(Error::BAD_DISPLAY, tmpError); });
}
+TEST_F(GraphicsComposerHidlTest, SetLayerPerFrameMetadataBlobs) {
+ Layer layer;
+ ASSERT_NO_FATAL_FAILURE(layer =
+ mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+
+ std::vector<IComposerClient::PerFrameMetadataBlob> metadata;
+ metadata.push_back(
+ {IComposerClient::PerFrameMetadataKey::HDR10_PLUS_SEI, std::vector<uint8_t>(1, 0xff)});
+
+ mWriter->setLayerPerFrameMetadataBlobs(metadata);
+ execute();
+
+ if (mReader->mErrors.size() == 1 &&
+ static_cast<Error>(mReader->mErrors[0].second) == Error::UNSUPPORTED) {
+ mReader->mErrors.clear();
+ GTEST_SUCCEED() << "setLayerDynamicPerFrameMetadata is not supported";
+ return;
+ }
+}
+
} // namespace
} // namespace vts
} // namespace V2_3
diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
index 967a9f2..3b4eb21 100644
--- a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
@@ -89,11 +89,22 @@
sp<ExecutionCallback>& callback) {
return preparedModel->execute_1_2(request, callback);
}
+static Return<ErrorStatus> ExecutePreparedModel(sp<V1_0::IPreparedModel>&, const Request&) {
+ ADD_FAILURE() << "asking for synchronous execution at V1_0";
+ return ErrorStatus::GENERAL_FAILURE;
+}
+static Return<ErrorStatus> ExecutePreparedModel(sp<V1_2::IPreparedModel>& preparedModel,
+ const Request& request) {
+ return preparedModel->executeSynchronously(request);
+}
+enum class Synchronously { NO, YES };
+const float kDefaultAtol = 1e-5f;
+const float kDefaultRtol = 1e-5f;
template <typename T_IPreparedModel>
void EvaluatePreparedModel(sp<T_IPreparedModel>& preparedModel, std::function<bool(int)> is_ignored,
const std::vector<MixedTypedExample>& examples,
- bool hasRelaxedFloat32Model = false, float fpAtol = 1e-5f,
- float fpRtol = 1e-5f) {
+ bool hasRelaxedFloat32Model = false, float fpAtol = kDefaultAtol,
+ float fpRtol = kDefaultRtol, Synchronously sync = Synchronously::NO) {
const uint32_t INPUT = 0;
const uint32_t OUTPUT = 1;
@@ -186,19 +197,31 @@
inputMemory->commit();
outputMemory->commit();
- // launch execution
- sp<ExecutionCallback> executionCallback = new ExecutionCallback();
- ASSERT_NE(nullptr, executionCallback.get());
- Return<ErrorStatus> executionLaunchStatus = ExecutePreparedModel(
- preparedModel, {.inputs = inputs_info, .outputs = outputs_info, .pools = pools},
- executionCallback);
- ASSERT_TRUE(executionLaunchStatus.isOk());
- EXPECT_EQ(ErrorStatus::NONE, static_cast<ErrorStatus>(executionLaunchStatus));
+ if (sync == Synchronously::NO) {
+ SCOPED_TRACE("asynchronous");
- // retrieve execution status
- executionCallback->wait();
- ErrorStatus executionReturnStatus = executionCallback->getStatus();
- EXPECT_EQ(ErrorStatus::NONE, executionReturnStatus);
+ // launch execution
+ sp<ExecutionCallback> executionCallback = new ExecutionCallback();
+ ASSERT_NE(nullptr, executionCallback.get());
+ Return<ErrorStatus> executionLaunchStatus = ExecutePreparedModel(
+ preparedModel, {.inputs = inputs_info, .outputs = outputs_info, .pools = pools},
+ executionCallback);
+ ASSERT_TRUE(executionLaunchStatus.isOk());
+ EXPECT_EQ(ErrorStatus::NONE, static_cast<ErrorStatus>(executionLaunchStatus));
+
+ // retrieve execution status
+ executionCallback->wait();
+ ErrorStatus executionReturnStatus = executionCallback->getStatus();
+ EXPECT_EQ(ErrorStatus::NONE, executionReturnStatus);
+ } else {
+ SCOPED_TRACE("synchronous");
+
+ // execute
+ Return<ErrorStatus> executionStatus = ExecutePreparedModel(
+ preparedModel, {.inputs = inputs_info, .outputs = outputs_info, .pools = pools});
+ ASSERT_TRUE(executionStatus.isOk());
+ EXPECT_EQ(ErrorStatus::NONE, static_cast<ErrorStatus>(executionStatus));
+ }
// validate results
outputMemory->read();
@@ -216,6 +239,13 @@
}
}
}
+template <typename T_IPreparedModel>
+void EvaluatePreparedModel(sp<T_IPreparedModel>& preparedModel, std::function<bool(int)> is_ignored,
+ const std::vector<MixedTypedExample>& examples,
+ bool hasRelaxedFloat32Model, Synchronously sync) {
+ EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model, kDefaultAtol,
+ kDefaultRtol, sync);
+}
static void getPreparedModel(sp<PreparedModelCallback> callback,
sp<V1_0::IPreparedModel>* preparedModel) {
@@ -363,7 +393,9 @@
ASSERT_NE(nullptr, preparedModel.get());
EvaluatePreparedModel(preparedModel, is_ignored, examples,
- model.relaxComputationFloat32toFloat16);
+ model.relaxComputationFloat32toFloat16, Synchronously::NO);
+ EvaluatePreparedModel(preparedModel, is_ignored, examples,
+ model.relaxComputationFloat32toFloat16, Synchronously::YES);
}
} // namespace generated_tests
diff --git a/neuralnetworks/1.2/IPreparedModel.hal b/neuralnetworks/1.2/IPreparedModel.hal
index 5590487..4e91c67 100644
--- a/neuralnetworks/1.2/IPreparedModel.hal
+++ b/neuralnetworks/1.2/IPreparedModel.hal
@@ -51,8 +51,9 @@
* and complete successfully (ErrorStatus::NONE). There must be
* no failure unless the device itself is in a bad state.
*
- * Multiple threads can call the execute_1_2 function on the same IPreparedModel
- * object concurrently with different requests.
+ * Any number of calls to the execute, execute_1_2, and executeSynchronously
+ * functions, in any combination, may be made concurrently, even on the same
+ * IPreparedModel object.
*
* @param request The input and output information on which the prepared
* model is to be executed.
@@ -71,4 +72,39 @@
*/
execute_1_2(Request request, IExecutionCallback callback)
generates (ErrorStatus status);
+
+ /**
+ * Performs a synchronous execution on a prepared model.
+ *
+ * The execution is performed synchronously with respect to the caller.
+ * executeSynchronously must verify the inputs to the function are
+ * correct. If there is an error, executeSynchronously must immediately
+ * return with the appropriate ErrorStatus value. If the inputs to the
+ * function are valid and there is no error, executeSynchronously must
+ * perform the execution, and must not return until the execution is
+ * complete.
+ *
+ * If the prepared model was prepared from a model wherein all tensor
+ * operands have fully specified dimensions, and the inputs to the function
+ * are valid, then the execution should complete successfully
+ * (ErrorStatus::NONE). There must be no failure unless the device itself is
+ * in a bad state.
+ *
+ * Any number of calls to the execute, execute_1_2, and executeSynchronously
+ * functions, in any combination, may be made concurrently, even on the same
+ * IPreparedModel object.
+ *
+ * @param request The input and output information on which the prepared
+ * model is to be executed.
+ * @return status Error status of the execution, must be:
+ * - NONE if execution is performed successfully
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if there is an unspecified error
+ * - OUTPUT_INSUFFICIENT_SIZE if provided output buffer is
+ * not large enough to store the resultant values
+ * - INVALID_ARGUMENT if one of the input arguments is
+ * invalid
+ */
+ executeSynchronously(Request request)
+ generates (ErrorStatus status);
};
diff --git a/neuralnetworks/1.2/vts/functional/ValidateModel.cpp b/neuralnetworks/1.2/vts/functional/ValidateModel.cpp
index 9621009..b1a0e53 100644
--- a/neuralnetworks/1.2/vts/functional/ValidateModel.cpp
+++ b/neuralnetworks/1.2/vts/functional/ValidateModel.cpp
@@ -327,6 +327,7 @@
// - CAST's argument can be any of TENSOR_(FLOAT16|FLOAT32|INT32|QUANT8_ASYMM).
// - RANDOM_MULTINOMIAL's argument can be either TENSOR_FLOAT16 or TENSOR_FLOAT32.
// - CONV_2D filter type (arg 1) can be QUANT8_ASYMM or QUANT8_SYMM_PER_CHANNEL
+ // - DEPTHWISE_CONV_2D filter type (arg 1) can be QUANT8_ASYMM or QUANT8_SYMM_PER_CHANNEL
switch (operation.type) {
case OperationType::LSH_PROJECTION: {
if (operand == operation.inputs[1]) {
@@ -346,6 +347,7 @@
return true;
}
} break;
+ case OperationType::DEPTHWISE_CONV_2D:
case OperationType::CONV_2D: {
if (operand == 1 && (type == OperandType::TENSOR_QUANT8_ASYMM ||
type == OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL)) {
diff --git a/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp b/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp
index e2722aa..d80fbcf 100644
--- a/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp
+++ b/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp
@@ -97,18 +97,29 @@
static void validate(const sp<IPreparedModel>& preparedModel, const std::string& message,
Request request, const std::function<void(Request*)>& mutation) {
mutation(&request);
- SCOPED_TRACE(message + " [execute]");
- sp<ExecutionCallback> executionCallback = new ExecutionCallback();
- ASSERT_NE(nullptr, executionCallback.get());
- Return<ErrorStatus> executeLaunchStatus =
- preparedModel->execute_1_2(request, executionCallback);
- ASSERT_TRUE(executeLaunchStatus.isOk());
- ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, static_cast<ErrorStatus>(executeLaunchStatus));
+ {
+ SCOPED_TRACE(message + " [execute_1_2]");
- executionCallback->wait();
- ErrorStatus executionReturnStatus = executionCallback->getStatus();
- ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, executionReturnStatus);
+ sp<ExecutionCallback> executionCallback = new ExecutionCallback();
+ ASSERT_NE(nullptr, executionCallback.get());
+ Return<ErrorStatus> executeLaunchStatus =
+ preparedModel->execute_1_2(request, executionCallback);
+ ASSERT_TRUE(executeLaunchStatus.isOk());
+ ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, static_cast<ErrorStatus>(executeLaunchStatus));
+
+ executionCallback->wait();
+ ErrorStatus executionReturnStatus = executionCallback->getStatus();
+ ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, executionReturnStatus);
+ }
+
+ {
+ SCOPED_TRACE(message + " [executeSynchronously]");
+
+ Return<ErrorStatus> executeStatus = preparedModel->executeSynchronously(request);
+ ASSERT_TRUE(executeStatus.isOk());
+ ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, static_cast<ErrorStatus>(executeStatus));
+ }
}
// Delete element from hidl_vec. hidl_vec doesn't support a "remove" operation,