Merge "Enhance Tuner 1.0 VTS testing and configurations"
diff --git a/audio/7.0/IDevice.hal b/audio/7.0/IDevice.hal
index d9e0ad2..e423f29 100644
--- a/audio/7.0/IDevice.hal
+++ b/audio/7.0/IDevice.hal
@@ -174,6 +174,9 @@
* Creates an audio patch between several source and sink ports. The handle
* is allocated by the HAL and must be unique for this audio HAL module.
*
+ * Optional method. HAL must support it if 'supportsAudioPatches' returns
+ * 'true'.
+ *
* @param sources patch sources.
* @param sinks patch sinks.
* @return retval operation completion status.
@@ -189,6 +192,9 @@
* as the HAL module can figure out a way of switching the route without
* causing audio disruption.
*
+ * Optional method. HAL must support it if 'supportsAudioPatches' returns
+ * 'true'.
+ *
* @param previousPatch handle of the previous patch to update.
* @param sources new patch sources.
* @param sinks new patch sinks.
@@ -204,6 +210,9 @@
/**
* Release an audio patch.
*
+ * Optional method. HAL must support it if 'supportsAudioPatches' returns
+ * 'true'.
+ *
* @param patch patch handle.
* @return retval operation completion status.
*/
diff --git a/audio/core/all-versions/default/Android.bp b/audio/core/all-versions/default/Android.bp
index e0f0860..c75c779 100644
--- a/audio/core/all-versions/default/Android.bp
+++ b/audio/core/all-versions/default/Android.bp
@@ -51,6 +51,7 @@
"libaudio_system_headers",
"libhardware_headers",
"libmedia_headers",
+ "libmediautils_headers",
],
export_header_lib_headers: [
diff --git a/audio/core/all-versions/default/Device.cpp b/audio/core/all-versions/default/Device.cpp
index 05c1066..7caed44 100644
--- a/audio/core/all-versions/default/Device.cpp
+++ b/audio/core/all-versions/default/Device.cpp
@@ -325,11 +325,17 @@
const hidl_vec<AudioPortConfig>& sinks) {
Result retval(Result::NOT_SUPPORTED);
if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
- std::unique_ptr<audio_port_config[]> halSources;
- HidlUtils::audioPortConfigsToHal(sources, &halSources);
- std::unique_ptr<audio_port_config[]> halSinks;
- HidlUtils::audioPortConfigsToHal(sinks, &halSinks);
audio_patch_handle_t halPatch = static_cast<audio_patch_handle_t>(patch);
+ std::unique_ptr<audio_port_config[]> halSources;
+ if (status_t status = HidlUtils::audioPortConfigsToHal(sources, &halSources);
+ status != NO_ERROR) {
+ return {analyzeStatus("audioPortConfigsToHal;sources", status), patch};
+ }
+ std::unique_ptr<audio_port_config[]> halSinks;
+ if (status_t status = HidlUtils::audioPortConfigsToHal(sinks, &halSinks);
+ status != NO_ERROR) {
+ return {analyzeStatus("audioPortConfigsToHal;sinks", status), patch};
+ }
retval = analyzeStatus("create_audio_patch",
mDevice->create_audio_patch(mDevice, sources.size(), &halSources[0],
sinks.size(), &halSinks[0], &halPatch));
@@ -364,7 +370,10 @@
Return<Result> Device::setAudioPortConfig(const AudioPortConfig& config) {
if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
struct audio_port_config halPortConfig;
- HidlUtils::audioPortConfigToHal(config, &halPortConfig);
+ if (status_t status = HidlUtils::audioPortConfigToHal(config, &halPortConfig);
+ status != NO_ERROR) {
+ return analyzeStatus("audioPortConfigToHal", status);
+ }
return analyzeStatus("set_audio_port_config",
mDevice->set_audio_port_config(mDevice, &halPortConfig));
}
diff --git a/audio/core/all-versions/default/StreamOut.cpp b/audio/core/all-versions/default/StreamOut.cpp
index ffd3b6b..357fd94 100644
--- a/audio/core/all-versions/default/StreamOut.cpp
+++ b/audio/core/all-versions/default/StreamOut.cpp
@@ -163,7 +163,7 @@
status_t status = EventFlag::deleteEventFlag(&mEfGroup);
ALOGE_IF(status, "write MQ event flag deletion error: %s", strerror(-status));
}
- mCallback.clear();
+ mCallback = nullptr;
#if MAJOR_VERSION <= 5
mDevice->closeOutputStream(mStream);
// Closing the output stream in the HAL waits for the callback to finish,
@@ -462,7 +462,7 @@
Return<Result> StreamOut::clearCallback() {
if (mStream->set_callback == NULL) return Result::NOT_SUPPORTED;
- mCallback.clear();
+ mCallback = nullptr;
return Result::OK;
}
@@ -477,7 +477,7 @@
// It's correct to hold an sp<> to callback because the reference
// in the StreamOut instance can be cleared in the meantime. There is
// no difference on which thread to run IStreamOutCallback's destructor.
- sp<IStreamOutCallback> callback = self->mCallback;
+ sp<IStreamOutCallback> callback = self->mCallback.load();
if (callback.get() == nullptr) return 0;
ALOGV("asyncCallback() event %d", event);
Return<void> result;
@@ -698,7 +698,7 @@
// static
int StreamOut::asyncEventCallback(stream_event_callback_type_t event, void* param, void* cookie) {
StreamOut* self = reinterpret_cast<StreamOut*>(cookie);
- sp<IStreamOutEventCallback> eventCallback = self->mEventCallback;
+ sp<IStreamOutEventCallback> eventCallback = self->mEventCallback.load();
if (eventCallback.get() == nullptr) return 0;
ALOGV("%s event %d", __func__, event);
Return<void> result;
diff --git a/audio/core/all-versions/default/include/core/default/StreamOut.h b/audio/core/all-versions/default/include/core/default/StreamOut.h
index b8e8515..02d8e89 100644
--- a/audio/core/all-versions/default/include/core/default/StreamOut.h
+++ b/audio/core/all-versions/default/include/core/default/StreamOut.h
@@ -29,6 +29,7 @@
#include <fmq/MessageQueue.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
+#include <mediautils/Synchronization.h>
#include <utils/Thread.h>
namespace android {
@@ -158,9 +159,9 @@
audio_stream_out_t* mStream;
const sp<Stream> mStreamCommon;
const sp<StreamMmap<audio_stream_out_t>> mStreamMmap;
- sp<IStreamOutCallback> mCallback; // Callback for non-blocking write and drain
+ mediautils::atomic_sp<IStreamOutCallback> mCallback; // for non-blocking write and drain
#if MAJOR_VERSION >= 6
- sp<IStreamOutEventCallback> mEventCallback;
+ mediautils::atomic_sp<IStreamOutEventCallback> mEventCallback;
#endif
std::unique_ptr<CommandMQ> mCommandMQ;
std::unique_ptr<DataMQ> mDataMQ;
diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
index 0f52a90..ef4daba 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -298,6 +298,18 @@
&DeviceConfigParameterToString);
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(InputBufferSizeInvalidConfig);
+static const DeviceAddress& getValidInputDeviceAddress() {
+ static const DeviceAddress valid = {
+ .deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_DEFAULT)};
+ return valid;
+}
+
+static const DeviceAddress& getValidOutputDeviceAddress() {
+ static const DeviceAddress valid = {
+ .deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_DEFAULT)};
+ return valid;
+}
+
static const DeviceAddress& getInvalidDeviceAddress() {
static const DeviceAddress valid = {.deviceType = "random_string"};
return valid;
@@ -311,6 +323,141 @@
getDevice()->setConnectedState(getInvalidDeviceAddress(), false));
}
+static std::vector<AudioPortConfig>& generatePortConfigs(bool valid) {
+ enum { // Note: This is for convenience when deriving "invalid" configs from "valid".
+ PORT_CONF_MINIMAL,
+ PORT_CONF_WITH_GAIN,
+ PORT_CONF_EXT_DEVICE,
+ PORT_CONF_EXT_MIX_SOURCE,
+ PORT_CONF_EXT_MIX_SINK,
+ PORT_CONF_EXT_SESSION
+ };
+ static std::vector<AudioPortConfig> valids = [] {
+ std::vector<AudioPortConfig> result;
+ result.reserve(PORT_CONF_EXT_SESSION + 1);
+ result.push_back(AudioPortConfig{});
+ AudioPortConfig configWithGain{};
+ configWithGain.gain.config(AudioGainConfig{
+ .index = 0,
+ .mode = {toString(xsd::AudioGainMode::AUDIO_GAIN_MODE_JOINT)},
+ .channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO),
+ .rampDurationMs = 1});
+ configWithGain.gain.config().values.resize(1);
+ configWithGain.gain.config().values[0] = 1000;
+ result.push_back(std::move(configWithGain));
+ AudioPortConfig configWithPortExtDevice{};
+ configWithPortExtDevice.ext.device(getValidOutputDeviceAddress());
+ result.push_back(std::move(configWithPortExtDevice));
+ AudioPortConfig configWithPortExtMixSource{};
+ configWithPortExtMixSource.ext.mix({});
+ configWithPortExtMixSource.ext.mix().useCase.stream(
+ toString(xsd::AudioStreamType::AUDIO_STREAM_VOICE_CALL));
+ result.push_back(std::move(configWithPortExtMixSource));
+ AudioPortConfig configWithPortExtMixSink{};
+ configWithPortExtMixSink.ext.mix({});
+ configWithPortExtMixSink.ext.mix().useCase.source(
+ toString(xsd::AudioSource::AUDIO_SOURCE_DEFAULT));
+ result.push_back(std::move(configWithPortExtMixSink));
+ AudioPortConfig configWithPortExtSession{};
+ configWithPortExtSession.ext.session(
+ static_cast<AudioSession>(AudioSessionConsts::OUTPUT_MIX));
+ result.push_back(std::move(configWithPortExtSession));
+ return result;
+ }();
+ static std::vector<AudioPortConfig> invalids = [&] {
+ std::vector<AudioPortConfig> result;
+ AudioPortConfig invalidBaseChannelMask = valids[PORT_CONF_MINIMAL];
+ invalidBaseChannelMask.base.channelMask = "random_string";
+ result.push_back(std::move(invalidBaseChannelMask));
+ AudioPortConfig invalidBaseFormat = valids[PORT_CONF_MINIMAL];
+ invalidBaseFormat.base.format = "random_string";
+ result.push_back(std::move(invalidBaseFormat));
+ AudioPortConfig invalidGainMode = valids[PORT_CONF_WITH_GAIN];
+ invalidGainMode.gain.config().mode = {{"random_string"}};
+ result.push_back(std::move(invalidGainMode));
+ AudioPortConfig invalidGainChannelMask = valids[PORT_CONF_WITH_GAIN];
+ invalidGainChannelMask.gain.config().channelMask = "random_string";
+ result.push_back(std::move(invalidGainChannelMask));
+ AudioPortConfig invalidDeviceType = valids[PORT_CONF_EXT_DEVICE];
+ invalidDeviceType.ext.device().deviceType = "random_string";
+ result.push_back(std::move(invalidDeviceType));
+ AudioPortConfig invalidStreamType = valids[PORT_CONF_EXT_MIX_SOURCE];
+ invalidStreamType.ext.mix().useCase.stream() = "random_string";
+ result.push_back(std::move(invalidStreamType));
+ AudioPortConfig invalidSource = valids[PORT_CONF_EXT_MIX_SINK];
+ invalidSource.ext.mix().useCase.source() = "random_string";
+ result.push_back(std::move(invalidSource));
+ return result;
+ }();
+ return valid ? valids : invalids;
+}
+
+TEST_P(AudioHidlDeviceTest, SetAudioPortConfigInvalidArguments) {
+ doc::test("Check that invalid port configs are rejected by IDevice::setAudioPortConfig");
+ for (const auto& invalidConfig : generatePortConfigs(false /*valid*/)) {
+ EXPECT_RESULT(invalidArgsOrNotSupported, getDevice()->setAudioPortConfig(invalidConfig))
+ << ::testing::PrintToString(invalidConfig);
+ }
+}
+
+TEST_P(AudioPatchHidlTest, CreatePatchInvalidArguments) {
+ doc::test("Check that invalid port configs are rejected by IDevice::createAudioPatch");
+ // Note that HAL actually might reject the proposed source / sink combo
+ // due to other reasons than presence of invalid enum-strings.
+ // TODO: Come up with a way to guarantee validity of a source / sink combo.
+ for (const auto& validSource : generatePortConfigs(true /*valid*/)) {
+ for (const auto& invalidSink : generatePortConfigs(false /*valid*/)) {
+ AudioPatchHandle handle;
+ EXPECT_OK(getDevice()->createAudioPatch(hidl_vec<AudioPortConfig>{validSource},
+ hidl_vec<AudioPortConfig>{invalidSink},
+ returnIn(res, handle)));
+ EXPECT_EQ(Result::INVALID_ARGUMENTS, res)
+ << "Source: " << ::testing::PrintToString(validSource)
+ << "; Sink: " << ::testing::PrintToString(invalidSink);
+ }
+ }
+ for (const auto& validSink : generatePortConfigs(true /*valid*/)) {
+ for (const auto& invalidSource : generatePortConfigs(false /*valid*/)) {
+ AudioPatchHandle handle;
+ EXPECT_OK(getDevice()->createAudioPatch(hidl_vec<AudioPortConfig>{invalidSource},
+ hidl_vec<AudioPortConfig>{validSink},
+ returnIn(res, handle)));
+ EXPECT_EQ(Result::INVALID_ARGUMENTS, res)
+ << "Source: " << ::testing::PrintToString(invalidSource)
+ << "; Sink: " << ::testing::PrintToString(validSink);
+ }
+ }
+}
+
+TEST_P(AudioPatchHidlTest, UpdatePatchInvalidArguments) {
+ doc::test("Check that invalid port configs are rejected by IDevice::updateAudioPatch");
+ // Note that HAL actually might reject the proposed source / sink combo
+ // due to other reasons than presence of invalid enum-strings.
+ // TODO: Come up with a way to guarantee validity of a source / sink combo.
+ for (const auto& validSource : generatePortConfigs(true /*valid*/)) {
+ for (const auto& invalidSink : generatePortConfigs(false /*valid*/)) {
+ AudioPatchHandle handle{};
+ EXPECT_OK(getDevice()->updateAudioPatch(handle, hidl_vec<AudioPortConfig>{validSource},
+ hidl_vec<AudioPortConfig>{invalidSink},
+ returnIn(res, handle)));
+ EXPECT_EQ(Result::INVALID_ARGUMENTS, res)
+ << "Source: " << ::testing::PrintToString(validSource)
+ << "; Sink: " << ::testing::PrintToString(invalidSink);
+ }
+ }
+ for (const auto& validSink : generatePortConfigs(true /*valid*/)) {
+ for (const auto& invalidSource : generatePortConfigs(false /*valid*/)) {
+ AudioPatchHandle handle{};
+ EXPECT_OK(getDevice()->updateAudioPatch(
+ handle, hidl_vec<AudioPortConfig>{invalidSource},
+ hidl_vec<AudioPortConfig>{validSink}, returnIn(res, handle)));
+ EXPECT_EQ(Result::INVALID_ARGUMENTS, res)
+ << "Source: " << ::testing::PrintToString(invalidSource)
+ << "; Sink: " << ::testing::PrintToString(validSink);
+ }
+ }
+}
+
enum { PARAM_DEVICE_CONFIG, PARAM_ADDRESS, PARAM_METADATA };
enum { INDEX_SINK, INDEX_SOURCE };
using SinkOrSourceMetadata = std::variant<SinkMetadata, SourceMetadata>;
@@ -362,18 +509,6 @@
}
};
-static const DeviceAddress& getValidInputDeviceAddress() {
- static const DeviceAddress valid = {
- .deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_DEFAULT)};
- return valid;
-}
-
-static const DeviceAddress& getValidOutputDeviceAddress() {
- static const DeviceAddress valid = {
- .deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_DEFAULT)};
- return valid;
-}
-
static const RecordTrackMetadata& getValidRecordTrackMetadata() {
static const RecordTrackMetadata valid = {
.source = toString(xsd::AudioSource::AUDIO_SOURCE_DEFAULT), .gain = 1};
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index 8ef2b60..73513f4 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -1153,6 +1153,47 @@
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
},
},
+ {
+ .config =
+ {
+ .prop = toInt(VehicleProperty::CLUSTER_SWITCH_UI),
+ .access = VehiclePropertyAccess::READ,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ },
+ },
+ {
+ .config =
+ {
+ .prop = toInt(VehicleProperty::CLUSTER_DISPLAY_STATE),
+ .access = VehiclePropertyAccess::READ,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ },
+ },
+ {
+ .config =
+ {
+ .prop = toInt(VehicleProperty::CLUSTER_REPORT_STATE),
+ .access = VehiclePropertyAccess::WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .configArray = {0, 0, 0, 9, 0, 0, 0, 0, 16},
+ },
+ },
+ {
+ .config =
+ {
+ .prop = toInt(VehicleProperty::CLUSTER_REQUEST_DISPLAY),
+ .access = VehiclePropertyAccess::WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ },
+ },
+ {
+ .config =
+ {
+ .prop = toInt(VehicleProperty::CLUSTER_NAVIGATION_STATE_LEGACY),
+ .access = VehiclePropertyAccess::WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ },
+ },
};
} // impl
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index f7e885d..ed75e1d 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -3027,6 +3027,115 @@
| VehiclePropertyGroup:SYSTEM
| VehiclePropertyType:INT64
| VehicleArea:GLOBAL),
+
+ /**
+ * Starts the ClusterUI in cluster display.
+ *
+ * int32[0]: the type of ClusterUI to show
+ * 0 indicates ClusterHome, that is a home screen of cluster display, and provides
+ * the default UI and a kind of launcher functionality for cluster display.
+ * the other values are followed by OEM's definition.
+ *
+ * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+ * @access VehiclePropertyAccess:READ
+ */
+ CLUSTER_SWITCH_UI = (
+ 0x0F34
+ | VehiclePropertyGroup:SYSTEM
+ | VehiclePropertyType:INT32
+ | VehicleArea:GLOBAL),
+
+ /**
+ * Changes the state of the cluster display.
+ *
+ * int32[0]: on/off: 0 - off, 1 - on, -1 - don't care
+ * int32[1]: width: positive number - actual width in pixels
+ -1 - don't care (should set "don't care" both width and height)
+ * int32[2]: height: ditto with width
+ * int32[3]: Inset - left: positive number - actual left inset value in pixels
+ -1 - don't care (should set "don't care" all Inset fields)
+ * int32[4]: Inset - top
+ * int32[5]: Inset - right
+ * int32[6]: Inset - bottom
+ *
+ * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+ * @access VehiclePropertyAccess:READ
+ */
+ CLUSTER_DISPLAY_STATE = (
+ 0x0F35
+ | VehiclePropertyGroup:SYSTEM
+ | VehiclePropertyType:INT32_VEC
+ | VehicleArea:GLOBAL),
+
+ /**
+ * Reports the current display state and ClusterUI state.
+ *
+ * ClusterHome will send this message when it handles CLUSTER_SWITCH_UI, CLUSTER_DISPLAY_STATE.
+ *
+ * In addition, ClusterHome should send this message when it starts for the first time.
+ * When ClusterOS receives this message and if the internal expectation is different with the
+ * received message, then it should send CLUSTER_SWITCH_UI, CLUSTER_DISPLAY_STATE again to
+ * match the state.
+ *
+ * int32[0]: on/off: 0 - off, 1 - on
+ * int32[1]: width
+ * int32[2]: height
+ * int32[3]: Inset - left
+ * int32[4]: Inset - top
+ * int32[5]: Inset - right
+ * int32[6]: Inset - bottom
+ * int32[7]: the type of ClusterUI in the fullscreen or main screen.
+ * 0 indicates ClusterHome.
+ * the other values are followed by OEM's definition.
+ * int32[8]: the type of ClusterUI in sub screen if the currently two UIs are shown.
+ * -1 indicates the area isn't used any more.
+ * bytes: the array to represent the availability of ClusterUI.
+ * 0 indicates non-available and 1 indicates available.
+ * For example, let's assume a car supports 3 UI like HOME, MAPS, CALL and it only supports
+ * CALL UI only when the cellular network is available. Then, if the nework is avaibale,
+ * it'll send [1 1 1], and if it's out of network, it'll send [1 1 0].
+ *
+ * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+ * @access VehiclePropertyAccess:WRITE
+ */
+ CLUSTER_REPORT_STATE = (
+ 0x0F36
+ | VehiclePropertyGroup:SYSTEM
+ | VehiclePropertyType:MIXED
+ | VehicleArea:GLOBAL),
+
+ /**
+ * Requests to change the cluster display state to show some ClusterUI.
+ *
+ * When the current display state is off and ClusterHome sends this message to ClusterOS to
+ * request to turn the display on to show some specific ClusterUI.
+ * ClusterOS should response this with CLUSTER_DISPLAY_STATE.
+ *
+ * int32[0]: the type of ClusterUI to show
+ *
+ * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+ * @access VehiclePropertyAccess:WRITE
+ */
+ CLUSTER_REQUEST_DISPLAY = (
+ 0x0F37
+ | VehiclePropertyGroup:SYSTEM
+ | VehiclePropertyType:INT32
+ | VehicleArea:GLOBAL),
+
+ /**
+ * Informs the current navigation state.
+ *
+ * bytes: the serialized message of NavigationStateProto.
+ *
+ * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+ * @access VehiclePropertyAccess:WRITE
+ */
+ CLUSTER_NAVIGATION_STATE_LEGACY = (
+ 0x0F38
+ | VehiclePropertyGroup:SYSTEM
+ | VehiclePropertyType:BYTES
+ | VehicleArea:GLOBAL),
+
};
/**
diff --git a/bluetooth/1.0/default/test/bluetooth_address_test.cc b/bluetooth/1.0/default/test/bluetooth_address_test.cc
index ee52d33..422d6a3 100644
--- a/bluetooth/1.0/default/test/bluetooth_address_test.cc
+++ b/bluetooth/1.0/default/test/bluetooth_address_test.cc
@@ -14,7 +14,6 @@
// limitations under the License.
//
-#include <cutils/properties.h>
#include <errno.h>
#include <fcntl.h>
#include <gtest/gtest.h>
@@ -39,12 +38,6 @@
"00:00:00:00:00:00";
constexpr uint8_t kZeros_bytes[BluetoothAddress::kBytes] = {0x00, 0x00, 0x00,
0x00, 0x00, 0x00};
-constexpr char kTestAddrBad1[BluetoothAddress::kStringLength + 1] =
- "bb:aa:dd:00:00:01";
-constexpr uint8_t kTestAddrBad1_bytes[BluetoothAddress::kBytes] = {
- 0xbb, 0xaa, 0xdd, 0x00, 0x00, 0x01};
-
-constexpr char kAddrPath[] = "/tmp/my_address_in_a_file.txt";
class BluetoothAddressTest : public ::testing::Test {
public:
@@ -120,45 +113,6 @@
EXPECT_FALSE(memcmp(addrA, addrB, BluetoothAddress::kStringLength) == 0);
}
-TEST_F(BluetoothAddressTest, get_local_address) {
- EXPECT_TRUE(property_set(PERSIST_BDADDR_PROPERTY, "") == 0);
- EXPECT_TRUE(property_set(FACTORY_BDADDR_PROPERTY, "") == 0);
- uint8_t address[BluetoothAddress::kBytes];
-
- // File contains a non-zero Address.
- FileWriteString(kAddrPath, kTestAddr1);
- EXPECT_TRUE(property_set(PROPERTY_BT_BDADDR_PATH, kAddrPath) == 0);
- EXPECT_TRUE(BluetoothAddress::get_local_address(address));
- EXPECT_TRUE(memcmp(address, kTestAddr1_bytes, BluetoothAddress::kBytes) == 0);
-
- // File contains a zero address. A random address will be generated.
- FileWriteString(kAddrPath, kZeros);
- EXPECT_TRUE(property_set(PROPERTY_BT_BDADDR_PATH, kAddrPath) == 0);
- EXPECT_TRUE(property_set(PERSIST_BDADDR_PROPERTY, kTestAddrBad1) == 0);
- EXPECT_TRUE(BluetoothAddress::get_local_address(address));
- EXPECT_TRUE(memcmp(address, kZeros_bytes, BluetoothAddress::kBytes) != 0);
- char prop[PROP_VALUE_MAX] = "Before reading";
- EXPECT_TRUE(property_get(PERSIST_BDADDR_PROPERTY, prop, NULL) ==
- BluetoothAddress::kStringLength);
- char address_str[BluetoothAddress::kStringLength + 1];
- BluetoothAddress::bytes_to_string(address, address_str);
- EXPECT_TRUE(memcmp(address_str, prop, BluetoothAddress::kStringLength) == 0);
-
- // Factory property contains an address.
- EXPECT_TRUE(property_set(PERSIST_BDADDR_PROPERTY, kTestAddrBad1) == 0);
- EXPECT_TRUE(property_set(FACTORY_BDADDR_PROPERTY, kTestAddr1) == 0);
- EXPECT_TRUE(BluetoothAddress::get_local_address(address));
- EXPECT_TRUE(memcmp(address, kTestAddr1_bytes, BluetoothAddress::kBytes) == 0);
-
- // Persistent property contains an address.
- memcpy(address, kTestAddrBad1_bytes, BluetoothAddress::kBytes);
- EXPECT_TRUE(property_set(PERSIST_BDADDR_PROPERTY, kTestAddr1) == 0);
- EXPECT_TRUE(property_set(FACTORY_BDADDR_PROPERTY, "") == 0);
- EXPECT_TRUE(property_set(PROPERTY_BT_BDADDR_PATH, "") == 0);
- EXPECT_TRUE(BluetoothAddress::get_local_address(address));
- EXPECT_TRUE(memcmp(address, kTestAddr1_bytes, BluetoothAddress::kBytes) == 0);
-}
-
} // namespace implementation
} // namespace V1_0
} // namespace bluetooth
diff --git a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
index 0328af1..76777dc 100644
--- a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
+++ b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
@@ -50,7 +50,7 @@
#define WAIT_FOR_HCI_EVENT_TIMEOUT std::chrono::milliseconds(2000)
#define WAIT_FOR_SCO_DATA_TIMEOUT std::chrono::milliseconds(1000)
#define WAIT_FOR_ACL_DATA_TIMEOUT std::chrono::milliseconds(1000)
-#define INTERFACE_CLOSE_DELAY_MS std::chrono::milliseconds(200)
+#define INTERFACE_CLOSE_DELAY_MS std::chrono::milliseconds(600)
#define COMMAND_HCI_SHOULD_BE_UNKNOWN \
{ 0xff, 0x3B, 0x08, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }
diff --git a/bluetooth/audio/2.1/default/LeAudioAudioProvider.cpp b/bluetooth/audio/2.1/default/LeAudioAudioProvider.cpp
index 1fa2dce..9c2b4fe 100644
--- a/bluetooth/audio/2.1/default/LeAudioAudioProvider.cpp
+++ b/bluetooth/audio/2.1/default/LeAudioAudioProvider.cpp
@@ -91,35 +91,30 @@
uint32_t kDataMqSize = 0;
switch (audioConfig.pcmConfig().sampleRate) {
+ case SampleRate::RATE_8000:
+ kDataMqSize = 8000;
+ break;
case SampleRate::RATE_16000:
kDataMqSize = 16000;
break;
case SampleRate::RATE_24000:
kDataMqSize = 24000;
break;
+ case SampleRate::RATE_32000:
+ kDataMqSize = 32000;
+ break;
case SampleRate::RATE_44100:
kDataMqSize = 44100;
break;
case SampleRate::RATE_48000:
kDataMqSize = 48000;
break;
- case SampleRate::RATE_88200:
- kDataMqSize = 88200;
- break;
- case SampleRate::RATE_96000:
- kDataMqSize = 96000;
- break;
- case SampleRate::RATE_176400:
- kDataMqSize = 176400;
- break;
- case SampleRate::RATE_192000:
- kDataMqSize = 192000;
- break;
default:
- /* This should never happen it would be caught while validating
- * parameters.
- */
- break;
+ LOG(WARNING) << __func__ << " - Unsupported sampling frequency="
+ << toString(audioConfig.pcmConfig());
+ _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
+ DataMQ::Descriptor());
+ return Void();
}
/* Number of samples per millisecond */
diff --git a/bluetooth/audio/2.1/default/session/BluetoothAudioSupportedCodecsDB.cpp b/bluetooth/audio/2.1/default/session/BluetoothAudioSupportedCodecsDB.cpp
index d15db49..0937f44 100644
--- a/bluetooth/audio/2.1/default/session/BluetoothAudioSupportedCodecsDB.cpp
+++ b/bluetooth/audio/2.1/default/session/BluetoothAudioSupportedCodecsDB.cpp
@@ -409,12 +409,14 @@
}
bool IsSoftwarePcmConfigurationValid_2_1(const PcmParameters& pcm_config) {
- if ((pcm_config.sampleRate != SampleRate::RATE_44100 &&
- pcm_config.sampleRate != SampleRate::RATE_48000 &&
+ if ((pcm_config.sampleRate != SampleRate::RATE_96000 &&
pcm_config.sampleRate != SampleRate::RATE_88200 &&
- pcm_config.sampleRate != SampleRate::RATE_96000 &&
+ pcm_config.sampleRate != SampleRate::RATE_48000 &&
+ pcm_config.sampleRate != SampleRate::RATE_44100 &&
+ pcm_config.sampleRate != SampleRate::RATE_32000 &&
+ pcm_config.sampleRate != SampleRate::RATE_24000 &&
pcm_config.sampleRate != SampleRate::RATE_16000 &&
- pcm_config.sampleRate != SampleRate::RATE_24000) ||
+ pcm_config.sampleRate != SampleRate::RATE_8000) ||
(pcm_config.bitsPerSample != BitsPerSample::BITS_16 &&
pcm_config.bitsPerSample != BitsPerSample::BITS_24 &&
pcm_config.bitsPerSample != BitsPerSample::BITS_32) ||
diff --git a/bluetooth/audio/2.1/vts/functional/VtsHalBluetoothAudioV2_1TargetTest.cpp b/bluetooth/audio/2.1/vts/functional/VtsHalBluetoothAudioV2_1TargetTest.cpp
index 37d1281..95903d1 100644
--- a/bluetooth/audio/2.1/vts/functional/VtsHalBluetoothAudioV2_1TargetTest.cpp
+++ b/bluetooth/audio/2.1/vts/functional/VtsHalBluetoothAudioV2_1TargetTest.cpp
@@ -1005,8 +1005,10 @@
BluetoothAudioProvidersFactoryHidlTest::TearDown();
}
- static constexpr SampleRate le_audio_output_sample_rates_[3] = {
- SampleRate::RATE_UNKNOWN, SampleRate::RATE_16000, SampleRate::RATE_24000};
+ static constexpr SampleRate le_audio_output_sample_rates_[11] = {
+ SampleRate::RATE_UNKNOWN, SampleRate::RATE_8000, SampleRate::RATE_16000,
+ SampleRate::RATE_24000, SampleRate::RATE_32000, SampleRate::RATE_44100,
+ SampleRate::RATE_48000};
static constexpr BitsPerSample le_audio_output_bits_per_samples_[3] = {
BitsPerSample::BITS_UNKNOWN, BitsPerSample::BITS_16,
BitsPerSample::BITS_24};
@@ -1097,8 +1099,10 @@
BluetoothAudioProvidersFactoryHidlTest::TearDown();
}
- static constexpr SampleRate le_audio_output_sample_rates_[3] = {
- SampleRate::RATE_UNKNOWN, SampleRate::RATE_16000, SampleRate::RATE_24000};
+ static constexpr SampleRate le_audio_output_sample_rates_[11] = {
+ SampleRate::RATE_UNKNOWN, SampleRate::RATE_8000, SampleRate::RATE_16000,
+ SampleRate::RATE_24000, SampleRate::RATE_32000, SampleRate::RATE_44100,
+ SampleRate::RATE_48000};
static constexpr BitsPerSample le_audio_output_bits_per_samples_[3] = {
BitsPerSample::BITS_UNKNOWN, BitsPerSample::BITS_16,
BitsPerSample::BITS_24};
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 7c41d1f..1c89e81 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -198,7 +198,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.drm</name>
- <version>1.3</version>
+ <version>1.3-4</version>
<interface>
<name>ICryptoFactory</name>
<regex-instance>.*</regex-instance>
@@ -485,6 +485,20 @@
<regex-instance>SIM[1-9][0-9]*</regex-instance>
</interface>
</hal>
+ <hal format="aidl" optional="true">
+ <name>android.hardware.security.secureclock</name>
+ <interface>
+ <name>ISecureClock</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="aidl" optional="true">
+ <name>android.hardware.security.sharedsecret</name>
+ <interface>
+ <name>ISharedSecret</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
<hal format="hidl" optional="true">
<name>android.hardware.sensors</name>
<version>1.0</version>
diff --git a/contexthub/1.2/types.hal b/contexthub/1.2/types.hal
index e6c8acc..5a11efe 100644
--- a/contexthub/1.2/types.hal
+++ b/contexthub/1.2/types.hal
@@ -33,6 +33,12 @@
*/
WIFI_AVAILABLE,
AIRPLANE_MODE,
+
+ /**
+ * Indicates if the microphone access was turned off globally by the user,
+ * in which case audio data cannot be used and propagated by CHRE.
+ */
+ GLOBAL_MIC_DISABLE,
};
struct ContextHubMsg {
diff --git a/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp b/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp
index 77883c2..782edae 100644
--- a/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp
+++ b/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp
@@ -62,6 +62,13 @@
ASSERT_OK(registerCallback(nullptr));
}
+TEST_P(ContexthubHidlTest, TestOnGlobalMicDisableSettingChanged) {
+ ASSERT_OK(registerCallback(new ContexthubCallbackBase()));
+ hubApi->onSettingChanged_1_2(Setting::GLOBAL_MIC_DISABLE, SettingValue::DISABLED);
+ hubApi->onSettingChanged_1_2(Setting::GLOBAL_MIC_DISABLE, SettingValue::ENABLED);
+ ASSERT_OK(registerCallback(nullptr));
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ContexthubHidlTest);
INSTANTIATE_TEST_SUITE_P(HubIdSpecificTests, ContexthubHidlTest, testing::ValuesIn(kTestParameters),
android::hardware::PrintInstanceTupleNameToString<>);
diff --git a/drm/1.4/Android.bp b/drm/1.4/Android.bp
new file mode 100644
index 0000000..8e1dc93
--- /dev/null
+++ b/drm/1.4/Android.bp
@@ -0,0 +1,20 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.drm@1.4",
+ root: "android.hardware",
+ srcs: [
+ "ICryptoFactory.hal",
+ "ICryptoPlugin.hal",
+ "IDrmFactory.hal",
+ "IDrmPlugin.hal",
+ ],
+ interfaces: [
+ "android.hardware.drm@1.0",
+ "android.hardware.drm@1.1",
+ "android.hardware.drm@1.2",
+ "android.hardware.drm@1.3",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: false,
+}
diff --git a/drm/1.4/ICryptoFactory.hal b/drm/1.4/ICryptoFactory.hal
new file mode 100644
index 0000000..6cbf9e3
--- /dev/null
+++ b/drm/1.4/ICryptoFactory.hal
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.drm@1.4;
+
+import @1.3::ICryptoFactory;
+
+/**
+ * ICryptoFactory is the main entry point for interacting with a vendor's
+ * crypto HAL to create crypto plugins. Crypto plugins create crypto sessions
+ * which are used by a codec to decrypt protected video content.
+ *
+ * The 1.4 factory must always create 1.4 ICryptoPlugin interfaces, which are
+ * returned via the 1.0 createPlugin method.
+ *
+ * To use 1.4 features the caller must cast the returned interface to a
+ * 1.4 HAL, using V1_4::ICryptoPlugin::castFrom().
+ */
+interface ICryptoFactory extends @1.3::ICryptoFactory {
+};
diff --git a/drm/1.4/ICryptoPlugin.hal b/drm/1.4/ICryptoPlugin.hal
new file mode 100644
index 0000000..874ef4c
--- /dev/null
+++ b/drm/1.4/ICryptoPlugin.hal
@@ -0,0 +1,26 @@
+/**
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.drm@1.4;
+
+import @1.2::ICryptoPlugin;
+
+/**
+ * ICryptoPlugin is the HAL for vendor-provided crypto plugins.
+ * It allows crypto sessions to be opened and operated on, to
+ * load crypto keys for a codec to decrypt protected video content.
+ */
+interface ICryptoPlugin extends @1.2::ICryptoPlugin {
+};
diff --git a/drm/1.4/IDrmFactory.hal b/drm/1.4/IDrmFactory.hal
new file mode 100644
index 0000000..035a298
--- /dev/null
+++ b/drm/1.4/IDrmFactory.hal
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.drm@1.4;
+
+import @1.3::IDrmFactory;
+
+/**
+ * IDrmFactory is the main entry point for interacting with a vendor's
+ * drm HAL to create drm plugin instances. A drm plugin instance
+ * creates drm sessions which are used to obtain keys for a crypto
+ * session so it can decrypt protected video content.
+ *
+ * The 1.4 factory must always create 1.4 IDrmPlugin interfaces, which are
+ * returned via the 1.0 createPlugin method.
+ *
+ * To use 1.4 features the caller must cast the returned interface to a
+ * 1.4 HAL, using V1_4::IDrmPlugin::castFrom().
+ */
+
+interface IDrmFactory extends @1.3::IDrmFactory {
+};
diff --git a/drm/1.4/IDrmPlugin.hal b/drm/1.4/IDrmPlugin.hal
new file mode 100644
index 0000000..9cc0600
--- /dev/null
+++ b/drm/1.4/IDrmPlugin.hal
@@ -0,0 +1,50 @@
+/**
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.drm@1.4;
+
+import @1.1::SecurityLevel;
+import @1.2::IDrmPlugin;
+
+/**
+ * IDrmPlugin is used to interact with a specific drm plugin that was
+ * created by IDrmFactory::createPlugin. A drm plugin provides methods for
+ * obtaining drm keys to be used by a codec to decrypt protected video
+ * content.
+ */
+interface IDrmPlugin extends @1.2::IDrmPlugin {
+
+ /**
+ * Check if the specified mime-type & security level require a secure decoder
+ * component.
+ *
+ * @param mime The content mime-type
+ * @param level the requested security level
+ * @return secureRequired must be true if and only if a secure decoder is required
+ * for the specified mime-type & security level
+ */
+ requiresSecureDecoder(string mime, @1.1::SecurityLevel level) generates (bool secureRequired);
+
+ /**
+ * Check if the specified mime-type requires a secure decoder component
+ * at the highest security level supported on the device.
+ *
+ * @param mime The content mime-type
+ * @return secureRequired must be true if and only if a secure decoder is required
+ * for the specified mime-type
+ */
+ requiresSecureDecoderDefault(string mime) generates (bool secureRequired);
+
+};
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl
index 89f5d53..0302676 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl
new file mode 100644
index 0000000..1f713fa
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl
@@ -0,0 +1,26 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@VintfStability
+parcelable CorrelationVector {
+ int frequencyOffsetMps;
+ double samplingWidthM;
+ double samplingStartM;
+ int[] magnitude;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl
index a0e8de4..933f659 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl
index 42b940e..53ac0ef 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl
index 30d0227..18fdfa9 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl
index 7ffabd2..73ead10 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl
index 73d8a86..3d287e4 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
@@ -42,6 +43,8 @@
double fullInterSignalBiasUncertaintyNs;
double satelliteInterSignalBiasNs;
double satelliteInterSignalBiasUncertaintyNs;
+ android.hardware.gnss.SatellitePvt satellitePvt;
+ android.hardware.gnss.CorrelationVector[] correlationVectors;
const int HAS_SNR = 1;
const int HAS_CARRIER_FREQUENCY = 512;
const int HAS_CARRIER_CYCLES = 1024;
@@ -52,6 +55,8 @@
const int HAS_FULL_ISB_UNCERTAINTY = 131072;
const int HAS_SATELLITE_ISB = 262144;
const int HAS_SATELLITE_ISB_UNCERTAINTY = 524288;
+ const int HAS_SATELLITE_PVT = 1048576;
+ const int HAS_CORRELATION_VECTOR = 2097152;
const int STATE_UNKNOWN = 0;
const int STATE_CODE_LOCK = 1;
const int STATE_BIT_SYNC = 2;
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl
index 75ca3af..5da60f7 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl
index d385fd4..358b570 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl
index f10b943..b2a498d 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
index 10ac150..bd6f1ff 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
index 62870d6..a0c4255 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
@@ -19,5 +20,7 @@
@VintfStability
interface IGnssCallback {
void gnssSetCapabilitiesCb(in int capabilities);
- const int CAPABILITY_SATELLITE_BLOCKLIST = 1;
+ const int CAPABILITY_SATELLITE_BLOCKLIST = 512;
+ const int CAPABILITY_CORRELATION_VECTOR = 4096;
+ const int CAPABILITY_SATELLITE_PVT = 8192;
}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl
index 5af30cf..eb4ad82 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl
index e05e9b9..764b896 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl
index 9576205..7cb7395 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
@@ -18,6 +19,6 @@
package android.hardware.gnss;
@VintfStability
interface IGnssMeasurementInterface {
- void setCallback(in android.hardware.gnss.IGnssMeasurementCallback callback, in boolean enableFullTracking);
+ void setCallback(in android.hardware.gnss.IGnssMeasurementCallback callback, in boolean enableFullTracking, in boolean enableCorrVecOutputs);
void close();
}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl
index 843489e..c44903e 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl
index 5281d29..12e6762 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl
index ddef928..cae2ea6 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl
index 8413d2c..6888632 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl
index 9d1984e..d348c63 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteClockInfo.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteClockInfo.aidl
new file mode 100644
index 0000000..bdba667
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteClockInfo.aidl
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@VintfStability
+parcelable SatelliteClockInfo {
+ double satHardwareCodeBiasMeters;
+ double satTimeCorrectionMeters;
+ double satClkDriftMps;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePositionEcef.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePositionEcef.aidl
new file mode 100644
index 0000000..550fa4d
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePositionEcef.aidl
@@ -0,0 +1,26 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@VintfStability
+parcelable SatellitePositionEcef {
+ double posXMeters;
+ double posYMeters;
+ double posZMeters;
+ double ureMeters;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl
new file mode 100644
index 0000000..4ff025e
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl
@@ -0,0 +1,27 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@VintfStability
+parcelable SatellitePvt {
+ android.hardware.gnss.SatellitePositionEcef satPosEcef;
+ android.hardware.gnss.SatelliteVelocityEcef satVelEcef;
+ android.hardware.gnss.SatelliteClockInfo satClockInfo;
+ double ionoDelayMeters;
+ double tropoDelayMeters;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteVelocityEcef.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteVelocityEcef.aidl
new file mode 100644
index 0000000..7db7ee6
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteVelocityEcef.aidl
@@ -0,0 +1,26 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@VintfStability
+parcelable SatelliteVelocityEcef {
+ double velXMps;
+ double velYMps;
+ double velZMps;
+ double ureRateMps;
+}
diff --git a/gnss/aidl/android/hardware/gnss/CorrelationVector.aidl b/gnss/aidl/android/hardware/gnss/CorrelationVector.aidl
new file mode 100644
index 0000000..22a80ce
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/CorrelationVector.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss;
+
+/**
+ * Contains info about the correlation output of incoming GNSS signal and a local copy of
+ * its corresponding spreading code at a given frequency offset.
+ */
+@VintfStability
+parcelable CorrelationVector {
+
+ /**
+ * Frequency offset from reported pseudorange rate for this Correlation Vector.
+ */
+ int frequencyOffsetMps;
+
+ /**
+ * Space between correlation samples in meters.
+ */
+ double samplingWidthM;
+
+ /**
+ * Offset of the first sampling bin in meters.
+ * The following sampling bins are located at positive offsets from this value as follows:
+ * samplingStartM, samplingStartM + samplingWidthM, ... , samplingStartM +
+ * (magnitude.size-1) * samplingWidthM.
+ */
+ double samplingStartM;
+
+ /**
+ * Normalized correlation magnitude values from -1 to 1, the reported value must be encoded as
+ * signed 16 bit integer where 1 is represented by 32767 and -1 is represented by -32768.
+ *
+ * The length of the array is defined by the GNSS chipset.
+ */
+ int[] magnitude;
+}
\ No newline at end of file
diff --git a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl
index ce88647..2c56a41 100644
--- a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl
+++ b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl
@@ -16,8 +16,10 @@
package android.hardware.gnss;
+import android.hardware.gnss.CorrelationVector;
import android.hardware.gnss.GnssSignalType;
import android.hardware.gnss.GnssMultipathIndicator;
+import android.hardware.gnss.SatellitePvt;
/**
* Represents a GNSS Measurement, it contains raw and computed information.
@@ -57,6 +59,14 @@
* GnssMeasurement.
*/
const int HAS_SATELLITE_ISB_UNCERTAINTY = 1 << 19;
+ /**
+ * Bit mask indicating a valid satellite PVT is stored in the GnssMeasurement.
+ */
+ const int HAS_SATELLITE_PVT = 1 << 20;
+ /**
+ * Bit mask indicating valid correlation vectors are stored in the GnssMeasurement.
+ */
+ const int HAS_CORRELATION_VECTOR = 1 << 21;
/**
* A bitfield of flags indicating the validity of the fields in this GnssMeasurement. The bit
@@ -612,4 +622,21 @@
* 1-sigma uncertainty associated with the satellite inter-signal bias in nanoseconds.
*/
double satelliteInterSignalBiasUncertaintyNs;
+
+ /**
+ * The GNSS satellite position, velocity and time information at the signal transmission time
+ * receivedSvTimeInNs.
+ *
+ * If the data is available, gnssMeasurementFlags must contain HAS_SATELLITE_PVT.
+ */
+ SatellitePvt satellitePvt;
+
+ /**
+ * A list of Correlation Vectors with each vector corresponding to a frequency offset.
+ *
+ * To represent correlation values over a 2D spaces (delay and frequency), a CorrelationVector
+ * is required per frequency offset, and each CorrelationVector contains correlation values
+ * at equally spaced spatial offsets.
+ */
+ CorrelationVector[] correlationVectors;
}
\ No newline at end of file
diff --git a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
index a46a018..8881ea7 100644
--- a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
@@ -27,8 +27,14 @@
@VintfStability
interface IGnssCallback {
- /** Capability bit mask indicating GNSS supports blocklisting satellites */
- const int CAPABILITY_SATELLITE_BLOCKLIST = 1 << 0;
+ /** Capability bit mask indicating that GNSS supports blocklisting satellites */
+ const int CAPABILITY_SATELLITE_BLOCKLIST = 1 << 9;
+
+ /** Capability bit mask indicating that GNSS supports correlation vector */
+ const int CAPABILITY_CORRELATION_VECTOR = 1 << 12;
+
+ /** Capability bit mask indicating that GNSS supports satellite PVT */
+ const int CAPABILITY_SATELLITE_PVT = 1 << 13;
/**
* Callback to inform framework of the GNSS HAL implementation's capabilities.
@@ -36,4 +42,4 @@
* @param capabilities Capability parameter is a bit field of the Capability bit masks.
*/
void gnssSetCapabilitiesCb(in int capabilities);
-}
\ No newline at end of file
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl b/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl
index fdeebde..04cdf64 100644
--- a/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl
@@ -37,12 +37,16 @@
* The GNSS chipset is allowed to consume more power in this mode. If false, API must
* optimize power via duty cycling, constellations and frequency limits, etc.
*
+ * @param enableCorrVecOutputs If true, enable correlation vectors as part of the raw GNSS
+ * measurements outputs. If false, disable correlation vectors.
+ *
* @return initRet Returns SUCCESS if successful. Returns ERROR_ALREADY_INIT if a callback has
* already been registered without a corresponding call to 'close'. Returns ERROR_GENERIC
* for any other error. The HAL must not generate any other updates upon returning this
* error code.
*/
- void setCallback(in IGnssMeasurementCallback callback, in boolean enableFullTracking);
+ void setCallback(in IGnssMeasurementCallback callback, in boolean enableFullTracking,
+ in boolean enableCorrVecOutputs);
/**
* Stops updates from the HAL, and unregisters the callback routines. After a call to close(),
diff --git a/gnss/aidl/android/hardware/gnss/SatelliteClockInfo.aidl b/gnss/aidl/android/hardware/gnss/SatelliteClockInfo.aidl
new file mode 100644
index 0000000..844fd1c
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/SatelliteClockInfo.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss;
+
+/**
+ * Contains estimates of the satellite clock info.
+ */
+@VintfStability
+parcelable SatelliteClockInfo {
+ /**
+ * Satellite hardware code bias of the reported code type w.r.t
+ * ionosphere-free measurement in meters.
+ */
+ double satHardwareCodeBiasMeters;
+
+ /**
+ * Satellite time correction for ionospheric-free signal measurement
+ * (meters). The satellite clock correction for the given signal type
+ * = satTimeCorrectionMeters - satHardwareCodeBiasMeters.
+ */
+ double satTimeCorrectionMeters;
+
+ /** Satellite clock drift (meters per second). */
+ double satClkDriftMps;
+}
\ No newline at end of file
diff --git a/gnss/aidl/android/hardware/gnss/SatellitePositionEcef.aidl b/gnss/aidl/android/hardware/gnss/SatellitePositionEcef.aidl
new file mode 100644
index 0000000..4b3615e
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/SatellitePositionEcef.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss;
+
+/**
+ * Contains estimates of the satellite position fields in ECEF coordinate frame.
+ */
+@VintfStability
+parcelable SatellitePositionEcef {
+ /** Satellite position X in WGS84 ECEF (meters). */
+ double posXMeters;
+
+ /** Satellite position Y in WGS84 ECEF (meters). */
+ double posYMeters;
+
+ /** Satellite position Z in WGS84 ECEF (meters). */
+ double posZMeters;
+
+ /**
+ * The Signal in Space User Range Error (URE) (meters).
+ *
+ * It covers satellite position and clock errors projected to the pseudorange measurements.
+ */
+ double ureMeters;
+}
\ No newline at end of file
diff --git a/gnss/aidl/android/hardware/gnss/SatellitePvt.aidl b/gnss/aidl/android/hardware/gnss/SatellitePvt.aidl
new file mode 100644
index 0000000..ea55f0c
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/SatellitePvt.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss;
+
+import android.hardware.gnss.SatellitePositionEcef;
+import android.hardware.gnss.SatelliteVelocityEcef;
+import android.hardware.gnss.SatelliteClockInfo;
+
+/**
+ * Contains estimates of the satellite position, velocity and time in the
+ * ECEF coordinate frame.
+ */
+@VintfStability
+parcelable SatellitePvt {
+ /**
+ * Satellite position in WGS84 ECEF. See comments of
+ * SatellitePositionEcef for units.
+ */
+ SatellitePositionEcef satPosEcef;
+
+ /**
+ * Satellite velocity in WGS84 ECEF. See comments of
+ * SatelliteVelocityEcef for units.
+ */
+ SatelliteVelocityEcef satVelEcef;
+
+ /** Satellite clock bias and drift info. */
+ SatelliteClockInfo satClockInfo;
+
+ /** Ionospheric delay in meters. */
+ double ionoDelayMeters;
+
+ /** Tropospheric delay in meters. */
+ double tropoDelayMeters;
+}
\ No newline at end of file
diff --git a/gnss/aidl/android/hardware/gnss/SatelliteVelocityEcef.aidl b/gnss/aidl/android/hardware/gnss/SatelliteVelocityEcef.aidl
new file mode 100644
index 0000000..25ece3a
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/SatelliteVelocityEcef.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss;
+
+/**
+ * Contains estimates of the satellite velocity fields in the ECEF coordinate frame.
+ */
+@VintfStability
+parcelable SatelliteVelocityEcef {
+ /** Satellite velocity X in WGS84 ECEF (meters per second). */
+ double velXMps;
+
+ /** Satellite velocity Y in WGS84 ECEF (meters per second). */
+ double velYMps;
+
+ /** Satellite velocity Z in WGS84 ECEF (meters per second). */
+ double velZMps;
+
+ /**
+ * The Signal in Space User Range Error Rate (URE Rate) (meters per second).
+ *
+ * It covers satellite velocity error and Satellite clock drift
+ * projected to the pseudorange rate measurements.
+ */
+ double ureRateMps;
+}
\ No newline at end of file
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index 02bad60..435afa3 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -36,7 +36,10 @@
sGnssCallback = callback;
- int capabilities = (int)IGnssCallback::CAPABILITY_SATELLITE_BLOCKLIST;
+ int capabilities = (int)(IGnssCallback::CAPABILITY_SATELLITE_BLOCKLIST |
+ IGnssCallback::CAPABILITY_SATELLITE_PVT |
+ IGnssCallback::CAPABILITY_CORRELATION_VECTOR);
+
auto status = sGnssCallback->gnssSetCapabilitiesCb(capabilities);
if (!status.isOk()) {
ALOGE("%s: Unable to invoke callback.gnssSetCapabilities", __func__);
diff --git a/gnss/aidl/default/GnssMeasurementInterface.cpp b/gnss/aidl/default/GnssMeasurementInterface.cpp
index d726d95..cae9499 100644
--- a/gnss/aidl/default/GnssMeasurementInterface.cpp
+++ b/gnss/aidl/default/GnssMeasurementInterface.cpp
@@ -34,8 +34,10 @@
}
ndk::ScopedAStatus GnssMeasurementInterface::setCallback(
- const std::shared_ptr<IGnssMeasurementCallback>& callback, const bool enableFullTracking) {
- ALOGD("setCallback: enableFullTracking: %d", (int)enableFullTracking);
+ const std::shared_ptr<IGnssMeasurementCallback>& callback, const bool enableFullTracking,
+ const bool enableCorrVecOutputs) {
+ ALOGD("setCallback: enableFullTracking: %d enableCorrVecOutputs: %d", (int)enableFullTracking,
+ (int)enableCorrVecOutputs);
std::unique_lock<std::mutex> lock(mMutex);
sCallback = callback;
@@ -43,7 +45,7 @@
ALOGW("GnssMeasurement callback already set. Resetting the callback...");
stop();
}
- start();
+ start(enableCorrVecOutputs);
return ndk::ScopedAStatus::ok();
}
@@ -56,12 +58,12 @@
return ndk::ScopedAStatus::ok();
}
-void GnssMeasurementInterface::start() {
+void GnssMeasurementInterface::start(const bool enableCorrVecOutputs) {
ALOGD("start");
mIsActive = true;
- mThread = std::thread([this]() {
+ mThread = std::thread([this, enableCorrVecOutputs]() {
while (mIsActive == true) {
- auto measurement = Utils::getMockMeasurement();
+ auto measurement = Utils::getMockMeasurement(enableCorrVecOutputs);
this->reportMeasurement(measurement);
std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis));
diff --git a/gnss/aidl/default/GnssMeasurementInterface.h b/gnss/aidl/default/GnssMeasurementInterface.h
index 69cd871..db63515 100644
--- a/gnss/aidl/default/GnssMeasurementInterface.h
+++ b/gnss/aidl/default/GnssMeasurementInterface.h
@@ -29,11 +29,12 @@
GnssMeasurementInterface();
~GnssMeasurementInterface();
ndk::ScopedAStatus setCallback(const std::shared_ptr<IGnssMeasurementCallback>& callback,
- const bool enableFullTracking) override;
+ const bool enableFullTracking,
+ const bool enableCorrVecOutputs) override;
ndk::ScopedAStatus close() override;
private:
- void start();
+ void start(const bool enableCorrVecOutputs);
void stop();
void reportMeasurement(const GnssData&);
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index 857c742..ae0551d 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -69,14 +69,21 @@
* 2. Sets a GnssMeasurementCallback, waits for a measurement, and verifies fields are valid.
*/
TEST_P(GnssHalTest, TestGnssMeasurementExtension) {
+ const bool kIsCorrelationVectorSupported = aidl_gnss_cb_->last_capabilities_ &
+ (int)GnssCallbackAidl::CAPABILITY_CORRELATION_VECTOR;
const int kFirstGnssMeasurementTimeoutSeconds = 10;
+
+ bool has_capability_satpvt = false;
+
sp<IGnssMeasurementInterface> iGnssMeasurement;
auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
ASSERT_TRUE(status.isOk());
ASSERT_TRUE(iGnssMeasurement != nullptr);
auto callback = sp<GnssMeasurementCallbackAidl>::make();
- status = iGnssMeasurement->setCallback(callback, /* enableFullTracking= */ true);
+ status =
+ iGnssMeasurement->setCallback(callback, /* enableFullTracking= */ true,
+ /* enableCorrVecOutputs */ kIsCorrelationVectorSupported);
ASSERT_TRUE(status.isOk());
android::hardware::gnss::GnssData lastMeasurement;
@@ -102,6 +109,10 @@
GnssClock::HAS_FULL_BIAS | GnssClock::HAS_BIAS |
GnssClock::HAS_BIAS_UNCERTAINTY | GnssClock::HAS_DRIFT |
GnssClock::HAS_DRIFT_UNCERTAINTY));
+
+ if (aidl_gnss_cb_->last_capabilities_ & (int)GnssCallbackAidl::CAPABILITY_SATELLITE_PVT) {
+ has_capability_satpvt = true;
+ }
for (const auto& measurement : lastMeasurement.measurements) {
ASSERT_TRUE(
measurement.flags >= 0 &&
@@ -112,7 +123,41 @@
GnssMeasurement::HAS_AUTOMATIC_GAIN_CONTROL |
GnssMeasurement::HAS_FULL_ISB | GnssMeasurement::HAS_FULL_ISB_UNCERTAINTY |
GnssMeasurement::HAS_SATELLITE_ISB |
- GnssMeasurement::HAS_SATELLITE_ISB_UNCERTAINTY));
+ GnssMeasurement::HAS_SATELLITE_ISB_UNCERTAINTY |
+ GnssMeasurement::HAS_SATELLITE_PVT |
+ GnssMeasurement::HAS_CORRELATION_VECTOR));
+
+ if ((measurement.flags & GnssMeasurement::HAS_SATELLITE_PVT) &&
+ (has_capability_satpvt == true)) {
+ ASSERT_TRUE(measurement.satellitePvt.satPosEcef.posXMeters >= -43000000 &&
+ measurement.satellitePvt.satPosEcef.posXMeters <= 43000000);
+ ASSERT_TRUE(measurement.satellitePvt.satPosEcef.posYMeters >= -43000000 &&
+ measurement.satellitePvt.satPosEcef.posYMeters <= 43000000);
+ ASSERT_TRUE(measurement.satellitePvt.satPosEcef.posZMeters >= -43000000 &&
+ measurement.satellitePvt.satPosEcef.posZMeters <= 43000000);
+ ASSERT_TRUE(measurement.satellitePvt.satPosEcef.ureMeters > 0);
+ ASSERT_TRUE(measurement.satellitePvt.satVelEcef.velXMps >= -4000 &&
+ measurement.satellitePvt.satVelEcef.velXMps <= 4000);
+ ASSERT_TRUE(measurement.satellitePvt.satVelEcef.velYMps >= -4000 &&
+ measurement.satellitePvt.satVelEcef.velYMps <= 4000);
+ ASSERT_TRUE(measurement.satellitePvt.satVelEcef.velZMps >= -4000 &&
+ measurement.satellitePvt.satVelEcef.velZMps <= 4000);
+ ASSERT_TRUE(measurement.satellitePvt.satVelEcef.ureRateMps > 0);
+ }
+
+ if (kIsCorrelationVectorSupported &&
+ measurement.flags & GnssMeasurement::HAS_CORRELATION_VECTOR) {
+ ASSERT_TRUE(measurement.correlationVectors.size() > 0);
+ for (const auto& correlationVector : measurement.correlationVectors) {
+ ASSERT_GE(correlationVector.frequencyOffsetMps, 0);
+ ASSERT_GT(correlationVector.samplingWidthM, 0);
+ ASSERT_GE(correlationVector.samplingStartM, 0);
+ ASSERT_TRUE(correlationVector.magnitude.size() > 0);
+ for (const auto& magnitude : correlationVector.magnitude) {
+ ASSERT_TRUE(magnitude >= -32768 && magnitude <= 32767);
+ }
+ }
+ }
}
status = iGnssMeasurement->close();
diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp
index 21282f4..ccc7145 100644
--- a/gnss/common/utils/default/Utils.cpp
+++ b/gnss/common/utils/default/Utils.cpp
@@ -140,7 +140,7 @@
return gnssData;
}
-GnssData Utils::getMockMeasurement() {
+GnssData Utils::getMockMeasurement(const bool enableCorrVecOutputs) {
aidl::android::hardware::gnss::GnssSignalType signalType = {
.constellation = aidl::android::hardware::gnss::GnssConstellationType::GLONASS,
.carrierFrequencyHz = 1.59975e+09,
@@ -152,10 +152,10 @@
GnssMeasurement::HAS_CARRIER_PHASE_UNCERTAINTY |
GnssMeasurement::HAS_FULL_ISB | GnssMeasurement::HAS_FULL_ISB_UNCERTAINTY |
GnssMeasurement::HAS_SATELLITE_ISB |
- GnssMeasurement::HAS_SATELLITE_ISB_UNCERTAINTY,
+ GnssMeasurement::HAS_SATELLITE_ISB_UNCERTAINTY |
+ GnssMeasurement::HAS_SATELLITE_PVT,
.svid = 13,
.signalType = signalType,
- .timeOffsetNs = 0.0,
.receivedSvTimeInNs = 8195997131077,
.receivedSvTimeUncertaintyInNs = 15,
.antennaCN0DbHz = 30.0,
@@ -175,7 +175,20 @@
.fullInterSignalBiasUncertaintyNs = 792.0,
.satelliteInterSignalBiasNs = 233.9,
.satelliteInterSignalBiasUncertaintyNs = 921.2,
- };
+ .satellitePvt = {.satPosEcef = {.posXMeters = 10442993.1153328,
+ .posYMeters = -19926932.8051666,
+ .posZMeters = -12034295.0216203,
+ .ureMeters = 1000.2345678},
+ .satVelEcef = {.velXMps = -478.667183715732,
+ .velYMps = 1580.68371984114,
+ .velZMps = -3030.52994449997,
+ .ureRateMps = 10.2345678},
+ .satClockInfo = {.satHardwareCodeBiasMeters = 1.396983861923e-09,
+ .satTimeCorrectionMeters = -7113.08964331,
+ .satClkDriftMps = 0},
+ .ionoDelayMeters = 3.069949602639317e-08,
+ .tropoDelayMeters = 3.882265204404031},
+ .correlationVectors = {}};
GnssClock clock = {.gnssClockFlags = GnssClock::HAS_FULL_BIAS | GnssClock::HAS_FULL_BIAS |
GnssClock::HAS_BIAS_UNCERTAINTY | GnssClock::HAS_DRIFT |
@@ -196,6 +209,21 @@
// or don't set the field.
.timeUncertaintyNs = 1020400};
+ if (enableCorrVecOutputs) {
+ aidl::android::hardware::gnss::CorrelationVector correlationVector1 = {
+ .frequencyOffsetMps = 10,
+ .samplingWidthM = 30,
+ .samplingStartM = 0,
+ .magnitude = {0, 5000, 10000, 5000, 0, 0, 3000, 0}};
+ aidl::android::hardware::gnss::CorrelationVector correlationVector2 = {
+ .frequencyOffsetMps = 20,
+ .samplingWidthM = 30,
+ .samplingStartM = 0,
+ .magnitude = {0, 3000, 5000, 3000, 0, 0, 1000, 0}};
+ measurement.correlationVectors = {correlationVector1, correlationVector2};
+ measurement.flags |= GnssMeasurement::HAS_CORRELATION_VECTOR;
+ }
+
GnssData gnssData = {
.measurements = {measurement}, .clock = clock, .elapsedRealtime = timestamp};
return gnssData;
diff --git a/gnss/common/utils/default/include/Utils.h b/gnss/common/utils/default/include/Utils.h
index 0ca1b00..771d39d 100644
--- a/gnss/common/utils/default/include/Utils.h
+++ b/gnss/common/utils/default/include/Utils.h
@@ -30,7 +30,8 @@
namespace common {
struct Utils {
- static aidl::android::hardware::gnss::GnssData getMockMeasurement();
+ static aidl::android::hardware::gnss::GnssData getMockMeasurement(
+ const bool enableCorrVecOutputs);
static V2_0::IGnssMeasurementCallback::GnssData getMockMeasurementV2_0();
static V2_1::IGnssMeasurementCallback::GnssData getMockMeasurementV2_1();
static V2_0::GnssLocation getMockLocationV2_0();
diff --git a/health/1.0/default/Android.bp b/health/1.0/default/Android.bp
index aab9cc7..ff4b875 100644
--- a/health/1.0/default/Android.bp
+++ b/health/1.0/default/Android.bp
@@ -17,62 +17,3 @@
],
}
-
-cc_library_static {
- name: "android.hardware.health@1.0-impl-helper",
- vendor: true,
- srcs: ["Health.cpp"],
-
- header_libs: [
- "libbase_headers",
- "libhealthd_headers",
- ],
-
- shared_libs: [
- "libcutils",
- "libhidlbase",
- "liblog",
- "libutils",
- "android.hardware.health@1.0",
- ],
-
- static_libs: [
- "android.hardware.health@1.0-convert",
- ],
-}
-
-cc_library_shared {
- name: "android.hardware.health@1.0-impl",
- vendor: true,
- relative_install_path: "hw",
-
- static_libs: [
- "android.hardware.health@1.0-impl-helper",
- "android.hardware.health@1.0-convert",
- "libhealthd.default",
- ],
-
- shared_libs: [
- "libhidlbase",
- "libutils",
- "android.hardware.health@1.0",
- ],
-}
-
-cc_binary {
- name: "android.hardware.health@1.0-service",
- vendor: true,
- relative_install_path: "hw",
- init_rc: ["android.hardware.health@1.0-service.rc"],
- srcs: ["HealthService.cpp"],
-
- shared_libs: [
- "liblog",
- "libcutils",
- "libdl",
- "libbase",
- "libutils",
- "libhidlbase",
- "android.hardware.health@1.0",
- ],
-}
diff --git a/health/1.0/default/Health.cpp b/health/1.0/default/Health.cpp
deleted file mode 100644
index 1a02956..0000000
--- a/health/1.0/default/Health.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "health-hal"
-
-#include <Health.h>
-#include <include/hal_conversion.h>
-
-namespace android {
-namespace hardware {
-namespace health {
-namespace V1_0 {
-namespace implementation {
-
-using ::android::hardware::health::V1_0::hal_conversion::convertToHealthConfig;
-using ::android::hardware::health::V1_0::hal_conversion::convertFromHealthConfig;
-using ::android::hardware::health::V1_0::hal_conversion::convertToHealthInfo;
-using ::android::hardware::health::V1_0::hal_conversion::convertFromHealthInfo;
-
-// Methods from ::android::hardware::health::V1_0::IHealth follow.
-Return<void> Health::init(const HealthConfig& config, init_cb _hidl_cb) {
- struct healthd_config healthd_config = {};
- HealthConfig configOut;
-
- // To keep working with existing healthd static HALs,
- // convert the new HealthConfig to the old healthd_config
- // and back.
-
- convertFromHealthConfig(config, &healthd_config);
- healthd_board_init(&healthd_config);
- mGetEnergyCounter = healthd_config.energyCounter;
- convertToHealthConfig(&healthd_config, configOut);
-
- _hidl_cb(configOut);
-
- return Void();
-}
-
-Return<void> Health::update(const HealthInfo& info, update_cb _hidl_cb) {
- struct android::BatteryProperties p = {};
- HealthInfo infoOut;
-
- // To keep working with existing healthd static HALs,
- // convert the new HealthInfo to android::Batteryproperties
- // and back.
-
- convertFromHealthInfo(info, &p);
- int skipLogging = healthd_board_battery_update(&p);
- convertToHealthInfo(&p, infoOut);
-
- _hidl_cb(!!skipLogging, infoOut);
-
- return Void();
-}
-
-Return<void> Health::energyCounter(energyCounter_cb _hidl_cb) {
- int64_t energy = 0;
- Result result = Result::NOT_SUPPORTED;
-
- if (mGetEnergyCounter) {
- int status = mGetEnergyCounter(&energy);
- if (status == 0) {
- result = Result::SUCCESS;
- }
- }
-
- _hidl_cb(result, energy);
-
- return Void();
-}
-
-IHealth* HIDL_FETCH_IHealth(const char* /* name */) {
- return new Health();
-}
-
-} // namespace implementation
-} // namespace V1_0
-} // namespace health
-} // namespace hardware
-} // namespace android
diff --git a/health/1.0/default/Health.h b/health/1.0/default/Health.h
deleted file mode 100644
index ed364c1..0000000
--- a/health/1.0/default/Health.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef ANDROID_HARDWARE_HEALTH_V1_0_HEALTH_H
-#define ANDROID_HARDWARE_HEALTH_V1_0_HEALTH_H
-
-#include <android/hardware/health/1.0/IHealth.h>
-#include <hidl/Status.h>
-#include <hidl/MQDescriptor.h>
-#include <healthd/healthd.h>
-#include <utils/String8.h>
-
-namespace android {
-namespace hardware {
-namespace health {
-namespace V1_0 {
-namespace implementation {
-
-using ::android::hardware::health::V1_0::HealthInfo;
-using ::android::hardware::health::V1_0::HealthConfig;
-using ::android::hardware::health::V1_0::IHealth;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::hidl_string;
-using ::android::sp;
-
-struct Health : public IHealth {
- // Methods from ::android::hardware::health::V1_0::IHealth follow.
- Return<void> init(const HealthConfig& config, init_cb _hidl_cb) override;
- Return<void> update(const HealthInfo& info, update_cb _hidl_cb) override;
- Return<void> energyCounter(energyCounter_cb _hidl_cb) override;
-private:
- std::function<int(int64_t *)> mGetEnergyCounter;
-};
-
-extern "C" IHealth* HIDL_FETCH_IHealth(const char* name);
-
-} // namespace implementation
-} // namespace V1_0
-} // namespace health
-} // namespace hardware
-} // namespace android
-
-#endif // ANDROID_HARDWARE_HEALTH_V1_0_HEALTH_H
diff --git a/health/1.0/default/HealthService.cpp b/health/1.0/default/HealthService.cpp
deleted file mode 100644
index 55848d2..0000000
--- a/health/1.0/default/HealthService.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "android.hardware.health@1.0-service"
-
-#include <android/hardware/health/1.0/IHealth.h>
-#include <hidl/LegacySupport.h>
-
-using android::hardware::health::V1_0::IHealth;
-using android::hardware::defaultPassthroughServiceImplementation;
-
-int main() {
- return defaultPassthroughServiceImplementation<IHealth>();
-}
diff --git a/health/1.0/default/README.md b/health/1.0/default/README.md
deleted file mode 100644
index 1ded7de..0000000
--- a/health/1.0/default/README.md
+++ /dev/null
@@ -1,66 +0,0 @@
-# Implement the 2.1 HAL instead!
-
-It is strongly recommended that you implement the 2.1 HAL directly. See
-`hardware/interfaces/health/2.1/README.md` for more details.
-
-# Implement Health 1.0 HAL
-
-1. Install common binderized service. The binderized service `dlopen()`s
- passthrough implementations on the device, so there is no need to write
- your own.
-
- ```mk
- # Install default binderized implementation to vendor.
- PRODUCT_PACKAGES += android.hardware.health@1.0-service
- ```
-
-1. Add proper VINTF manifest entry to your device manifest. Example:
-
- ```xml
- <hal format="hidl">
- <name>android.hardware.health</name>
- <transport>hwbinder</transport>
- <version>1.0</version>
- <interface>
- <name>IHealth</name>
- <instance>default</instance>
- </interface>
- </hal>
- ```
-
-1. Install the proper passthrough implemetation.
-
- 1. If you want to use the default implementation (with default `libhealthd`),
- add the following to `device.mk`:
-
- ```mk
- PRODUCT_PACKAGES += \
- android.hardware.health@1.0-impl
- ```
-
- 1. Otherwise, if you have a customized `libhealthd.<board>`:
-
- 1. Define your passthrough implementation. Example (replace `<device>`
- and `<board>` accordingly):
-
- ```bp
- cc_library_shared {
- name: "android.hardware.health@1.0-impl-<device>",
- vendor: true,
- relative_install_path: "hw",
-
- static_libs: [
- "android.hardware.health@1.0-impl-helper",
- "android.hardware.health@1.0-convert",
- "libhealthd.<board>",
- ],
- }
- ```
-
- 1. Add to `device.mk`.
-
- ```
- PRODUCT_PACKAGES += android.hardware.health@1.0-impl-<device>
- ```
-
- 1. Define appropriate SELinux permissions.
diff --git a/health/1.0/default/android.hardware.health@1.0-service.rc b/health/1.0/default/android.hardware.health@1.0-service.rc
deleted file mode 100644
index 569dc88..0000000
--- a/health/1.0/default/android.hardware.health@1.0-service.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-service vendor.health-hal-1-0 /vendor/bin/hw/android.hardware.health@1.0-service
- class hal
- user system
- group system
- capabilities WAKE_ALARM BLOCK_SUSPEND
diff --git a/health/1.0/default/libhealthd/Android.bp b/health/1.0/default/libhealthd/Android.bp
deleted file mode 100644
index 43463eb..0000000
--- a/health/1.0/default/libhealthd/Android.bp
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2016 The Android Open Source Project
-
-cc_library_static {
- srcs: ["healthd_board_default.cpp"],
- name: "libhealthd.default",
- vendor_available: true,
- recovery_available: true,
- cflags: ["-Werror"],
- include_dirs: ["system/libbase/include"],
- header_libs: ["libhealthd_headers"],
-}
diff --git a/health/1.0/default/libhealthd/healthd_board_default.cpp b/health/1.0/default/libhealthd/healthd_board_default.cpp
deleted file mode 100644
index 127f98e..0000000
--- a/health/1.0/default/libhealthd/healthd_board_default.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <healthd/healthd.h>
-
-void healthd_board_init(struct healthd_config*)
-{
- // use defaults
-}
-
-int healthd_board_battery_update(struct android::BatteryProperties*)
-{
- // return 0 to log periodic polled battery status to kernel log
- return 0;
-}
diff --git a/health/1.0/vts/functional/Android.bp b/health/1.0/vts/functional/Android.bp
deleted file mode 100644
index f4a04a7..0000000
--- a/health/1.0/vts/functional/Android.bp
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// 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.
-//
-
-cc_test {
- name: "VtsHalHealthV1_0TargetTest",
- defaults: ["VtsHalTargetTestDefaults"],
- srcs: ["VtsHalHealthV1_0TargetTest.cpp"],
- static_libs: ["android.hardware.health@1.0"],
- test_suites: ["general-tests", "vts"],
-}
diff --git a/health/1.0/vts/functional/VtsHalHealthV1_0TargetTest.cpp b/health/1.0/vts/functional/VtsHalHealthV1_0TargetTest.cpp
deleted file mode 100644
index 8b3dcc1..0000000
--- a/health/1.0/vts/functional/VtsHalHealthV1_0TargetTest.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "health_hidl_hal_test"
-
-#include <android/hardware/health/1.0/IHealth.h>
-#include <android/hardware/health/1.0/types.h>
-#include <gtest/gtest.h>
-#include <hidl/GtestPrinter.h>
-#include <hidl/ServiceManagement.h>
-#include <log/log.h>
-
-using HealthConfig = ::android::hardware::health::V1_0::HealthConfig;
-using HealthInfo = ::android::hardware::health::V1_0::HealthInfo;
-using IHealth = ::android::hardware::health::V1_0::IHealth;
-using Result = ::android::hardware::health::V1_0::Result;
-
-using ::android::sp;
-
-class HealthHidlTest : public ::testing::TestWithParam<std::string> {
- public:
- virtual void SetUp() override {
- health = IHealth::getService(GetParam());
- ASSERT_NE(health, nullptr);
- health->init(config,
- [&](const auto& halConfigOut) { config = halConfigOut; });
- }
-
- sp<IHealth> health;
- HealthConfig config;
-};
-
-/**
- * Ensure EnergyCounter call returns positive energy counter or NOT_SUPPORTED
- */
-TEST_P(HealthHidlTest, TestEnergyCounter) {
- Result result;
- int64_t energy = 0;
- health->energyCounter([&](Result ret, int64_t energyOut) {
- result = ret;
- energy = energyOut;
- });
-
- ASSERT_TRUE(result == Result::SUCCESS || result == Result::NOT_SUPPORTED);
- ASSERT_TRUE(result != Result::SUCCESS || energy > 0);
-}
-
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HealthHidlTest);
-INSTANTIATE_TEST_SUITE_P(
- PerInstance, HealthHidlTest,
- testing::ValuesIn(android::hardware::getAllHalInstanceNames(IHealth::descriptor)),
- android::hardware::PrintInstanceNameToString);
diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Burst.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Burst.h
new file mode 100644
index 0000000..f2cbe93
--- /dev/null
+++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Burst.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_BURST_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_BURST_H
+
+#include <nnapi/IBurst.h>
+#include <nnapi/IPreparedModel.h>
+#include <nnapi/Result.h>
+#include <nnapi/Types.h>
+
+#include <memory>
+#include <optional>
+#include <utility>
+
+// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface
+// lifetimes across processes and for protecting asynchronous calls across HIDL.
+
+namespace android::hardware::neuralnetworks::V1_0::utils {
+
+// Class that adapts nn::IPreparedModel to nn::IBurst.
+class Burst final : public nn::IBurst {
+ struct PrivateConstructorTag {};
+
+ public:
+ static nn::GeneralResult<std::shared_ptr<const Burst>> create(
+ nn::SharedPreparedModel preparedModel);
+
+ Burst(PrivateConstructorTag tag, nn::SharedPreparedModel preparedModel);
+
+ OptionalCacheHold cacheMemory(const nn::Memory& memory) const override;
+
+ nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> execute(
+ const nn::Request& request, nn::MeasureTiming measure) const override;
+
+ private:
+ const nn::SharedPreparedModel kPreparedModel;
+};
+
+} // namespace android::hardware::neuralnetworks::V1_0::utils
+
+#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_BURST_H
diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h
index 2de1828..8853eea 100644
--- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h
+++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h
@@ -35,7 +35,8 @@
namespace android::hardware::neuralnetworks::V1_0::utils {
// Class that adapts V1_0::IPreparedModel to nn::IPreparedModel.
-class PreparedModel final : public nn::IPreparedModel {
+class PreparedModel final : public nn::IPreparedModel,
+ public std::enable_shared_from_this<PreparedModel> {
struct PrivateConstructorTag {};
public:
@@ -56,6 +57,8 @@
const nn::OptionalDuration& loopTimeoutDuration,
const nn::OptionalDuration& timeoutDurationAfterFence) const override;
+ nn::GeneralResult<nn::SharedBurst> configureExecutionBurst() const override;
+
std::any getUnderlyingResource() const override;
private:
diff --git a/neuralnetworks/1.0/utils/src/Burst.cpp b/neuralnetworks/1.0/utils/src/Burst.cpp
new file mode 100644
index 0000000..384bd9b
--- /dev/null
+++ b/neuralnetworks/1.0/utils/src/Burst.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Burst.h"
+
+#include <android-base/logging.h>
+#include <nnapi/IBurst.h>
+#include <nnapi/IPreparedModel.h>
+#include <nnapi/Result.h>
+#include <nnapi/Types.h>
+
+#include <memory>
+#include <optional>
+#include <utility>
+
+namespace android::hardware::neuralnetworks::V1_0::utils {
+
+nn::GeneralResult<std::shared_ptr<const Burst>> Burst::create(
+ nn::SharedPreparedModel preparedModel) {
+ if (preparedModel == nullptr) {
+ return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
+ << "V1_0::utils::Burst::create must have non-null preparedModel";
+ }
+
+ return std::make_shared<const Burst>(PrivateConstructorTag{}, std::move(preparedModel));
+}
+
+Burst::Burst(PrivateConstructorTag /*tag*/, nn::SharedPreparedModel preparedModel)
+ : kPreparedModel(std::move(preparedModel)) {
+ CHECK(kPreparedModel != nullptr);
+}
+
+Burst::OptionalCacheHold Burst::cacheMemory(const nn::Memory& /*memory*/) const {
+ return nullptr;
+}
+
+nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> Burst::execute(
+ const nn::Request& request, nn::MeasureTiming measure) const {
+ return kPreparedModel->execute(request, measure, {}, {});
+}
+
+} // namespace android::hardware::neuralnetworks::V1_0::utils
diff --git a/neuralnetworks/1.0/utils/src/PreparedModel.cpp b/neuralnetworks/1.0/utils/src/PreparedModel.cpp
index c0c22fb..858571d 100644
--- a/neuralnetworks/1.0/utils/src/PreparedModel.cpp
+++ b/neuralnetworks/1.0/utils/src/PreparedModel.cpp
@@ -16,6 +16,7 @@
#include "PreparedModel.h"
+#include "Burst.h"
#include "Callbacks.h"
#include "Conversions.h"
#include "Utils.h"
@@ -90,6 +91,10 @@
<< "IPreparedModel::executeFenced is not supported on 1.0 HAL service";
}
+nn::GeneralResult<nn::SharedBurst> PreparedModel::configureExecutionBurst() const {
+ return Burst::create(shared_from_this());
+}
+
std::any PreparedModel::getUnderlyingResource() const {
sp<V1_0::IPreparedModel> resource = kPreparedModel;
return resource;
diff --git a/neuralnetworks/1.2/utils/Android.bp b/neuralnetworks/1.2/utils/Android.bp
index 0fec41c..6959056 100644
--- a/neuralnetworks/1.2/utils/Android.bp
+++ b/neuralnetworks/1.2/utils/Android.bp
@@ -18,6 +18,7 @@
name: "neuralnetworks_utils_hal_1_2",
defaults: ["neuralnetworks_utils_defaults"],
srcs: ["src/*"],
+ exclude_srcs: ["src/ExecutionBurst*"],
local_include_dirs: ["include/nnapi/hal/1.2/"],
export_include_dirs: ["include"],
cflags: ["-Wthread-safety"],
diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstController.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstController.h
new file mode 100644
index 0000000..5356a91
--- /dev/null
+++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstController.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_FRAMEWORKS_ML_NN_COMMON_EXECUTION_BURST_CONTROLLER_H
+#define ANDROID_FRAMEWORKS_ML_NN_COMMON_EXECUTION_BURST_CONTROLLER_H
+
+#include "ExecutionBurstUtils.h"
+
+#include <android-base/macros.h>
+#include <android/hardware/neuralnetworks/1.0/types.h>
+#include <android/hardware/neuralnetworks/1.1/types.h>
+#include <android/hardware/neuralnetworks/1.2/IBurstCallback.h>
+#include <android/hardware/neuralnetworks/1.2/IBurstContext.h>
+#include <android/hardware/neuralnetworks/1.2/IPreparedModel.h>
+#include <android/hardware/neuralnetworks/1.2/types.h>
+#include <fmq/MessageQueue.h>
+#include <hidl/MQDescriptor.h>
+
+#include <atomic>
+#include <chrono>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <stack>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+namespace android::nn {
+
+/**
+ * The ExecutionBurstController class manages both the serialization and
+ * deserialization of data across FMQ, making it appear to the runtime as a
+ * regular synchronous inference. Additionally, this class manages the burst's
+ * memory cache.
+ */
+class ExecutionBurstController {
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ExecutionBurstController);
+
+ public:
+ /**
+ * NN runtime burst callback object and memory cache.
+ *
+ * ExecutionBurstCallback associates a hidl_memory object with a slot number
+ * to be passed across FMQ. The ExecutionBurstServer can use this callback
+ * to retrieve this hidl_memory corresponding to the slot via HIDL.
+ *
+ * Whenever a hidl_memory object is copied, it will duplicate the underlying
+ * file descriptor. Because the NN runtime currently copies the hidl_memory
+ * on each execution, it is difficult to associate hidl_memory objects with
+ * previously cached hidl_memory objects. For this reason, callers of this
+ * class must pair each hidl_memory object with an associated key. For
+ * efficiency, if two hidl_memory objects represent the same underlying
+ * buffer, they must use the same key.
+ */
+ class ExecutionBurstCallback : public hardware::neuralnetworks::V1_2::IBurstCallback {
+ DISALLOW_COPY_AND_ASSIGN(ExecutionBurstCallback);
+
+ public:
+ ExecutionBurstCallback() = default;
+
+ hardware::Return<void> getMemories(const hardware::hidl_vec<int32_t>& slots,
+ getMemories_cb cb) override;
+
+ /**
+ * This function performs one of two different actions:
+ * 1) If a key corresponding to a memory resource is unrecognized by the
+ * ExecutionBurstCallback object, the ExecutionBurstCallback object
+ * will allocate a slot, bind the memory to the slot, and return the
+ * slot identifier.
+ * 2) If a key corresponding to a memory resource is recognized by the
+ * ExecutionBurstCallback object, the ExecutionBurstCallback object
+ * will return the existing slot identifier.
+ *
+ * @param memories Memory resources used in an inference.
+ * @param keys Unique identifiers where each element corresponds to a
+ * memory resource element in "memories".
+ * @return Unique slot identifiers where each returned slot element
+ * corresponds to a memory resource element in "memories".
+ */
+ std::vector<int32_t> getSlots(const hardware::hidl_vec<hardware::hidl_memory>& memories,
+ const std::vector<intptr_t>& keys);
+
+ /*
+ * This function performs two different actions:
+ * 1) Removes an entry from the cache (if present), including the local
+ * storage of the hidl_memory object. Note that this call does not
+ * free any corresponding hidl_memory object in ExecutionBurstServer,
+ * which is separately freed via IBurstContext::freeMemory.
+ * 2) Return whether a cache entry was removed and which slot was removed if
+ * found. If the key did not to correspond to any entry in the cache, a
+ * slot number of 0 is returned. The slot number and whether the entry
+ * existed is useful so the same slot can be freed in the
+ * ExecutionBurstServer's cache via IBurstContext::freeMemory.
+ */
+ std::pair<bool, int32_t> freeMemory(intptr_t key);
+
+ private:
+ int32_t getSlotLocked(const hardware::hidl_memory& memory, intptr_t key);
+ int32_t allocateSlotLocked();
+
+ std::mutex mMutex;
+ std::stack<int32_t, std::vector<int32_t>> mFreeSlots;
+ std::map<intptr_t, int32_t> mMemoryIdToSlot;
+ std::vector<hardware::hidl_memory> mMemoryCache;
+ };
+
+ /**
+ * Creates a burst controller on a prepared model.
+ *
+ * Prefer this over ExecutionBurstController's constructor.
+ *
+ * @param preparedModel Model prepared for execution to execute on.
+ * @param pollingTimeWindow How much time (in microseconds) the
+ * ExecutionBurstController is allowed to poll the FMQ before waiting on
+ * the blocking futex. Polling may result in lower latencies at the
+ * potential cost of more power usage.
+ * @return ExecutionBurstController Execution burst controller object.
+ */
+ static std::unique_ptr<ExecutionBurstController> create(
+ const sp<hardware::neuralnetworks::V1_2::IPreparedModel>& preparedModel,
+ std::chrono::microseconds pollingTimeWindow);
+
+ // prefer calling ExecutionBurstController::create
+ ExecutionBurstController(const std::shared_ptr<RequestChannelSender>& requestChannelSender,
+ const std::shared_ptr<ResultChannelReceiver>& resultChannelReceiver,
+ const sp<hardware::neuralnetworks::V1_2::IBurstContext>& burstContext,
+ const sp<ExecutionBurstCallback>& callback,
+ const sp<hardware::hidl_death_recipient>& deathHandler = nullptr);
+
+ // explicit destructor to unregister the death recipient
+ ~ExecutionBurstController();
+
+ /**
+ * Execute a request on a model.
+ *
+ * @param request Arguments to be executed on a model.
+ * @param measure Whether to collect timing measurements, either YES or NO
+ * @param memoryIds Identifiers corresponding to each memory object in the
+ * request's pools.
+ * @return A tuple of:
+ * - result code of the execution
+ * - dynamic output shapes from the execution
+ * - any execution time measurements of the execution
+ * - whether or not a failed burst execution should be re-run using a
+ * different path (e.g., IPreparedModel::executeSynchronously)
+ */
+ std::tuple<int, std::vector<hardware::neuralnetworks::V1_2::OutputShape>,
+ hardware::neuralnetworks::V1_2::Timing, bool>
+ compute(const hardware::neuralnetworks::V1_0::Request& request,
+ hardware::neuralnetworks::V1_2::MeasureTiming measure,
+ const std::vector<intptr_t>& memoryIds);
+
+ /**
+ * Propagate a user's freeing of memory to the service.
+ *
+ * @param key Key corresponding to the memory object.
+ */
+ void freeMemory(intptr_t key);
+
+ private:
+ std::mutex mMutex;
+ const std::shared_ptr<RequestChannelSender> mRequestChannelSender;
+ const std::shared_ptr<ResultChannelReceiver> mResultChannelReceiver;
+ const sp<hardware::neuralnetworks::V1_2::IBurstContext> mBurstContext;
+ const sp<ExecutionBurstCallback> mMemoryCache;
+ const sp<hardware::hidl_death_recipient> mDeathHandler;
+};
+
+} // namespace android::nn
+
+#endif // ANDROID_FRAMEWORKS_ML_NN_COMMON_EXECUTION_BURST_CONTROLLER_H
diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstServer.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstServer.h
new file mode 100644
index 0000000..2e109b2
--- /dev/null
+++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstServer.h
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_FRAMEWORKS_ML_NN_COMMON_EXECUTION_BURST_SERVER_H
+#define ANDROID_FRAMEWORKS_ML_NN_COMMON_EXECUTION_BURST_SERVER_H
+
+#include "ExecutionBurstUtils.h"
+
+#include <android-base/macros.h>
+#include <android/hardware/neuralnetworks/1.0/types.h>
+#include <android/hardware/neuralnetworks/1.1/types.h>
+#include <android/hardware/neuralnetworks/1.2/IBurstCallback.h>
+#include <android/hardware/neuralnetworks/1.2/IPreparedModel.h>
+#include <android/hardware/neuralnetworks/1.2/types.h>
+#include <fmq/MessageQueue.h>
+#include <hidl/MQDescriptor.h>
+
+#include <atomic>
+#include <chrono>
+#include <memory>
+#include <optional>
+#include <thread>
+#include <tuple>
+#include <vector>
+
+namespace android::nn {
+
+/**
+ * The ExecutionBurstServer class is responsible for waiting for and
+ * deserializing a request object from a FMQ, performing the inference, and
+ * serializing the result back across another FMQ.
+ */
+class ExecutionBurstServer : public hardware::neuralnetworks::V1_2::IBurstContext {
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ExecutionBurstServer);
+
+ public:
+ /**
+ * IBurstExecutorWithCache is a callback object passed to
+ * ExecutionBurstServer's factory function that is used to perform an
+ * execution. Because some memory resources are needed across multiple
+ * executions, this object also contains a local cache that can directly be
+ * used in the execution.
+ *
+ * ExecutionBurstServer will never access its IBurstExecutorWithCache object
+ * with concurrent calls.
+ */
+ class IBurstExecutorWithCache {
+ DISALLOW_COPY_AND_ASSIGN(IBurstExecutorWithCache);
+
+ public:
+ IBurstExecutorWithCache() = default;
+ virtual ~IBurstExecutorWithCache() = default;
+
+ /**
+ * Checks if a cache entry specified by a slot is present in the cache.
+ *
+ * @param slot Identifier of the cache entry.
+ * @return 'true' if the cache entry is present in the cache, 'false'
+ * otherwise.
+ */
+ virtual bool isCacheEntryPresent(int32_t slot) const = 0;
+
+ /**
+ * Adds an entry specified by a slot to the cache.
+ *
+ * The caller of this function must ensure that the cache entry that is
+ * being added is not already present in the cache. This can be checked
+ * via isCacheEntryPresent.
+ *
+ * @param memory Memory resource to be cached.
+ * @param slot Slot identifier corresponding to the memory resource.
+ */
+ virtual void addCacheEntry(const hardware::hidl_memory& memory, int32_t slot) = 0;
+
+ /**
+ * Removes an entry specified by a slot from the cache.
+ *
+ * If the cache entry corresponding to the slot number does not exist,
+ * the call does nothing.
+ *
+ * @param slot Slot identifier corresponding to the memory resource.
+ */
+ virtual void removeCacheEntry(int32_t slot) = 0;
+
+ /**
+ * Perform an execution.
+ *
+ * @param request Request object with inputs and outputs specified.
+ * Request::pools is empty, and DataLocation::poolIndex instead
+ * refers to the 'slots' argument as if it were Request::pools.
+ * @param slots Slots corresponding to the cached memory entries to be
+ * used.
+ * @param measure Whether timing information is requested for the
+ * execution.
+ * @return Result of the execution, including the status of the
+ * execution, dynamic output shapes, and any timing information.
+ */
+ virtual std::tuple<hardware::neuralnetworks::V1_0::ErrorStatus,
+ hardware::hidl_vec<hardware::neuralnetworks::V1_2::OutputShape>,
+ hardware::neuralnetworks::V1_2::Timing>
+ execute(const hardware::neuralnetworks::V1_0::Request& request,
+ const std::vector<int32_t>& slots,
+ hardware::neuralnetworks::V1_2::MeasureTiming measure) = 0;
+ };
+
+ /**
+ * Create automated context to manage FMQ-based executions.
+ *
+ * This function is intended to be used by a service to automatically:
+ * 1) Receive data from a provided FMQ
+ * 2) Execute a model with the given information
+ * 3) Send the result to the created FMQ
+ *
+ * @param callback Callback used to retrieve memories corresponding to
+ * unrecognized slots.
+ * @param requestChannel Input FMQ channel through which the client passes the
+ * request to the service.
+ * @param resultChannel Output FMQ channel from which the client can retrieve
+ * the result of the execution.
+ * @param executorWithCache Object which maintains a local cache of the
+ * memory pools and executes using the cached memory pools.
+ * @param pollingTimeWindow How much time (in microseconds) the
+ * ExecutionBurstServer is allowed to poll the FMQ before waiting on
+ * the blocking futex. Polling may result in lower latencies at the
+ * potential cost of more power usage.
+ * @result IBurstContext Handle to the burst context.
+ */
+ static sp<ExecutionBurstServer> create(
+ const sp<hardware::neuralnetworks::V1_2::IBurstCallback>& callback,
+ const FmqRequestDescriptor& requestChannel, const FmqResultDescriptor& resultChannel,
+ std::shared_ptr<IBurstExecutorWithCache> executorWithCache,
+ std::chrono::microseconds pollingTimeWindow = std::chrono::microseconds{0});
+
+ /**
+ * Create automated context to manage FMQ-based executions.
+ *
+ * This function is intended to be used by a service to automatically:
+ * 1) Receive data from a provided FMQ
+ * 2) Execute a model with the given information
+ * 3) Send the result to the created FMQ
+ *
+ * @param callback Callback used to retrieve memories corresponding to
+ * unrecognized slots.
+ * @param requestChannel Input FMQ channel through which the client passes the
+ * request to the service.
+ * @param resultChannel Output FMQ channel from which the client can retrieve
+ * the result of the execution.
+ * @param preparedModel PreparedModel that the burst object was created from.
+ * IPreparedModel::executeSynchronously will be used to perform the
+ * execution.
+ * @param pollingTimeWindow How much time (in microseconds) the
+ * ExecutionBurstServer is allowed to poll the FMQ before waiting on
+ * the blocking futex. Polling may result in lower latencies at the
+ * potential cost of more power usage.
+ * @result IBurstContext Handle to the burst context.
+ */
+ static sp<ExecutionBurstServer> create(
+ const sp<hardware::neuralnetworks::V1_2::IBurstCallback>& callback,
+ const FmqRequestDescriptor& requestChannel, const FmqResultDescriptor& resultChannel,
+ hardware::neuralnetworks::V1_2::IPreparedModel* preparedModel,
+ std::chrono::microseconds pollingTimeWindow = std::chrono::microseconds{0});
+
+ ExecutionBurstServer(const sp<hardware::neuralnetworks::V1_2::IBurstCallback>& callback,
+ std::unique_ptr<RequestChannelReceiver> requestChannel,
+ std::unique_ptr<ResultChannelSender> resultChannel,
+ std::shared_ptr<IBurstExecutorWithCache> cachedExecutor);
+ ~ExecutionBurstServer();
+
+ // Used by the NN runtime to preemptively remove any stored memory.
+ hardware::Return<void> freeMemory(int32_t slot) override;
+
+ private:
+ // Ensures all cache entries contained in mExecutorWithCache are present in
+ // the cache. If they are not present, they are retrieved (via
+ // IBurstCallback::getMemories) and added to mExecutorWithCache.
+ //
+ // This method is locked via mMutex when it is called.
+ void ensureCacheEntriesArePresentLocked(const std::vector<int32_t>& slots);
+
+ // Work loop that will continue processing execution requests until the
+ // ExecutionBurstServer object is freed.
+ void task();
+
+ std::thread mWorker;
+ std::mutex mMutex;
+ std::atomic<bool> mTeardown{false};
+ const sp<hardware::neuralnetworks::V1_2::IBurstCallback> mCallback;
+ const std::unique_ptr<RequestChannelReceiver> mRequestChannelReceiver;
+ const std::unique_ptr<ResultChannelSender> mResultChannelSender;
+ const std::shared_ptr<IBurstExecutorWithCache> mExecutorWithCache;
+};
+
+} // namespace android::nn
+
+#endif // ANDROID_FRAMEWORKS_ML_NN_COMMON_EXECUTION_BURST_SERVER_H
diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstUtils.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstUtils.h
new file mode 100644
index 0000000..8a41591
--- /dev/null
+++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstUtils.h
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_EXECUTION_BURST_UTILS_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_EXECUTION_BURST_UTILS_H
+
+#include <android/hardware/neuralnetworks/1.0/types.h>
+#include <android/hardware/neuralnetworks/1.1/types.h>
+#include <android/hardware/neuralnetworks/1.2/types.h>
+#include <fmq/MessageQueue.h>
+#include <hidl/MQDescriptor.h>
+
+#include <atomic>
+#include <chrono>
+#include <memory>
+#include <optional>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+namespace android::hardware::neuralnetworks::V1_2::utils {
+
+/**
+ * Number of elements in the FMQ.
+ */
+constexpr const size_t kExecutionBurstChannelLength = 1024;
+
+using FmqRequestDescriptor = MQDescriptorSync<FmqRequestDatum>;
+using FmqResultDescriptor = MQDescriptorSync<FmqResultDatum>;
+
+/**
+ * Function to serialize a request.
+ *
+ * Prefer calling RequestChannelSender::send.
+ *
+ * @param request Request object without the pool information.
+ * @param measure Whether to collect timing information for the execution.
+ * @param memoryIds Slot identifiers corresponding to memory resources for the
+ * request.
+ * @return Serialized FMQ request data.
+ */
+std::vector<hardware::neuralnetworks::V1_2::FmqRequestDatum> serialize(
+ const hardware::neuralnetworks::V1_0::Request& request,
+ hardware::neuralnetworks::V1_2::MeasureTiming measure, const std::vector<int32_t>& slots);
+
+/**
+ * Deserialize the FMQ request data.
+ *
+ * The three resulting fields are the Request object (where Request::pools is
+ * empty), slot identifiers (which are stand-ins for Request::pools), and
+ * whether timing information must be collected for the run.
+ *
+ * @param data Serialized FMQ request data.
+ * @return Request object if successfully deserialized, std::nullopt otherwise.
+ */
+std::optional<std::tuple<hardware::neuralnetworks::V1_0::Request, std::vector<int32_t>,
+ hardware::neuralnetworks::V1_2::MeasureTiming>>
+deserialize(const std::vector<hardware::neuralnetworks::V1_2::FmqRequestDatum>& data);
+
+/**
+ * Function to serialize results.
+ *
+ * Prefer calling ResultChannelSender::send.
+ *
+ * @param errorStatus Status of the execution.
+ * @param outputShapes Dynamic shapes of the output tensors.
+ * @param timing Timing information of the execution.
+ * @return Serialized FMQ result data.
+ */
+std::vector<hardware::neuralnetworks::V1_2::FmqResultDatum> serialize(
+ hardware::neuralnetworks::V1_0::ErrorStatus errorStatus,
+ const std::vector<hardware::neuralnetworks::V1_2::OutputShape>& outputShapes,
+ hardware::neuralnetworks::V1_2::Timing timing);
+
+/**
+ * Deserialize the FMQ result data.
+ *
+ * The three resulting fields are the status of the execution, the dynamic
+ * shapes of the output tensors, and the timing information of the execution.
+ *
+ * @param data Serialized FMQ result data.
+ * @return Result object if successfully deserialized, std::nullopt otherwise.
+ */
+std::optional<std::tuple<hardware::neuralnetworks::V1_0::ErrorStatus,
+ std::vector<hardware::neuralnetworks::V1_2::OutputShape>,
+ hardware::neuralnetworks::V1_2::Timing>>
+deserialize(const std::vector<hardware::neuralnetworks::V1_2::FmqResultDatum>& data);
+
+/**
+ * Convert result code to error status.
+ *
+ * @param resultCode Result code to be converted.
+ * @return ErrorStatus Resultant error status.
+ */
+hardware::neuralnetworks::V1_0::ErrorStatus legacyConvertResultCodeToErrorStatus(int resultCode);
+
+/**
+ * RequestChannelSender is responsible for serializing the result packet of
+ * information, sending it on the result channel, and signaling that the data is
+ * available.
+ */
+class RequestChannelSender {
+ using FmqRequestDescriptor =
+ hardware::MQDescriptorSync<hardware::neuralnetworks::V1_2::FmqRequestDatum>;
+ using FmqRequestChannel =
+ hardware::MessageQueue<hardware::neuralnetworks::V1_2::FmqRequestDatum,
+ hardware::kSynchronizedReadWrite>;
+
+ public:
+ /**
+ * Create the sending end of a request channel.
+ *
+ * Prefer this call over the constructor.
+ *
+ * @param channelLength Number of elements in the FMQ.
+ * @return A pair of ResultChannelReceiver and the FMQ descriptor on
+ * successful creation, both nullptr otherwise.
+ */
+ static std::pair<std::unique_ptr<RequestChannelSender>, const FmqRequestDescriptor*> create(
+ size_t channelLength);
+
+ /**
+ * Send the request to the channel.
+ *
+ * @param request Request object without the pool information.
+ * @param measure Whether to collect timing information for the execution.
+ * @param memoryIds Slot identifiers corresponding to memory resources for
+ * the request.
+ * @return 'true' on successful send, 'false' otherwise.
+ */
+ bool send(const hardware::neuralnetworks::V1_0::Request& request,
+ hardware::neuralnetworks::V1_2::MeasureTiming measure,
+ const std::vector<int32_t>& slots);
+
+ /**
+ * Method to mark the channel as invalid, causing all future calls to
+ * RequestChannelSender::send to immediately return false without attempting
+ * to send a message across the FMQ.
+ */
+ void invalidate();
+
+ // prefer calling RequestChannelSender::send
+ bool sendPacket(const std::vector<hardware::neuralnetworks::V1_2::FmqRequestDatum>& packet);
+
+ RequestChannelSender(std::unique_ptr<FmqRequestChannel> fmqRequestChannel);
+
+ private:
+ const std::unique_ptr<FmqRequestChannel> mFmqRequestChannel;
+ std::atomic<bool> mValid{true};
+};
+
+/**
+ * RequestChannelReceiver is responsible for waiting on the channel until the
+ * packet is available, extracting the packet from the channel, and
+ * deserializing the packet.
+ *
+ * Because the receiver can wait on a packet that may never come (e.g., because
+ * the sending side of the packet has been closed), this object can be
+ * invalidated, unblocking the receiver.
+ */
+class RequestChannelReceiver {
+ using FmqRequestChannel =
+ hardware::MessageQueue<hardware::neuralnetworks::V1_2::FmqRequestDatum,
+ hardware::kSynchronizedReadWrite>;
+
+ public:
+ /**
+ * Create the receiving end of a request channel.
+ *
+ * Prefer this call over the constructor.
+ *
+ * @param requestChannel Descriptor for the request channel.
+ * @param pollingTimeWindow How much time (in microseconds) the
+ * RequestChannelReceiver is allowed to poll the FMQ before waiting on
+ * the blocking futex. Polling may result in lower latencies at the
+ * potential cost of more power usage.
+ * @return RequestChannelReceiver on successful creation, nullptr otherwise.
+ */
+ static std::unique_ptr<RequestChannelReceiver> create(
+ const FmqRequestDescriptor& requestChannel,
+ std::chrono::microseconds pollingTimeWindow);
+
+ /**
+ * Get the request from the channel.
+ *
+ * This method will block until either:
+ * 1) The packet has been retrieved, or
+ * 2) The receiver has been invalidated
+ *
+ * @return Request object if successfully received, std::nullopt if error or
+ * if the receiver object was invalidated.
+ */
+ std::optional<std::tuple<hardware::neuralnetworks::V1_0::Request, std::vector<int32_t>,
+ hardware::neuralnetworks::V1_2::MeasureTiming>>
+ getBlocking();
+
+ /**
+ * Method to mark the channel as invalid, unblocking any current or future
+ * calls to RequestChannelReceiver::getBlocking.
+ */
+ void invalidate();
+
+ RequestChannelReceiver(std::unique_ptr<FmqRequestChannel> fmqRequestChannel,
+ std::chrono::microseconds pollingTimeWindow);
+
+ private:
+ std::optional<std::vector<hardware::neuralnetworks::V1_2::FmqRequestDatum>> getPacketBlocking();
+
+ const std::unique_ptr<FmqRequestChannel> mFmqRequestChannel;
+ std::atomic<bool> mTeardown{false};
+ const std::chrono::microseconds kPollingTimeWindow;
+};
+
+/**
+ * ResultChannelSender is responsible for serializing the result packet of
+ * information, sending it on the result channel, and signaling that the data is
+ * available.
+ */
+class ResultChannelSender {
+ using FmqResultChannel = hardware::MessageQueue<hardware::neuralnetworks::V1_2::FmqResultDatum,
+ hardware::kSynchronizedReadWrite>;
+
+ public:
+ /**
+ * Create the sending end of a result channel.
+ *
+ * Prefer this call over the constructor.
+ *
+ * @param resultChannel Descriptor for the result channel.
+ * @return ResultChannelSender on successful creation, nullptr otherwise.
+ */
+ static std::unique_ptr<ResultChannelSender> create(const FmqResultDescriptor& resultChannel);
+
+ /**
+ * Send the result to the channel.
+ *
+ * @param errorStatus Status of the execution.
+ * @param outputShapes Dynamic shapes of the output tensors.
+ * @param timing Timing information of the execution.
+ * @return 'true' on successful send, 'false' otherwise.
+ */
+ bool send(hardware::neuralnetworks::V1_0::ErrorStatus errorStatus,
+ const std::vector<hardware::neuralnetworks::V1_2::OutputShape>& outputShapes,
+ hardware::neuralnetworks::V1_2::Timing timing);
+
+ // prefer calling ResultChannelSender::send
+ bool sendPacket(const std::vector<hardware::neuralnetworks::V1_2::FmqResultDatum>& packet);
+
+ ResultChannelSender(std::unique_ptr<FmqResultChannel> fmqResultChannel);
+
+ private:
+ const std::unique_ptr<FmqResultChannel> mFmqResultChannel;
+};
+
+/**
+ * ResultChannelReceiver is responsible for waiting on the channel until the
+ * packet is available, extracting the packet from the channel, and
+ * deserializing the packet.
+ *
+ * Because the receiver can wait on a packet that may never come (e.g., because
+ * the sending side of the packet has been closed), this object can be
+ * invalidated, unblocking the receiver.
+ */
+class ResultChannelReceiver {
+ using FmqResultDescriptor =
+ hardware::MQDescriptorSync<hardware::neuralnetworks::V1_2::FmqResultDatum>;
+ using FmqResultChannel = hardware::MessageQueue<hardware::neuralnetworks::V1_2::FmqResultDatum,
+ hardware::kSynchronizedReadWrite>;
+
+ public:
+ /**
+ * Create the receiving end of a result channel.
+ *
+ * Prefer this call over the constructor.
+ *
+ * @param channelLength Number of elements in the FMQ.
+ * @param pollingTimeWindow How much time (in microseconds) the
+ * ResultChannelReceiver is allowed to poll the FMQ before waiting on
+ * the blocking futex. Polling may result in lower latencies at the
+ * potential cost of more power usage.
+ * @return A pair of ResultChannelReceiver and the FMQ descriptor on
+ * successful creation, both nullptr otherwise.
+ */
+ static std::pair<std::unique_ptr<ResultChannelReceiver>, const FmqResultDescriptor*> create(
+ size_t channelLength, std::chrono::microseconds pollingTimeWindow);
+
+ /**
+ * Get the result from the channel.
+ *
+ * This method will block until either:
+ * 1) The packet has been retrieved, or
+ * 2) The receiver has been invalidated
+ *
+ * @return Result object if successfully received, std::nullopt if error or
+ * if the receiver object was invalidated.
+ */
+ std::optional<std::tuple<hardware::neuralnetworks::V1_0::ErrorStatus,
+ std::vector<hardware::neuralnetworks::V1_2::OutputShape>,
+ hardware::neuralnetworks::V1_2::Timing>>
+ getBlocking();
+
+ /**
+ * Method to mark the channel as invalid, unblocking any current or future
+ * calls to ResultChannelReceiver::getBlocking.
+ */
+ void invalidate();
+
+ // prefer calling ResultChannelReceiver::getBlocking
+ std::optional<std::vector<hardware::neuralnetworks::V1_2::FmqResultDatum>> getPacketBlocking();
+
+ ResultChannelReceiver(std::unique_ptr<FmqResultChannel> fmqResultChannel,
+ std::chrono::microseconds pollingTimeWindow);
+
+ private:
+ const std::unique_ptr<FmqResultChannel> mFmqResultChannel;
+ std::atomic<bool> mValid{true};
+ const std::chrono::microseconds kPollingTimeWindow;
+};
+
+} // namespace android::hardware::neuralnetworks::V1_2::utils
+
+#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_EXECUTION_BURST_UTILS_H
diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h
index 6a56a82..fb11130 100644
--- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h
+++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h
@@ -36,7 +36,8 @@
namespace android::hardware::neuralnetworks::V1_2::utils {
// Class that adapts V1_2::IPreparedModel to nn::IPreparedModel.
-class PreparedModel final : public nn::IPreparedModel {
+class PreparedModel final : public nn::IPreparedModel,
+ public std::enable_shared_from_this<PreparedModel> {
struct PrivateConstructorTag {};
public:
@@ -57,6 +58,8 @@
const nn::OptionalDuration& loopTimeoutDuration,
const nn::OptionalDuration& timeoutDurationAfterFence) const override;
+ nn::GeneralResult<nn::SharedBurst> configureExecutionBurst() const override;
+
std::any getUnderlyingResource() const override;
private:
diff --git a/neuralnetworks/1.2/utils/src/ExecutionBurstController.cpp b/neuralnetworks/1.2/utils/src/ExecutionBurstController.cpp
new file mode 100644
index 0000000..2265861
--- /dev/null
+++ b/neuralnetworks/1.2/utils/src/ExecutionBurstController.cpp
@@ -0,0 +1,299 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ExecutionBurstController"
+
+#include "ExecutionBurstController.h"
+
+#include <android-base/logging.h>
+
+#include <algorithm>
+#include <cstring>
+#include <limits>
+#include <memory>
+#include <string>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+#include "ExecutionBurstUtils.h"
+#include "HalInterfaces.h"
+#include "Tracing.h"
+#include "Utils.h"
+
+namespace android::nn {
+namespace {
+
+class BurstContextDeathHandler : public hardware::hidl_death_recipient {
+ public:
+ using Callback = std::function<void()>;
+
+ BurstContextDeathHandler(const Callback& onDeathCallback) : mOnDeathCallback(onDeathCallback) {
+ CHECK(onDeathCallback != nullptr);
+ }
+
+ void serviceDied(uint64_t /*cookie*/, const wp<hidl::base::V1_0::IBase>& /*who*/) override {
+ LOG(ERROR) << "BurstContextDeathHandler::serviceDied -- service unexpectedly died!";
+ mOnDeathCallback();
+ }
+
+ private:
+ const Callback mOnDeathCallback;
+};
+
+} // anonymous namespace
+
+hardware::Return<void> ExecutionBurstController::ExecutionBurstCallback::getMemories(
+ const hardware::hidl_vec<int32_t>& slots, getMemories_cb cb) {
+ std::lock_guard<std::mutex> guard(mMutex);
+
+ // get all memories
+ hardware::hidl_vec<hardware::hidl_memory> memories(slots.size());
+ std::transform(slots.begin(), slots.end(), memories.begin(), [this](int32_t slot) {
+ return slot < mMemoryCache.size() ? mMemoryCache[slot] : hardware::hidl_memory{};
+ });
+
+ // ensure all memories are valid
+ if (!std::all_of(memories.begin(), memories.end(),
+ [](const hardware::hidl_memory& memory) { return memory.valid(); })) {
+ cb(V1_0::ErrorStatus::INVALID_ARGUMENT, {});
+ return hardware::Void();
+ }
+
+ // return successful
+ cb(V1_0::ErrorStatus::NONE, std::move(memories));
+ return hardware::Void();
+}
+
+std::vector<int32_t> ExecutionBurstController::ExecutionBurstCallback::getSlots(
+ const hardware::hidl_vec<hardware::hidl_memory>& memories,
+ const std::vector<intptr_t>& keys) {
+ std::lock_guard<std::mutex> guard(mMutex);
+
+ // retrieve (or bind) all slots corresponding to memories
+ std::vector<int32_t> slots;
+ slots.reserve(memories.size());
+ for (size_t i = 0; i < memories.size(); ++i) {
+ slots.push_back(getSlotLocked(memories[i], keys[i]));
+ }
+ return slots;
+}
+
+std::pair<bool, int32_t> ExecutionBurstController::ExecutionBurstCallback::freeMemory(
+ intptr_t key) {
+ std::lock_guard<std::mutex> guard(mMutex);
+
+ auto iter = mMemoryIdToSlot.find(key);
+ if (iter == mMemoryIdToSlot.end()) {
+ return {false, 0};
+ }
+ const int32_t slot = iter->second;
+ mMemoryIdToSlot.erase(key);
+ mMemoryCache[slot] = {};
+ mFreeSlots.push(slot);
+ return {true, slot};
+}
+
+int32_t ExecutionBurstController::ExecutionBurstCallback::getSlotLocked(
+ const hardware::hidl_memory& memory, intptr_t key) {
+ auto iter = mMemoryIdToSlot.find(key);
+ if (iter == mMemoryIdToSlot.end()) {
+ const int32_t slot = allocateSlotLocked();
+ mMemoryIdToSlot[key] = slot;
+ mMemoryCache[slot] = memory;
+ return slot;
+ } else {
+ const int32_t slot = iter->second;
+ return slot;
+ }
+}
+
+int32_t ExecutionBurstController::ExecutionBurstCallback::allocateSlotLocked() {
+ constexpr size_t kMaxNumberOfSlots = std::numeric_limits<int32_t>::max();
+
+ // if there is a free slot, use it
+ if (mFreeSlots.size() > 0) {
+ const int32_t slot = mFreeSlots.top();
+ mFreeSlots.pop();
+ return slot;
+ }
+
+ // otherwise use a slot for the first time
+ CHECK(mMemoryCache.size() < kMaxNumberOfSlots) << "Exceeded maximum number of slots!";
+ const int32_t slot = static_cast<int32_t>(mMemoryCache.size());
+ mMemoryCache.emplace_back();
+
+ return slot;
+}
+
+std::unique_ptr<ExecutionBurstController> ExecutionBurstController::create(
+ const sp<V1_2::IPreparedModel>& preparedModel,
+ std::chrono::microseconds pollingTimeWindow) {
+ // check inputs
+ if (preparedModel == nullptr) {
+ LOG(ERROR) << "ExecutionBurstController::create passed a nullptr";
+ return nullptr;
+ }
+
+ // create callback object
+ sp<ExecutionBurstCallback> callback = new ExecutionBurstCallback();
+
+ // create FMQ objects
+ auto [requestChannelSenderTemp, requestChannelDescriptor] =
+ RequestChannelSender::create(kExecutionBurstChannelLength);
+ auto [resultChannelReceiverTemp, resultChannelDescriptor] =
+ ResultChannelReceiver::create(kExecutionBurstChannelLength, pollingTimeWindow);
+ std::shared_ptr<RequestChannelSender> requestChannelSender =
+ std::move(requestChannelSenderTemp);
+ std::shared_ptr<ResultChannelReceiver> resultChannelReceiver =
+ std::move(resultChannelReceiverTemp);
+
+ // check FMQ objects
+ if (!requestChannelSender || !resultChannelReceiver || !requestChannelDescriptor ||
+ !resultChannelDescriptor) {
+ LOG(ERROR) << "ExecutionBurstController::create failed to create FastMessageQueue";
+ return nullptr;
+ }
+
+ // configure burst
+ V1_0::ErrorStatus errorStatus;
+ sp<IBurstContext> burstContext;
+ const hardware::Return<void> ret = preparedModel->configureExecutionBurst(
+ callback, *requestChannelDescriptor, *resultChannelDescriptor,
+ [&errorStatus, &burstContext](V1_0::ErrorStatus status,
+ const sp<IBurstContext>& context) {
+ errorStatus = status;
+ burstContext = context;
+ });
+
+ // check burst
+ if (!ret.isOk()) {
+ LOG(ERROR) << "IPreparedModel::configureExecutionBurst failed with description "
+ << ret.description();
+ return nullptr;
+ }
+ if (errorStatus != V1_0::ErrorStatus::NONE) {
+ LOG(ERROR) << "IPreparedModel::configureExecutionBurst failed with status "
+ << toString(errorStatus);
+ return nullptr;
+ }
+ if (burstContext == nullptr) {
+ LOG(ERROR) << "IPreparedModel::configureExecutionBurst returned nullptr for burst";
+ return nullptr;
+ }
+
+ // create death handler object
+ BurstContextDeathHandler::Callback onDeathCallback = [requestChannelSender,
+ resultChannelReceiver] {
+ requestChannelSender->invalidate();
+ resultChannelReceiver->invalidate();
+ };
+ const sp<BurstContextDeathHandler> deathHandler = new BurstContextDeathHandler(onDeathCallback);
+
+ // linkToDeath registers a callback that will be invoked on service death to
+ // proactively handle service crashes. If the linkToDeath call fails,
+ // asynchronous calls are susceptible to hangs if the service crashes before
+ // providing the response.
+ const hardware::Return<bool> deathHandlerRet = burstContext->linkToDeath(deathHandler, 0);
+ if (!deathHandlerRet.isOk() || deathHandlerRet != true) {
+ LOG(ERROR) << "ExecutionBurstController::create -- Failed to register a death recipient "
+ "for the IBurstContext object.";
+ return nullptr;
+ }
+
+ // make and return controller
+ return std::make_unique<ExecutionBurstController>(requestChannelSender, resultChannelReceiver,
+ burstContext, callback, deathHandler);
+}
+
+ExecutionBurstController::ExecutionBurstController(
+ const std::shared_ptr<RequestChannelSender>& requestChannelSender,
+ const std::shared_ptr<ResultChannelReceiver>& resultChannelReceiver,
+ const sp<IBurstContext>& burstContext, const sp<ExecutionBurstCallback>& callback,
+ const sp<hardware::hidl_death_recipient>& deathHandler)
+ : mRequestChannelSender(requestChannelSender),
+ mResultChannelReceiver(resultChannelReceiver),
+ mBurstContext(burstContext),
+ mMemoryCache(callback),
+ mDeathHandler(deathHandler) {}
+
+ExecutionBurstController::~ExecutionBurstController() {
+ // It is safe to ignore any errors resulting from this unlinkToDeath call
+ // because the ExecutionBurstController object is already being destroyed
+ // and its underlying IBurstContext object is no longer being used by the NN
+ // runtime.
+ if (mDeathHandler) {
+ mBurstContext->unlinkToDeath(mDeathHandler).isOk();
+ }
+}
+
+static std::tuple<int, std::vector<V1_2::OutputShape>, V1_2::Timing, bool> getExecutionResult(
+ V1_0::ErrorStatus status, std::vector<V1_2::OutputShape> outputShapes, V1_2::Timing timing,
+ bool fallback) {
+ auto [n, checkedOutputShapes, checkedTiming] =
+ getExecutionResult(convertToV1_3(status), std::move(outputShapes), timing);
+ return {n, convertToV1_2(checkedOutputShapes), convertToV1_2(checkedTiming), fallback};
+}
+
+std::tuple<int, std::vector<V1_2::OutputShape>, V1_2::Timing, bool>
+ExecutionBurstController::compute(const V1_0::Request& request, V1_2::MeasureTiming measure,
+ const std::vector<intptr_t>& memoryIds) {
+ // This is the first point when we know an execution is occurring, so begin
+ // to collect systraces. Note that the first point we can begin collecting
+ // systraces in ExecutionBurstServer is when the RequestChannelReceiver
+ // realizes there is data in the FMQ, so ExecutionBurstServer collects
+ // systraces at different points in the code.
+ NNTRACE_FULL(NNTRACE_LAYER_IPC, NNTRACE_PHASE_EXECUTION, "ExecutionBurstController::compute");
+
+ std::lock_guard<std::mutex> guard(mMutex);
+
+ // send request packet
+ const std::vector<int32_t> slots = mMemoryCache->getSlots(request.pools, memoryIds);
+ const bool success = mRequestChannelSender->send(request, measure, slots);
+ if (!success) {
+ LOG(ERROR) << "Error sending FMQ packet";
+ // only use fallback execution path if the packet could not be sent
+ return getExecutionResult(V1_0::ErrorStatus::GENERAL_FAILURE, {}, kNoTiming12,
+ /*fallback=*/true);
+ }
+
+ // get result packet
+ const auto result = mResultChannelReceiver->getBlocking();
+ if (!result) {
+ LOG(ERROR) << "Error retrieving FMQ packet";
+ // only use fallback execution path if the packet could not be sent
+ return getExecutionResult(V1_0::ErrorStatus::GENERAL_FAILURE, {}, kNoTiming12,
+ /*fallback=*/false);
+ }
+
+ // unpack results and return (only use fallback execution path if the
+ // packet could not be sent)
+ auto [status, outputShapes, timing] = std::move(*result);
+ return getExecutionResult(status, std::move(outputShapes), timing, /*fallback=*/false);
+}
+
+void ExecutionBurstController::freeMemory(intptr_t key) {
+ std::lock_guard<std::mutex> guard(mMutex);
+
+ bool valid;
+ int32_t slot;
+ std::tie(valid, slot) = mMemoryCache->freeMemory(key);
+ if (valid) {
+ mBurstContext->freeMemory(slot).isOk();
+ }
+}
+
+} // namespace android::nn
diff --git a/neuralnetworks/1.2/utils/src/ExecutionBurstServer.cpp b/neuralnetworks/1.2/utils/src/ExecutionBurstServer.cpp
new file mode 100644
index 0000000..022548d
--- /dev/null
+++ b/neuralnetworks/1.2/utils/src/ExecutionBurstServer.cpp
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ExecutionBurstServer"
+
+#include "ExecutionBurstServer.h"
+
+#include <android-base/logging.h>
+
+#include <algorithm>
+#include <cstring>
+#include <limits>
+#include <map>
+#include <memory>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+#include "ExecutionBurstUtils.h"
+#include "HalInterfaces.h"
+#include "Tracing.h"
+
+namespace android::nn {
+namespace {
+
+// DefaultBurstExecutorWithCache adapts an IPreparedModel so that it can be
+// used as an IBurstExecutorWithCache. Specifically, the cache simply stores the
+// hidl_memory object, and the execution forwards calls to the provided
+// IPreparedModel's "executeSynchronously" method. With this class, hidl_memory
+// must be mapped and unmapped for each execution.
+class DefaultBurstExecutorWithCache : public ExecutionBurstServer::IBurstExecutorWithCache {
+ public:
+ DefaultBurstExecutorWithCache(V1_2::IPreparedModel* preparedModel)
+ : mpPreparedModel(preparedModel) {}
+
+ bool isCacheEntryPresent(int32_t slot) const override {
+ const auto it = mMemoryCache.find(slot);
+ return (it != mMemoryCache.end()) && it->second.valid();
+ }
+
+ void addCacheEntry(const hardware::hidl_memory& memory, int32_t slot) override {
+ mMemoryCache[slot] = memory;
+ }
+
+ void removeCacheEntry(int32_t slot) override { mMemoryCache.erase(slot); }
+
+ std::tuple<V1_0::ErrorStatus, hardware::hidl_vec<V1_2::OutputShape>, V1_2::Timing> execute(
+ const V1_0::Request& request, const std::vector<int32_t>& slots,
+ V1_2::MeasureTiming measure) override {
+ // convert slots to pools
+ hardware::hidl_vec<hardware::hidl_memory> pools(slots.size());
+ std::transform(slots.begin(), slots.end(), pools.begin(),
+ [this](int32_t slot) { return mMemoryCache[slot]; });
+
+ // create full request
+ V1_0::Request fullRequest = request;
+ fullRequest.pools = std::move(pools);
+
+ // setup execution
+ V1_0::ErrorStatus returnedStatus = V1_0::ErrorStatus::GENERAL_FAILURE;
+ hardware::hidl_vec<V1_2::OutputShape> returnedOutputShapes;
+ V1_2::Timing returnedTiming;
+ auto cb = [&returnedStatus, &returnedOutputShapes, &returnedTiming](
+ V1_0::ErrorStatus status,
+ const hardware::hidl_vec<V1_2::OutputShape>& outputShapes,
+ const V1_2::Timing& timing) {
+ returnedStatus = status;
+ returnedOutputShapes = outputShapes;
+ returnedTiming = timing;
+ };
+
+ // execute
+ const hardware::Return<void> ret =
+ mpPreparedModel->executeSynchronously(fullRequest, measure, cb);
+ if (!ret.isOk() || returnedStatus != V1_0::ErrorStatus::NONE) {
+ LOG(ERROR) << "IPreparedModelAdapter::execute -- Error executing";
+ return {returnedStatus, std::move(returnedOutputShapes), kNoTiming};
+ }
+
+ return std::make_tuple(returnedStatus, std::move(returnedOutputShapes), returnedTiming);
+ }
+
+ private:
+ V1_2::IPreparedModel* const mpPreparedModel;
+ std::map<int32_t, hardware::hidl_memory> mMemoryCache;
+};
+
+} // anonymous namespace
+
+// ExecutionBurstServer methods
+
+sp<ExecutionBurstServer> ExecutionBurstServer::create(
+ const sp<IBurstCallback>& callback, const MQDescriptorSync<FmqRequestDatum>& requestChannel,
+ const MQDescriptorSync<FmqResultDatum>& resultChannel,
+ std::shared_ptr<IBurstExecutorWithCache> executorWithCache,
+ std::chrono::microseconds pollingTimeWindow) {
+ // check inputs
+ if (callback == nullptr || executorWithCache == nullptr) {
+ LOG(ERROR) << "ExecutionBurstServer::create passed a nullptr";
+ return nullptr;
+ }
+
+ // create FMQ objects
+ std::unique_ptr<RequestChannelReceiver> requestChannelReceiver =
+ RequestChannelReceiver::create(requestChannel, pollingTimeWindow);
+ std::unique_ptr<ResultChannelSender> resultChannelSender =
+ ResultChannelSender::create(resultChannel);
+
+ // check FMQ objects
+ if (!requestChannelReceiver || !resultChannelSender) {
+ LOG(ERROR) << "ExecutionBurstServer::create failed to create FastMessageQueue";
+ return nullptr;
+ }
+
+ // make and return context
+ return new ExecutionBurstServer(callback, std::move(requestChannelReceiver),
+ std::move(resultChannelSender), std::move(executorWithCache));
+}
+
+sp<ExecutionBurstServer> ExecutionBurstServer::create(
+ const sp<IBurstCallback>& callback, const MQDescriptorSync<FmqRequestDatum>& requestChannel,
+ const MQDescriptorSync<FmqResultDatum>& resultChannel, V1_2::IPreparedModel* preparedModel,
+ std::chrono::microseconds pollingTimeWindow) {
+ // check relevant input
+ if (preparedModel == nullptr) {
+ LOG(ERROR) << "ExecutionBurstServer::create passed a nullptr";
+ return nullptr;
+ }
+
+ // adapt IPreparedModel to have caching
+ const std::shared_ptr<DefaultBurstExecutorWithCache> preparedModelAdapter =
+ std::make_shared<DefaultBurstExecutorWithCache>(preparedModel);
+
+ // make and return context
+ return ExecutionBurstServer::create(callback, requestChannel, resultChannel,
+ preparedModelAdapter, pollingTimeWindow);
+}
+
+ExecutionBurstServer::ExecutionBurstServer(
+ const sp<IBurstCallback>& callback, std::unique_ptr<RequestChannelReceiver> requestChannel,
+ std::unique_ptr<ResultChannelSender> resultChannel,
+ std::shared_ptr<IBurstExecutorWithCache> executorWithCache)
+ : mCallback(callback),
+ mRequestChannelReceiver(std::move(requestChannel)),
+ mResultChannelSender(std::move(resultChannel)),
+ mExecutorWithCache(std::move(executorWithCache)) {
+ // TODO: highly document the threading behavior of this class
+ mWorker = std::thread([this] { task(); });
+}
+
+ExecutionBurstServer::~ExecutionBurstServer() {
+ // set teardown flag
+ mTeardown = true;
+ mRequestChannelReceiver->invalidate();
+
+ // wait for task thread to end
+ mWorker.join();
+}
+
+hardware::Return<void> ExecutionBurstServer::freeMemory(int32_t slot) {
+ std::lock_guard<std::mutex> hold(mMutex);
+ mExecutorWithCache->removeCacheEntry(slot);
+ return hardware::Void();
+}
+
+void ExecutionBurstServer::ensureCacheEntriesArePresentLocked(const std::vector<int32_t>& slots) {
+ const auto slotIsKnown = [this](int32_t slot) {
+ return mExecutorWithCache->isCacheEntryPresent(slot);
+ };
+
+ // find unique unknown slots
+ std::vector<int32_t> unknownSlots = slots;
+ auto unknownSlotsEnd = unknownSlots.end();
+ std::sort(unknownSlots.begin(), unknownSlotsEnd);
+ unknownSlotsEnd = std::unique(unknownSlots.begin(), unknownSlotsEnd);
+ unknownSlotsEnd = std::remove_if(unknownSlots.begin(), unknownSlotsEnd, slotIsKnown);
+ unknownSlots.erase(unknownSlotsEnd, unknownSlots.end());
+
+ // quick-exit if all slots are known
+ if (unknownSlots.empty()) {
+ return;
+ }
+
+ V1_0::ErrorStatus errorStatus = V1_0::ErrorStatus::GENERAL_FAILURE;
+ std::vector<hardware::hidl_memory> returnedMemories;
+ auto cb = [&errorStatus, &returnedMemories](
+ V1_0::ErrorStatus status,
+ const hardware::hidl_vec<hardware::hidl_memory>& memories) {
+ errorStatus = status;
+ returnedMemories = memories;
+ };
+
+ const hardware::Return<void> ret = mCallback->getMemories(unknownSlots, cb);
+
+ if (!ret.isOk() || errorStatus != V1_0::ErrorStatus::NONE ||
+ returnedMemories.size() != unknownSlots.size()) {
+ LOG(ERROR) << "Error retrieving memories";
+ return;
+ }
+
+ // add memories to unknown slots
+ for (size_t i = 0; i < unknownSlots.size(); ++i) {
+ mExecutorWithCache->addCacheEntry(returnedMemories[i], unknownSlots[i]);
+ }
+}
+
+void ExecutionBurstServer::task() {
+ // loop until the burst object is being destroyed
+ while (!mTeardown) {
+ // receive request
+ auto arguments = mRequestChannelReceiver->getBlocking();
+
+ // if the request packet was not properly received, return a generic
+ // error and skip the execution
+ //
+ // if the burst is being torn down, skip the execution so the "task"
+ // function can end
+ if (!arguments) {
+ if (!mTeardown) {
+ mResultChannelSender->send(V1_0::ErrorStatus::GENERAL_FAILURE, {}, kNoTiming);
+ }
+ continue;
+ }
+
+ // otherwise begin tracing execution
+ NNTRACE_FULL(NNTRACE_LAYER_IPC, NNTRACE_PHASE_EXECUTION,
+ "ExecutionBurstServer getting memory, executing, and returning results");
+
+ // unpack the arguments; types are Request, std::vector<int32_t>, and
+ // MeasureTiming, respectively
+ const auto [requestWithoutPools, slotsOfPools, measure] = std::move(*arguments);
+
+ // ensure executor with cache has required memory
+ std::lock_guard<std::mutex> hold(mMutex);
+ ensureCacheEntriesArePresentLocked(slotsOfPools);
+
+ // perform computation; types are ErrorStatus, hidl_vec<OutputShape>,
+ // and Timing, respectively
+ const auto [errorStatus, outputShapes, returnedTiming] =
+ mExecutorWithCache->execute(requestWithoutPools, slotsOfPools, measure);
+
+ // return result
+ mResultChannelSender->send(errorStatus, outputShapes, returnedTiming);
+ }
+}
+
+} // namespace android::nn
diff --git a/neuralnetworks/1.2/utils/src/ExecutionBurstUtils.cpp b/neuralnetworks/1.2/utils/src/ExecutionBurstUtils.cpp
new file mode 100644
index 0000000..f0275f9
--- /dev/null
+++ b/neuralnetworks/1.2/utils/src/ExecutionBurstUtils.cpp
@@ -0,0 +1,749 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ExecutionBurstUtils"
+
+#include "ExecutionBurstUtils.h"
+
+#include <android-base/logging.h>
+#include <android/hardware/neuralnetworks/1.0/types.h>
+#include <android/hardware/neuralnetworks/1.1/types.h>
+#include <android/hardware/neuralnetworks/1.2/types.h>
+#include <fmq/MessageQueue.h>
+#include <hidl/MQDescriptor.h>
+
+#include <atomic>
+#include <chrono>
+#include <memory>
+#include <thread>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+namespace android::hardware::neuralnetworks::V1_2::utils {
+namespace {
+
+constexpr V1_2::Timing kNoTiming = {std::numeric_limits<uint64_t>::max(),
+ std::numeric_limits<uint64_t>::max()};
+
+}
+
+// serialize a request into a packet
+std::vector<FmqRequestDatum> serialize(const V1_0::Request& request, V1_2::MeasureTiming measure,
+ const std::vector<int32_t>& slots) {
+ // count how many elements need to be sent for a request
+ size_t count = 2 + request.inputs.size() + request.outputs.size() + request.pools.size();
+ for (const auto& input : request.inputs) {
+ count += input.dimensions.size();
+ }
+ for (const auto& output : request.outputs) {
+ count += output.dimensions.size();
+ }
+
+ // create buffer to temporarily store elements
+ std::vector<FmqRequestDatum> data;
+ data.reserve(count);
+
+ // package packetInfo
+ {
+ FmqRequestDatum datum;
+ datum.packetInformation(
+ {/*.packetSize=*/static_cast<uint32_t>(count),
+ /*.numberOfInputOperands=*/static_cast<uint32_t>(request.inputs.size()),
+ /*.numberOfOutputOperands=*/static_cast<uint32_t>(request.outputs.size()),
+ /*.numberOfPools=*/static_cast<uint32_t>(request.pools.size())});
+ data.push_back(datum);
+ }
+
+ // package input data
+ for (const auto& input : request.inputs) {
+ // package operand information
+ FmqRequestDatum datum;
+ datum.inputOperandInformation(
+ {/*.hasNoValue=*/input.hasNoValue,
+ /*.location=*/input.location,
+ /*.numberOfDimensions=*/static_cast<uint32_t>(input.dimensions.size())});
+ data.push_back(datum);
+
+ // package operand dimensions
+ for (uint32_t dimension : input.dimensions) {
+ FmqRequestDatum datum;
+ datum.inputOperandDimensionValue(dimension);
+ data.push_back(datum);
+ }
+ }
+
+ // package output data
+ for (const auto& output : request.outputs) {
+ // package operand information
+ FmqRequestDatum datum;
+ datum.outputOperandInformation(
+ {/*.hasNoValue=*/output.hasNoValue,
+ /*.location=*/output.location,
+ /*.numberOfDimensions=*/static_cast<uint32_t>(output.dimensions.size())});
+ data.push_back(datum);
+
+ // package operand dimensions
+ for (uint32_t dimension : output.dimensions) {
+ FmqRequestDatum datum;
+ datum.outputOperandDimensionValue(dimension);
+ data.push_back(datum);
+ }
+ }
+
+ // package pool identifier
+ for (int32_t slot : slots) {
+ FmqRequestDatum datum;
+ datum.poolIdentifier(slot);
+ data.push_back(datum);
+ }
+
+ // package measureTiming
+ {
+ FmqRequestDatum datum;
+ datum.measureTiming(measure);
+ data.push_back(datum);
+ }
+
+ // return packet
+ return data;
+}
+
+// serialize result
+std::vector<FmqResultDatum> serialize(V1_0::ErrorStatus errorStatus,
+ const std::vector<V1_2::OutputShape>& outputShapes,
+ V1_2::Timing timing) {
+ // count how many elements need to be sent for a request
+ size_t count = 2 + outputShapes.size();
+ for (const auto& outputShape : outputShapes) {
+ count += outputShape.dimensions.size();
+ }
+
+ // create buffer to temporarily store elements
+ std::vector<FmqResultDatum> data;
+ data.reserve(count);
+
+ // package packetInfo
+ {
+ FmqResultDatum datum;
+ datum.packetInformation({/*.packetSize=*/static_cast<uint32_t>(count),
+ /*.errorStatus=*/errorStatus,
+ /*.numberOfOperands=*/static_cast<uint32_t>(outputShapes.size())});
+ data.push_back(datum);
+ }
+
+ // package output shape data
+ for (const auto& operand : outputShapes) {
+ // package operand information
+ FmqResultDatum::OperandInformation info{};
+ info.isSufficient = operand.isSufficient;
+ info.numberOfDimensions = static_cast<uint32_t>(operand.dimensions.size());
+
+ FmqResultDatum datum;
+ datum.operandInformation(info);
+ data.push_back(datum);
+
+ // package operand dimensions
+ for (uint32_t dimension : operand.dimensions) {
+ FmqResultDatum datum;
+ datum.operandDimensionValue(dimension);
+ data.push_back(datum);
+ }
+ }
+
+ // package executionTiming
+ {
+ FmqResultDatum datum;
+ datum.executionTiming(timing);
+ data.push_back(datum);
+ }
+
+ // return result
+ return data;
+}
+
+// deserialize request
+std::optional<std::tuple<V1_0::Request, std::vector<int32_t>, V1_2::MeasureTiming>> deserialize(
+ const std::vector<FmqRequestDatum>& data) {
+ using discriminator = FmqRequestDatum::hidl_discriminator;
+
+ size_t index = 0;
+
+ // validate packet information
+ if (data.size() == 0 || data[index].getDiscriminator() != discriminator::packetInformation) {
+ LOG(ERROR) << "FMQ Request packet ill-formed";
+ return std::nullopt;
+ }
+
+ // unpackage packet information
+ const FmqRequestDatum::PacketInformation& packetInfo = data[index].packetInformation();
+ index++;
+ const uint32_t packetSize = packetInfo.packetSize;
+ const uint32_t numberOfInputOperands = packetInfo.numberOfInputOperands;
+ const uint32_t numberOfOutputOperands = packetInfo.numberOfOutputOperands;
+ const uint32_t numberOfPools = packetInfo.numberOfPools;
+
+ // verify packet size
+ if (data.size() != packetSize) {
+ LOG(ERROR) << "FMQ Request packet ill-formed";
+ return std::nullopt;
+ }
+
+ // unpackage input operands
+ std::vector<V1_0::RequestArgument> inputs;
+ inputs.reserve(numberOfInputOperands);
+ for (size_t operand = 0; operand < numberOfInputOperands; ++operand) {
+ // validate input operand information
+ if (data[index].getDiscriminator() != discriminator::inputOperandInformation) {
+ LOG(ERROR) << "FMQ Request packet ill-formed";
+ return std::nullopt;
+ }
+
+ // unpackage operand information
+ const FmqRequestDatum::OperandInformation& operandInfo =
+ data[index].inputOperandInformation();
+ index++;
+ const bool hasNoValue = operandInfo.hasNoValue;
+ const V1_0::DataLocation location = operandInfo.location;
+ const uint32_t numberOfDimensions = operandInfo.numberOfDimensions;
+
+ // unpackage operand dimensions
+ std::vector<uint32_t> dimensions;
+ dimensions.reserve(numberOfDimensions);
+ for (size_t i = 0; i < numberOfDimensions; ++i) {
+ // validate dimension
+ if (data[index].getDiscriminator() != discriminator::inputOperandDimensionValue) {
+ LOG(ERROR) << "FMQ Request packet ill-formed";
+ return std::nullopt;
+ }
+
+ // unpackage dimension
+ const uint32_t dimension = data[index].inputOperandDimensionValue();
+ index++;
+
+ // store result
+ dimensions.push_back(dimension);
+ }
+
+ // store result
+ inputs.push_back(
+ {/*.hasNoValue=*/hasNoValue, /*.location=*/location, /*.dimensions=*/dimensions});
+ }
+
+ // unpackage output operands
+ std::vector<V1_0::RequestArgument> outputs;
+ outputs.reserve(numberOfOutputOperands);
+ for (size_t operand = 0; operand < numberOfOutputOperands; ++operand) {
+ // validate output operand information
+ if (data[index].getDiscriminator() != discriminator::outputOperandInformation) {
+ LOG(ERROR) << "FMQ Request packet ill-formed";
+ return std::nullopt;
+ }
+
+ // unpackage operand information
+ const FmqRequestDatum::OperandInformation& operandInfo =
+ data[index].outputOperandInformation();
+ index++;
+ const bool hasNoValue = operandInfo.hasNoValue;
+ const V1_0::DataLocation location = operandInfo.location;
+ const uint32_t numberOfDimensions = operandInfo.numberOfDimensions;
+
+ // unpackage operand dimensions
+ std::vector<uint32_t> dimensions;
+ dimensions.reserve(numberOfDimensions);
+ for (size_t i = 0; i < numberOfDimensions; ++i) {
+ // validate dimension
+ if (data[index].getDiscriminator() != discriminator::outputOperandDimensionValue) {
+ LOG(ERROR) << "FMQ Request packet ill-formed";
+ return std::nullopt;
+ }
+
+ // unpackage dimension
+ const uint32_t dimension = data[index].outputOperandDimensionValue();
+ index++;
+
+ // store result
+ dimensions.push_back(dimension);
+ }
+
+ // store result
+ outputs.push_back(
+ {/*.hasNoValue=*/hasNoValue, /*.location=*/location, /*.dimensions=*/dimensions});
+ }
+
+ // unpackage pools
+ std::vector<int32_t> slots;
+ slots.reserve(numberOfPools);
+ for (size_t pool = 0; pool < numberOfPools; ++pool) {
+ // validate input operand information
+ if (data[index].getDiscriminator() != discriminator::poolIdentifier) {
+ LOG(ERROR) << "FMQ Request packet ill-formed";
+ return std::nullopt;
+ }
+
+ // unpackage operand information
+ const int32_t poolId = data[index].poolIdentifier();
+ index++;
+
+ // store result
+ slots.push_back(poolId);
+ }
+
+ // validate measureTiming
+ if (data[index].getDiscriminator() != discriminator::measureTiming) {
+ LOG(ERROR) << "FMQ Request packet ill-formed";
+ return std::nullopt;
+ }
+
+ // unpackage measureTiming
+ const V1_2::MeasureTiming measure = data[index].measureTiming();
+ index++;
+
+ // validate packet information
+ if (index != packetSize) {
+ LOG(ERROR) << "FMQ Result packet ill-formed";
+ return std::nullopt;
+ }
+
+ // return request
+ V1_0::Request request = {/*.inputs=*/inputs, /*.outputs=*/outputs, /*.pools=*/{}};
+ return std::make_tuple(std::move(request), std::move(slots), measure);
+}
+
+// deserialize a packet into the result
+std::optional<std::tuple<V1_0::ErrorStatus, std::vector<V1_2::OutputShape>, V1_2::Timing>>
+deserialize(const std::vector<FmqResultDatum>& data) {
+ using discriminator = FmqResultDatum::hidl_discriminator;
+
+ std::vector<V1_2::OutputShape> outputShapes;
+ size_t index = 0;
+
+ // validate packet information
+ if (data.size() == 0 || data[index].getDiscriminator() != discriminator::packetInformation) {
+ LOG(ERROR) << "FMQ Result packet ill-formed";
+ return std::nullopt;
+ }
+
+ // unpackage packet information
+ const FmqResultDatum::PacketInformation& packetInfo = data[index].packetInformation();
+ index++;
+ const uint32_t packetSize = packetInfo.packetSize;
+ const V1_0::ErrorStatus errorStatus = packetInfo.errorStatus;
+ const uint32_t numberOfOperands = packetInfo.numberOfOperands;
+
+ // verify packet size
+ if (data.size() != packetSize) {
+ LOG(ERROR) << "FMQ Result packet ill-formed";
+ return std::nullopt;
+ }
+
+ // unpackage operands
+ for (size_t operand = 0; operand < numberOfOperands; ++operand) {
+ // validate operand information
+ if (data[index].getDiscriminator() != discriminator::operandInformation) {
+ LOG(ERROR) << "FMQ Result packet ill-formed";
+ return std::nullopt;
+ }
+
+ // unpackage operand information
+ const FmqResultDatum::OperandInformation& operandInfo = data[index].operandInformation();
+ index++;
+ const bool isSufficient = operandInfo.isSufficient;
+ const uint32_t numberOfDimensions = operandInfo.numberOfDimensions;
+
+ // unpackage operand dimensions
+ std::vector<uint32_t> dimensions;
+ dimensions.reserve(numberOfDimensions);
+ for (size_t i = 0; i < numberOfDimensions; ++i) {
+ // validate dimension
+ if (data[index].getDiscriminator() != discriminator::operandDimensionValue) {
+ LOG(ERROR) << "FMQ Result packet ill-formed";
+ return std::nullopt;
+ }
+
+ // unpackage dimension
+ const uint32_t dimension = data[index].operandDimensionValue();
+ index++;
+
+ // store result
+ dimensions.push_back(dimension);
+ }
+
+ // store result
+ outputShapes.push_back({/*.dimensions=*/dimensions, /*.isSufficient=*/isSufficient});
+ }
+
+ // validate execution timing
+ if (data[index].getDiscriminator() != discriminator::executionTiming) {
+ LOG(ERROR) << "FMQ Result packet ill-formed";
+ return std::nullopt;
+ }
+
+ // unpackage execution timing
+ const V1_2::Timing timing = data[index].executionTiming();
+ index++;
+
+ // validate packet information
+ if (index != packetSize) {
+ LOG(ERROR) << "FMQ Result packet ill-formed";
+ return std::nullopt;
+ }
+
+ // return result
+ return std::make_tuple(errorStatus, std::move(outputShapes), timing);
+}
+
+V1_0::ErrorStatus legacyConvertResultCodeToErrorStatus(int resultCode) {
+ return convertToV1_0(convertResultCodeToErrorStatus(resultCode));
+}
+
+// RequestChannelSender methods
+
+std::pair<std::unique_ptr<RequestChannelSender>, const FmqRequestDescriptor*>
+RequestChannelSender::create(size_t channelLength) {
+ std::unique_ptr<FmqRequestChannel> fmqRequestChannel =
+ std::make_unique<FmqRequestChannel>(channelLength, /*confEventFlag=*/true);
+ if (!fmqRequestChannel->isValid()) {
+ LOG(ERROR) << "Unable to create RequestChannelSender";
+ return {nullptr, nullptr};
+ }
+
+ const FmqRequestDescriptor* descriptor = fmqRequestChannel->getDesc();
+ return std::make_pair(std::make_unique<RequestChannelSender>(std::move(fmqRequestChannel)),
+ descriptor);
+}
+
+RequestChannelSender::RequestChannelSender(std::unique_ptr<FmqRequestChannel> fmqRequestChannel)
+ : mFmqRequestChannel(std::move(fmqRequestChannel)) {}
+
+bool RequestChannelSender::send(const V1_0::Request& request, V1_2::MeasureTiming measure,
+ const std::vector<int32_t>& slots) {
+ const std::vector<FmqRequestDatum> serialized = serialize(request, measure, slots);
+ return sendPacket(serialized);
+}
+
+bool RequestChannelSender::sendPacket(const std::vector<FmqRequestDatum>& packet) {
+ if (!mValid) {
+ return false;
+ }
+
+ if (packet.size() > mFmqRequestChannel->availableToWrite()) {
+ LOG(ERROR)
+ << "RequestChannelSender::sendPacket -- packet size exceeds size available in FMQ";
+ return false;
+ }
+
+ // Always send the packet with "blocking" because this signals the futex and
+ // unblocks the consumer if it is waiting on the futex.
+ return mFmqRequestChannel->writeBlocking(packet.data(), packet.size());
+}
+
+void RequestChannelSender::invalidate() {
+ mValid = false;
+}
+
+// RequestChannelReceiver methods
+
+std::unique_ptr<RequestChannelReceiver> RequestChannelReceiver::create(
+ const FmqRequestDescriptor& requestChannel, std::chrono::microseconds pollingTimeWindow) {
+ std::unique_ptr<FmqRequestChannel> fmqRequestChannel =
+ std::make_unique<FmqRequestChannel>(requestChannel);
+
+ if (!fmqRequestChannel->isValid()) {
+ LOG(ERROR) << "Unable to create RequestChannelReceiver";
+ return nullptr;
+ }
+ if (fmqRequestChannel->getEventFlagWord() == nullptr) {
+ LOG(ERROR)
+ << "RequestChannelReceiver::create was passed an MQDescriptor without an EventFlag";
+ return nullptr;
+ }
+
+ return std::make_unique<RequestChannelReceiver>(std::move(fmqRequestChannel),
+ pollingTimeWindow);
+}
+
+RequestChannelReceiver::RequestChannelReceiver(std::unique_ptr<FmqRequestChannel> fmqRequestChannel,
+ std::chrono::microseconds pollingTimeWindow)
+ : mFmqRequestChannel(std::move(fmqRequestChannel)), kPollingTimeWindow(pollingTimeWindow) {}
+
+std::optional<std::tuple<V1_0::Request, std::vector<int32_t>, V1_2::MeasureTiming>>
+RequestChannelReceiver::getBlocking() {
+ const auto packet = getPacketBlocking();
+ if (!packet) {
+ return std::nullopt;
+ }
+
+ return deserialize(*packet);
+}
+
+void RequestChannelReceiver::invalidate() {
+ mTeardown = true;
+
+ // force unblock
+ // ExecutionBurstServer is by default waiting on a request packet. If the
+ // client process destroys its burst object, the server may still be waiting
+ // on the futex. This force unblock wakes up any thread waiting on the
+ // futex.
+ // TODO: look for a different/better way to signal/notify the futex to wake
+ // up any thread waiting on it
+ FmqRequestDatum datum;
+ datum.packetInformation({/*.packetSize=*/0, /*.numberOfInputOperands=*/0,
+ /*.numberOfOutputOperands=*/0, /*.numberOfPools=*/0});
+ mFmqRequestChannel->writeBlocking(&datum, 1);
+}
+
+std::optional<std::vector<FmqRequestDatum>> RequestChannelReceiver::getPacketBlocking() {
+ if (mTeardown) {
+ return std::nullopt;
+ }
+
+ // First spend time polling if results are available in FMQ instead of
+ // waiting on the futex. Polling is more responsive (yielding lower
+ // latencies), but can take up more power, so only poll for a limited period
+ // of time.
+
+ auto& getCurrentTime = std::chrono::high_resolution_clock::now;
+ const auto timeToStopPolling = getCurrentTime() + kPollingTimeWindow;
+
+ while (getCurrentTime() < timeToStopPolling) {
+ // if class is being torn down, immediately return
+ if (mTeardown.load(std::memory_order_relaxed)) {
+ return std::nullopt;
+ }
+
+ // Check if data is available. If it is, immediately retrieve it and
+ // return.
+ const size_t available = mFmqRequestChannel->availableToRead();
+ if (available > 0) {
+ // This is the first point when we know an execution is occurring,
+ // so begin to collect systraces. Note that a similar systrace does
+ // not exist at the corresponding point in
+ // ResultChannelReceiver::getPacketBlocking because the execution is
+ // already in flight.
+ NNTRACE_FULL(NNTRACE_LAYER_IPC, NNTRACE_PHASE_EXECUTION,
+ "ExecutionBurstServer getting packet");
+ std::vector<FmqRequestDatum> packet(available);
+ const bool success = mFmqRequestChannel->read(packet.data(), available);
+ if (!success) {
+ LOG(ERROR) << "Error receiving packet";
+ return std::nullopt;
+ }
+ return std::make_optional(std::move(packet));
+ }
+ }
+
+ // If we get to this point, we either stopped polling because it was taking
+ // too long or polling was not allowed. Instead, perform a blocking call
+ // which uses a futex to save power.
+
+ // wait for request packet and read first element of request packet
+ FmqRequestDatum datum;
+ bool success = mFmqRequestChannel->readBlocking(&datum, 1);
+
+ // This is the first point when we know an execution is occurring, so begin
+ // to collect systraces. Note that a similar systrace does not exist at the
+ // corresponding point in ResultChannelReceiver::getPacketBlocking because
+ // the execution is already in flight.
+ NNTRACE_FULL(NNTRACE_LAYER_IPC, NNTRACE_PHASE_EXECUTION, "ExecutionBurstServer getting packet");
+
+ // retrieve remaining elements
+ // NOTE: all of the data is already available at this point, so there's no
+ // need to do a blocking wait to wait for more data. This is known because
+ // in FMQ, all writes are published (made available) atomically. Currently,
+ // the producer always publishes the entire packet in one function call, so
+ // if the first element of the packet is available, the remaining elements
+ // are also available.
+ const size_t count = mFmqRequestChannel->availableToRead();
+ std::vector<FmqRequestDatum> packet(count + 1);
+ std::memcpy(&packet.front(), &datum, sizeof(datum));
+ success &= mFmqRequestChannel->read(packet.data() + 1, count);
+
+ // terminate loop
+ if (mTeardown) {
+ return std::nullopt;
+ }
+
+ // ensure packet was successfully received
+ if (!success) {
+ LOG(ERROR) << "Error receiving packet";
+ return std::nullopt;
+ }
+
+ return std::make_optional(std::move(packet));
+}
+
+// ResultChannelSender methods
+
+std::unique_ptr<ResultChannelSender> ResultChannelSender::create(
+ const FmqResultDescriptor& resultChannel) {
+ std::unique_ptr<FmqResultChannel> fmqResultChannel =
+ std::make_unique<FmqResultChannel>(resultChannel);
+
+ if (!fmqResultChannel->isValid()) {
+ LOG(ERROR) << "Unable to create RequestChannelSender";
+ return nullptr;
+ }
+ if (fmqResultChannel->getEventFlagWord() == nullptr) {
+ LOG(ERROR) << "ResultChannelSender::create was passed an MQDescriptor without an EventFlag";
+ return nullptr;
+ }
+
+ return std::make_unique<ResultChannelSender>(std::move(fmqResultChannel));
+}
+
+ResultChannelSender::ResultChannelSender(std::unique_ptr<FmqResultChannel> fmqResultChannel)
+ : mFmqResultChannel(std::move(fmqResultChannel)) {}
+
+bool ResultChannelSender::send(V1_0::ErrorStatus errorStatus,
+ const std::vector<V1_2::OutputShape>& outputShapes,
+ V1_2::Timing timing) {
+ const std::vector<FmqResultDatum> serialized = serialize(errorStatus, outputShapes, timing);
+ return sendPacket(serialized);
+}
+
+bool ResultChannelSender::sendPacket(const std::vector<FmqResultDatum>& packet) {
+ if (packet.size() > mFmqResultChannel->availableToWrite()) {
+ LOG(ERROR)
+ << "ResultChannelSender::sendPacket -- packet size exceeds size available in FMQ";
+ const std::vector<FmqResultDatum> errorPacket =
+ serialize(V1_0::ErrorStatus::GENERAL_FAILURE, {}, kNoTiming);
+
+ // Always send the packet with "blocking" because this signals the futex
+ // and unblocks the consumer if it is waiting on the futex.
+ return mFmqResultChannel->writeBlocking(errorPacket.data(), errorPacket.size());
+ }
+
+ // Always send the packet with "blocking" because this signals the futex and
+ // unblocks the consumer if it is waiting on the futex.
+ return mFmqResultChannel->writeBlocking(packet.data(), packet.size());
+}
+
+// ResultChannelReceiver methods
+
+std::pair<std::unique_ptr<ResultChannelReceiver>, const FmqResultDescriptor*>
+ResultChannelReceiver::create(size_t channelLength, std::chrono::microseconds pollingTimeWindow) {
+ std::unique_ptr<FmqResultChannel> fmqResultChannel =
+ std::make_unique<FmqResultChannel>(channelLength, /*confEventFlag=*/true);
+ if (!fmqResultChannel->isValid()) {
+ LOG(ERROR) << "Unable to create ResultChannelReceiver";
+ return {nullptr, nullptr};
+ }
+
+ const FmqResultDescriptor* descriptor = fmqResultChannel->getDesc();
+ return std::make_pair(
+ std::make_unique<ResultChannelReceiver>(std::move(fmqResultChannel), pollingTimeWindow),
+ descriptor);
+}
+
+ResultChannelReceiver::ResultChannelReceiver(std::unique_ptr<FmqResultChannel> fmqResultChannel,
+ std::chrono::microseconds pollingTimeWindow)
+ : mFmqResultChannel(std::move(fmqResultChannel)), kPollingTimeWindow(pollingTimeWindow) {}
+
+std::optional<std::tuple<V1_0::ErrorStatus, std::vector<V1_2::OutputShape>, V1_2::Timing>>
+ResultChannelReceiver::getBlocking() {
+ const auto packet = getPacketBlocking();
+ if (!packet) {
+ return std::nullopt;
+ }
+
+ return deserialize(*packet);
+}
+
+void ResultChannelReceiver::invalidate() {
+ mValid = false;
+
+ // force unblock
+ // ExecutionBurstController waits on a result packet after sending a
+ // request. If the driver containing ExecutionBurstServer crashes, the
+ // controller may be waiting on the futex. This force unblock wakes up any
+ // thread waiting on the futex.
+ // TODO: look for a different/better way to signal/notify the futex to
+ // wake up any thread waiting on it
+ FmqResultDatum datum;
+ datum.packetInformation({/*.packetSize=*/0,
+ /*.errorStatus=*/V1_0::ErrorStatus::GENERAL_FAILURE,
+ /*.numberOfOperands=*/0});
+ mFmqResultChannel->writeBlocking(&datum, 1);
+}
+
+std::optional<std::vector<FmqResultDatum>> ResultChannelReceiver::getPacketBlocking() {
+ if (!mValid) {
+ return std::nullopt;
+ }
+
+ // First spend time polling if results are available in FMQ instead of
+ // waiting on the futex. Polling is more responsive (yielding lower
+ // latencies), but can take up more power, so only poll for a limited period
+ // of time.
+
+ auto& getCurrentTime = std::chrono::high_resolution_clock::now;
+ const auto timeToStopPolling = getCurrentTime() + kPollingTimeWindow;
+
+ while (getCurrentTime() < timeToStopPolling) {
+ // if class is being torn down, immediately return
+ if (!mValid.load(std::memory_order_relaxed)) {
+ return std::nullopt;
+ }
+
+ // Check if data is available. If it is, immediately retrieve it and
+ // return.
+ const size_t available = mFmqResultChannel->availableToRead();
+ if (available > 0) {
+ std::vector<FmqResultDatum> packet(available);
+ const bool success = mFmqResultChannel->read(packet.data(), available);
+ if (!success) {
+ LOG(ERROR) << "Error receiving packet";
+ return std::nullopt;
+ }
+ return std::make_optional(std::move(packet));
+ }
+ }
+
+ // If we get to this point, we either stopped polling because it was taking
+ // too long or polling was not allowed. Instead, perform a blocking call
+ // which uses a futex to save power.
+
+ // wait for result packet and read first element of result packet
+ FmqResultDatum datum;
+ bool success = mFmqResultChannel->readBlocking(&datum, 1);
+
+ // retrieve remaining elements
+ // NOTE: all of the data is already available at this point, so there's no
+ // need to do a blocking wait to wait for more data. This is known because
+ // in FMQ, all writes are published (made available) atomically. Currently,
+ // the producer always publishes the entire packet in one function call, so
+ // if the first element of the packet is available, the remaining elements
+ // are also available.
+ const size_t count = mFmqResultChannel->availableToRead();
+ std::vector<FmqResultDatum> packet(count + 1);
+ std::memcpy(&packet.front(), &datum, sizeof(datum));
+ success &= mFmqResultChannel->read(packet.data() + 1, count);
+
+ if (!mValid) {
+ return std::nullopt;
+ }
+
+ // ensure packet was successfully received
+ if (!success) {
+ LOG(ERROR) << "Error receiving packet";
+ return std::nullopt;
+ }
+
+ return std::make_optional(std::move(packet));
+}
+
+} // namespace android::hardware::neuralnetworks::V1_2::utils
diff --git a/neuralnetworks/1.2/utils/src/PreparedModel.cpp b/neuralnetworks/1.2/utils/src/PreparedModel.cpp
index 6d00082..6841c5e 100644
--- a/neuralnetworks/1.2/utils/src/PreparedModel.cpp
+++ b/neuralnetworks/1.2/utils/src/PreparedModel.cpp
@@ -27,6 +27,7 @@
#include <nnapi/IPreparedModel.h>
#include <nnapi/Result.h>
#include <nnapi/Types.h>
+#include <nnapi/hal/1.0/Burst.h>
#include <nnapi/hal/1.0/Conversions.h>
#include <nnapi/hal/CommonUtils.h>
#include <nnapi/hal/HandleError.h>
@@ -117,6 +118,10 @@
<< "IPreparedModel::executeFenced is not supported on 1.2 HAL service";
}
+nn::GeneralResult<nn::SharedBurst> PreparedModel::configureExecutionBurst() const {
+ return V1_0::utils::Burst::create(shared_from_this());
+}
+
std::any PreparedModel::getUnderlyingResource() const {
sp<V1_2::IPreparedModel> resource = kPreparedModel;
return resource;
diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h
index 664d87a..690fecc 100644
--- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h
+++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h
@@ -35,7 +35,8 @@
namespace android::hardware::neuralnetworks::V1_3::utils {
// Class that adapts V1_3::IPreparedModel to nn::IPreparedModel.
-class PreparedModel final : public nn::IPreparedModel {
+class PreparedModel final : public nn::IPreparedModel,
+ public std::enable_shared_from_this<PreparedModel> {
struct PrivateConstructorTag {};
public:
@@ -56,6 +57,8 @@
const nn::OptionalDuration& loopTimeoutDuration,
const nn::OptionalDuration& timeoutDurationAfterFence) const override;
+ nn::GeneralResult<nn::SharedBurst> configureExecutionBurst() const override;
+
std::any getUnderlyingResource() const override;
private:
diff --git a/neuralnetworks/1.3/utils/src/PreparedModel.cpp b/neuralnetworks/1.3/utils/src/PreparedModel.cpp
index 7b4b7ba..725e4f5 100644
--- a/neuralnetworks/1.3/utils/src/PreparedModel.cpp
+++ b/neuralnetworks/1.3/utils/src/PreparedModel.cpp
@@ -29,6 +29,7 @@
#include <nnapi/Result.h>
#include <nnapi/TypeUtils.h>
#include <nnapi/Types.h>
+#include <nnapi/hal/1.0/Burst.h>
#include <nnapi/hal/1.2/Conversions.h>
#include <nnapi/hal/CommonUtils.h>
#include <nnapi/hal/HandleError.h>
@@ -197,6 +198,10 @@
return std::make_pair(std::move(syncFence), std::move(callback));
}
+nn::GeneralResult<nn::SharedBurst> PreparedModel::configureExecutionBurst() const {
+ return V1_0::utils::Burst::create(shared_from_this());
+}
+
std::any PreparedModel::getUnderlyingResource() const {
sp<V1_3::IPreparedModel> resource = kPreparedModel;
return resource;
diff --git a/neuralnetworks/utils/common/include/nnapi/hal/InvalidBurst.h b/neuralnetworks/utils/common/include/nnapi/hal/InvalidBurst.h
new file mode 100644
index 0000000..83e60b6
--- /dev/null
+++ b/neuralnetworks/utils/common/include/nnapi/hal/InvalidBurst.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_BURST_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_BURST_H
+
+#include <nnapi/IBurst.h>
+#include <nnapi/Result.h>
+#include <nnapi/Types.h>
+
+#include <memory>
+#include <optional>
+#include <utility>
+
+namespace android::hardware::neuralnetworks::utils {
+
+class InvalidBurst final : public nn::IBurst {
+ public:
+ OptionalCacheHold cacheMemory(const nn::Memory& memory) const override;
+
+ nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> execute(
+ const nn::Request& request, nn::MeasureTiming measure) const override;
+};
+
+} // namespace android::hardware::neuralnetworks::utils
+
+#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_BURST_H
diff --git a/neuralnetworks/utils/common/include/nnapi/hal/InvalidPreparedModel.h b/neuralnetworks/utils/common/include/nnapi/hal/InvalidPreparedModel.h
index 985cddb..3e1dca7 100644
--- a/neuralnetworks/utils/common/include/nnapi/hal/InvalidPreparedModel.h
+++ b/neuralnetworks/utils/common/include/nnapi/hal/InvalidPreparedModel.h
@@ -40,6 +40,8 @@
const nn::OptionalDuration& loopTimeoutDuration,
const nn::OptionalDuration& timeoutDurationAfterFence) const override;
+ nn::GeneralResult<nn::SharedBurst> configureExecutionBurst() const override;
+
std::any getUnderlyingResource() const override;
};
diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientBurst.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientBurst.h
new file mode 100644
index 0000000..0df287f
--- /dev/null
+++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientBurst.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_RESILIENT_BURST_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_RESILIENT_BURST_H
+
+#include <android-base/thread_annotations.h>
+#include <nnapi/IBurst.h>
+#include <nnapi/Result.h>
+#include <nnapi/Types.h>
+
+#include <functional>
+#include <memory>
+#include <mutex>
+#include <optional>
+#include <utility>
+
+namespace android::hardware::neuralnetworks::utils {
+
+class ResilientBurst final : public nn::IBurst,
+ public std::enable_shared_from_this<ResilientBurst> {
+ struct PrivateConstructorTag {};
+
+ public:
+ using Factory = std::function<nn::GeneralResult<nn::SharedBurst>()>;
+
+ static nn::GeneralResult<std::shared_ptr<const ResilientBurst>> create(Factory makeBurst);
+
+ ResilientBurst(PrivateConstructorTag tag, Factory makeBurst, nn::SharedBurst burst);
+
+ nn::SharedBurst getBurst() const;
+ nn::GeneralResult<nn::SharedBurst> recover(const nn::IBurst* failingBurst) const;
+
+ OptionalCacheHold cacheMemory(const nn::Memory& memory) const override;
+
+ nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> execute(
+ const nn::Request& request, nn::MeasureTiming measure) const override;
+
+ private:
+ const Factory kMakeBurst;
+ mutable std::mutex mMutex;
+ mutable nn::SharedBurst mBurst GUARDED_BY(mMutex);
+};
+
+} // namespace android::hardware::neuralnetworks::utils
+
+#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_RESILIENT_BURST_H
diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h
index 9b8d924..a6c1b19 100644
--- a/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h
+++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h
@@ -30,7 +30,8 @@
namespace android::hardware::neuralnetworks::utils {
-class ResilientPreparedModel final : public nn::IPreparedModel {
+class ResilientPreparedModel final : public nn::IPreparedModel,
+ public std::enable_shared_from_this<ResilientPreparedModel> {
struct PrivateConstructorTag {};
public:
@@ -57,9 +58,14 @@
const nn::OptionalDuration& loopTimeoutDuration,
const nn::OptionalDuration& timeoutDurationAfterFence) const override;
+ nn::GeneralResult<nn::SharedBurst> configureExecutionBurst() const override;
+
std::any getUnderlyingResource() const override;
private:
+ bool isValidInternal() const EXCLUDES(mMutex);
+ nn::GeneralResult<nn::SharedBurst> configureExecutionBurstInternal() const;
+
const Factory kMakePreparedModel;
mutable std::mutex mMutex;
mutable nn::SharedPreparedModel mPreparedModel GUARDED_BY(mMutex);
diff --git a/neuralnetworks/utils/common/src/InvalidBurst.cpp b/neuralnetworks/utils/common/src/InvalidBurst.cpp
new file mode 100644
index 0000000..4ca6603
--- /dev/null
+++ b/neuralnetworks/utils/common/src/InvalidBurst.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "InvalidBurst.h"
+
+#include <nnapi/IBurst.h>
+#include <nnapi/Result.h>
+#include <nnapi/Types.h>
+
+#include <memory>
+#include <optional>
+#include <utility>
+
+namespace android::hardware::neuralnetworks::utils {
+
+InvalidBurst::OptionalCacheHold InvalidBurst::cacheMemory(const nn::Memory& /*memory*/) const {
+ return nullptr;
+}
+
+nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> InvalidBurst::execute(
+ const nn::Request& /*request*/, nn::MeasureTiming /*measure*/) const {
+ return NN_ERROR() << "InvalidBurst";
+}
+
+} // namespace android::hardware::neuralnetworks::utils
diff --git a/neuralnetworks/utils/common/src/InvalidPreparedModel.cpp b/neuralnetworks/utils/common/src/InvalidPreparedModel.cpp
index a46f4ac..9081e1f 100644
--- a/neuralnetworks/utils/common/src/InvalidPreparedModel.cpp
+++ b/neuralnetworks/utils/common/src/InvalidPreparedModel.cpp
@@ -42,6 +42,10 @@
return NN_ERROR() << "InvalidPreparedModel";
}
+nn::GeneralResult<nn::SharedBurst> InvalidPreparedModel::configureExecutionBurst() const {
+ return NN_ERROR() << "InvalidPreparedModel";
+}
+
std::any InvalidPreparedModel::getUnderlyingResource() const {
return {};
}
diff --git a/neuralnetworks/utils/common/src/ResilientBurst.cpp b/neuralnetworks/utils/common/src/ResilientBurst.cpp
new file mode 100644
index 0000000..0d3cb33
--- /dev/null
+++ b/neuralnetworks/utils/common/src/ResilientBurst.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ResilientBurst.h"
+
+#include <android-base/logging.h>
+#include <android-base/thread_annotations.h>
+#include <nnapi/IBurst.h>
+#include <nnapi/Result.h>
+#include <nnapi/TypeUtils.h>
+#include <nnapi/Types.h>
+
+#include <functional>
+#include <memory>
+#include <mutex>
+#include <optional>
+#include <utility>
+
+namespace android::hardware::neuralnetworks::utils {
+namespace {
+
+template <typename FnType>
+auto protect(const ResilientBurst& resilientBurst, const FnType& fn)
+ -> decltype(fn(*resilientBurst.getBurst())) {
+ auto burst = resilientBurst.getBurst();
+ auto result = fn(*burst);
+
+ // Immediately return if burst is not dead.
+ if (result.has_value() || result.error().code != nn::ErrorStatus::DEAD_OBJECT) {
+ return result;
+ }
+
+ // Attempt recovery and return if it fails.
+ auto maybeBurst = resilientBurst.recover(burst.get());
+ if (!maybeBurst.has_value()) {
+ auto [resultErrorMessage, resultErrorCode, resultOutputShapes] = std::move(result).error();
+ const auto& [recoveryErrorMessage, recoveryErrorCode] = maybeBurst.error();
+ return nn::error(resultErrorCode, std::move(resultOutputShapes))
+ << resultErrorMessage << ", and failed to recover dead burst object with error "
+ << recoveryErrorCode << ": " << recoveryErrorMessage;
+ }
+ burst = std::move(maybeBurst).value();
+
+ return fn(*burst);
+}
+
+} // namespace
+
+nn::GeneralResult<std::shared_ptr<const ResilientBurst>> ResilientBurst::create(Factory makeBurst) {
+ if (makeBurst == nullptr) {
+ return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
+ << "utils::ResilientBurst::create must have non-empty makeBurst";
+ }
+ auto burst = NN_TRY(makeBurst());
+ CHECK(burst != nullptr);
+ return std::make_shared<ResilientBurst>(PrivateConstructorTag{}, std::move(makeBurst),
+ std::move(burst));
+}
+
+ResilientBurst::ResilientBurst(PrivateConstructorTag /*tag*/, Factory makeBurst,
+ nn::SharedBurst burst)
+ : kMakeBurst(std::move(makeBurst)), mBurst(std::move(burst)) {
+ CHECK(kMakeBurst != nullptr);
+ CHECK(mBurst != nullptr);
+}
+
+nn::SharedBurst ResilientBurst::getBurst() const {
+ std::lock_guard guard(mMutex);
+ return mBurst;
+}
+
+nn::GeneralResult<nn::SharedBurst> ResilientBurst::recover(const nn::IBurst* failingBurst) const {
+ std::lock_guard guard(mMutex);
+
+ // Another caller updated the failing burst.
+ if (mBurst.get() != failingBurst) {
+ return mBurst;
+ }
+
+ mBurst = NN_TRY(kMakeBurst());
+ return mBurst;
+}
+
+ResilientBurst::OptionalCacheHold ResilientBurst::cacheMemory(const nn::Memory& memory) const {
+ return getBurst()->cacheMemory(memory);
+}
+
+nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> ResilientBurst::execute(
+ const nn::Request& request, nn::MeasureTiming measure) const {
+ const auto fn = [&request, measure](const nn::IBurst& burst) {
+ return burst.execute(request, measure);
+ };
+ return protect(*this, fn);
+}
+
+} // namespace android::hardware::neuralnetworks::utils
diff --git a/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp b/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp
index 667df2b..5dd5f99 100644
--- a/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp
+++ b/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp
@@ -16,6 +16,9 @@
#include "ResilientPreparedModel.h"
+#include "InvalidBurst.h"
+#include "ResilientBurst.h"
+
#include <android-base/logging.h>
#include <android-base/thread_annotations.h>
#include <nnapi/IPreparedModel.h>
@@ -124,8 +127,35 @@
return protect(*this, fn);
}
+nn::GeneralResult<nn::SharedBurst> ResilientPreparedModel::configureExecutionBurst() const {
+#if 0
+ auto self = shared_from_this();
+ ResilientBurst::Factory makeBurst =
+ [preparedModel = std::move(self)]() -> nn::GeneralResult<nn::SharedBurst> {
+ return preparedModel->configureExecutionBurst();
+ };
+ return ResilientBurst::create(std::move(makeBurst));
+#else
+ return configureExecutionBurstInternal();
+#endif
+}
+
std::any ResilientPreparedModel::getUnderlyingResource() const {
return getPreparedModel()->getUnderlyingResource();
}
+bool ResilientPreparedModel::isValidInternal() const {
+ return true;
+}
+
+nn::GeneralResult<nn::SharedBurst> ResilientPreparedModel::configureExecutionBurstInternal() const {
+ if (!isValidInternal()) {
+ return std::make_shared<const InvalidBurst>();
+ }
+ const auto fn = [](const nn::IPreparedModel& preparedModel) {
+ return preparedModel.configureExecutionBurst();
+ };
+ return protect(*this, fn);
+}
+
} // namespace android::hardware::neuralnetworks::utils
diff --git a/neuralnetworks/utils/common/test/MockPreparedModel.h b/neuralnetworks/utils/common/test/MockPreparedModel.h
index 928508e..418af61 100644
--- a/neuralnetworks/utils/common/test/MockPreparedModel.h
+++ b/neuralnetworks/utils/common/test/MockPreparedModel.h
@@ -35,6 +35,7 @@
const OptionalDuration& loopTimeoutDuration,
const OptionalDuration& timeoutDurationAfterFence),
(const, override));
+ MOCK_METHOD(GeneralResult<SharedBurst>, configureExecutionBurst, (), (const, override));
MOCK_METHOD(std::any, getUnderlyingResource, (), (const, override));
};
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
index 7166654..0b49b36 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
@@ -236,7 +236,12 @@
ALOGI("setSignalStrengthReportingCriteria_1_5_NGRAN_SSRSRP, rspInfo.error = %s\n",
toString(radioRsp_v1_5->rspInfo.error).c_str());
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error, {RadioError::NONE}));
+
+ // Allow REQUEST_NOT_SUPPORTED because some non-5G device may not support NGRAN for
+ // setSignalStrengthReportingCriteria_1_5()
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
}
/*
@@ -261,7 +266,12 @@
ALOGI("setSignalStrengthReportingCriteria_1_5_NGRAN_SSRSRQ, rspInfo.error = %s\n",
toString(radioRsp_v1_5->rspInfo.error).c_str());
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error, {RadioError::NONE}));
+
+ // Allow REQUEST_NOT_SUPPORTED because some non-5G device may not support NGRAN for
+ // setSignalStrengthReportingCriteria_1_5()
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
}
/*
@@ -307,7 +317,12 @@
ALOGI("setSignalStrengthReportingCriteria_1_5_NGRAN_SSSINR, rspInfo.error = %s\n",
toString(radioRsp_v1_5->rspInfo.error).c_str());
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error, {RadioError::NONE}));
+
+ // Allow REQUEST_NOT_SUPPORTED because some non-5G device may not support NGRAN for
+ // setSignalStrengthReportingCriteria_1_5()
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
}
/*
diff --git a/radio/1.6/IRadioIndication.hal b/radio/1.6/IRadioIndication.hal
index 1b56d40..a53d7c1 100644
--- a/radio/1.6/IRadioIndication.hal
+++ b/radio/1.6/IRadioIndication.hal
@@ -23,6 +23,7 @@
import @1.6::NetworkScanResult;
import @1.6::SignalStrength;
import @1.6::SetupDataCallResult;
+import @1.6::PhysicalChannelConfig;
/**
* Interface declaring unsolicited radio indications.
@@ -101,4 +102,15 @@
* CellInfo.
*/
oneway networkScanResult_1_6(RadioIndicationType type, NetworkScanResult result);
+
+ /**
+ * Indicates physical channel configurations.
+ *
+ * An empty configs list indicates that the radio is in idle mode.
+ *
+ * @param type Type of radio indication
+ * @param configs Vector of PhysicalChannelConfigs
+ */
+ oneway currentPhysicalChannelConfigs_1_6(RadioIndicationType type,
+ vec<PhysicalChannelConfig> configs);
};
diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal
index 594c208..d475ed3 100644
--- a/radio/1.6/types.hal
+++ b/radio/1.6/types.hal
@@ -23,7 +23,10 @@
import @1.0::RadioError;
import @1.0::RadioResponseType;
import @1.0::RegState;
+import @1.1::EutranBands;
+import @1.1::GeranBands;
import @1.1::ScanStatus;
+import @1.1::UtranBands;
import @1.2::Call;
import @1.2::CellInfoCdma;
import @1.2::CellConnectionStatus;
@@ -41,6 +44,7 @@
import @1.5::CellInfoWcdma;
import @1.5::CellInfoTdscdma;
import @1.5::LinkAddress;
+import @1.5::NgranBands;
import @1.5::RegStateResult.AccessTechnologySpecificInfo.Cdma2000RegistrationInfo;
import @1.5::RegStateResult.AccessTechnologySpecificInfo.EutranRegistrationInfo;
import @1.5::RegistrationFailCause;
@@ -347,7 +351,7 @@
/**
* The allocated pdu session id for this data call.
- * A value of -1 means no pdu session id was attached to this call.
+ * A value of 0 means no pdu session id was attached to this call.
*
* Reference: 3GPP TS 24.007 section 11.2.3.1b
*/
@@ -818,3 +822,70 @@
*/
SLICE_REJECTED = 0x8CC,
};
+
+struct PhysicalChannelConfig {
+ /** Connection status for cell. Valid values are PRIMARY_SERVING and SECONDARY_SERVING */
+ CellConnectionStatus status;
+
+ /** The radio technology for this physical channel */
+ RadioTechnology rat;
+
+ /** Downlink Absolute Radio Frequency Channel Number */
+ int32_t downlinkChannelNumber;
+
+ /** Uplink Absolute Radio Frequency Channel Number */
+ int32_t uplinkChannelNumber;
+
+ /** Downlink cell bandwidth, in kHz */
+ int32_t cellBandwidthDownlink;
+
+ /** Uplink cell bandwidth, in kHz */
+ int32_t cellBandwidthUplink;
+
+ /**
+ * A list of data calls mapped to this physical channel. The context id must match the cid of
+ * @1.5::SetupDataCallResult. An empty list means the physical channel has no data call mapped
+ * to it.
+ */
+ vec<int32_t> contextIds;
+
+ /**
+ * The physical cell identifier for this cell.
+ *
+ * In UTRAN, this value is primary scrambling code. The range is [0, 511].
+ * Reference: 3GPP TS 25.213 section 5.2.2.
+ *
+ * In EUTRAN, this value is physical layer cell identity. The range is [0, 503].
+ * Reference: 3GPP TS 36.211 section 6.11.
+ *
+ * In 5G RAN, this value is physical layer cell identity. The range is [0, 1007].
+ * Reference: 3GPP TS 38.211 section 7.4.2.1.
+ */
+ uint32_t physicalCellId;
+
+ /**
+ * The frequency band to scan.
+ */
+ safe_union Band {
+ /** Valid only if radioAccessNetwork = GERAN. */
+ GeranBands geranBand;
+ /** Valid only if radioAccessNetwork = UTRAN. */
+ UtranBands utranBand;
+ /** Valid only if radioAccessNetwork = EUTRAN. */
+ EutranBands eutranBand;
+ /** Valid only if radioAccessNetwork = NGRAN. */
+ NgranBands ngranBand;
+ } band;
+};
+
+/**
+ * Extended from @1.5 NgranBands
+ * IRadio 1.6 supports NGRAN bands up to V16.5.0
+ */
+enum NgranBands : @1.5::NgranBands {
+ /** 3GPP TS 38.101-1, Table 5.2-1: FR1 bands */
+ BAND_26 = 26,
+ BAND_46 = 46,
+ BAND_53 = 53,
+ BAND_96 = 96,
+};
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
index fbcd7a9..5fcfa3b 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
+++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
@@ -857,6 +857,11 @@
const ::android::hardware::hidl_vec<::android::hardware::radio::V1_6::CellInfo>&
records);
+ Return<void> currentPhysicalChannelConfigs_1_6(
+ RadioIndicationType type,
+ const ::android::hardware::hidl_vec<
+ ::android::hardware::radio::V1_6::PhysicalChannelConfig>& configs);
+
/* 1.5 Api */
Return<void> uiccApplicationsEnablementChanged(RadioIndicationType type, bool enabled);
diff --git a/radio/1.6/vts/functional/radio_indication.cpp b/radio/1.6/vts/functional/radio_indication.cpp
index bfc54c0..e7a9680 100644
--- a/radio/1.6/vts/functional/radio_indication.cpp
+++ b/radio/1.6/vts/functional/radio_indication.cpp
@@ -30,6 +30,13 @@
return Void();
}
+Return<void> RadioIndication_v1_6::currentPhysicalChannelConfigs_1_6(
+ RadioIndicationType /*type*/,
+ const ::android::hardware::hidl_vec<
+ ::android::hardware::radio::V1_6::PhysicalChannelConfig>& /*configs*/) {
+ return Void();
+}
+
/* 1.5 Apis */
Return<void> RadioIndication_v1_6::uiccApplicationsEnablementChanged(RadioIndicationType /*type*/,
bool /*enabled*/) {
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Algorithm.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Algorithm.aidl
index 46e0ae0..a6c3e65 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Algorithm.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Algorithm.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BeginResult.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BeginResult.aidl
index ed96485..84395af 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BeginResult.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BeginResult.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BlockMode.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BlockMode.aidl
index dddc9d8..e914823 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BlockMode.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BlockMode.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ByteArray.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ByteArray.aidl
index 3d18a26..cef8eca 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ByteArray.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ByteArray.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Certificate.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Certificate.aidl
index 9e0f8dc..2277831 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Certificate.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Certificate.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Digest.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Digest.aidl
index 8fc4d42..2e583ce 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Digest.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Digest.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/EcCurve.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/EcCurve.aidl
index 7c3f2f3..b372822 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/EcCurve.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/EcCurve.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl
index 8694b32..aa8c071 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl
index 9ea24f5..0d43d8d 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthenticatorType.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthenticatorType.aidl
index aef5ee0..9ab00c1 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthenticatorType.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthenticatorType.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl
index 3d08cfe..07c2844 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
@@ -21,9 +22,9 @@
android.hardware.security.keymint.KeyMintHardwareInfo getHardwareInfo();
android.hardware.security.keymint.VerificationToken verifyAuthorization(in long challenge, in android.hardware.security.keymint.HardwareAuthToken token);
void addRngEntropy(in byte[] data);
- void generateKey(in android.hardware.security.keymint.KeyParameter[] keyParams, out android.hardware.security.keymint.ByteArray generatedKeyBlob, out android.hardware.security.keymint.KeyCharacteristics generatedKeyCharacteristics, out android.hardware.security.keymint.Certificate[] outCertChain);
- void importKey(in android.hardware.security.keymint.KeyParameter[] inKeyParams, in android.hardware.security.keymint.KeyFormat inKeyFormat, in byte[] inKeyData, out android.hardware.security.keymint.ByteArray outImportedKeyBlob, out android.hardware.security.keymint.KeyCharacteristics outImportedKeyCharacteristics, out android.hardware.security.keymint.Certificate[] outCertChain);
- void importWrappedKey(in byte[] inWrappedKeyData, in byte[] inWrappingKeyBlob, in byte[] inMaskingKey, in android.hardware.security.keymint.KeyParameter[] inUnwrappingParams, in long inPasswordSid, in long inBiometricSid, out android.hardware.security.keymint.ByteArray outImportedKeyBlob, out android.hardware.security.keymint.KeyCharacteristics outImportedKeyCharacteristics);
+ android.hardware.security.keymint.KeyCreationResult generateKey(in android.hardware.security.keymint.KeyParameter[] keyParams);
+ android.hardware.security.keymint.KeyCreationResult importKey(in android.hardware.security.keymint.KeyParameter[] keyParams, in android.hardware.security.keymint.KeyFormat keyFormat, in byte[] keyData);
+ android.hardware.security.keymint.KeyCreationResult importWrappedKey(in byte[] wrappedKeyData, in byte[] wrappingKeyBlob, in byte[] maskingKey, in android.hardware.security.keymint.KeyParameter[] unwrappingParams, in long passwordSid, in long biometricSid);
byte[] upgradeKey(in byte[] inKeyBlobToUpgrade, in android.hardware.security.keymint.KeyParameter[] inUpgradeParams);
void deleteKey(in byte[] inKeyBlob);
void deleteAllKeys();
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl
index 8e3b0fc..08aa00a 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl
index fb4214c..49ea8af 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
@@ -18,6 +19,6 @@
package android.hardware.security.keymint;
@VintfStability
parcelable KeyCharacteristics {
- android.hardware.security.keymint.KeyParameter[] softwareEnforced;
- android.hardware.security.keymint.KeyParameter[] hardwareEnforced;
+ android.hardware.security.keymint.SecurityLevel securityLevel;
+ android.hardware.security.keymint.KeyParameter[] authorizations;
}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCreationResult.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCreationResult.aidl
new file mode 100644
index 0000000..4b9ac79
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCreationResult.aidl
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.security.keymint;
+@VintfStability
+parcelable KeyCreationResult {
+ byte[] keyBlob;
+ android.hardware.security.keymint.KeyCharacteristics[] keyCharacteristics;
+ android.hardware.security.keymint.Certificate[] certificateChain;
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyFormat.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyFormat.aidl
index f701c80..4eb5a78 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyFormat.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyFormat.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
index 5e9f7ae..0390ec9 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyOrigin.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyOrigin.aidl
index 9728bf9..e84cf74 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyOrigin.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyOrigin.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl
index 4985768..6829a2b 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterArray.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterArray.aidl
index 2c3b768..882ca89 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterArray.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterArray.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterValue.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterValue.aidl
index ecf20ad..6c11a92 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterValue.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterValue.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyPurpose.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyPurpose.aidl
index a6fd8c3..ff8d85a 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyPurpose.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyPurpose.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/PaddingMode.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/PaddingMode.aidl
index 2ecfa1e..6c61312 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/PaddingMode.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/PaddingMode.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/SecurityLevel.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/SecurityLevel.aidl
index 601693f..c4812ed 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/SecurityLevel.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/SecurityLevel.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl
index 814405c..ce12fed 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/TagType.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/TagType.aidl
index bb2766c..41c8832 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/TagType.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/TagType.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Timestamp.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Timestamp.aidl
index 4d5b659..963e66e 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Timestamp.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Timestamp.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/VerificationToken.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/VerificationToken.aidl
index 5c76816..7dc556c 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/VerificationToken.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/VerificationToken.aidl
@@ -2,13 +2,14 @@
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/security/keymint/aidl/android/hardware/security/keymint/Certificate.aidl b/security/keymint/aidl/android/hardware/security/keymint/Certificate.aidl
index a953859..0e5d898 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/Certificate.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/Certificate.aidl
@@ -17,9 +17,8 @@
package android.hardware.security.keymint;
/**
- * This encodes the IKeyMintDevice attestation generated certificate.
+ * This encodes an IKeyMintDevice certificate, generated for a KeyMint asymmetric public key.
*/
-
@VintfStability
parcelable Certificate {
/**
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
index 4944acb..820e135 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -18,10 +18,9 @@
import android.hardware.security.keymint.BeginResult;
import android.hardware.security.keymint.ByteArray;
-import android.hardware.security.keymint.Certificate;
import android.hardware.security.keymint.HardwareAuthToken;
import android.hardware.security.keymint.IKeyMintOperation;
-import android.hardware.security.keymint.KeyCharacteristics;
+import android.hardware.security.keymint.KeyCreationResult;
import android.hardware.security.keymint.KeyFormat;
import android.hardware.security.keymint.KeyParameter;
import android.hardware.security.keymint.KeyMintHardwareInfo;
@@ -126,16 +125,22 @@
* attacker can use them at will (though they're more secure than keys which can be
* exfiltrated). Therefore, IKeyMintDevice must enforce access controls.
*
- * Access controls are defined as an "authorization list" of tag/value pairs. Authorization tags
- * are 32-bit integers from the Tag enum, and the values are a variety of types, defined in the
- * TagType enum. Some tags may be repeated to specify multiple values. Whether a tag may be
- * repeated is specified in the documentation for the tag and in the TagType. When a key is
- * created or imported, the caller specifies an authorization list. The IKeyMintDevice must divide
- * the caller-provided authorizations into two lists, those it enforces in tee secure zone and
- * those enforced in the strongBox hardware. These two lists are returned as the "teeEnforced"
- * and "strongboxEnforced" elements of the KeyCharacteristics struct. Note that software enforced
- * authorization list entries are not returned because they are not enforced by keymint. The
- * IKeyMintDevice must also add the following authorizations to the appropriate list:
+ * Access controls are defined as "authorization lists" of tag/value pairs. Authorization tags are
+ * 32-bit integers from the Tag enum, and the values are a variety of types, defined in the TagType
+ * enum. Some tags may be repeated to specify multiple values. Whether a tag may be repeated is
+ * specified in the documentation for the tag and in the TagType. When a key is created or
+ * imported, the caller specifies a `key_description` authorization list. The IKeyMintDevice must
+ * determine which tags it can and cannot enforce, and at what SecurityLevel, and return an array of
+ * `KeyCharacteristics` structures that contains everything it will enforce, associated with the
+ * appropriate security level, which is one of SOFTWARE, TRUSTED_ENVIRONMENT and STRONGBOX.
+ * Typically, implementations will only return a single KeyCharacteristics structure, because
+ * everything they enforce is enforced at the same security level. There may be cases, however, for
+ * which multiple security levels are relevant. One example is that of a StrongBox IKeyMintDevice
+ * that relies on a TEE to enforce biometric user authentication. In that case, the generate/import
+ * methods must return two KeyCharacteristics structs, one with SecurityLevel::TRUSTED_ENVIRONMENT
+ * and the biometric authentication-related tags, and another with SecurityLevel::STRONGBOX and
+ * everything else. The IKeyMintDevice must also add the following authorizations to the
+ * appropriate list:
*
* o Tag::OS_VERSION
* o Tag::OS_PATCHLEVEL
@@ -148,26 +153,27 @@
* The caller must always provide the current date time in the keyParameter CREATION_DATETIME
* tags.
*
- * All authorization tags and their values, both teeEnforced and strongboxEnforced, including
- * unknown tags, must be cryptographically bound to the private/secret key material such that any
- * modification of the portion of the key blob that contains the authorization list makes it
- * impossible for the secure environment to obtain the private/secret key material. The
- * recommended approach to meet this requirement is to use the full set of authorization tags
- * associated with a key as input to a secure key derivation function used to derive a key that
- * is used to encrypt the private/secret key material.
+ * All authorization tags and their values enforced by an IKeyMintDevice must be cryptographically
+ * bound to the private/secret key material such that any modification of the portion of the key
+ * blob that contains the authorization list makes it impossible for the secure environment to
+ * obtain the private/secret key material. The recommended approach to meet this requirement is to
+ * use the full set of authorization tags associated with a key as input to a secure key derivation
+ * function used to derive a key (the KEK) that is used to encrypt the private/secret key material.
+ * Note that it is NOT acceptable to use a static KEK to encrypt the private/secret key material
+ * with an AEAD cipher mode, using the enforced authorization tags as AAD. This is because
+ * Tag::APPLICATION_DATA must not be included in the authorization tags stored in the key blob, but
+ * must be provided by the caller for every use. Assuming the Tag::APPLICATION_DATA value has
+ * sufficient entropy, this provides a cryptographic guarantee that an attacker cannot use a key
+ * without knowing the Tag::APPLICATION_DATA value, even if they compromise the IKeyMintDevice.
*
- * IKeyMintDevice implementations ignore any tags they cannot enforce and do not return them
- * in KeyCharacteristics. For example, Tag::ORIGINATION_EXPIRE_DATETIME provides the date and
- * time after which a key may not be used to encrypt or sign new messages. Unless the
- * IKeyMintDevice has access to a secure source of current date/time information, it is not
- * possible for the IKeyMintDevice to enforce this tag. An IKeyMintDevice implementation will
- * not rely on the non-secure world's notion of time, because it could be controlled by an
- * attacker. Similarly, it cannot rely on GPSr time, even if it has exclusive control of the
- * GPSr, because that might be spoofed by attacker RF signals.
- *
- * IKeyMintDevices do not use or enforce any tags they place in the softwareEnforced
- * list. The IKeyMintDevice caller must enforce them, and it is unnecessary to enforce them
- * twice.
+ * IKeyMintDevice implementations must ignore any tags they cannot enforce and must not return them
+ * in KeyCharacteristics. For example, Tag::ORIGINATION_EXPIRE_DATETIME provides the date and time
+ * after which a key may not be used to encrypt or sign new messages. Unless the IKeyMintDevice has
+ * access to a secure source of current date/time information, it is not possible for the
+ * IKeyMintDevice to enforce this tag. An IKeyMintDevice implementation will not rely on the
+ * non-secure world's notion of time, because it could be controlled by an attacker. Similarly, it
+ * cannot rely on GPSr time, even if it has exclusive control of the GPSr, because that might be
+ * spoofed by attacker RF signals.
*
* Some tags must be enforced by the IKeyMintDevice. See the detailed documentation on each Tag
* in Tag.aidl.
@@ -337,38 +343,9 @@
* provided in params. See above for detailed specifications of which tags are required
* for which types of keys.
*
- * @return generatedKeyBlob Opaque descriptor of the generated key. The recommended
- * implementation strategy is to include an encrypted copy of the key material, wrapped
- * in a key unavailable outside secure hardware.
- *
- * @return generatedKeyCharacteristics Description of the generated key, divided into two sets:
- * hardware-enforced and software-enforced. The description here applies equally
- * to the key characteristics lists returned by generateKey, importKey and
- * importWrappedKey. The characteristics returned by this parameter completely
- * describe the type and usage of the specified key.
- *
- * The rule that IKeyMintDevice implementations must use for deciding whether a
- * given tag belongs in the hardware-enforced or software-enforced list is that if
- * the meaning of the tag is fully assured by secure hardware, it is hardware
- * enforced. Otherwise, it's software enforced.
- *
- * @return outCertChain If the key is an asymmetric key, and proper keyparameters for
- * attestation (such as challenge) is provided, then this parameter will return the
- * attestation certificate. If the signing of the attestation certificate is from a
- * factory key, additional certificates back to the root attestation certificate will
- * also be provided. Clients will need to check root certificate against a known-good
- * value. The certificates must be DER-encoded. Caller needs to provide
- * CREATION_DATETIME as one of the attestation parameters, otherwise the attestation
- * certificate will not contain the creation datetime. The first certificate in the
- * vector is the attestation for the generated key itself, the next certificate is
- * the key that signs the first certificate, and so forth. The last certificate in
- * the chain is the root certificate. If the key is a symmetric key, then no
- * certificate will be returned and this variable will return empty. TODO: change
- * certificate return to a single certificate and make it nullable b/163604282.
+ * @return The result of key creation. See KeyCreationResult.aidl.
*/
- void generateKey(in KeyParameter[] keyParams, out ByteArray generatedKeyBlob,
- out KeyCharacteristics generatedKeyCharacteristics,
- out Certificate[] outCertChain);
+ KeyCreationResult generateKey(in KeyParameter[] keyParams);
/**
* Imports key material into an IKeyMintDevice. Key definition parameters and return values
@@ -396,29 +373,10 @@
*
* @param inKeyData The key material to import, in the format specified in keyFormat.
*
- * @return outImportedKeyBlob descriptor of the imported key. The format of the keyblob will
- * be the google specified keyblob format.
- *
- * @return outImportedKeyCharacteristics Description of the generated key. See the
- * keyCharacteristics description in generateKey.
- *
- * @return outCertChain If the key is an asymmetric key, and proper keyparameters for
- * attestation (such as challenge) is provided, then this parameter will return the
- * attestation certificate. If the signing of the attestation certificate is from a
- * factory key, additional certificates back to the root attestation certificate will
- * also be provided. Clients will need to check root certificate against a known-good
- * value. The certificates must be DER-encoded. Caller needs to provide
- * CREATION_DATETIME as one of the attestation parameters, otherwise the attestation
- * certificate will not contain the creation datetime. The first certificate in the
- * vector is the attestation for the generated key itself, the next certificate is
- * the key that signs the first certificate, and so forth. The last certificate in
- * the chain is the root certificate. If the key is a symmetric key, then no
- * certificate will be returned and this variable will return empty.
+ * @return The result of key creation. See KeyCreationResult.aidl.
*/
- void importKey(in KeyParameter[] inKeyParams, in KeyFormat inKeyFormat,
- in byte[] inKeyData, out ByteArray outImportedKeyBlob,
- out KeyCharacteristics outImportedKeyCharacteristics,
- out Certificate[] outCertChain);
+ KeyCreationResult importKey(in KeyParameter[] keyParams, in KeyFormat keyFormat,
+ in byte[] keyData);
/**
* Securely imports a key, or key pair, returning a key blob and a description of the imported
@@ -474,45 +432,38 @@
* 5. Perform the equivalent of calling importKey(keyParams, keyFormat, keyData), except
* that the origin tag should be set to SECURELY_IMPORTED.
*
- * @param inWrappingKeyBlob The opaque key descriptor returned by generateKey() or importKey().
+ * @param wrappingKeyBlob The opaque key descriptor returned by generateKey() or importKey().
* This key must have been created with Purpose::WRAP_KEY.
*
- * @param inMaskingKey The 32-byte value XOR'd with the transport key in the SecureWrappedKey
+ * @param maskingKey The 32-byte value XOR'd with the transport key in the SecureWrappedKey
* structure.
*
- * @param inUnwrappingParams must contain any parameters needed to perform the unwrapping
- * operation. For example, if the wrapping key is an AES key the block and padding
- * modes must be specified in this argument.
+ * @param unwrappingParams must contain any parameters needed to perform the unwrapping
+ * operation. For example, if the wrapping key is an AES key the block and padding modes
+ * must be specified in this argument.
*
- * @param inPasswordSid specifies the password secure ID (SID) of the user that owns the key
- * being installed. If the authorization list in wrappedKeyData contains a
- * Tag::USER_SECURE_IDwith a value that has the HardwareAuthenticatorType::PASSWORD
- * bit set, the constructed key must be bound to the SID value provided by this
- * argument. If the wrappedKeyData does not contain such a tag and value, this argument
- * must be ignored.
+ * @param passwordSid specifies the password secure ID (SID) of the user that owns the key being
+ * installed. If the authorization list in wrappedKeyData contains a
+ * Tag::USER_SECURE_IDwith a value that has the HardwareAuthenticatorType::PASSWORD bit
+ * set, the constructed key must be bound to the SID value provided by this argument. If
+ * the wrappedKeyData does not contain such a tag and value, this argument must be
+ * ignored.
*
- * @param inBiometricSid specifies the biometric secure ID (SID) of the user that owns the key
+ * @param biometricSid specifies the biometric secure ID (SID) of the user that owns the key
* being installed. If the authorization list in wrappedKeyData contains a
* Tag::USER_SECURE_ID with a value that has the HardwareAuthenticatorType::FINGERPRINT
* bit set, the constructed key must be bound to the SID value provided by this argument.
* If the wrappedKeyData does not contain such a tag and value, this argument must be
* ignored.
*
- * @return outImportedKeyBlob Opaque descriptor of the imported key. It is recommended that
- * the keyBlob contain a copy of the key material, wrapped in a key unavailable outside
- * secure hardware.
- *
- * @return outImportedKeyCharacteristics Description of the generated key. See the description
- * of keyCharacteristics parameter in generateKey.
+ * @return The result of key creation. See KeyCreationResult.aidl.
*/
- void importWrappedKey(in byte[] inWrappedKeyData,
- in byte[] inWrappingKeyBlob,
- in byte[] inMaskingKey,
- in KeyParameter[] inUnwrappingParams,
- in long inPasswordSid,
- in long inBiometricSid,
- out ByteArray outImportedKeyBlob,
- out KeyCharacteristics outImportedKeyCharacteristics);
+ KeyCreationResult importWrappedKey(in byte[] wrappedKeyData,
+ in byte[] wrappingKeyBlob,
+ in byte[] maskingKey,
+ in KeyParameter[] unwrappingParams,
+ in long passwordSid,
+ in long biometricSid);
/**
* Upgrades an old key blob. Keys can become "old" in two ways: IKeyMintDevice can be
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyCharacteristics.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyCharacteristics.aidl
index 0801868..edd4d8f 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyCharacteristics.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyCharacteristics.aidl
@@ -17,25 +17,20 @@
package android.hardware.security.keymint;
import android.hardware.security.keymint.KeyParameter;
+import android.hardware.security.keymint.SecurityLevel;
/**
- * KeyCharacteristics defines the attributes of a key, including cryptographic parameters, and usage
- * restrictions. It consits of two vectors of KeyParameters, one for "softwareEnforced" attributes
- * and one for "hardwareEnforced" attributes.
+ * KeyCharacteristics defines the attributes of a key that are enforced by KeyMint, and the security
+ * level (see SecurityLevel.aidl) of that enforcement.
*
- * KeyCharacteristics objects are returned by generateKey, importKey, importWrappedKey and
- * getKeyCharacteristics. The IKeyMintDevice secure environment is responsible for allocating the
- * parameters, all of which are Tags with associated values, to the correct vector. The
- * hardwareEnforced vector must contain only those attributes which are enforced by secure hardware.
- * All others should be in the softwareEnforced vector. See the definitions of individual Tag enums
- * for specification of which must be hardware-enforced, which may be software-enforced and which
- * must never appear in KeyCharacteristics.
+ * The `generateKey` `importKey` and `importWrappedKey` methods each return an array of
+ * KeyCharacteristics, specifying the security levels of enforcement and the authorizations
+ * enforced. Note that enforcement at a given security level means that the semantics of the tag
+ * and value are fully enforced. See the definition of individual tags for specifications of what
+ * must be enforced.
*/
@VintfStability
parcelable KeyCharacteristics {
- /* TODO(seleneh) get rid of the software enforced in keymint. replace hardware enforced with
- * tee enforced and strongbox enforced.
- */
- KeyParameter[] softwareEnforced;
- KeyParameter[] hardwareEnforced;
+ SecurityLevel securityLevel;
+ KeyParameter[] authorizations;
}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
new file mode 100644
index 0000000..b149ac9
--- /dev/null
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.security.keymint;
+
+import android.hardware.security.keymint.Certificate;
+import android.hardware.security.keymint.KeyCharacteristics;
+
+/**
+ * This structure is returned when a new key is created with generateKey(), importKey() or
+ * importWrappedKey().
+ */
+@VintfStability
+parcelable KeyCreationResult {
+ /**
+ * `keyBlob` is an descriptor of the generated/imported key key.
+ */
+ byte[] keyBlob;
+
+ /**
+ * `keyCharacteristics` is a description of the generated key in the form of authorization lists
+ * associated with security levels. The rules that IKeyMintDevice implementations must use for
+ * deciding whether a given tag from `keyParams` argument to the generation/import method should
+ * be returned in `keyCharacteristics` are:
+ *
+ * - If the IKeyMintDevice cannot fully enforce the semantics of the tag, it should be omitted.
+ * - If the semantics of the tag are fully enforced by the IKeyMintDevice, without any
+ * assistance from components running at other security levels, it should be included in an
+ * entry with the SecurityLevel of the IKeyMintDevice.
+ * - If the semantics of the tag are fully enforced, but with the assistance of components
+ * running at another SecurityLevel, it should be included in an entry with the minimum
+ * SecurityLevel of the involved components. For example if a StrongBox IKeyMintDevice relies
+ * on a TEE to validate biometric authentication, biometric authentication tags go in an entry
+ * with SecurityLevel::TRUSTED_ENVIRONMENT.
+ */
+ KeyCharacteristics[] keyCharacteristics;
+
+ /**
+ * If the generated/imported key is an asymmetric key, `certificateChain` will contain a chain
+ * of one or more certificates. If the key parameters provided to the generate/import method
+ * contains Tag::ATTESTATION_CHALLENGE the first certificate will contain an attestation
+ * extension, and will be signed by a factory-installed attestation key and followed by a chain
+ * of certificates leading to an authoritative root. If there is no attestation challenge, only
+ * one certificate will be returned, and it will be self-signed or contain a fake signature,
+ * depending on whether the key has KeyPurpose::SIGN. If the generated key is symmetric,
+ * certificateChain will be empty.
+ */
+ Certificate[] certificateChain;
+}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
index 9f41b4e..f92bf00 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
@@ -512,10 +512,10 @@
/**
* Tag::APPLICATION_DATA. When provided to generateKey or importKey, this tag specifies data
- * that is necessary during all uses of the key. In particular, calls to exportKey() and
- * getKeyCharacteristics() must provide the same value to the appData parameter, and calls to
- * begin must provide this tag and the same associated data as part of the inParams set. If
- * the correct data is not provided, the method must return ErrorCode::INVALID_KEY_BLOB.
+ * that is necessary during all uses of the key. In particular, calls to begin() and
+ * exportKey() must provide the same value to the appData parameter, and calls to begin must
+ * provide this tag and the same associated data as part of the inParams set. If the correct
+ * data is not provided, the method must return ErrorCode::INVALID_KEY_BLOB.
*
* The content of this tag msut be bound to the key cryptographically, meaning it must not be
* possible for an adversary who has access to all of the secure world secrets but does not have
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 94bc199..93a216f 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -17,6 +17,7 @@
#include "KeyMintAidlTestBase.h"
#include <chrono>
+#include <unordered_set>
#include <vector>
#include <android-base/logging.h>
@@ -43,6 +44,34 @@
namespace test {
+namespace {
+
+// Predicate for testing basic characteristics validity in generation or import.
+bool KeyCharacteristicsBasicallyValid(SecurityLevel secLevel,
+ const vector<KeyCharacteristics>& key_characteristics) {
+ if (key_characteristics.empty()) return false;
+
+ std::unordered_set<SecurityLevel> levels_seen;
+ for (auto& entry : key_characteristics) {
+ if (entry.authorizations.empty()) return false;
+
+ if (levels_seen.find(entry.securityLevel) != levels_seen.end()) return false;
+ levels_seen.insert(entry.securityLevel);
+
+ // Generally, we should only have one entry, at the same security level as the KM
+ // instance. There is an exception: StrongBox KM can have some authorizations that are
+ // enforced by the TEE.
+ bool isExpectedSecurityLevel = secLevel == entry.securityLevel ||
+ (secLevel == SecurityLevel::STRONGBOX &&
+ entry.securityLevel == SecurityLevel::TRUSTED_ENVIRONMENT);
+
+ if (!isExpectedSecurityLevel) return false;
+ }
+ return true;
+}
+
+} // namespace
+
ErrorCode KeyMintAidlTestBase::GetReturnErrorCode(const Status& result) {
if (result.isOk()) return ErrorCode::OK;
@@ -78,35 +107,30 @@
}
ErrorCode KeyMintAidlTestBase::GenerateKey(const AuthorizationSet& key_desc,
- vector<uint8_t>* keyBlob, KeyCharacteristics* keyChar) {
- EXPECT_NE(keyBlob, nullptr) << "Key blob pointer must not be null. Test bug";
- EXPECT_NE(keyChar, nullptr)
+ vector<uint8_t>* key_blob,
+ vector<KeyCharacteristics>* key_characteristics) {
+ EXPECT_NE(key_blob, nullptr) << "Key blob pointer must not be null. Test bug";
+ EXPECT_NE(key_characteristics, nullptr)
<< "Previous characteristics not deleted before generating key. Test bug.";
// Aidl does not clear these output parameters if the function returns
// error. This is different from hal where output parameter is always
// cleared due to hal returning void. So now we need to do our own clearing
// of the output variables prior to calling keyMint aidl libraries.
- keyBlob->clear();
- keyChar->softwareEnforced.clear();
- keyChar->hardwareEnforced.clear();
- certChain_.clear();
+ key_blob->clear();
+ key_characteristics->clear();
+ cert_chain_.clear();
- Status result;
- ByteArray blob;
+ KeyCreationResult creationResult;
+ Status result = keymint_->generateKey(key_desc.vector_data(), &creationResult);
- result = keymint_->generateKey(key_desc.vector_data(), &blob, keyChar, &certChain_);
-
- // On result, blob & characteristics should be empty.
if (result.isOk()) {
- if (SecLevel() != SecurityLevel::SOFTWARE) {
- EXPECT_GT(keyChar->hardwareEnforced.size(), 0);
- }
- EXPECT_GT(keyChar->softwareEnforced.size(), 0);
- // TODO(seleneh) in a later version where we return @nullable
- // single Certificate, check non-null single certificate is always
- // non-empty.
- *keyBlob = blob.data;
+ EXPECT_PRED2(KeyCharacteristicsBasicallyValid, SecLevel(),
+ creationResult.keyCharacteristics);
+ EXPECT_GT(creationResult.keyBlob.size(), 0);
+ *key_blob = std::move(creationResult.keyBlob);
+ *key_characteristics = std::move(creationResult.keyCharacteristics);
+ cert_chain_ = std::move(creationResult.certificateChain);
}
return GetReturnErrorCode(result);
@@ -118,25 +142,26 @@
ErrorCode KeyMintAidlTestBase::ImportKey(const AuthorizationSet& key_desc, KeyFormat format,
const string& key_material, vector<uint8_t>* key_blob,
- KeyCharacteristics* key_characteristics) {
+ vector<KeyCharacteristics>* key_characteristics) {
Status result;
- certChain_.clear();
- key_characteristics->softwareEnforced.clear();
- key_characteristics->hardwareEnforced.clear();
+ cert_chain_.clear();
+ key_characteristics->clear();
key_blob->clear();
- ByteArray blob;
+ KeyCreationResult creationResult;
result = keymint_->importKey(key_desc.vector_data(), format,
- vector<uint8_t>(key_material.begin(), key_material.end()), &blob,
- key_characteristics, &certChain_);
+ vector<uint8_t>(key_material.begin(), key_material.end()),
+ &creationResult);
if (result.isOk()) {
- if (SecLevel() != SecurityLevel::SOFTWARE) {
- EXPECT_GT(key_characteristics->hardwareEnforced.size(), 0);
- }
- EXPECT_GT(key_characteristics->softwareEnforced.size(), 0);
- *key_blob = blob.data;
+ EXPECT_PRED2(KeyCharacteristicsBasicallyValid, SecLevel(),
+ creationResult.keyCharacteristics);
+ EXPECT_GT(creationResult.keyBlob.size(), 0);
+
+ *key_blob = std::move(creationResult.keyBlob);
+ *key_characteristics = std::move(creationResult.keyCharacteristics);
+ cert_chain_ = std::move(creationResult.certificateChain);
}
return GetReturnErrorCode(result);
@@ -151,25 +176,25 @@
const AuthorizationSet& wrapping_key_desc,
string masking_key,
const AuthorizationSet& unwrapping_params) {
- Status result;
EXPECT_EQ(ErrorCode::OK, ImportKey(wrapping_key_desc, KeyFormat::PKCS8, wrapping_key));
- ByteArray outBlob;
- key_characteristics_.softwareEnforced.clear();
- key_characteristics_.hardwareEnforced.clear();
+ key_characteristics_.clear();
- result = keymint_->importWrappedKey(vector<uint8_t>(wrapped_key.begin(), wrapped_key.end()),
- key_blob_,
- vector<uint8_t>(masking_key.begin(), masking_key.end()),
- unwrapping_params.vector_data(), 0 /* passwordSid */,
- 0 /* biometricSid */, &outBlob, &key_characteristics_);
+ KeyCreationResult creationResult;
+ Status result = keymint_->importWrappedKey(
+ vector<uint8_t>(wrapped_key.begin(), wrapped_key.end()), key_blob_,
+ vector<uint8_t>(masking_key.begin(), masking_key.end()),
+ unwrapping_params.vector_data(), 0 /* passwordSid */, 0 /* biometricSid */,
+ &creationResult);
if (result.isOk()) {
- key_blob_ = outBlob.data;
- if (SecLevel() != SecurityLevel::SOFTWARE) {
- EXPECT_GT(key_characteristics_.hardwareEnforced.size(), 0);
- }
- EXPECT_GT(key_characteristics_.softwareEnforced.size(), 0);
+ EXPECT_PRED2(KeyCharacteristicsBasicallyValid, SecLevel(),
+ creationResult.keyCharacteristics);
+ EXPECT_GT(creationResult.keyBlob.size(), 0);
+
+ key_blob_ = std::move(creationResult.keyBlob);
+ key_characteristics_ = std::move(creationResult.keyCharacteristics);
+ cert_chain_ = std::move(creationResult.certificateChain);
}
return GetReturnErrorCode(result);
@@ -754,6 +779,15 @@
return {};
}
+static const vector<KeyParameter> kEmptyAuthList{};
+
+const vector<KeyParameter>& KeyMintAidlTestBase::SecLevelAuthorizations(
+ const vector<KeyCharacteristics>& key_characteristics) {
+ auto found = std::find_if(key_characteristics.begin(), key_characteristics.end(),
+ [this](auto& entry) { return entry.securityLevel == SecLevel(); });
+ return (found == key_characteristics.end()) ? kEmptyAuthList : found->authorizations;
+}
+
} // namespace test
} // namespace aidl::android::hardware::security::keymint
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index f73c26d..f36c397 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -56,13 +56,13 @@
ErrorCode GetReturnErrorCode(const Status& result);
ErrorCode GenerateKey(const AuthorizationSet& key_desc, vector<uint8_t>* key_blob,
- KeyCharacteristics* key_characteristics);
+ vector<KeyCharacteristics>* key_characteristics);
ErrorCode GenerateKey(const AuthorizationSet& key_desc);
ErrorCode ImportKey(const AuthorizationSet& key_desc, KeyFormat format,
const string& key_material, vector<uint8_t>* key_blob,
- KeyCharacteristics* key_characteristics);
+ vector<KeyCharacteristics>* key_characteristics);
ErrorCode ImportKey(const AuthorizationSet& key_desc, KeyFormat format,
const string& key_material);
@@ -147,8 +147,8 @@
std::pair<ErrorCode, vector<uint8_t>> UpgradeKey(const vector<uint8_t>& key_blob);
- bool IsSecure() { return securityLevel_ != SecurityLevel::SOFTWARE; }
- SecurityLevel SecLevel() { return securityLevel_; }
+ bool IsSecure() const { return securityLevel_ != SecurityLevel::SOFTWARE; }
+ SecurityLevel SecLevel() const { return securityLevel_; }
vector<uint32_t> ValidKeySizes(Algorithm algorithm);
vector<uint32_t> InvalidKeySizes(Algorithm algorithm);
@@ -164,9 +164,15 @@
}
std::shared_ptr<IKeyMintOperation> op_;
- vector<Certificate> certChain_;
+ vector<Certificate> cert_chain_;
vector<uint8_t> key_blob_;
- KeyCharacteristics key_characteristics_;
+ vector<KeyCharacteristics> key_characteristics_;
+
+ const vector<KeyParameter>& SecLevelAuthorizations(
+ const vector<KeyCharacteristics>& key_characteristics);
+ inline const vector<KeyParameter>& SecLevelAuthorizations() {
+ return SecLevelAuthorizations(key_characteristics_);
+ }
private:
std::shared_ptr<IKeyMintDevice> keymint_;
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index eeb7491..bd36b8e 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -56,18 +56,16 @@
template <>
struct std::equal_to<KeyCharacteristics> {
bool operator()(const KeyCharacteristics& a, const KeyCharacteristics& b) const {
- // This isn't very efficient. Oh, well.
- AuthorizationSet a_sw(a.softwareEnforced);
- AuthorizationSet b_sw(b.softwareEnforced);
- AuthorizationSet a_tee(b.hardwareEnforced);
- AuthorizationSet b_tee(b.hardwareEnforced);
+ if (a.securityLevel != b.securityLevel) return false;
- a_sw.Sort();
- b_sw.Sort();
- a_tee.Sort();
- b_tee.Sort();
+ // this isn't very efficient. Oh, well.
+ AuthorizationSet a_auths(a.authorizations);
+ AuthorizationSet b_auths(b.authorizations);
- return ((a_sw == b_sw) && (a_tee == b_tee));
+ a_auths.Sort();
+ b_auths.Sort();
+
+ return a_auths == b_auths;
}
};
@@ -229,19 +227,20 @@
class NewKeyGenerationTest : public KeyMintAidlTestBase {
protected:
- void CheckBaseParams(const KeyCharacteristics& keyCharacteristics) {
+ void CheckBaseParams(const vector<KeyCharacteristics>& keyCharacteristics) {
// TODO(swillden): Distinguish which params should be in which auth list.
- AuthorizationSet auths(keyCharacteristics.hardwareEnforced);
- auths.push_back(AuthorizationSet(keyCharacteristics.softwareEnforced));
+ AuthorizationSet auths;
+ for (auto& entry : keyCharacteristics) {
+ auths.push_back(AuthorizationSet(entry.authorizations));
+ }
EXPECT_TRUE(auths.Contains(TAG_ORIGIN, KeyOrigin::GENERATED));
EXPECT_TRUE(auths.Contains(TAG_PURPOSE, KeyPurpose::SIGN));
EXPECT_TRUE(auths.Contains(TAG_PURPOSE, KeyPurpose::VERIFY));
- // Verify that App ID, App data and ROT are NOT included.
+ // Verify that App data and ROT are NOT included.
EXPECT_FALSE(auths.Contains(TAG_ROOT_OF_TRUST));
- EXPECT_FALSE(auths.Contains(TAG_APPLICATION_ID));
EXPECT_FALSE(auths.Contains(TAG_APPLICATION_DATA));
// Check that some unexpected tags/values are NOT present.
@@ -249,15 +248,13 @@
EXPECT_FALSE(auths.Contains(TAG_PURPOSE, KeyPurpose::DECRYPT));
EXPECT_FALSE(auths.Contains(TAG_AUTH_TIMEOUT, 301U));
- // Now check that unspecified, defaulted tags are correct.
- EXPECT_TRUE(auths.Contains(TAG_CREATION_DATETIME));
+ auto os_ver = auths.GetTagValue(TAG_OS_VERSION);
+ ASSERT_TRUE(os_ver);
+ EXPECT_EQ(*os_ver, os_version());
- EXPECT_TRUE(auths.Contains(TAG_OS_VERSION, os_version()))
- << "OS version is " << os_version() << " key reported "
- << auths.GetTagValue(TAG_OS_VERSION)->get();
- EXPECT_TRUE(auths.Contains(TAG_OS_PATCHLEVEL, os_patch_level()))
- << "OS patch level is " << os_patch_level() << " key reported "
- << auths.GetTagValue(TAG_OS_PATCHLEVEL)->get();
+ auto os_pl = auths.GetTagValue(TAG_OS_PATCHLEVEL);
+ ASSERT_TRUE(os_pl);
+ EXPECT_EQ(*os_pl, os_patch_level());
}
};
@@ -270,7 +267,7 @@
TEST_P(NewKeyGenerationTest, Rsa) {
for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
vector<uint8_t> key_blob;
- KeyCharacteristics key_characteristics;
+ vector<KeyCharacteristics> key_characteristics;
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(key_size, 65537)
.Digest(Digest::NONE)
@@ -280,12 +277,7 @@
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
- AuthorizationSet crypto_params;
- if (IsSecure()) {
- crypto_params = key_characteristics.hardwareEnforced;
- } else {
- crypto_params = key_characteristics.softwareEnforced;
- }
+ AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::RSA));
EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
@@ -304,7 +296,7 @@
TEST_P(NewKeyGenerationTest, NoInvalidRsaSizes) {
for (auto key_size : InvalidKeySizes(Algorithm::RSA)) {
vector<uint8_t> key_blob;
- KeyCharacteristics key_characteristics;
+ vector<KeyCharacteristics> key_characteristics;
ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE,
GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(key_size, 65537)
@@ -337,7 +329,7 @@
TEST_P(NewKeyGenerationTest, Ecdsa) {
for (auto key_size : ValidKeySizes(Algorithm::EC)) {
vector<uint8_t> key_blob;
- KeyCharacteristics key_characteristics;
+ vector<KeyCharacteristics> key_characteristics;
ASSERT_EQ(ErrorCode::OK,
GenerateKey(
AuthorizationSetBuilder().EcdsaSigningKey(key_size).Digest(Digest::NONE),
@@ -345,12 +337,7 @@
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
- AuthorizationSet crypto_params;
- if (IsSecure()) {
- crypto_params = key_characteristics.hardwareEnforced;
- } else {
- crypto_params = key_characteristics.softwareEnforced;
- }
+ AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC));
EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
@@ -383,7 +370,7 @@
TEST_P(NewKeyGenerationTest, EcdsaInvalidSize) {
for (auto key_size : InvalidKeySizes(Algorithm::EC)) {
vector<uint8_t> key_blob;
- KeyCharacteristics key_characteristics;
+ vector<KeyCharacteristics> key_characteristics;
ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE,
GenerateKey(
AuthorizationSetBuilder().EcdsaSigningKey(key_size).Digest(Digest::NONE),
@@ -454,7 +441,7 @@
TEST_P(NewKeyGenerationTest, Hmac) {
for (auto digest : ValidDigests(false /* withNone */, true /* withMD5 */)) {
vector<uint8_t> key_blob;
- KeyCharacteristics key_characteristics;
+ vector<KeyCharacteristics> key_characteristics;
constexpr size_t key_size = 128;
ASSERT_EQ(ErrorCode::OK,
GenerateKey(
@@ -465,17 +452,10 @@
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
- AuthorizationSet hardwareEnforced = key_characteristics.hardwareEnforced;
- AuthorizationSet softwareEnforced = key_characteristics.softwareEnforced;
- if (IsSecure()) {
- EXPECT_TRUE(hardwareEnforced.Contains(TAG_ALGORITHM, Algorithm::HMAC));
- EXPECT_TRUE(hardwareEnforced.Contains(TAG_KEY_SIZE, key_size))
- << "Key size " << key_size << "missing";
- } else {
- EXPECT_TRUE(softwareEnforced.Contains(TAG_ALGORITHM, Algorithm::HMAC));
- EXPECT_TRUE(softwareEnforced.Contains(TAG_KEY_SIZE, key_size))
- << "Key size " << key_size << "missing";
- }
+ AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+ EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::HMAC));
+ EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
+ << "Key size " << key_size << "missing";
CheckedDeleteKey(&key_blob);
}
@@ -600,7 +580,7 @@
/*
* SigningOperationsTest.RsaUseRequiresCorrectAppIdAppData
*
- * Verifies that using an RSA key requires the correct app ID/data.
+ * Verifies that using an RSA key requires the correct app data.
*/
TEST_P(SigningOperationsTest, RsaUseRequiresCorrectAppIdAppData) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
@@ -1412,7 +1392,7 @@
string key_material = "HelloThisIsAKey";
vector<uint8_t> signing_key, verification_key;
- KeyCharacteristics signing_key_chars, verification_key_chars;
+ vector<KeyCharacteristics> signing_key_chars, verification_key_chars;
EXPECT_EQ(ErrorCode::OK,
ImportKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
@@ -1466,28 +1446,22 @@
template <TagType tag_type, Tag tag, typename ValueT>
void CheckCryptoParam(TypedTag<tag_type, tag> ttag, ValueT expected) {
SCOPED_TRACE("CheckCryptoParam");
- if (IsSecure()) {
- EXPECT_TRUE(contains(key_characteristics_.hardwareEnforced, ttag, expected))
- << "Tag " << tag << " with value " << expected << " not found";
- EXPECT_FALSE(contains(key_characteristics_.softwareEnforced, ttag))
- << "Tag " << tag << " found";
- } else {
- EXPECT_TRUE(contains(key_characteristics_.softwareEnforced, ttag, expected))
- << "Tag " << tag << " with value " << expected << " not found";
- EXPECT_FALSE(contains(key_characteristics_.hardwareEnforced, ttag))
- << "Tag " << tag << " found";
+ for (auto& entry : key_characteristics_) {
+ if (entry.securityLevel == SecLevel()) {
+ EXPECT_TRUE(contains(entry.authorizations, ttag, expected))
+ << "Tag " << tag << " with value " << expected
+ << " not found at security level" << entry.securityLevel;
+ } else {
+ EXPECT_FALSE(contains(entry.authorizations, ttag, expected))
+ << "Tag " << tag << " found at security level " << entry.securityLevel;
+ }
}
}
void CheckOrigin() {
SCOPED_TRACE("CheckOrigin");
- if (IsSecure()) {
- EXPECT_TRUE(contains(key_characteristics_.hardwareEnforced, TAG_ORIGIN,
- KeyOrigin::IMPORTED));
- } else {
- EXPECT_TRUE(contains(key_characteristics_.softwareEnforced, TAG_ORIGIN,
- KeyOrigin::IMPORTED));
- }
+ // Origin isn't a crypto param, but it always lives with them.
+ return CheckCryptoParam(TAG_ORIGIN, KeyOrigin::IMPORTED);
}
};
@@ -3950,7 +3924,7 @@
// Delete must work if rollback protection is implemented
if (error == ErrorCode::OK) {
- AuthorizationSet hardwareEnforced(key_characteristics_.hardwareEnforced);
+ AuthorizationSet hardwareEnforced(SecLevelAuthorizations());
ASSERT_TRUE(hardwareEnforced.Contains(TAG_ROLLBACK_RESISTANCE));
ASSERT_EQ(ErrorCode::OK, DeleteKey(true /* keep key blob */));
@@ -3983,8 +3957,8 @@
// Delete must work if rollback protection is implemented
if (error == ErrorCode::OK) {
- AuthorizationSet hardwareEnforced(key_characteristics_.hardwareEnforced);
- ASSERT_TRUE(hardwareEnforced.Contains(TAG_ROLLBACK_RESISTANCE));
+ AuthorizationSet enforced(SecLevelAuthorizations());
+ ASSERT_TRUE(enforced.Contains(TAG_ROLLBACK_RESISTANCE));
// Delete the key we don't care about the result at this point.
DeleteKey();
@@ -4019,7 +3993,7 @@
// Delete must work if rollback protection is implemented
if (error == ErrorCode::OK) {
- AuthorizationSet hardwareEnforced(key_characteristics_.hardwareEnforced);
+ AuthorizationSet hardwareEnforced(SecLevelAuthorizations());
ASSERT_TRUE(hardwareEnforced.Contains(TAG_ROLLBACK_RESISTANCE));
ASSERT_EQ(ErrorCode::OK, DeleteAllKeys());
diff --git a/security/keymint/support/include/keymint_support/key_param_output.h b/security/keymint/support/include/keymint_support/key_param_output.h
index 5f004fe..c2b0029 100644
--- a/security/keymint/support/include/keymint_support/key_param_output.h
+++ b/security/keymint/support/include/keymint_support/key_param_output.h
@@ -84,8 +84,10 @@
::std::ostream& operator<<(::std::ostream& os, const KeyParameter& param);
inline ::std::ostream& operator<<(::std::ostream& os, const KeyCharacteristics& value) {
- return os << "SW: " << value.softwareEnforced << ::std::endl
- << "HW: " << value.hardwareEnforced << ::std::endl;
+ for (auto& entry : value.authorizations) {
+ os << value.securityLevel << ": " << entry;
+ }
+ return os;
}
inline ::std::ostream& operator<<(::std::ostream& os, KeyPurpose value) {
diff --git a/security/secureclock/aidl/Android.bp b/security/secureclock/aidl/Android.bp
new file mode 100644
index 0000000..7d26a9b
--- /dev/null
+++ b/security/secureclock/aidl/Android.bp
@@ -0,0 +1,24 @@
+aidl_interface {
+ name: "android.hardware.security.secureclock",
+ vendor_available: true,
+ srcs: [
+ "android/hardware/security/secureclock/*.aidl",
+ ],
+ stability: "vintf",
+ imports: [
+ "android.hardware.security.keymint",
+ ],
+ backend: {
+ java: {
+ sdk_version: "module_current",
+ },
+ ndk: {
+ vndk: {
+ enabled: true,
+ },
+ },
+ rust: {
+ enabled: true,
+ },
+ },
+}
diff --git a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/ISecureClock.aidl b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/ISecureClock.aidl
new file mode 100644
index 0000000..c16b312
--- /dev/null
+++ b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/ISecureClock.aidl
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.security.secureclock;
+@VintfStability
+interface ISecureClock {
+ android.hardware.security.secureclock.TimeStampToken generateTimeStamp(in long challenge);
+ const String TIME_STAMP_MAC_LABEL = "Time Verification";
+}
diff --git a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/TimeStampToken.aidl b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/TimeStampToken.aidl
new file mode 100644
index 0000000..c23ddca
--- /dev/null
+++ b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/TimeStampToken.aidl
@@ -0,0 +1,26 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.security.secureclock;
+@VintfStability
+parcelable TimeStampToken {
+ long challenge;
+ android.hardware.security.keymint.Timestamp timestamp;
+ android.hardware.security.keymint.SecurityLevel securityLevel;
+ byte[] mac;
+}
diff --git a/security/secureclock/aidl/android/hardware/security/secureclock/ISecureClock.aidl b/security/secureclock/aidl/android/hardware/security/secureclock/ISecureClock.aidl
new file mode 100644
index 0000000..7d416dd
--- /dev/null
+++ b/security/secureclock/aidl/android/hardware/security/secureclock/ISecureClock.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * limitations under the License.
+ */
+
+package android.hardware.security.secureclock;
+import android.hardware.security.secureclock.TimeStampToken;
+
+/**
+ * Secure Clock definition.
+ *
+ * An ISecureClock provides a keymint service to generate secure timestamp using a secure platform.
+ * The secure time stamp contains time in milliseconds. This time stamp also contains a 256-bit MAC
+ * which provides integrity protection. The MAC is generated using HMAC-SHA-256 and a shared
+ * secret. The shared secret must be available to secure clock service by implementing
+ * ISharedSecret aidl. Note: ISecureClock depends on the shared secret, without which the secure
+ * time stamp token cannot be generated.
+ */
+
+@VintfStability
+interface ISecureClock {
+ /**
+ * String used as context in the HMAC computation signing the generated time stamp.
+ * See TimeStampToken.mac for details.
+ */
+ const String TIME_STAMP_MAC_LABEL = "Time Verification";
+
+ /**
+ * Generates an authenticated timestamp.
+ *
+ * @param A challenge value provided by the relying party. It will be included in the generated
+ * TimeStampToken to ensure freshness. The relying service must ensure that the
+ * challenge cannot be specified or predicted by an attacker.
+ *
+ * @return the TimeStampToken, see the definition for details.
+ */
+ TimeStampToken generateTimeStamp(in long challenge);
+}
diff --git a/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl b/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl
new file mode 100644
index 0000000..76a2d28
--- /dev/null
+++ b/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.security.secureclock;
+
+import android.hardware.security.keymint.SecurityLevel;
+import android.hardware.security.keymint.Timestamp;
+
+/**
+ * TimeStampToken instances are used for secure environments that requires secure time information.
+ */
+
+@VintfStability
+parcelable TimeStampToken {
+ /**
+ * The challenge that was provided as argument to ISecureClock.generateTimeStamp by the client.
+ */
+ long challenge;
+
+ /**
+ * The current time of the secure environment that generates the TimeStampToken.
+ */
+ Timestamp timestamp;
+
+ /**
+ * SecurityLevel of the secure environment that generated the token.
+ */
+ SecurityLevel securityLevel;
+
+ /**
+ * 32-byte HMAC-SHA256 of the above values, computed as:
+ *
+ * HMAC(H,
+ * ISecureClock.TIME_STAMP_MAC_LABEL || challenge || timestamp)
+ *
+ * where:
+ *
+ * ``ISecureClock.TIME_STAMP_MAC_LABEL'' is a sting constant defined in ISecureClock.aidl.
+ *
+ * ``H'' is the shared HMAC key (see computeSharedHmac() in ISharedHmacSecret).
+ *
+ * ``||'' represents concatenation
+ *
+ * The representation of challenge and timestamp is as 64-bit unsigned integers in big-endian
+ * order. securityLevel is represented as a 32-bit unsigned integer in big-endian order.
+ */
+ byte[] mac;
+}
diff --git a/security/sharedsecret/aidl/Android.bp b/security/sharedsecret/aidl/Android.bp
new file mode 100644
index 0000000..ab44110
--- /dev/null
+++ b/security/sharedsecret/aidl/Android.bp
@@ -0,0 +1,21 @@
+aidl_interface {
+ name: "android.hardware.security.sharedsecret",
+ vendor_available: true,
+ srcs: [
+ "android/hardware/security/sharedsecret/*.aidl",
+ ],
+ stability: "vintf",
+ backend: {
+ java: {
+ sdk_version: "module_current",
+ },
+ ndk: {
+ vndk: {
+ enabled: true,
+ },
+ },
+ rust: {
+ enabled: true,
+ },
+ },
+}
diff --git a/security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/current/android/hardware/security/sharedsecret/ISharedSecret.aidl b/security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/current/android/hardware/security/sharedsecret/ISharedSecret.aidl
new file mode 100644
index 0000000..2509936
--- /dev/null
+++ b/security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/current/android/hardware/security/sharedsecret/ISharedSecret.aidl
@@ -0,0 +1,26 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.security.sharedsecret;
+@VintfStability
+interface ISharedSecret {
+ android.hardware.security.sharedsecret.SharedSecretParameters getSharedSecretParameters();
+ byte[] computeSharedSecret(in android.hardware.security.sharedsecret.SharedSecretParameters[] params);
+ const String KEY_AGREEMENT_LABEL = "KeymasterSharedMac";
+ const String KEY_CHECK_LABEL = "Keymaster HMAC Verification";
+}
diff --git a/security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/current/android/hardware/security/sharedsecret/SharedSecretParameters.aidl b/security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/current/android/hardware/security/sharedsecret/SharedSecretParameters.aidl
new file mode 100644
index 0000000..9b65046
--- /dev/null
+++ b/security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/current/android/hardware/security/sharedsecret/SharedSecretParameters.aidl
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.security.sharedsecret;
+@VintfStability
+parcelable SharedSecretParameters {
+ byte[] seed;
+ byte[] nonce;
+}
diff --git a/security/sharedsecret/aidl/android/hardware/security/sharedsecret/ISharedSecret.aidl b/security/sharedsecret/aidl/android/hardware/security/sharedsecret/ISharedSecret.aidl
new file mode 100644
index 0000000..906303f
--- /dev/null
+++ b/security/sharedsecret/aidl/android/hardware/security/sharedsecret/ISharedSecret.aidl
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * limitations under the License.
+ */
+
+package android.hardware.security.sharedsecret;
+import android.hardware.security.sharedsecret.SharedSecretParameters;
+
+/**
+ * Shared Secret definition.
+ *
+ * An ISharedSecret enables any service that implements this interface to establish a shared secret
+ * with one or more other services such as ISecureClock, TEE IKeymintDevice, StrongBox
+ * IKeymintDevice, etc. The shared secret is a 256-bit HMAC key and it is further used to generate
+ * secure tokens with integrity protection. There are two steps to establish a shared secret between
+ * the collaborating services:
+ *
+ * Step 1: During Android startup the system calls each service that implements this interface to
+ * get the shared secret parameters. This is done using getSharedSecretParameters method defined
+ * below.
+ * Step 2: The system lexicographically sorts the shared secret parameters received from each
+ * service and then sends these sorted parameter list to each service in a computeSharedSecret
+ * method defined below. The services individually computes the shared secret and returns back
+ * the 32 byte sharing check hash value generated by using the computed shared secret.
+ * Step 3: The system collects sharing check hash values from each service and evaluates them. If
+ * they are all equal, then the shared secret generation is considered to be successful else it is
+ * considered to have failed.
+ */
+
+@VintfStability
+interface ISharedSecret {
+ /**
+ * String used as label in the shared key derivation. See computeSharedSecret below.
+ */
+ const String KEY_AGREEMENT_LABEL = "KeymasterSharedMac";
+
+ /**
+ * String used as context in the computation of the sharingCheck. See computeSharedSecret
+ * below.
+ */
+ const String KEY_CHECK_LABEL = "Keymaster HMAC Verification";
+
+ /**
+ * This method is the first step in the process for agreeing on a shared key. It is called by
+ * Android during startup. The system calls it on each of the HAL instances and collects the
+ * results in preparation for the second step.
+ *
+ * @return The SharedSecretParameters to use. As specified in the SharedSecretParameters
+ * documentation, the seed must contain the same value in every invocation
+ * of the method on a given device, and the nonce must return the same value for every
+ * invocation during a boot session.
+ */
+ SharedSecretParameters getSharedSecretParameters();
+
+ /**
+ * This method is the second and final step in the process for agreeing on a shared key. It is
+ * called by Android during startup. The system calls it on each of the keymint services, and
+ * sends to it all of the SharedSecretParameters returned by all keymint services.
+ *
+ * This method computes the shared 32-byte HMAC key ``H'' as follows (all keymint services
+ * instances perform the same computation to arrive at the same result):
+ *
+ * H = CKDF(key = K,
+ * context = P1 || P2 || ... || Pn,
+ * label = KEY_AGREEMENT_LABEL)
+ *
+ * where:
+ *
+ * ``CKDF'' is the standard AES-CMAC KDF from NIST SP 800-108 in counter mode (see Section
+ * 5.1 of the referenced publication). ``key'', ``context'', and ``label'' are
+ * defined in the standard. The counter is prefixed and length L appended, as shown
+ * in the construction on page 12 of the standard. The label string is UTF-8 encoded.
+ *
+ * ``K'' is a pre-established shared secret, set up during factory reset. The mechanism for
+ * establishing this shared secret is implementation-defined.Any method of securely
+ * establishing K that ensures that an attacker cannot obtain or derive its value is
+ * acceptable.
+ *
+ * CRITICAL SECURITY REQUIREMENT: All keys created by a IKeymintDevice instance must
+ * be cryptographically bound to the value of K, such that establishing a new K
+ * permanently destroys them.
+ *
+ * ``||'' represents concatenation.
+ *
+ * ``Pi'' is the i'th SharedSecretParameters value in the params vector. Encoding of an
+ * SharedSecretParameters is the concatenation of its two fields, i.e. seed || nonce.
+ *
+ * Note that the label "KeymasterSharedMac" is the 18-byte UTF-8 encoding of the string.
+ *
+ * @param params is an array of SharedSecretParameters The lexicographically sorted
+ * SharedSecretParameters data returned by all keymint services when getSharedSecretParameters
+ * was called.
+ *
+ * @return sharingCheck A 32-byte value used to verify that all the keymint services have
+ * computed the same shared HMAC key. The sharingCheck value is computed as follows:
+ *
+ * sharingCheck = HMAC(H, KEY_CHECK_LABEL)
+ *
+ * The string is UTF-8 encoded, 27 bytes in length. If the returned values of all
+ * keymint services don't match, clients must assume that HMAC agreement
+ * failed.
+ */
+ byte[] computeSharedSecret(in SharedSecretParameters[] params);
+}
diff --git a/security/sharedsecret/aidl/android/hardware/security/sharedsecret/SharedSecretParameters.aidl b/security/sharedsecret/aidl/android/hardware/security/sharedsecret/SharedSecretParameters.aidl
new file mode 100644
index 0000000..691b3f1
--- /dev/null
+++ b/security/sharedsecret/aidl/android/hardware/security/sharedsecret/SharedSecretParameters.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.security.sharedsecret;
+
+/**
+ * SharedSecretParameters holds the data used in the process of establishing a shared secret i.e.
+ * HMAC key between multiple keymint services. These parameters are returned in by
+ * getSharedSecretParameters() and send to computeShareSecret(). See the named methods in
+ * ISharedSecret for details of usage.
+ */
+
+@VintfStability
+parcelable SharedSecretParameters {
+ /**
+ * Either empty or contains a non zero persistent value that is associated with the pre-shared
+ * HMAC agreement key. It is either empty or 32 bytes in length.
+ */
+ byte[] seed;
+
+ /**
+ * A 32-byte value which is guaranteed to be different each time
+ * getSharedSecretParameters() is called. Probabilistic uniqueness (i.e. random) is acceptable,
+ * though a stronger uniqueness guarantee (e.g. counter) is recommended where possible.
+ */
+ byte[] nonce;
+}
diff --git a/tv/input/1.0/default/TvInput.cpp b/tv/input/1.0/default/TvInput.cpp
index 4ea1dec..7583a67 100644
--- a/tv/input/1.0/default/TvInput.cpp
+++ b/tv/input/1.0/default/TvInput.cpp
@@ -142,7 +142,7 @@
// static
void TvInput::notify(struct tv_input_device* __unused, tv_input_event_t* event,
- void* __unused) {
+ void* optionalStatus) {
if (mCallback != nullptr && event != nullptr) {
// Capturing is no longer supported.
if (event->type >= TV_INPUT_EVENT_CAPTURE_SUCCEEDED) {
@@ -154,7 +154,17 @@
tvInputEvent.deviceInfo.type = static_cast<TvInputType>(
event->device_info.type);
tvInputEvent.deviceInfo.portId = event->device_info.hdmi.port_id;
- tvInputEvent.deviceInfo.cableConnectionStatus = CableConnectionStatus::UNKNOWN;
+ CableConnectionStatus connectionStatus = CableConnectionStatus::UNKNOWN;
+ if (optionalStatus != nullptr &&
+ ((event->type == TV_INPUT_EVENT_STREAM_CONFIGURATIONS_CHANGED) ||
+ (event->type == TV_INPUT_EVENT_DEVICE_AVAILABLE))) {
+ int newStatus = *reinterpret_cast<int*>(optionalStatus);
+ if (newStatus <= static_cast<int>(CableConnectionStatus::DISCONNECTED) &&
+ newStatus >= static_cast<int>(CableConnectionStatus::UNKNOWN)) {
+ connectionStatus = static_cast<CableConnectionStatus>(newStatus);
+ }
+ }
+ tvInputEvent.deviceInfo.cableConnectionStatus = connectionStatus;
// TODO: Ensure the legacy audio type code is the same once audio HAL default
// implementation is ready.
tvInputEvent.deviceInfo.audioType = static_cast<AudioDevice>(
diff --git a/wifi/1.5/types.hal b/wifi/1.5/types.hal
index 3fbec82..9fa5c80 100644
--- a/wifi/1.5/types.hal
+++ b/wifi/1.5/types.hal
@@ -19,7 +19,7 @@
import @1.0::StaLinkLayerIfaceStats;
import @1.0::StaLinkLayerIfacePacketStats;
import @1.0::TimeStampInMs;
-import @1.0::WifiBand;
+import @1.4::WifiBand;
import @1.0::NanCipherSuiteType;
import @1.0::NanCapabilities;
import @1.2::NanConfigRequestSupplemental;
@@ -28,7 +28,7 @@
/**
* Wifi bands defined in 80211 spec.
*/
-enum WifiBand : @1.0::WifiBand {
+enum WifiBand : @1.4::WifiBand {
/**
* 60 GHz.
*/
diff --git a/wifi/1.5/vts/functional/Android.bp b/wifi/1.5/vts/functional/Android.bp
index 2d8b412..118822a 100644
--- a/wifi/1.5/vts/functional/Android.bp
+++ b/wifi/1.5/vts/functional/Android.bp
@@ -14,6 +14,27 @@
// limitations under the License.
//
+cc_library_static {
+ name: "VtsHalWifiV1_5TargetTestUtil",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: [
+ "wifi_hidl_test_utils_1_5.cpp",
+ ],
+ export_include_dirs: [
+ ".",
+ ],
+ shared_libs: [
+ "libnativehelper",
+ ],
+ static_libs: [
+ "VtsHalWifiV1_0TargetTestUtil",
+ "android.hardware.wifi@1.0",
+ "android.hardware.wifi@1.3",
+ "android.hardware.wifi@1.5",
+ "libwifi-system-iface",
+ ],
+}
+
cc_test {
name: "VtsHalWifiV1_5TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
@@ -67,9 +88,11 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: [
"wifi_chip_hidl_ap_test.cpp",
+ "wifi_ap_iface_hidl_test.cpp",
],
static_libs: [
"VtsHalWifiV1_0TargetTestUtil",
+ "VtsHalWifiV1_5TargetTestUtil",
"android.hardware.wifi@1.0",
"android.hardware.wifi@1.1",
"android.hardware.wifi@1.2",
diff --git a/wifi/1.5/vts/functional/wifi_ap_iface_hidl_test.cpp b/wifi/1.5/vts/functional/wifi_ap_iface_hidl_test.cpp
new file mode 100644
index 0000000..e47b14d
--- /dev/null
+++ b/wifi/1.5/vts/functional/wifi_ap_iface_hidl_test.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <VtsCoreUtil.h>
+#include <VtsHalHidlTargetCallbackBase.h>
+#include <android-base/logging.h>
+
+#undef NAN // NAN is defined in bionic/libc/include/math.h:38
+
+#include <android/hardware/wifi/1.4/IWifiChipEventCallback.h>
+#include <android/hardware/wifi/1.5/IWifi.h>
+#include <android/hardware/wifi/1.5/IWifiApIface.h>
+#include <android/hardware/wifi/1.5/IWifiChip.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+#include "wifi_hidl_call_util.h"
+#include "wifi_hidl_test_utils.h"
+#include "wifi_hidl_test_utils_1_5.h"
+
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::wifi::V1_0::ChipModeId;
+using ::android::hardware::wifi::V1_0::IfaceType;
+using ::android::hardware::wifi::V1_0::IWifiIface;
+using ::android::hardware::wifi::V1_0::WifiDebugRingBufferStatus;
+using ::android::hardware::wifi::V1_0::WifiStatus;
+using ::android::hardware::wifi::V1_0::WifiStatusCode;
+using ::android::hardware::wifi::V1_4::IWifiChipEventCallback;
+using ::android::hardware::wifi::V1_5::IWifiApIface;
+using ::android::hardware::wifi::V1_5::IWifiChip;
+
+/**
+ * Fixture for IWifiChip tests that are conditioned on SoftAP support.
+ */
+class WifiApIfaceHidlTest : public ::testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ isBridgedSupport_ = testing::checkSubstringInCommandOutput(
+ "/system/bin/cmd wifi get-softap-supported-features",
+ "wifi_softap_bridged_ap_supported");
+ // Make sure to start with a clean state
+ stopWifi(GetInstanceName());
+ }
+
+ virtual void TearDown() override { stopWifi(GetInstanceName()); }
+
+ protected:
+ bool isBridgedSupport_ = false;
+ std::string GetInstanceName() { return GetParam(); }
+};
+
+/*
+ * resetToFactoryMacAddress
+ */
+TEST_P(WifiApIfaceHidlTest, resetToFactoryMacAddressInBridgedModeTest) {
+ if (!isBridgedSupport_) GTEST_SKIP() << "Missing Bridged AP support";
+ sp<IWifiApIface> wifi_ap_iface =
+ getBridgedWifiApIface_1_5(GetInstanceName());
+ ASSERT_NE(nullptr, wifi_ap_iface.get());
+ const auto& status = HIDL_INVOKE(wifi_ap_iface, resetToFactoryMacAddress);
+ EXPECT_EQ(WifiStatusCode::SUCCESS, status.code);
+}
+
+/*
+ * resetToFactoryMacAddress
+ */
+TEST_P(WifiApIfaceHidlTest, resetToFactoryMacAddressTest) {
+ sp<IWifiApIface> wifi_ap_iface = getWifiApIface_1_5(GetInstanceName());
+ ASSERT_NE(nullptr, wifi_ap_iface.get());
+ const auto& status = HIDL_INVOKE(wifi_ap_iface, resetToFactoryMacAddress);
+ EXPECT_EQ(WifiStatusCode::SUCCESS, status.code);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiApIfaceHidlTest);
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, WifiApIfaceHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ::android::hardware::wifi::V1_5::IWifi::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/wifi/1.5/vts/functional/wifi_chip_hidl_ap_test.cpp b/wifi/1.5/vts/functional/wifi_chip_hidl_ap_test.cpp
index 395d317..922c9a7 100644
--- a/wifi/1.5/vts/functional/wifi_chip_hidl_ap_test.cpp
+++ b/wifi/1.5/vts/functional/wifi_chip_hidl_ap_test.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <VtsCoreUtil.h>
#include <VtsHalHidlTargetCallbackBase.h>
#include <android-base/logging.h>
@@ -51,6 +52,9 @@
class WifiChipHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
+ isBridgedSupport_ = testing::checkSubstringInCommandOutput(
+ "/system/bin/cmd wifi get-softap-supported-features",
+ "wifi_softap_bridged_ap_supported");
// Make sure to start with a clean state
stopWifi(GetInstanceName());
@@ -61,6 +65,7 @@
virtual void TearDown() override { stopWifi(GetInstanceName()); }
protected:
+ bool isBridgedSupport_ = false;
// Helper function to configure the Chip in one of the supported modes.
// Most of the non-mode-configuration-related methods require chip
// to be first configured.
@@ -71,19 +76,12 @@
return mode_id;
}
- WifiStatusCode createApIface(sp<IWifiApIface>* ap_iface) {
- configureChipForIfaceType(IfaceType::AP, true);
- const auto& status_and_iface = HIDL_INVOKE(wifi_chip_, createApIface);
- *ap_iface = IWifiApIface::castFrom(status_and_iface.second);
- return status_and_iface.first.code;
- }
-
- WifiStatusCode createBridgedApIface(sp<IWifiApIface>* ap_iface) {
+ void createBridgedApIface(sp<IWifiApIface>* ap_iface) {
configureChipForIfaceType(IfaceType::AP, true);
const auto& status_and_iface =
HIDL_INVOKE(wifi_chip_, createBridgedApIface);
*ap_iface = status_and_iface.second;
- return status_and_iface.first.code;
+ EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface.first.code);
}
sp<IWifiChip> wifi_chip_;
@@ -92,19 +90,25 @@
std::string GetInstanceName() { return GetParam(); }
};
-// TODO: b/173999527. Add test for bridged API.
-
-/*
- * resetToFactoryMacAddress
+/**
+ * createBridgedApIface & removeIfaceInstanceFromBridgedApIface
*/
-TEST_P(WifiChipHidlTest, resetToFactoryMacAddressTest) {
+TEST_P(WifiChipHidlTest,
+ createBridgedApIfaceAndremoveIfaceInstanceFromBridgedApIfaceTest) {
+ if (!isBridgedSupport_) GTEST_SKIP() << "Missing Bridged AP support";
sp<IWifiApIface> wifi_ap_iface;
- const auto& status_code = createApIface(&wifi_ap_iface);
- if (status_code != WifiStatusCode::SUCCESS) {
- EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status_code);
- }
- const auto& status = HIDL_INVOKE(wifi_ap_iface, resetToFactoryMacAddress);
- EXPECT_EQ(WifiStatusCode::SUCCESS, status.code);
+ createBridgedApIface(&wifi_ap_iface);
+ ASSERT_NE(nullptr, wifi_ap_iface.get());
+ const auto& status_and_name = HIDL_INVOKE(wifi_ap_iface, getName);
+ EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_name.first.code);
+ // TODO: b/173999527, add API to get instance name to replace it.
+ std::string br_name = status_and_name.second; // ap_br_ is the pre-fix
+ std::string instance_name =
+ br_name.substr(6, br_name.length()); // remove the pre-fex
+ const auto& status_code =
+ HIDL_INVOKE(wifi_chip_, removeIfaceInstanceFromBridgedApIface, br_name,
+ instance_name);
+ EXPECT_EQ(WifiStatusCode::SUCCESS, status_code.code);
}
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipHidlTest);
diff --git a/wifi/1.5/vts/functional/wifi_hidl_test_utils_1_5.cpp b/wifi/1.5/vts/functional/wifi_hidl_test_utils_1_5.cpp
new file mode 100644
index 0000000..f1da2ea
--- /dev/null
+++ b/wifi/1.5/vts/functional/wifi_hidl_test_utils_1_5.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <VtsHalHidlTargetCallbackBase.h>
+#include <android-base/logging.h>
+
+#undef NAN // NAN is defined in bionic/libc/include/math.h:38
+
+#include <android/hardware/wifi/1.5/IWifi.h>
+#include <android/hardware/wifi/1.5/IWifiApIface.h>
+#include <android/hardware/wifi/1.5/IWifiChip.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+#include "wifi_hidl_call_util.h"
+#include "wifi_hidl_test_utils.h"
+
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::wifi::V1_0::ChipModeId;
+using ::android::hardware::wifi::V1_0::IfaceType;
+using ::android::hardware::wifi::V1_5::IWifiApIface;
+using ::android::hardware::wifi::V1_5::IWifiChip;
+
+sp<IWifiChip> getWifiChip_1_5(const std::string& instance_name) {
+ return IWifiChip::castFrom(getWifiChip(instance_name));
+}
+
+sp<IWifiApIface> getWifiApIface_1_5(const std::string& instance_name) {
+ ChipModeId mode_id;
+ sp<IWifiChip> wifi_chip_ = getWifiChip_1_5(instance_name);
+ configureChipToSupportIfaceType(wifi_chip_, IfaceType::AP, &mode_id);
+ const auto& status_and_iface = HIDL_INVOKE(wifi_chip_, createApIface);
+ return IWifiApIface::castFrom(status_and_iface.second);
+}
+
+sp<IWifiApIface> getBridgedWifiApIface_1_5(const std::string& instance_name) {
+ ChipModeId mode_id;
+ sp<IWifiChip> wifi_chip_ = getWifiChip_1_5(instance_name);
+ configureChipToSupportIfaceType(wifi_chip_, IfaceType::AP, &mode_id);
+ const auto& status_and_iface =
+ HIDL_INVOKE(wifi_chip_, createBridgedApIface);
+ return IWifiApIface::castFrom(status_and_iface.second);
+}
diff --git a/wifi/1.5/vts/functional/wifi_hidl_test_utils_1_5.h b/wifi/1.5/vts/functional/wifi_hidl_test_utils_1_5.h
new file mode 100644
index 0000000..1b8b737
--- /dev/null
+++ b/wifi/1.5/vts/functional/wifi_hidl_test_utils_1_5.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/wifi/1.5/IWifi.h>
+#include <android/hardware/wifi/1.5/IWifiApIface.h>
+#include <android/hardware/wifi/1.5/IWifiChip.h>
+
+#include <getopt.h>
+
+#include <VtsHalHidlTargetTestEnvBase.h>
+// Helper functions to obtain references to the various HIDL interface objects.
+// Note: We only have a single instance of each of these objects currently.
+// These helper functions should be modified to return vectors if we support
+// multiple instances.
+android::sp<android::hardware::wifi::V1_5::IWifiChip> getWifiChip_1_5(
+ const std::string& instance_name);
+android::sp<android::hardware::wifi::V1_5::IWifiApIface> getWifiApIface_1_5(
+ const std::string& instance_name);
+android::sp<android::hardware::wifi::V1_5::IWifiApIface>
+getBridgedWifiApIface_1_5(const std::string& instance_name);
diff --git a/wifi/hostapd/1.3/vts/functional/Android.bp b/wifi/hostapd/1.3/vts/functional/Android.bp
index 07cebb0..ed18bb6 100644
--- a/wifi/hostapd/1.3/vts/functional/Android.bp
+++ b/wifi/hostapd/1.3/vts/functional/Android.bp
@@ -22,12 +22,18 @@
],
static_libs: [
"VtsHalWifiV1_0TargetTestUtil",
+ "VtsHalWifiV1_5TargetTestUtil",
"VtsHalWifiHostapdV1_0TargetTestUtil",
"android.hardware.wifi.hostapd@1.0",
"android.hardware.wifi.hostapd@1.1",
"android.hardware.wifi.hostapd@1.2",
"android.hardware.wifi.hostapd@1.3",
"android.hardware.wifi@1.0",
+ "android.hardware.wifi@1.1",
+ "android.hardware.wifi@1.2",
+ "android.hardware.wifi@1.3",
+ "android.hardware.wifi@1.4",
+ "android.hardware.wifi@1.5",
"libgmock",
"libwifi-system",
"libwifi-system-iface",
diff --git a/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp
index a22252c..4e63c56 100644
--- a/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp
+++ b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp
@@ -28,6 +28,7 @@
#include "hostapd_hidl_call_util.h"
#include "hostapd_hidl_test_utils.h"
+#include "wifi_hidl_test_utils_1_5.h"
using ::android::sp;
using ::android::hardware::hidl_string;
@@ -38,6 +39,8 @@
using ::android::hardware::wifi::hostapd::V1_2::Ieee80211ReasonCode;
using ::android::hardware::wifi::hostapd::V1_3::IHostapd;
using ::android::hardware::wifi::V1_0::IWifi;
+using ::android::hardware::wifi::V1_0::WifiStatusCode;
+using ::android::hardware::wifi::V1_5::IWifiApIface;
namespace {
constexpr unsigned char kNwSsid[] = {'t', 'e', 's', 't', '1',
@@ -71,16 +74,39 @@
isWpa3SaeSupport_ = testing::checkSubstringInCommandOutput(
"/system/bin/cmd wifi get-softap-supported-features",
"wifi_softap_wpa3_sae_supported");
+ isBridgedSupport_ = testing::checkSubstringInCommandOutput(
+ "/system/bin/cmd wifi get-softap-supported-features",
+ "wifi_softap_bridged_ap_supported");
}
virtual void TearDown() override {
HIDL_INVOKE_VOID_WITHOUT_ARGUMENTS(hostapd_, terminate);
stopHostapd(wifi_instance_name_);
+ // Wait 3 seconds to allow driver processing load/unload between two
+ // test cases.
+ sleep(3);
}
protected:
bool isWpa3SaeSupport_ = false;
bool isAcsSupport_ = false;
+ bool isBridgedSupport_ = false;
+
+ std::string setupApIfaceAndGetName(bool isBridged) {
+ sp<IWifiApIface> wifi_ap_iface;
+ if (isBridged) {
+ wifi_ap_iface = getBridgedWifiApIface_1_5(wifi_instance_name_);
+ } else {
+ wifi_ap_iface = getWifiApIface_1_5(wifi_instance_name_);
+ }
+ EXPECT_NE(nullptr, wifi_ap_iface.get());
+
+ const auto& status_and_name = HIDL_INVOKE(wifi_ap_iface, getName);
+ EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_name.first.code);
+ return status_and_name.second;
+ }
+
+ // TODO: b/177483254, remove it after fix wlan1 failure case.
std::string getPrimaryWlanIfaceName() {
std::array<char, PROPERTY_VALUE_MAX> buffer;
auto res = property_get("ro.vendor.wifi.sap.interface", buffer.data(),
@@ -90,7 +116,7 @@
return buffer.data();
}
- IHostapd::IfaceParams getIfaceParamsWithoutAcs() {
+ IHostapd::IfaceParams getIfaceParamsWithoutAcs(std::string iface_name) {
::android::hardware::wifi::hostapd::V1_0::IHostapd::IfaceParams
iface_params;
::android::hardware::wifi::hostapd::V1_1::IHostapd::IfaceParams
@@ -106,7 +132,7 @@
::android::hardware::wifi::hostapd::V1_3::IHostapd::ChannelParams
channelParams_1_3;
- iface_params.ifaceName = getPrimaryWlanIfaceName();
+ iface_params.ifaceName = iface_name;
iface_params.hwModeParams.enable80211N = true;
iface_params.hwModeParams.enable80211AC = false;
iface_params.channelParams.enableAcs = false;
@@ -133,9 +159,41 @@
return iface_params_1_3;
}
- IHostapd::IfaceParams getIfaceParamsWithAcs() {
+ IHostapd::IfaceParams getIfaceParamsWithBridgedModeACS(
+ std::string iface_name) {
// First get the settings for WithoutAcs and then make changes
- IHostapd::IfaceParams iface_params_1_3 = getIfaceParamsWithoutAcs();
+ IHostapd::IfaceParams iface_params_1_3 =
+ getIfaceParamsWithoutAcs(iface_name);
+ iface_params_1_3.V1_2.V1_1.V1_0.channelParams.enableAcs = true;
+ iface_params_1_3.V1_2.V1_1.V1_0.channelParams.acsShouldExcludeDfs =
+ true;
+
+ std::vector<
+ ::android::hardware::wifi::hostapd::V1_3::IHostapd::ChannelParams>
+ vec_channelParams;
+
+ vec_channelParams.push_back(iface_params_1_3.channelParamsList[0]);
+
+ ::android::hardware::wifi::hostapd::V1_3::IHostapd::ChannelParams
+ second_channelParams_1_3;
+ second_channelParams_1_3.channel = 0;
+ second_channelParams_1_3.enableAcs = true;
+ second_channelParams_1_3.bandMask = 0;
+ second_channelParams_1_3.bandMask |= IHostapd::BandMask::BAND_5_GHZ;
+ second_channelParams_1_3.V1_2 = iface_params_1_3.V1_2.channelParams;
+ second_channelParams_1_3.V1_2.bandMask = 0;
+ second_channelParams_1_3.V1_2.bandMask |=
+ IHostapd::BandMask::BAND_5_GHZ;
+ vec_channelParams.push_back(second_channelParams_1_3);
+
+ iface_params_1_3.channelParamsList = vec_channelParams;
+ return iface_params_1_3;
+ }
+
+ IHostapd::IfaceParams getIfaceParamsWithAcs(std::string iface_name) {
+ // First get the settings for WithoutAcs and then make changes
+ IHostapd::IfaceParams iface_params_1_3 =
+ getIfaceParamsWithoutAcs(iface_name);
iface_params_1_3.V1_2.V1_1.V1_0.channelParams.enableAcs = true;
iface_params_1_3.V1_2.V1_1.V1_0.channelParams.acsShouldExcludeDfs =
true;
@@ -153,8 +211,10 @@
return iface_params_1_3;
}
- IHostapd::IfaceParams getIfaceParamsWithAcsAndFreqRange() {
- IHostapd::IfaceParams iface_params_1_3 = getIfaceParamsWithAcs();
+ IHostapd::IfaceParams getIfaceParamsWithAcsAndFreqRange(
+ std::string iface_name) {
+ IHostapd::IfaceParams iface_params_1_3 =
+ getIfaceParamsWithAcs(iface_name);
::android::hardware::wifi::hostapd::V1_2::IHostapd::AcsFrequencyRange
acsFrequencyRange;
acsFrequencyRange.start = 2412;
@@ -170,9 +230,10 @@
return iface_params_1_3;
}
- IHostapd::IfaceParams getIfaceParamsWithAcsAndInvalidFreqRange() {
+ IHostapd::IfaceParams getIfaceParamsWithAcsAndInvalidFreqRange(
+ std::string iface_name) {
IHostapd::IfaceParams iface_params_1_3 =
- getIfaceParamsWithAcsAndFreqRange();
+ getIfaceParamsWithAcsAndFreqRange(iface_name);
iface_params_1_3.V1_2.channelParams.acsChannelFreqRangesMhz[0].start =
222;
iface_params_1_3.V1_2.channelParams.acsChannelFreqRangesMhz[0].end =
@@ -250,8 +311,10 @@
return nw_params_1_3;
}
- IHostapd::IfaceParams getIfaceParamsWithInvalidChannel() {
- IHostapd::IfaceParams iface_params_1_3 = getIfaceParamsWithoutAcs();
+ IHostapd::IfaceParams getIfaceParamsWithInvalidChannel(
+ std::string iface_name) {
+ IHostapd::IfaceParams iface_params_1_3 =
+ getIfaceParamsWithoutAcs(iface_name);
iface_params_1_3.V1_2.V1_1.V1_0.channelParams.channel =
kIfaceInvalidChannel;
iface_params_1_3.channelParamsList[0].channel =
@@ -271,8 +334,11 @@
*/
TEST_P(HostapdHidlTest, AddPskAccessPointWithAcs) {
if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
+ // TODO: Use setupApIfaceAndGetName after fixing b/177483254
+ // std::string ifname = setupApIfaceAndGetName(false);
+ std::string ifname = getPrimaryWlanIfaceName();
auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
- getIfaceParamsWithAcs(), getPskNwParams());
+ getIfaceParamsWithAcs(ifname), getPskNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
}
@@ -282,9 +348,12 @@
*/
TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndFreqRange) {
if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
- auto status =
- HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
- getIfaceParamsWithAcsAndFreqRange(), getPskNwParams());
+ // TODO: Use setupApIfaceAndGetName after fixing b/177483254
+ // std::string ifname = setupApIfaceAndGetName(false);
+ std::string ifname = getPrimaryWlanIfaceName();
+ auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithAcsAndFreqRange(ifname),
+ getPskNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
}
@@ -294,8 +363,11 @@
*/
TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndInvalidFreqRange) {
if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
+ // TODO: Use setupApIfaceAndGetName after fixing b/177483254
+ // std::string ifname = setupApIfaceAndGetName(false);
+ std::string ifname = getPrimaryWlanIfaceName();
auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
- getIfaceParamsWithAcsAndInvalidFreqRange(),
+ getIfaceParamsWithAcsAndInvalidFreqRange(ifname),
getPskNwParams());
EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
}
@@ -306,8 +378,11 @@
*/
TEST_P(HostapdHidlTest, AddOpenAccessPointWithAcs) {
if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
+ // TODO: Use setupApIfaceAndGetName after fixing b/177483254
+ // std::string ifname = setupApIfaceAndGetName(false);
+ std::string ifname = getPrimaryWlanIfaceName();
auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
- getIfaceParamsWithAcs(), getOpenNwParams());
+ getIfaceParamsWithAcs(ifname), getOpenNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
}
@@ -316,8 +391,12 @@
* Access point creation should pass.
*/
TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcs) {
- auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
- getIfaceParamsWithoutAcs(), getPskNwParams());
+ // TODO: Use setupApIfaceAndGetName after fixing b/177483254
+ // std::string ifname = setupApIfaceAndGetName(false);
+ std::string ifname = getPrimaryWlanIfaceName();
+ auto status =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithoutAcs(ifname), getPskNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
}
@@ -326,9 +405,12 @@
* Access point creation should pass.
*/
TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcsAndNonMetered) {
- auto status =
- HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(),
- getPskNwParamsWithNonMetered());
+ // TODO: Use setupApIfaceAndGetName after fixing b/177483254
+ // std::string ifname = setupApIfaceAndGetName(false);
+ std::string ifname = getPrimaryWlanIfaceName();
+ auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithoutAcs(ifname),
+ getPskNwParamsWithNonMetered());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
}
@@ -337,8 +419,12 @@
* Access point creation should pass.
*/
TEST_P(HostapdHidlTest, AddOpenAccessPointWithoutAcs) {
- auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
- getIfaceParamsWithoutAcs(), getOpenNwParams());
+ // TODO: Use setupApIfaceAndGetName after fixing b/177483254
+ // std::string ifname = setupApIfaceAndGetName(false);
+ std::string ifname = getPrimaryWlanIfaceName();
+ auto status =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithoutAcs(ifname), getOpenNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
}
@@ -348,9 +434,12 @@
*/
TEST_P(HostapdHidlTest, AddSaeTransitionAccessPointWithoutAcs) {
if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
- auto status =
- HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(),
- getSaeTransitionNwParams());
+ // TODO: Use setupApIfaceAndGetName after fixing b/177483254
+ // std::string ifname = setupApIfaceAndGetName(false);
+ std::string ifname = getPrimaryWlanIfaceName();
+ auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithoutAcs(ifname),
+ getSaeTransitionNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
}
@@ -360,8 +449,12 @@
*/
TEST_P(HostapdHidlTest, AddSAEAccessPointWithoutAcs) {
if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
- auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
- getIfaceParamsWithoutAcs(), getSaeNwParams());
+ // TODO: Use setupApIfaceAndGetName after fixing b/177483254
+ // std::string ifname = setupApIfaceAndGetName(false);
+ std::string ifname = getPrimaryWlanIfaceName();
+ auto status =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithoutAcs(ifname), getSaeNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
}
@@ -371,11 +464,14 @@
*/
TEST_P(HostapdHidlTest, RemoveAccessPointWithAcs) {
if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
- auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
- getIfaceParamsWithAcs(), getPskNwParams());
+ // TODO: Use setupApIfaceAndGetName after fixing b/177483254
+ // std::string ifname = setupApIfaceAndGetName(false);
+ std::string ifname = getPrimaryWlanIfaceName();
+ auto status_1_2 =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithAcs(ifname),
+ getPskNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code);
- auto status =
- HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName());
+ auto status = HIDL_INVOKE(hostapd_, removeAccessPoint, ifname);
EXPECT_EQ(
android::hardware::wifi::hostapd::V1_0::HostapdStatusCode::SUCCESS,
status.code);
@@ -386,11 +482,14 @@
* Access point creation & removal should pass.
*/
TEST_P(HostapdHidlTest, RemoveAccessPointWithoutAcs) {
- auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
- getIfaceParamsWithoutAcs(), getPskNwParams());
+ // TODO: Use setupApIfaceAndGetName after fixing b/177483254
+ // std::string ifname = setupApIfaceAndGetName(false);
+ std::string ifname = getPrimaryWlanIfaceName();
+ auto status_1_2 =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithoutAcs(ifname), getPskNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code);
- auto status =
- HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName());
+ auto status = HIDL_INVOKE(hostapd_, removeAccessPoint, ifname);
EXPECT_EQ(
android::hardware::wifi::hostapd::V1_0::HostapdStatusCode::SUCCESS,
status.code);
@@ -401,9 +500,12 @@
* Access point creation should fail.
*/
TEST_P(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) {
+ // TODO: Use setupApIfaceAndGetName after fixing b/177483254
+ // std::string ifname = setupApIfaceAndGetName(false);
+ std::string ifname = getPrimaryWlanIfaceName();
auto status =
HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
- getIfaceParamsWithInvalidChannel(), getPskNwParams());
+ getIfaceParamsWithInvalidChannel(ifname), getPskNwParams());
EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
}
@@ -412,9 +514,12 @@
* Access point creation should fail.
*/
TEST_P(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) {
+ // TODO: Use setupApIfaceAndGetName after fixing b/177483254
+ // std::string ifname = setupApIfaceAndGetName(false);
+ std::string ifname = getPrimaryWlanIfaceName();
auto status =
- HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(),
- getInvalidPskNwParams());
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithoutAcs(ifname), getInvalidPskNwParams());
EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
}
@@ -424,9 +529,12 @@
*/
TEST_P(HostapdHidlTest, AddInvalidSaeTransitionAccessPointWithoutAcs) {
if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
- auto status =
- HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(),
- getInvalidSaeTransitionNwParams());
+ // TODO: Use setupApIfaceAndGetName after fixing b/177483254
+ // std::string ifname = setupApIfaceAndGetName(false);
+ std::string ifname = getPrimaryWlanIfaceName();
+ auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithoutAcs(ifname),
+ getInvalidSaeTransitionNwParams());
EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
}
@@ -436,9 +544,12 @@
*/
TEST_P(HostapdHidlTest, AddInvalidSaeAccessPointWithoutAcs) {
if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
+ // TODO: Use setupApIfaceAndGetName after fixing b/177483254
+ // std::string ifname = setupApIfaceAndGetName(false);
+ std::string ifname = getPrimaryWlanIfaceName();
auto status =
- HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(),
- getInvalidSaeNwParams());
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithoutAcs(ifname), getInvalidSaeNwParams());
EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
}
@@ -447,21 +558,30 @@
* when hotspot interface available.
*/
TEST_P(HostapdHidlTest, DisconnectClientWhenIfacAvailable) {
+ // TODO: Use setupApIfaceAndGetName after fixing b/177483254
+ // std::string ifname = setupApIfaceAndGetName(false);
+ std::string ifname = getPrimaryWlanIfaceName();
auto status_1_2 =
- HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(),
- getOpenNwParams());
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithoutAcs(ifname), getOpenNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code);
- status_1_2 =
- HIDL_INVOKE(hostapd_, forceClientDisconnect, getPrimaryWlanIfaceName(),
- kTestZeroMacAddr, kTestDisconnectReasonCode);
+ status_1_2 = HIDL_INVOKE(hostapd_, forceClientDisconnect, ifname,
+ kTestZeroMacAddr, kTestDisconnectReasonCode);
EXPECT_EQ(HostapdStatusCode::FAILURE_CLIENT_UNKNOWN, status_1_2.code);
}
/**
* AddAccessPointWithDualBandConfig should pass
*/
-// TODO: Add it after VendorHal ready & add feature support check.
+TEST_P(HostapdHidlTest, AddAccessPointWithDualBandConfig) {
+ if (!isBridgedSupport_) GTEST_SKIP() << "Missing Bridged AP support";
+ std::string ifname = setupApIfaceAndGetName(true);
+ auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithBridgedModeACS(ifname),
+ getOpenNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code);
+}
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HostapdHidlTest);
INSTANTIATE_TEST_CASE_P(