Merge "Make return values of IContextHub.aidl more consistent"
diff --git a/automotive/can/1.0/tools/libprotocan/Android.bp b/automotive/can/1.0/tools/libprotocan/Android.bp
new file mode 100644
index 0000000..4c23fad
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/Android.bp
@@ -0,0 +1,42 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library_static {
+ name: "libprotocan",
+ defaults: ["android.hardware.automotive.can@defaults"],
+ vendor: true,
+ srcs: [
+ "Checksum.cpp",
+ "MessageCounter.cpp",
+ "MessageDef.cpp",
+ "MessageInjector.cpp",
+ "Signal.cpp",
+ ],
+ export_include_dirs: ["include"],
+
+ shared_libs: [
+ "android.hardware.automotive.can@1.0",
+ ],
+}
diff --git a/automotive/can/1.0/tools/libprotocan/Checksum.cpp b/automotive/can/1.0/tools/libprotocan/Checksum.cpp
new file mode 100644
index 0000000..72fb0af
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/Checksum.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libprotocan/Checksum.h>
+
+namespace android::hardware::automotive::protocan {
+
+Checksum::Checksum(Signal signal, formula f) : mSignal(signal), mFormula(f) {}
+
+void Checksum::update(can::V1_0::CanMessage& msg) const {
+ mSignal.set(msg, 0);
+ mSignal.set(msg, mFormula(msg) % (mSignal.maxValue + 1));
+}
+
+} // namespace android::hardware::automotive::protocan
diff --git a/automotive/can/1.0/tools/libprotocan/MessageCounter.cpp b/automotive/can/1.0/tools/libprotocan/MessageCounter.cpp
new file mode 100644
index 0000000..ef9882f
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/MessageCounter.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libprotocan/MessageCounter.h>
+
+#include <android-base/logging.h>
+
+namespace android::hardware::automotive::protocan {
+
+/** Whether to log counter state messages. */
+static constexpr bool kSuperVerbose = false;
+
+MessageCounter::MessageCounter(Signal signal) : upperBound(signal.maxValue + 1), mSignal(signal) {}
+
+Signal::value MessageCounter::next() const {
+ CHECK(mCurrent.has_value()) << "Counter not initialized. Did you call isReady?";
+ return (*mCurrent + 1) % upperBound;
+}
+
+void MessageCounter::read(const can::V1_0::CanMessage& msg) {
+ auto val = mSignal.get(msg);
+
+ if (!mCurrent.has_value()) {
+ LOG(VERBOSE) << "Got first counter val of " << val;
+ mCurrent = val;
+ return;
+ }
+
+ auto nextVal = next();
+ if (nextVal == val) {
+ if constexpr (kSuperVerbose) {
+ LOG(VERBOSE) << "Got next counter val of " << nextVal;
+ }
+ mCurrent = nextVal;
+ } else {
+ LOG(DEBUG) << "Ignoring next counter val of " << val << ", waiting for " << nextVal;
+ }
+}
+
+bool MessageCounter::isReady() const { return mCurrent.has_value(); }
+
+void MessageCounter::increment(can::V1_0::CanMessage& msg) {
+ auto newVal = next();
+ mCurrent = newVal;
+ mSignal.set(msg, newVal);
+}
+
+} // namespace android::hardware::automotive::protocan
diff --git a/automotive/can/1.0/tools/libprotocan/MessageDef.cpp b/automotive/can/1.0/tools/libprotocan/MessageDef.cpp
new file mode 100644
index 0000000..23ce1df
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/MessageDef.cpp
@@ -0,0 +1,62 @@
+/*
+ * 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 <libprotocan/MessageDef.h>
+
+#include <android-base/logging.h>
+
+namespace android::hardware::automotive::protocan {
+
+using can::V1_0::CanMessage;
+using can::V1_0::CanMessageId;
+
+MessageDef::MessageDef(CanMessageId id, uint16_t len, std::map<std::string, Signal> signals,
+ std::optional<Signal> counter, std::optional<Checksum> checksum)
+ : id(id), kLen(len), kSignals(std::move(signals)), kCounter(counter), kChecksum(checksum) {}
+
+const Signal& MessageDef::operator[](const std::string& signalName) const {
+ auto it = kSignals.find(signalName);
+ CHECK(it != kSignals.end()) << "Signal " << signalName << " doesn't exist";
+ return it->second;
+}
+
+CanMessage MessageDef::makeDefault() const {
+ CanMessage msg = {};
+ msg.id = id;
+ msg.payload.resize(kLen);
+
+ for (auto const& [name, signal] : kSignals) {
+ signal.setDefault(msg);
+ }
+
+ return msg;
+}
+
+MessageCounter MessageDef::makeCounter() const {
+ CHECK(kCounter.has_value()) << "Can't build a counter for message without such signal";
+ return MessageCounter(*kCounter);
+}
+
+void MessageDef::updateChecksum(can::V1_0::CanMessage& msg) const {
+ if (!kChecksum.has_value()) return;
+ kChecksum->update(msg);
+}
+
+bool MessageDef::validate(const can::V1_0::CanMessage& msg) const {
+ return msg.payload.size() >= kLen;
+}
+
+} // namespace android::hardware::automotive::protocan
diff --git a/automotive/can/1.0/tools/libprotocan/MessageInjector.cpp b/automotive/can/1.0/tools/libprotocan/MessageInjector.cpp
new file mode 100644
index 0000000..7c45eaa
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/MessageInjector.cpp
@@ -0,0 +1,110 @@
+/*
+ * 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 <libprotocan/MessageInjector.h>
+
+#include <android-base/logging.h>
+
+#include <thread>
+
+namespace android::hardware::automotive::protocan {
+
+/** Whether to log injected messages. */
+static constexpr bool kSuperVerbose = true;
+
+using namespace std::literals::chrono_literals;
+
+using can::V1_0::CanMessage;
+using can::V1_0::CanMessageId;
+using can::V1_0::ICanBus;
+using can::V1_0::Result;
+
+MessageInjector::MessageInjector(MessageDef msgDef,
+ std::optional<std::chrono::milliseconds> interMessageDelay)
+ : kMsgDef(std::move(msgDef)),
+ kInterMessageDelay(interMessageDelay),
+ mCounter(msgDef.makeCounter()) {}
+
+void MessageInjector::inject(const CanMessage& msg) { inject({msg}); }
+
+void MessageInjector::inject(const std::initializer_list<can::V1_0::CanMessage> msgs) {
+ std::lock_guard<std::mutex> lock(mMessagesGuard);
+ for (const auto& msg : msgs) {
+ if constexpr (kSuperVerbose) {
+ LOG(VERBOSE) << "Message scheduled for injection: " << toString(msg);
+ }
+
+ mMessages.push(msg);
+ }
+}
+
+void MessageInjector::processQueueLocked(can::V1_0::ICanBus& bus) {
+ if (mMessages.empty() || !mCounter.isReady()) return;
+
+ auto paddingMessagesCount = mCounter.upperBound - (mMessages.size() % mCounter.upperBound);
+ auto padMessage = kMsgDef.makeDefault();
+ for (unsigned i = 0; i < paddingMessagesCount; i++) {
+ mMessages.push(padMessage);
+ }
+
+ while (!mMessages.empty()) {
+ auto&& outMsg = mMessages.front();
+
+ mCounter.increment(outMsg);
+ kMsgDef.updateChecksum(outMsg);
+
+ if constexpr (kSuperVerbose) {
+ LOG(VERBOSE) << "Injecting message: " << toString(outMsg);
+ }
+ auto result = bus.send(outMsg);
+ if (result != Result::OK) {
+ LOG(ERROR) << "Message injection failed: " << toString(result);
+ }
+
+ mMessages.pop();
+
+ // This would block onReceive, but the class is not supposed to be used in production anyway
+ // (see MessageInjector docstring).
+ if (kInterMessageDelay.has_value()) {
+ std::this_thread::sleep_for(*kInterMessageDelay);
+ }
+ }
+}
+
+void MessageInjector::onReceive(ICanBus& bus, const CanMessage& msg) {
+ if (!kMsgDef.validate(msg)) return;
+
+ std::lock_guard<std::mutex> lock(mMessagesGuard);
+
+ mCounter.read(msg);
+ processQueueLocked(bus);
+}
+
+MessageInjectorManager::MessageInjectorManager(
+ std::initializer_list<std::shared_ptr<MessageInjector>> injectors) {
+ std::transform(injectors.begin(), injectors.end(), std::inserter(mInjectors, mInjectors.end()),
+ [](const std::shared_ptr<MessageInjector>& injector) {
+ return std::make_pair(injector->kMsgDef.id, std::move(injector));
+ });
+}
+
+void MessageInjectorManager::onReceive(sp<ICanBus> bus, const CanMessage& msg) {
+ auto it = mInjectors.find(msg.id);
+ if (it == mInjectors.end()) return;
+ it->second->onReceive(*bus, msg);
+}
+
+} // namespace android::hardware::automotive::protocan
diff --git a/automotive/can/1.0/tools/libprotocan/Signal.cpp b/automotive/can/1.0/tools/libprotocan/Signal.cpp
new file mode 100644
index 0000000..bc3e070
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/Signal.cpp
@@ -0,0 +1,84 @@
+/*
+ * 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 <libprotocan/Signal.h>
+
+#include <android-base/logging.h>
+
+namespace android::hardware::automotive::protocan {
+
+static uint8_t calculateLastByteMask(uint16_t start, uint8_t length) {
+ unsigned lastByteBits = (start + length) % 8;
+ unsigned lastBytePadding = (8 - lastByteBits) % 8;
+ return 0xFF >> lastBytePadding;
+}
+
+static uint8_t calculateFirstByteMask(uint16_t firstByte, uint8_t firstBit, uint16_t lastByte,
+ uint8_t lastMask) {
+ uint8_t firstMask = 0xFF << firstBit;
+ if (firstByte == lastByte) firstMask &= lastMask;
+ return firstMask;
+}
+
+Signal::Signal(uint16_t start, uint8_t length, value defVal)
+ : maxValue((1u << length) - 1),
+ kFirstByte(start / 8),
+ kFirstBit(start % 8),
+ kFirstByteBits(8 - kFirstBit),
+ kLastByte((start + length - 1) / 8),
+ kLastMask(calculateLastByteMask(start, length)),
+ kFirstMask(calculateFirstByteMask(kFirstByte, kFirstBit, kLastByte, kLastMask)),
+ kDefVal(defVal) {
+ CHECK(length > 0) << "Signal length must not be zero";
+}
+
+Signal::value Signal::get(const can::V1_0::CanMessage& msg) const {
+ CHECK(msg.payload.size() > kLastByte)
+ << "Message is too short. Did you call MessageDef::validate?";
+
+ Signal::value v = 0;
+ if (kLastByte != kFirstByte) v = kLastMask & msg.payload[kLastByte];
+
+ for (int i = kLastByte - 1; i > kFirstByte; i--) {
+ v = (v << 8) | msg.payload[i];
+ }
+
+ return (v << kFirstByteBits) | ((msg.payload[kFirstByte] & kFirstMask) >> kFirstBit);
+}
+
+void Signal::set(can::V1_0::CanMessage& msg, Signal::value val) const {
+ CHECK(msg.payload.size() > kLastByte)
+ << "Signal requires message of length " << (kLastByte + 1)
+ << " which is beyond message length of " << msg.payload.size();
+
+ uint8_t firstByte = val << kFirstBit;
+ val >>= kFirstByteBits;
+
+ msg.payload[kFirstByte] = (msg.payload[kFirstByte] & ~kFirstMask) | (firstByte & kFirstMask);
+
+ for (int i = kFirstByte + 1; i < kLastByte; i++) {
+ msg.payload[i] = val & 0xFF;
+ val >>= 8;
+ }
+
+ if (kLastByte != kFirstByte) {
+ msg.payload[kLastByte] = (msg.payload[kLastByte] & ~kLastMask) | (val & kLastMask);
+ }
+}
+
+void Signal::setDefault(can::V1_0::CanMessage& msg) const { set(msg, kDefVal); }
+
+} // namespace android::hardware::automotive::protocan
diff --git a/automotive/can/1.0/tools/libprotocan/include/libprotocan/Checksum.h b/automotive/can/1.0/tools/libprotocan/include/libprotocan/Checksum.h
new file mode 100644
index 0000000..ff1dc91
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/include/libprotocan/Checksum.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/automotive/can/1.0/types.h>
+#include <libprotocan/Signal.h>
+
+namespace android::hardware::automotive::protocan {
+
+class Checksum {
+ public:
+ using formula = std::function<Signal::value(const can::V1_0::CanMessage&)>;
+
+ Checksum(Signal signal, formula f);
+
+ void update(can::V1_0::CanMessage& msg) const;
+
+ private:
+ const Signal mSignal;
+ const formula mFormula;
+};
+
+} // namespace android::hardware::automotive::protocan
diff --git a/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageCounter.h b/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageCounter.h
new file mode 100644
index 0000000..56113be
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageCounter.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.
+ */
+
+#pragma once
+
+#include <android/hardware/automotive/can/1.0/types.h>
+#include <libprotocan/Signal.h>
+
+namespace android::hardware::automotive::protocan {
+
+class MessageCounter {
+ public:
+ const Signal::value upperBound;
+
+ MessageCounter(Signal signal);
+
+ /**
+ * Parse CAN message sent by external ECU to determine current counter value.
+ */
+ void read(const can::V1_0::CanMessage& msg);
+
+ /**
+ * States whether current counter value is determined.
+ */
+ bool isReady() const;
+
+ /**
+ * Increment current counter value and set it in a new message.
+ *
+ * Caller must check isReady() at least once before calling this method.
+ */
+ void increment(can::V1_0::CanMessage& msg);
+
+ private:
+ const Signal mSignal;
+
+ std::optional<Signal::value> mCurrent = std::nullopt;
+
+ Signal::value next() const;
+};
+
+} // namespace android::hardware::automotive::protocan
diff --git a/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageDef.h b/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageDef.h
new file mode 100644
index 0000000..79b21e1
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageDef.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/automotive/can/1.0/types.h>
+#include <libprotocan/Checksum.h>
+#include <libprotocan/MessageCounter.h>
+#include <libprotocan/Signal.h>
+
+namespace android::hardware::automotive::protocan {
+
+/**
+ * CAN message definition (not the actual message data).
+ *
+ * Describes static message properties (message ID, signals etc).
+ */
+class MessageDef {
+ public:
+ const can::V1_0::CanMessageId id;
+
+ /**
+ * Create message definition.
+ *
+ * Currently only constant length messages are supported.
+ *
+ * \param id CAN message ID
+ * \param len CAN message length
+ * \param signals CAN signal definitions
+ * \param counter Designated CAN signal definition for message counter, if the message has one
+ * \param checksum Designated CAN signal definition for payload checksum, if the message has one
+ */
+ MessageDef(can::V1_0::CanMessageId id, uint16_t len, std::map<std::string, Signal> signals,
+ std::optional<Signal> counter = std::nullopt,
+ std::optional<Checksum> checksum = std::nullopt);
+
+ const Signal& operator[](const std::string& signalName) const;
+
+ can::V1_0::CanMessage makeDefault() const;
+ MessageCounter makeCounter() const;
+
+ void updateChecksum(can::V1_0::CanMessage& msg) const;
+
+ /**
+ * Validate the message payload is large enough to hold all the signals.
+ */
+ bool validate(const can::V1_0::CanMessage& msg) const;
+
+private:
+ const uint16_t kLen;
+ const std::map<std::string, Signal> kSignals;
+ const std::optional<Signal> kCounter;
+ const std::optional<Checksum> kChecksum;
+};
+
+} // namespace android::hardware::automotive::protocan
diff --git a/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageInjector.h b/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageInjector.h
new file mode 100644
index 0000000..b0ea260
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageInjector.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android-base/macros.h>
+#include <android/hardware/automotive/can/1.0/ICanBus.h>
+#include <libprotocan/MessageCounter.h>
+#include <libprotocan/MessageDef.h>
+#include <utils/Mutex.h>
+
+#include <queue>
+
+namespace android::hardware::automotive::protocan {
+
+class MessageInjectorManager;
+
+/**
+ * Injects CAN messages with a counter to an existing system.
+ *
+ * This class is NOT meant to use in production - there should be no need to inject counted CAN
+ * messages where the other sender is also broadcasting them. If this is the case, it may be a sign
+ * your CAN network needs a redesign. This tool is intended for use for testing and demo purposes.
+ */
+class MessageInjector {
+ public:
+ MessageInjector(MessageDef msgDef, std::optional<std::chrono::milliseconds> interMessageDelay);
+
+ void inject(const can::V1_0::CanMessage& msg);
+ void inject(const std::initializer_list<can::V1_0::CanMessage> msgs);
+
+ private:
+ const MessageDef kMsgDef;
+ const std::optional<std::chrono::milliseconds> kInterMessageDelay;
+ MessageCounter mCounter;
+
+ mutable std::mutex mMessagesGuard;
+ std::queue<can::V1_0::CanMessage> mMessages GUARDED_BY(mMessagesGuard);
+
+ void onReceive(can::V1_0::ICanBus& bus, const can::V1_0::CanMessage& msg);
+ void processQueueLocked(can::V1_0::ICanBus& bus);
+
+ friend class MessageInjectorManager;
+
+ DISALLOW_COPY_AND_ASSIGN(MessageInjector);
+};
+
+/**
+ * Routes intercepted messages to MessageInjector instances configured to handle specific CAN
+ * message (CAN message ID). Intercepted messages from other nodes in CAN network are used to read
+ * current counter value in order to spoof the next packet.
+ */
+class MessageInjectorManager {
+ public:
+ MessageInjectorManager(std::initializer_list<std::shared_ptr<MessageInjector>> injectors);
+
+ void onReceive(sp<can::V1_0::ICanBus> bus, const can::V1_0::CanMessage& msg);
+
+ private:
+ std::map<can::V1_0::CanMessageId, std::shared_ptr<MessageInjector>> mInjectors;
+
+ DISALLOW_COPY_AND_ASSIGN(MessageInjectorManager);
+};
+
+} // namespace android::hardware::automotive::protocan
diff --git a/automotive/can/1.0/tools/libprotocan/include/libprotocan/Signal.h b/automotive/can/1.0/tools/libprotocan/include/libprotocan/Signal.h
new file mode 100644
index 0000000..7c0f119
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/include/libprotocan/Signal.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android-base/macros.h>
+#include <android/hardware/automotive/can/1.0/types.h>
+
+namespace android::hardware::automotive::protocan {
+
+/**
+ * TODO(twasilczyk): right now, only Little Endian signals are supported.
+ */
+class Signal {
+ public:
+ using value = uint64_t;
+
+ const value maxValue;
+
+ Signal(uint16_t start, uint8_t length, value defVal = 0);
+
+ value get(const can::V1_0::CanMessage& msg) const;
+ void set(can::V1_0::CanMessage& msg, value val) const;
+ void setDefault(can::V1_0::CanMessage& msg) const;
+
+ private:
+ const uint16_t kFirstByte; ///< Index of first byte that holds the signal
+ const uint8_t kFirstBit; ///< Index of first bit within first byte
+ const uint8_t kFirstByteBits; ///< How many bits of the first byte belong to the signal
+ const uint16_t kLastByte; ///< Index of last byte that holds the signal
+ const uint8_t kLastMask; ///< Bits of the last byte that belong to the signal
+ const uint8_t kFirstMask; ///< Bits of the first byte that belong to the signal
+
+ const value kDefVal;
+};
+
+} // namespace android::hardware::automotive::protocan
diff --git a/automotive/can/1.0/tools/libprotocan/tests/Android.bp b/automotive/can/1.0/tools/libprotocan/tests/Android.bp
new file mode 100644
index 0000000..251cc06
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/tests/Android.bp
@@ -0,0 +1,39 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+ name: "libprotocan_signal_test",
+ defaults: ["android.hardware.automotive.can@defaults"],
+ vendor: true,
+ gtest: true,
+ srcs: ["libprotocan_signal_test.cpp"],
+ static_libs: [
+ "libprotocan",
+ ],
+ shared_libs: [
+ "android.hardware.automotive.can@1.0",
+ "libhidlbase",
+ ],
+}
diff --git a/automotive/can/1.0/tools/libprotocan/tests/libprotocan_signal_test.cpp b/automotive/can/1.0/tools/libprotocan/tests/libprotocan_signal_test.cpp
new file mode 100644
index 0000000..19c1209
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/tests/libprotocan_signal_test.cpp
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libprotocan/Signal.h>
+
+#include <gtest/gtest.h>
+
+namespace android::hardware::automotive::protocan::unittest {
+
+TEST(SignalTest, TestGetSingleBytes) {
+ can::V1_0::CanMessage msg = {};
+ msg.payload = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ for (unsigned i = 0; i < msg.payload.size(); i++) {
+ Signal signal(8 * i, 8);
+ ASSERT_EQ(i, signal.get(msg));
+ }
+}
+
+TEST(SignalTest, TestSetSingleBytes) {
+ std::vector<can::V1_0::CanMessage> msgs = {{}, {}, {}};
+ msgs[0].payload = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+ msgs[1].payload = {0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB};
+ msgs[2].payload = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ for (unsigned i = 0; i < msgs[0].payload.size(); i++) {
+ Signal signal(8 * i, 8);
+
+ for (auto&& msgOriginal : msgs) {
+ auto msgModified = msgOriginal;
+ signal.set(msgModified, 0xBA);
+
+ auto msgExpected = msgOriginal;
+ msgExpected.payload[i] = 0xBA;
+
+ ASSERT_EQ(msgExpected, msgModified) << "i=" << i;
+ }
+ }
+}
+
+TEST(SignalTest, TestGetStart4) {
+ /* Data generated with Python3:
+ *
+ * from cantools.database.can import *
+ * hex(Message(1, 'm', 4, [Signal('s', 4, 16, byte_order='little_endian')]).
+ * decode(b'\xde\xad\xbe\xef')['s'])
+ */
+
+ can::V1_0::CanMessage msg = {};
+ msg.payload = {0xDE, 0xAD, 0xBE, 0xEF};
+ can::V1_0::CanMessage msg2 = {};
+ msg2.payload = {0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD};
+
+ Signal s0_4(0, 4);
+ Signal s4_4(4, 4);
+ Signal s4_8(4, 8);
+ Signal s4_16(4, 16);
+ Signal s4_28(4, 28);
+ Signal s12_8(12, 8);
+ Signal s12_12(12, 12);
+ Signal s12_16(12, 16);
+ Signal s12_20(12, 20);
+ Signal s12_32(12, 32);
+
+ ASSERT_EQ(0xEu, s0_4.get(msg));
+ ASSERT_EQ(0xDu, s4_4.get(msg));
+ ASSERT_EQ(0xDDu, s4_8.get(msg));
+ ASSERT_EQ(0xEADDu, s4_16.get(msg));
+ ASSERT_EQ(0xEFBEADDu, s4_28.get(msg));
+ ASSERT_EQ(0xEAu, s12_8.get(msg));
+ ASSERT_EQ(0xBEAu, s12_12.get(msg));
+ ASSERT_EQ(0xFBEAu, s12_16.get(msg));
+ ASSERT_EQ(0xEFBEAu, s12_20.get(msg));
+ ASSERT_EQ(0xDDEEFBEAu, s12_32.get(msg2));
+}
+
+TEST(SignalTest, TestGet64) {
+ /* Data generated with Python3:
+ *
+ * from cantools.database.can import *
+ * hex(Message(1, 'm', 9, [Signal('s', 4, 64, byte_order='little_endian')]).
+ * decode(b'\xde\xad\xbe\xef\xab\xbc\xcd\xde\xef')['s'])
+ */
+
+ can::V1_0::CanMessage msg = {};
+ msg.payload = {0xDE, 0xAD, 0xBE, 0xEF, 0xAB, 0xBC, 0xCD, 0xDE, 0xEF};
+
+ Signal s0_64(0, 64);
+ Signal s8_64(8, 64);
+ Signal s4_64(4, 64);
+ Signal s1_64(1, 64);
+
+ ASSERT_EQ(0xDECDBCABEFBEADDEu, s0_64.get(msg));
+ ASSERT_EQ(0xEFDECDBCABEFBEADu, s8_64.get(msg));
+ ASSERT_EQ(0xFDECDBCABEFBEADDu, s4_64.get(msg));
+ ASSERT_EQ(0xEF66DE55F7DF56EFu, s1_64.get(msg));
+}
+
+TEST(SignalTest, TestGetAllStarts) {
+ /* Data generated with Python3:
+ *
+ * from cantools.database.can import *
+ * hex(Message(1, 'm', 6, [Signal('s', 0, 20, byte_order='little_endian')]).
+ * decode(b'\xde\xad\xbe\xef\xde\xad')['s'])
+ */
+
+ std::map<int, Signal::value> shifts = {
+ {0, 0xEADDEu}, {1, 0xF56EFu}, {2, 0xFAB77u}, {3, 0x7D5BBu}, {4, 0xBEADDu}, {5, 0xDF56Eu},
+ {6, 0xEFAB7u}, {7, 0xF7D5Bu}, {8, 0xFBEADu}, {9, 0x7DF56u}, {10, 0xBEFABu}, {11, 0xDF7D5u},
+ };
+
+ can::V1_0::CanMessage msg = {};
+ msg.payload = {0xDE, 0xAD, 0xBE, 0xEF, 0xCC, 0xCC};
+
+ for (auto const& [start, expected] : shifts) {
+ Signal s(start, 20);
+ ASSERT_EQ(expected, s.get(msg)) << "shift of " << start << " failed";
+ }
+}
+
+TEST(SignalTest, TestSetStart4) {
+ /* Data generated with Python3:
+ *
+ * from cantools.database.can import *
+ * so=4 ; sl=8
+ * md = Message(1, 'm', 4, [Signal('a1', 0, so), Signal('a2', so+sl, 32-so-sl),
+ * Signal('s', so, sl, byte_order='little_endian')])
+ * m = md.decode(b'\xcc\xcc\xcc\xcc')
+ * m['s'] = 0xDE
+ * binascii.hexlify(md.encode(m)).upper()
+ */
+ typedef struct {
+ int start;
+ int length;
+ Signal::value setValue;
+ hidl_vec<uint8_t> payload;
+ } case_t;
+
+ std::vector<case_t> cases = {
+ {0, 4, 0xDu, {0xCD, 0xCC, 0xCC, 0xCC}}, {4, 4, 0xDu, {0xDC, 0xCC, 0xCC, 0xCC}},
+ {4, 8, 0xDEu, {0xEC, 0xCD, 0xCC, 0xCC}}, {4, 16, 0xDEADu, {0xDC, 0xEA, 0xCD, 0xCC}},
+ {4, 24, 0xDEADBEu, {0xEC, 0xDB, 0xEA, 0xCD}}, {4, 28, 0xDEADBEEu, {0xEC, 0xBE, 0xAD, 0xDE}},
+ {12, 8, 0xDEu, {0xCC, 0xEC, 0xCD, 0xCC}}, {12, 12, 0xDEAu, {0xCC, 0xAC, 0xDE, 0xCC}},
+ {12, 16, 0xDEADu, {0xCC, 0xDC, 0xEA, 0xCD}}, {12, 20, 0xDEADBu, {0xCC, 0xBC, 0xAD, 0xDE}},
+ };
+
+ can::V1_0::CanMessage msg = {};
+ msg.payload = {0xCC, 0xCC, 0xCC, 0xCC};
+
+ for (auto const& tcase : cases) {
+ Signal s(tcase.start, tcase.length);
+
+ can::V1_0::CanMessage expectedMsg = {};
+ expectedMsg.payload = tcase.payload;
+
+ can::V1_0::CanMessage editedMsg = msg;
+ s.set(editedMsg, tcase.setValue);
+
+ ASSERT_EQ(expectedMsg, editedMsg) << " set(" << tcase.start << ", " << tcase.length << ")";
+ }
+}
+
+TEST(SignalTest, TestSetAllStarts) {
+ /* Data generated with Python3:
+ * from cantools.database.can import *
+ * import binascii
+ * import textwrap
+ *
+ * length = 20
+ * for start in range(0, 32 - length):
+ * signals = [Signal('s', start, length, byte_order='little_endian')]
+ * if start > 0: signals.append(Signal('a', 0, start, byte_order='little_endian'))
+ * signals.append(Signal('b', start + length, 32 - start - length,
+ * byte_order='little_endian'))
+ *
+ * md = Message(1, 'm', 4, signals)
+ * m = md.decode(b'\xcc\xcc\xcc\xcc')
+ * m['s'] = 0xDEADB
+ * out = binascii.hexlify(md.encode(m)).decode('ascii').upper()
+ * out = ', '.join(['0x{}'.format(v) for v in textwrap.wrap(out, 2)])
+ * print('{{ {:d}, {{ {:s} }}}},'.format(start, out))
+ */
+
+ std::map<int, hidl_vec<uint8_t>> shifts = {
+ {0, {0xDB, 0xEA, 0xCD, 0xCC}}, {1, {0xB6, 0xD5, 0xDB, 0xCC}}, {2, {0x6C, 0xAB, 0xF7, 0xCC}},
+ {3, {0xDC, 0x56, 0xEF, 0xCC}}, {4, {0xBC, 0xAD, 0xDE, 0xCC}}, {5, {0x6C, 0x5B, 0xBD, 0xCD}},
+ {6, {0xCC, 0xB6, 0x7A, 0xCF}}, {7, {0xCC, 0x6D, 0xF5, 0xCE}}, {8, {0xCC, 0xDB, 0xEA, 0xCD}},
+ {9, {0xCC, 0xB6, 0xD5, 0xDB}}, {10, {0xCC, 0x6C, 0xAB, 0xF7}}, {11, {0xCC, 0xDC, 0x56, 0xEF}},
+ };
+
+ can::V1_0::CanMessage msg = {};
+ msg.payload = {0xCC, 0xCC, 0xCC, 0xCC};
+
+ for (auto const& [start, expectedPayload] : shifts) {
+ Signal s(start, 20);
+
+ can::V1_0::CanMessage expectedMsg = {};
+ expectedMsg.payload = expectedPayload;
+
+ can::V1_0::CanMessage editedMsg = msg;
+ s.set(editedMsg, 0xDEADB);
+
+ ASSERT_EQ(expectedMsg, editedMsg) << "shift of " << start << " failed";
+ }
+}
+
+} // namespace android::hardware::automotive::protocan::unittest
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h
index 63eb747..49b33d5 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h
@@ -213,7 +213,7 @@
::ndk::ScopedAStatus toScopedAStatus(
const ::android::base::Result<T>& result,
::aidl::android::hardware::automotive::vehicle::StatusCode status,
- std::string additionalErrorMsg) {
+ const std::string& additionalErrorMsg) {
if (result.ok()) {
return ::ndk::ScopedAStatus::ok();
}
@@ -236,10 +236,50 @@
template <class T>
::ndk::ScopedAStatus toScopedAStatus(const ::android::base::Result<T>& result,
- std::string additionalErrorMsg) {
+ const std::string& additionalErrorMsg) {
return toScopedAStatus(result, getErrorCode(result), additionalErrorMsg);
}
+// Check whether the value is valid according to config.
+// We check for the following:
+// * If the type is INT32, {@code value.int32Values} must contain one element.
+// * If the type is INT32_VEC, {@code value.int32Values} must contain at least one element.
+// * If the type is INT64, {@code value.int64Values} must contain one element.
+// * If the type is INT64_VEC, {@code value.int64Values} must contain at least one element.
+// * If the type is FLOAT, {@code value.floatValues} must contain one element.
+// * If the type is FLOAT_VEC, {@code value.floatValues} must contain at least one element.
+// * If the type is MIXED, see checkVendorMixedPropValue.
+::android::base::Result<void> checkPropValue(
+ const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value,
+ const ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig* config);
+
+// Check whether the Mixed type value is valid according to config.
+// We check for the following:
+// * configArray[1] + configArray[2] + configArray[3] must be equal to the number of
+// {@code value.int32Values} elements.
+// * configArray[4] + configArray[5] must be equal to the number of {@code value.int64Values}
+// elements.
+// * configArray[6] + configArray[7] must be equal to the number of {@code value.floatValues}
+// elements.
+// * configArray[8] must be equal to the number of {@code value.byteValues} elements.
+::android::base::Result<void> checkVendorMixedPropValue(
+ const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value,
+ const ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig* config);
+
+// Check whether the value is within the configured range.
+// We check for the following types:
+// * If type is INT32 or INT32_VEC, all {@code value.int32Values} elements must be within
+// {@code minInt32Value} and {@code maxInt32Value} if either of them is not 0.
+// * If type is INT64 or INT64_VEC, all {@code value.int64Values} elements must be within
+// {@code minInt64Value} and {@code maxInt64Value} if either of them is not 0.
+// * If type is FLOAT or FLOAT_VEC, all {@code value.floatValues} elements must be within
+// {@code minFloatValues} and {@code maxFloatValues} if either of them is not 0.
+// We don't check other types. If more checks are required, they should be added in VehicleHardware
+// implementation.
+::android::base::Result<void> checkValueRange(
+ const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value,
+ const ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig* config);
+
} // namespace vehicle
} // namespace automotive
} // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/VehicleUtils.cpp b/automotive/vehicle/aidl/impl/utils/common/src/VehicleUtils.cpp
new file mode 100644
index 0000000..5abde8d
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/utils/common/src/VehicleUtils.cpp
@@ -0,0 +1,210 @@
+/*
+ * 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 "VehicleUtils.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyGroup;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
+using ::android::base::Error;
+using ::android::base::Result;
+using ::ndk::ScopedAStatus;
+
+Result<void> checkPropValue(const VehiclePropValue& value, const VehiclePropConfig* config) {
+ int32_t property = value.prop;
+ VehiclePropertyType type = getPropType(property);
+ switch (type) {
+ case VehiclePropertyType::BOOLEAN:
+ [[fallthrough]];
+ case VehiclePropertyType::INT32:
+ if (value.value.int32Values.size() != 1) {
+ return Error() << "expect 1 int32Values for INT32 type";
+ }
+ break;
+ case VehiclePropertyType::INT32_VEC:
+ if (value.value.int32Values.size() < 1) {
+ return Error() << "expect >=1 int32Values for INT32_VEC type";
+ }
+ break;
+ case VehiclePropertyType::INT64:
+ if (value.value.int64Values.size() != 1) {
+ return Error() << "expect 1 int64Values for INT64 type";
+ }
+ break;
+ case VehiclePropertyType::INT64_VEC:
+ if (value.value.int64Values.size() < 1) {
+ return Error() << "expect >=1 int64Values for INT64_VEC type";
+ }
+ break;
+ case VehiclePropertyType::FLOAT:
+ if (value.value.floatValues.size() != 1) {
+ return Error() << "expect 1 floatValues for FLOAT type";
+ }
+ break;
+ case VehiclePropertyType::FLOAT_VEC:
+ if (value.value.floatValues.size() < 1) {
+ return Error() << "expect >=1 floatValues for FLOAT_VEC type";
+ }
+ break;
+ case VehiclePropertyType::BYTES:
+ // We allow setting an empty bytes array.
+ break;
+ case VehiclePropertyType::STRING:
+ // We allow setting an empty string.
+ break;
+ case VehiclePropertyType::MIXED:
+ if (getPropGroup(property) == VehiclePropertyGroup::VENDOR) {
+ // We only checks vendor mixed properties.
+ return checkVendorMixedPropValue(value, config);
+ }
+ break;
+ default:
+ return Error() << "unknown property type: " << toInt(type);
+ }
+ return {};
+}
+
+Result<void> checkVendorMixedPropValue(const VehiclePropValue& value,
+ const VehiclePropConfig* config) {
+ auto configArray = config->configArray;
+ // configArray[0], 1 indicates the property has a String value, we allow the string value to
+ // be empty.
+
+ size_t int32Count = 0;
+ // configArray[1], 1 indicates the property has a Boolean value.
+ if (configArray[1] == 1) {
+ int32Count++;
+ }
+ // configArray[2], 1 indicates the property has an Integer value.
+ if (configArray[2] == 1) {
+ int32Count++;
+ }
+ // configArray[3], the number indicates the size of Integer[] in the property.
+ int32Count += static_cast<size_t>(configArray[3]);
+ size_t int32Size = value.value.int32Values.size();
+ if (int32Size != int32Count) {
+ return Error() << "invalid mixed property, got " << int32Size << " int32Values, expect "
+ << int32Count;
+ }
+
+ size_t int64Count = 0;
+ // configArray[4], 1 indicates the property has a Long value.
+ if (configArray[4] == 1) {
+ int64Count++;
+ }
+ // configArray[5], the number indicates the size of Long[] in the property.
+ int64Count += static_cast<size_t>(configArray[5]);
+ size_t int64Size = value.value.int64Values.size();
+ if (int64Size != int64Count) {
+ return Error() << "invalid mixed property, got " << int64Size << " int64Values, expect "
+ << int64Count;
+ }
+
+ size_t floatCount = 0;
+ // configArray[6], 1 indicates the property has a Float value.
+ if (configArray[6] == 1) {
+ floatCount++;
+ }
+ // configArray[7], the number indicates the size of Float[] in the property.
+ floatCount += static_cast<size_t>(configArray[7]);
+ size_t floatSize = value.value.floatValues.size();
+ if (floatSize != floatCount) {
+ return Error() << "invalid mixed property, got " << floatSize << " floatValues, expect "
+ << floatCount;
+ }
+
+ // configArray[8], the number indicates the size of byte[] in the property.
+ size_t byteSize = value.value.byteValues.size();
+ size_t byteCount = static_cast<size_t>(configArray[8]);
+ if (byteCount != 0 && byteSize != byteCount) {
+ return Error() << "invalid mixed property, got " << byteSize << " byteValues, expect "
+ << byteCount;
+ }
+ return {};
+}
+
+Result<void> checkValueRange(const VehiclePropValue& value, const VehicleAreaConfig* areaConfig) {
+ if (areaConfig == nullptr) {
+ return {};
+ }
+ int32_t property = value.prop;
+ VehiclePropertyType type = getPropType(property);
+ switch (type) {
+ case VehiclePropertyType::INT32:
+ [[fallthrough]];
+ case VehiclePropertyType::INT32_VEC:
+ if (areaConfig->minInt32Value == 0 && areaConfig->maxInt32Value == 0) {
+ break;
+ }
+ for (int32_t int32Value : value.value.int32Values) {
+ if (int32Value < areaConfig->minInt32Value ||
+ int32Value > areaConfig->maxInt32Value) {
+ return Error() << "int32Value: " << int32Value
+ << " out of range, min: " << areaConfig->minInt32Value
+ << " max: " << areaConfig->maxInt32Value;
+ }
+ }
+ break;
+ case VehiclePropertyType::INT64:
+ [[fallthrough]];
+ case VehiclePropertyType::INT64_VEC:
+ if (areaConfig->minInt64Value == 0 && areaConfig->maxInt64Value == 0) {
+ break;
+ }
+ for (int64_t int64Value : value.value.int64Values) {
+ if (int64Value < areaConfig->minInt64Value ||
+ int64Value > areaConfig->maxInt64Value) {
+ return Error() << "int64Value: " << int64Value
+ << " out of range, min: " << areaConfig->minInt64Value
+ << " max: " << areaConfig->maxInt64Value;
+ }
+ }
+ break;
+ case VehiclePropertyType::FLOAT:
+ [[fallthrough]];
+ case VehiclePropertyType::FLOAT_VEC:
+ if (areaConfig->minFloatValue == 0.f && areaConfig->maxFloatValue == 0.f) {
+ break;
+ }
+ for (float floatValue : value.value.floatValues) {
+ if (floatValue < areaConfig->minFloatValue ||
+ floatValue > areaConfig->maxFloatValue) {
+ return Error() << "floatValue: " << floatValue
+ << " out of range, min: " << areaConfig->minFloatValue
+ << " max: " << areaConfig->maxFloatValue;
+ }
+ }
+ break;
+ default:
+ // We don't check the rest of property types. Additional logic needs to be added if
+ // required in VehicleHardware, e.g. you might want to check the range for mixed
+ // property.
+ break;
+ }
+ return {};
+}
+
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/Android.bp b/automotive/vehicle/aidl/impl/utils/common/test/Android.bp
index dd43712..250b331 100644
--- a/automotive/vehicle/aidl/impl/utils/common/test/Android.bp
+++ b/automotive/vehicle/aidl/impl/utils/common/test/Android.bp
@@ -27,6 +27,7 @@
"libgtest",
"libgmock",
],
+ header_libs: ["VehicleHalTestUtilHeaders"],
defaults: ["VehicleHalDefaults"],
test_suites: ["device-tests"],
}
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/VehicleUtilsTest.cpp b/automotive/vehicle/aidl/impl/utils/common/test/VehicleUtilsTest.cpp
index 131eb3b..de8b26d 100644
--- a/automotive/vehicle/aidl/impl/utils/common/test/VehicleUtilsTest.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/test/VehicleUtilsTest.cpp
@@ -16,6 +16,7 @@
#include <ConcurrentQueue.h>
#include <PropertyUtils.h>
+#include <TestPropertyUtils.h>
#include <VehicleUtils.h>
#include <gtest/gtest.h>
@@ -29,6 +30,8 @@
namespace automotive {
namespace vehicle {
+namespace {
+
using ::aidl::android::hardware::automotive::vehicle::VehicleArea;
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
@@ -37,6 +40,427 @@
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
+struct InvalidPropValueTestCase {
+ std::string name;
+ VehiclePropValue value;
+ bool valid = false;
+ VehiclePropConfig config;
+};
+
+constexpr int32_t int32Prop = toInt(VehicleProperty::INFO_MODEL_YEAR);
+constexpr int32_t int32VecProp = toInt(VehicleProperty::INFO_FUEL_TYPE);
+constexpr int32_t int64Prop = toInt(VehicleProperty::ANDROID_EPOCH_TIME);
+constexpr int32_t int64VecProp = toInt(VehicleProperty::WHEEL_TICK);
+constexpr int32_t floatProp = toInt(VehicleProperty::ENV_OUTSIDE_TEMPERATURE);
+constexpr int32_t floatVecProp = toInt(VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION);
+
+std::vector<InvalidPropValueTestCase> getInvalidPropValuesTestCases() {
+ return std::vector<InvalidPropValueTestCase>(
+ {
+ InvalidPropValueTestCase{
+ .name = "int32_normal",
+ .value =
+ {
+ .prop = int32Prop,
+ .value.int32Values = {0},
+ },
+ .valid = true,
+ },
+ InvalidPropValueTestCase{
+ .name = "int32_no_value",
+ .value =
+ {
+ .prop = int32Prop,
+ },
+ },
+ InvalidPropValueTestCase{
+ .name = "int32_more_than_one_value",
+ .value =
+ {
+ .prop = int32Prop,
+ .value.int32Values = {0, 1},
+ },
+ },
+ InvalidPropValueTestCase{
+ .name = "int32_vec_normal",
+ .value =
+ {
+ .prop = int32VecProp,
+ .value.int32Values = {0, 1},
+ },
+ .valid = true,
+ },
+ InvalidPropValueTestCase{
+ .name = "int32_vec_no_value",
+ .value =
+ {
+ .prop = int32VecProp,
+ },
+ },
+ InvalidPropValueTestCase{
+ .name = "int64_normal",
+ .value =
+ {
+ .prop = int64Prop,
+ .value.int64Values = {0},
+ },
+ .valid = true,
+ },
+ InvalidPropValueTestCase{
+ .name = "int64_no_value",
+ .value =
+ {
+ .prop = int64Prop,
+ },
+ },
+ InvalidPropValueTestCase{
+ .name = "int64_more_than_one_value",
+ .value =
+ {
+ .prop = int64Prop,
+ .value.int64Values = {0, 1},
+ },
+ },
+ InvalidPropValueTestCase{
+ .name = "int64_vec_normal",
+ .value =
+ {
+ .prop = int64VecProp,
+ .value.int64Values = {0, 1},
+ },
+ .valid = true,
+ },
+ InvalidPropValueTestCase{
+ .name = "int64_vec_no_value",
+ .value =
+ {
+ .prop = int64VecProp,
+ },
+ },
+ InvalidPropValueTestCase{
+ .name = "float_normal",
+ .value =
+ {
+ .prop = floatProp,
+ .value.floatValues = {0.0},
+ },
+ .valid = true,
+ },
+ InvalidPropValueTestCase{
+ .name = "float_no_value",
+ .value =
+ {
+ .prop = floatProp,
+ },
+ },
+ InvalidPropValueTestCase{
+ .name = "float_more_than_one_value",
+ .value =
+ {
+ .prop = floatProp,
+ .value.floatValues = {0.0, 1.0},
+ },
+ },
+ InvalidPropValueTestCase{
+ .name = "float_vec_normal",
+ .value =
+ {
+ .prop = floatVecProp,
+ .value.floatValues = {0.0, 1.0},
+ },
+ .valid = true,
+ },
+ InvalidPropValueTestCase{
+ .name = "float_vec_no_value",
+ .value =
+ {
+ .prop = floatVecProp,
+ },
+ },
+ InvalidPropValueTestCase{
+ .name = "mixed_normal",
+ .value =
+ {
+ .prop = kMixedTypePropertyForTest,
+ // Expect 3 values.
+ .value.int32Values = {0, 1, 2},
+ // Expect 2 values.
+ .value.int64Values = {0, 1},
+ // Expect 2 values.
+ .value.floatValues = {0.0, 1.0},
+ // Expect 1 value.
+ .value.byteValues = {static_cast<uint8_t>(0)},
+ },
+ .config =
+ {
+ .prop = kMixedTypePropertyForTest,
+ .configArray = {0, 1, 1, 1, 1, 1, 1, 1, 1},
+ },
+ .valid = true,
+ },
+ InvalidPropValueTestCase{
+ .name = "mixed_mismatch_int32_values_count",
+ .value =
+ {
+ .prop = kMixedTypePropertyForTest,
+ // Expect 3 values.
+ .value.int32Values = {0, 1},
+ // Expect 2 values.
+ .value.int64Values = {0, 1},
+ // Expect 2 values.
+ .value.floatValues = {0.0, 1.0},
+ // Expect 1 value.
+ .value.byteValues = {static_cast<uint8_t>(0)},
+ },
+ .config =
+ {
+ .prop = kMixedTypePropertyForTest,
+ .configArray = {0, 1, 1, 1, 1, 1, 1, 1, 1},
+ },
+ },
+ InvalidPropValueTestCase{
+ .name = "mixed_mismatch_int64_values_count",
+ .value =
+ {
+ .prop = kMixedTypePropertyForTest,
+ // Expect 3 values.
+ .value.int32Values = {0, 1, 2},
+ // Expect 2 values.
+ .value.int64Values = {0},
+ // Expect 2 values.
+ .value.floatValues = {0.0, 1.0},
+ // Expect 1 value.
+ .value.byteValues = {static_cast<uint8_t>(0)},
+ },
+ .config =
+ {
+ .prop = kMixedTypePropertyForTest,
+ .configArray = {0, 1, 1, 1, 1, 1, 1, 1, 1},
+ },
+ },
+ InvalidPropValueTestCase{
+ .name = "mixed_mismatch_float_values_count",
+ .value =
+ {
+ .prop = kMixedTypePropertyForTest,
+ // Expect 3 values.
+ .value.int32Values = {0, 1, 2},
+ // Expect 2 values.
+ .value.int64Values = {0, 1},
+ // Expect 2 values.
+ .value.floatValues = {0.0},
+ // Expect 1 value.
+ .value.byteValues = {static_cast<uint8_t>(0)},
+ },
+ .config =
+ {
+ .prop = kMixedTypePropertyForTest,
+ .configArray = {0, 1, 1, 1, 1, 1, 1, 1, 1},
+ },
+ },
+ InvalidPropValueTestCase{
+ .name = "mixed_mismatch_byte_values_count",
+ .value =
+ {
+ .prop = kMixedTypePropertyForTest,
+ // Expect 3 values.
+ .value.int32Values = {0, 1, 2},
+ // Expect 2 values.
+ .value.int64Values = {0, 1},
+ // Expect 2 values.
+ .value.floatValues = {0.0, 1.0},
+ // Expect 1 value.
+ .value.byteValues = {static_cast<uint8_t>(0),
+ static_cast<uint8_t>(1)},
+ },
+ .config =
+ {
+ .prop = kMixedTypePropertyForTest,
+ .configArray = {0, 1, 1, 1, 1, 1, 1, 1, 1},
+ },
+ },
+ });
+}
+
+struct InvalidValueRangeTestCase {
+ std::string name;
+ VehiclePropValue value;
+ bool valid = false;
+ VehicleAreaConfig config;
+};
+
+std::vector<InvalidValueRangeTestCase> getInvalidValueRangeTestCases() {
+ return std::vector<InvalidValueRangeTestCase>({{
+ InvalidValueRangeTestCase{
+ .name = "int32_normal",
+ .value =
+ {
+ .prop = int32Prop,
+ .value.int32Values = {0},
+ },
+ .valid = true,
+ .config =
+ {
+ .minInt32Value = 0,
+ .maxInt32Value = 10,
+ },
+ },
+ InvalidValueRangeTestCase{
+ .name = "int32_vec_normal",
+ .value =
+ {
+ .prop = int32VecProp,
+ .value.int32Values = {0, 1},
+ },
+ .valid = true,
+ .config =
+ {
+ .minInt32Value = 0,
+ .maxInt32Value = 10,
+ },
+ },
+ InvalidValueRangeTestCase{
+ .name = "int32_vec_underflow",
+ .value =
+ {
+ .prop = int32VecProp,
+ .value.int32Values = {-1, 1},
+ },
+
+ .config =
+ {
+ .minInt32Value = 0,
+ .maxInt32Value = 10,
+ },
+ },
+ InvalidValueRangeTestCase{
+ .name = "int32_vec_overflow",
+ .value =
+ {
+ .prop = int32VecProp,
+ .value.int32Values = {0, 100},
+ },
+ .config =
+ {
+ .minInt32Value = 0,
+ .maxInt32Value = 10,
+ },
+ },
+ InvalidValueRangeTestCase{
+ .name = "int64_normal",
+ .value =
+ {
+ .prop = int64Prop,
+ .value.int64Values = {0},
+ },
+ .valid = true,
+ .config =
+ {
+ .minInt64Value = 0,
+ .maxInt64Value = 10,
+ },
+ },
+ InvalidValueRangeTestCase{
+ .name = "int64_vec_normal",
+ .value =
+ {
+ .prop = int64VecProp,
+ .value.int64Values = {0, 1},
+ },
+ .valid = true,
+ .config =
+ {
+ .minInt64Value = 0,
+ .maxInt64Value = 10,
+ },
+ },
+ InvalidValueRangeTestCase{
+ .name = "int64_vec_underflow",
+ .value =
+ {
+ .prop = int64VecProp,
+ .value.int64Values = {-1, 1},
+ },
+
+ .config =
+ {
+ .minInt64Value = 0,
+ .maxInt64Value = 10,
+ },
+ },
+ InvalidValueRangeTestCase{
+ .name = "int64_vec_overflow",
+ .value =
+ {
+ .prop = int64VecProp,
+ .value.int64Values = {0, 100},
+ },
+ .config =
+ {
+ .minInt64Value = 0,
+ .maxInt64Value = 10,
+ },
+ },
+ InvalidValueRangeTestCase{
+ .name = "float_normal",
+ .value =
+ {
+ .prop = floatProp,
+ .value.floatValues = {0.0},
+ },
+ .valid = true,
+ .config =
+ {
+ .minFloatValue = 0.0,
+ .maxFloatValue = 10.0,
+ },
+ },
+ InvalidValueRangeTestCase{
+ .name = "float_vec_normal",
+ .value =
+ {
+ .prop = floatVecProp,
+ .value.floatValues = {0.0, 10.0},
+ },
+ .valid = true,
+ .config =
+ {
+ .minFloatValue = 0.0,
+ .maxFloatValue = 10.0,
+ },
+ },
+ InvalidValueRangeTestCase{
+ .name = "float_vec_underflow",
+ .value =
+ {
+ .prop = floatVecProp,
+ .value.floatValues = {-0.1, 1.1},
+ },
+
+ .config =
+ {
+ .minFloatValue = 0.0,
+ .maxFloatValue = 10.0,
+ },
+ },
+ InvalidValueRangeTestCase{
+ .name = "float_vec_overflow",
+ .value =
+ {
+ .prop = floatVecProp,
+ .value.floatValues = {0.0, 10.1},
+ },
+ .config =
+ {
+ .minFloatValue = 0.0,
+ .maxFloatValue = 10.0,
+ },
+ },
+ }});
+}
+
+} // namespace
+
TEST(VehicleUtilsTest, testToInt) {
int areaGlobal = toInt(VehicleArea::GLOBAL);
@@ -335,6 +759,40 @@
t.join();
}
+class InvalidPropValueTest : public testing::TestWithParam<InvalidPropValueTestCase> {};
+
+INSTANTIATE_TEST_SUITE_P(InvalidPropValueTests, InvalidPropValueTest,
+ testing::ValuesIn(getInvalidPropValuesTestCases()),
+ [](const testing::TestParamInfo<InvalidPropValueTest::ParamType>& info) {
+ return info.param.name;
+ });
+
+TEST_P(InvalidPropValueTest, testCheckPropValue) {
+ InvalidPropValueTestCase tc = GetParam();
+
+ // Config is not used for non-mixed types.
+ auto result = checkPropValue(tc.value, &tc.config);
+
+ ASSERT_EQ(tc.valid, result.ok());
+}
+
+class InvalidValueRangeTest : public testing::TestWithParam<InvalidValueRangeTestCase> {};
+
+INSTANTIATE_TEST_SUITE_P(InvalidValueRangeTests, InvalidValueRangeTest,
+ testing::ValuesIn(getInvalidValueRangeTestCases()),
+ [](const testing::TestParamInfo<InvalidValueRangeTest::ParamType>& info) {
+ return info.param.name;
+ });
+
+TEST_P(InvalidValueRangeTest, testCheckValueRange) {
+ InvalidValueRangeTestCase tc = GetParam();
+
+ // Config is not used for non-mixed types.
+ auto result = checkValueRange(tc.value, &tc.config);
+
+ ASSERT_EQ(tc.valid, result.ok());
+}
+
} // namespace vehicle
} // namespace automotive
} // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
index 43bdca2..4ee3ee9 100644
--- a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
+++ b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
@@ -17,10 +17,14 @@
#ifndef android_hardware_automotive_vehicle_aidl_impl_vhal_include_DefaultVehicleHal_H_
#define android_hardware_automotive_vehicle_aidl_impl_vhal_include_DefaultVehicleHal_H_
+#include "ConnectedClient.h"
+#include "ParcelableUtils.h"
+
#include <IVehicleHardware.h>
-#include <LargeParcelableBase.h>
#include <VehicleUtils.h>
#include <aidl/android/hardware/automotive/vehicle/BnVehicle.h>
+#include <android-base/expected.h>
+#include <android-base/thread_annotations.h>
#include <android/binder_auto_utils.h>
#include <memory>
@@ -37,59 +41,24 @@
constexpr int INVALID_MEMORY_FD = -1;
-template <class T>
-::ndk::ScopedAStatus toScopedAStatus(
- const ::android::base::Result<T>& result,
- ::aidl::android::hardware::automotive::vehicle::StatusCode status) {
- if (result.ok()) {
- return ::ndk::ScopedAStatus::ok();
- }
- return ::ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(toInt(status),
- getErrorMsg(result).c_str());
-}
-
-template <class T>
-::ndk::ScopedAStatus toScopedAStatus(const ::android::base::Result<T>& result) {
- return toScopedAStatus(result, getErrorCode(result));
-}
-
-template <class T1, class T2>
-::ndk::ScopedAStatus vectorToStableLargeParcelable(std::vector<T1>& values, T2* output) {
- auto result = ::android::automotive::car_binder_lib::LargeParcelableBase::
- parcelableVectorToStableLargeParcelable(values);
- if (!result.ok()) {
- return toScopedAStatus(
- result, ::aidl::android::hardware::automotive::vehicle::StatusCode::INTERNAL_ERROR);
- }
- auto& fd = result.value();
- if (fd == nullptr) {
- output->payloads = values;
- } else {
- // Move the returned ScopedFileDescriptor pointer to ScopedFileDescriptor value in
- // 'sharedMemoryFd' field.
- output->sharedMemoryFd.set(fd->get());
- *(fd->getR()) = INVALID_MEMORY_FD;
- }
- return ::ndk::ScopedAStatus::ok();
-}
-
} // namespace defaultvehiclehal_impl
class DefaultVehicleHal final : public ::aidl::android::hardware::automotive::vehicle::BnVehicle {
public:
+ using CallbackType =
+ std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>;
+
explicit DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware);
::ndk::ScopedAStatus getAllPropConfigs(
::aidl::android::hardware::automotive::vehicle::VehiclePropConfigs* returnConfigs)
override;
::ndk::ScopedAStatus getValues(
- const std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>&
- callback,
+ const CallbackType& callback,
const ::aidl::android::hardware::automotive::vehicle::GetValueRequests& requests)
override;
::ndk::ScopedAStatus setValues(
- const std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>&
- callback,
+ const CallbackType& callback,
const ::aidl::android::hardware::automotive::vehicle::SetValueRequests& requests)
override;
::ndk::ScopedAStatus getPropConfigs(
@@ -97,27 +66,49 @@
::aidl::android::hardware::automotive::vehicle::VehiclePropConfigs* returnConfigs)
override;
::ndk::ScopedAStatus subscribe(
- const std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>&
- callback,
+ const CallbackType& callback,
const std::vector<::aidl::android::hardware::automotive::vehicle::SubscribeOptions>&
options,
int32_t maxSharedMemoryFileCount) override;
- ::ndk::ScopedAStatus unsubscribe(
- const std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>&
- callback,
- const std::vector<int32_t>& propIds) override;
- ::ndk::ScopedAStatus returnSharedMemory(
- const std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>&
- callback,
- int64_t sharedMemoryId) override;
+ ::ndk::ScopedAStatus unsubscribe(const CallbackType& callback,
+ const std::vector<int32_t>& propIds) override;
+ ::ndk::ScopedAStatus returnSharedMemory(const CallbackType& callback,
+ int64_t sharedMemoryId) override;
IVehicleHardware* getHardware();
private:
+ // friend class for unit testing.
+ friend class DefaultVehicleHalTest;
+
+ using GetValuesClient =
+ GetSetValuesClient<::aidl::android::hardware::automotive::vehicle::GetValueResult,
+ ::aidl::android::hardware::automotive::vehicle::GetValueResults>;
+ using SetValuesClient =
+ GetSetValuesClient<::aidl::android::hardware::automotive::vehicle::SetValueResult,
+ ::aidl::android::hardware::automotive::vehicle::SetValueResults>;
+
const std::unique_ptr<IVehicleHardware> mVehicleHardware;
+
+ // mConfigsByPropId and mConfigFile are only modified during initialization, so no need to
+ // lock guard them.
std::unordered_map<int32_t, ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig>
mConfigsByPropId;
std::unique_ptr<::ndk::ScopedFileDescriptor> mConfigFile;
+
+ std::mutex mLock;
+ std::unordered_map<CallbackType, std::shared_ptr<GetValuesClient>> mGetValuesClients
+ GUARDED_BY(mLock);
+ std::unordered_map<CallbackType, std::shared_ptr<SetValuesClient>> mSetValuesClients
+ GUARDED_BY(mLock);
+
+ template <class T>
+ std::shared_ptr<T> getOrCreateClient(
+ std::unordered_map<CallbackType, std::shared_ptr<T>>* clients,
+ const CallbackType& callback) REQUIRES(mLock);
+
+ ::android::base::Result<void> checkProperty(
+ const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& propValue);
};
} // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
index fd9e331..e98f021 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
@@ -21,6 +21,7 @@
#include <LargeParcelableBase.h>
#include <VehicleHalTypes.h>
#include <VehicleUtils.h>
+
#include <android-base/result.h>
#include <utils/Log.h>
@@ -29,14 +30,24 @@
namespace automotive {
namespace vehicle {
+using ::aidl::android::hardware::automotive::vehicle::GetValueRequest;
using ::aidl::android::hardware::automotive::vehicle::GetValueRequests;
+using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
+using ::aidl::android::hardware::automotive::vehicle::GetValueResults;
using ::aidl::android::hardware::automotive::vehicle::IVehicleCallback;
+using ::aidl::android::hardware::automotive::vehicle::SetValueRequest;
using ::aidl::android::hardware::automotive::vehicle::SetValueRequests;
+using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
+using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
using ::aidl::android::hardware::automotive::vehicle::StatusCode;
using ::aidl::android::hardware::automotive::vehicle::SubscribeOptions;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfigs;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
using ::android::automotive::car_binder_lib::LargeParcelableBase;
+using ::android::base::Error;
+using ::android::base::expected;
using ::android::base::Result;
using ::ndk::ScopedAStatus;
@@ -70,15 +81,141 @@
return ScopedAStatus::ok();
}
-ScopedAStatus DefaultVehicleHal::getValues(const std::shared_ptr<IVehicleCallback>&,
- const GetValueRequests&) {
- // TODO(b/200737967): implement this.
+template <class T>
+std::shared_ptr<T> DefaultVehicleHal::getOrCreateClient(
+ std::unordered_map<CallbackType, std::shared_ptr<T>>* clients,
+ const CallbackType& callback) {
+ if (clients->find(callback) == clients->end()) {
+ // TODO(b/204943359): Remove client from clients when linkToDeath is implemented.
+ (*clients)[callback] = std::make_shared<T>(callback);
+ }
+ return (*clients)[callback];
+}
+
+template std::shared_ptr<DefaultVehicleHal::GetValuesClient>
+DefaultVehicleHal::getOrCreateClient<DefaultVehicleHal::GetValuesClient>(
+ std::unordered_map<CallbackType, std::shared_ptr<GetValuesClient>>* clients,
+ const CallbackType& callback);
+
+template std::shared_ptr<DefaultVehicleHal::SetValuesClient>
+DefaultVehicleHal::getOrCreateClient<DefaultVehicleHal::SetValuesClient>(
+ std::unordered_map<CallbackType, std::shared_ptr<SetValuesClient>>* clients,
+ const CallbackType& callback);
+
+Result<void> DefaultVehicleHal::checkProperty(const VehiclePropValue& propValue) {
+ int32_t propId = propValue.prop;
+ auto it = mConfigsByPropId.find(propId);
+ if (it == mConfigsByPropId.end()) {
+ return Error() << "no config for property, ID: " << propId;
+ }
+ const VehiclePropConfig& config = it->second;
+ const VehicleAreaConfig* areaConfig = getAreaConfig(propValue, config);
+ if (!isGlobalProp(propId) && areaConfig == nullptr) {
+ // Ignore areaId for global property. For non global property, check whether areaId is
+ // allowed. areaId must appear in areaConfig.
+ return Error() << "invalid area ID: " << propValue.areaId << " for prop ID: " << propId
+ << ", not listed in config";
+ }
+ if (auto result = checkPropValue(propValue, &config); !result.ok()) {
+ return Error() << "invalid property value: " << propValue.toString()
+ << ", error: " << result.error().message();
+ }
+ if (auto result = checkValueRange(propValue, areaConfig); !result.ok()) {
+ return Error() << "property value out of range: " << propValue.toString()
+ << ", error: " << result.error().message();
+ }
+ return {};
+}
+
+ScopedAStatus DefaultVehicleHal::getValues(const CallbackType& callback,
+ const GetValueRequests& requests) {
+ // TODO(b/203713317): check for duplicate properties and duplicate request IDs.
+
+ const std::vector<GetValueRequest>* getValueRequests;
+ // Define deserializedResults here because we need it to have the same lifetime as
+ // getValueRequests.
+ expected<std::vector<GetValueRequest>, ScopedAStatus> deserializedResults;
+ if (!requests.payloads.empty()) {
+ getValueRequests = &requests.payloads;
+ } else {
+ deserializedResults = stableLargeParcelableToVector<GetValueRequest>(requests);
+ if (!deserializedResults.ok()) {
+ ALOGE("failed to parse getValues requests");
+ return std::move(deserializedResults.error());
+ }
+ getValueRequests = &deserializedResults.value();
+ }
+
+ std::shared_ptr<GetValuesClient> client;
+ {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ client = getOrCreateClient(&mGetValuesClients, callback);
+ }
+
+ if (StatusCode status =
+ mVehicleHardware->getValues(client->getResultCallback(), *getValueRequests);
+ status != StatusCode::OK) {
+ return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ toInt(status), "failed to get value from VehicleHardware");
+ }
+
return ScopedAStatus::ok();
}
-ScopedAStatus DefaultVehicleHal::setValues(const std::shared_ptr<IVehicleCallback>&,
- const SetValueRequests&) {
- // TODO(b/200737967): implement this.
+ScopedAStatus DefaultVehicleHal::setValues(const CallbackType& callback,
+ const SetValueRequests& requests) {
+ // TODO(b/203713317): check for duplicate properties and duplicate request IDs.
+
+ const std::vector<SetValueRequest>* setValueRequests;
+ // Define deserializedResults here because we need it to have the same lifetime as
+ // setValueRequests.
+ expected<std::vector<SetValueRequest>, ScopedAStatus> deserializedResults;
+ if (!requests.payloads.empty()) {
+ setValueRequests = &requests.payloads;
+ } else {
+ deserializedResults = stableLargeParcelableToVector<SetValueRequest>(requests);
+ if (!deserializedResults.ok()) {
+ ALOGE("failed to parse setValues requests");
+ return std::move(deserializedResults.error());
+ }
+ setValueRequests = &deserializedResults.value();
+ }
+
+ // A list of failed result we already know before sending to hardware.
+ std::vector<SetValueResult> failedResults;
+ // The list of requests that we would send to hardware.
+ std::vector<SetValueRequest> hardwareRequests;
+
+ for (auto& request : *setValueRequests) {
+ int64_t requestId = request.requestId;
+ if (auto result = checkProperty(request.value); !result.ok()) {
+ ALOGW("property not valid: %s", result.error().message().c_str());
+ failedResults.push_back(SetValueResult{
+ .requestId = requestId,
+ .status = StatusCode::INVALID_ARG,
+ });
+ continue;
+ }
+ hardwareRequests.push_back(request);
+ }
+
+ std::shared_ptr<SetValuesClient> client;
+ {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ client = getOrCreateClient(&mSetValuesClients, callback);
+ }
+
+ if (!failedResults.empty()) {
+ client->sendResults(failedResults);
+ }
+
+ if (StatusCode status =
+ mVehicleHardware->setValues(client->getResultCallback(), hardwareRequests);
+ status != StatusCode::OK) {
+ return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ toInt(status), "failed to set value to VehicleHardware");
+ }
+
return ScopedAStatus::ok();
}
@@ -90,23 +227,21 @@
configs.push_back(mConfigsByPropId[prop]);
}
}
- return defaultvehiclehal_impl::vectorToStableLargeParcelable(configs, output);
+ return vectorToStableLargeParcelable(std::move(configs), output);
}
-ScopedAStatus DefaultVehicleHal::subscribe(const std::shared_ptr<IVehicleCallback>&,
+ScopedAStatus DefaultVehicleHal::subscribe(const CallbackType&,
const std::vector<SubscribeOptions>&, int32_t) {
// TODO(b/200737967): implement this.
return ScopedAStatus::ok();
}
-ScopedAStatus DefaultVehicleHal::unsubscribe(const std::shared_ptr<IVehicleCallback>&,
- const std::vector<int32_t>&) {
+ScopedAStatus DefaultVehicleHal::unsubscribe(const CallbackType&, const std::vector<int32_t>&) {
// TODO(b/200737967): implement this.
return ScopedAStatus::ok();
}
-ScopedAStatus DefaultVehicleHal::returnSharedMemory(const std::shared_ptr<IVehicleCallback>&,
- int64_t) {
+ScopedAStatus DefaultVehicleHal::returnSharedMemory(const CallbackType&, int64_t) {
// TODO(b/200737967): implement this.
return ScopedAStatus::ok();
}
diff --git a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
index 2b5ca70..8934a7b 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
@@ -15,17 +15,24 @@
*/
#include "DefaultVehicleHal.h"
+#include "MockVehicleCallback.h"
#include <IVehicleHardware.h>
#include <LargeParcelableBase.h>
#include <aidl/android/hardware/automotive/vehicle/IVehicle.h>
-#include <android-base/thread_annotations.h>
+#include <aidl/android/hardware/automotive/vehicle/IVehicleCallback.h>
+#include <android-base/thread_annotations.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
+#include <utils/Log.h>
+#include <list>
#include <memory>
+#include <mutex>
#include <optional>
+#include <thread>
+#include <unordered_map>
#include <vector>
namespace android {
@@ -36,38 +43,77 @@
namespace {
using ::aidl::android::hardware::automotive::vehicle::GetValueRequest;
+using ::aidl::android::hardware::automotive::vehicle::GetValueRequests;
using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
+using ::aidl::android::hardware::automotive::vehicle::GetValueResults;
using ::aidl::android::hardware::automotive::vehicle::IVehicle;
+using ::aidl::android::hardware::automotive::vehicle::IVehicleCallback;
using ::aidl::android::hardware::automotive::vehicle::SetValueRequest;
+using ::aidl::android::hardware::automotive::vehicle::SetValueRequests;
using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
+using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
using ::aidl::android::hardware::automotive::vehicle::StatusCode;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAreaWindow;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfigs;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropErrors;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropValues;
using ::android::automotive::car_binder_lib::LargeParcelableBase;
using ::android::base::Result;
+using ::ndk::ScopedAStatus;
+using ::ndk::ScopedFileDescriptor;
+
using ::testing::Eq;
using ::testing::WhenSortedBy;
+constexpr int32_t INVALID_PROP_ID = 0;
+// VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
+constexpr int32_t INT32_WINDOW_PROP = 10001 + 0x10000000 + 0x03000000 + 0x00400000;
+
+template <class T>
+std::optional<T> pop(std::list<T>& items) {
+ if (items.size() > 0) {
+ auto item = std::move(items.front());
+ items.pop_front();
+ return item;
+ }
+ return std::nullopt;
+}
+
+int32_t testInt32VecProp(size_t i) {
+ // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+ return static_cast<int32_t>(i) + 0x10000000 + 0x01000000 + 0x00410000;
+}
+
class MockVehicleHardware final : public IVehicleHardware {
public:
+ ~MockVehicleHardware() {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ for (auto& thread : mThreads) {
+ thread.join();
+ }
+ }
+
std::vector<VehiclePropConfig> getAllPropertyConfigs() const override {
std::scoped_lock<std::mutex> lockGuard(mLock);
return mPropertyConfigs;
}
- StatusCode setValues(std::shared_ptr<const SetValuesCallback>,
- const std::vector<SetValueRequest>&) override {
- // TODO(b/200737967): mock this.
- return StatusCode::OK;
+ StatusCode setValues(std::shared_ptr<const SetValuesCallback> callback,
+ const std::vector<SetValueRequest>& requests) override {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ return handleRequests(__func__, callback, requests, &mSetValueRequests,
+ &mSetValueResponses);
}
- StatusCode getValues(std::shared_ptr<const GetValuesCallback>,
- const std::vector<GetValueRequest>&) const override {
- // TODO(b/200737967): mock this.
- return StatusCode::OK;
+ StatusCode getValues(std::shared_ptr<const GetValuesCallback> callback,
+ const std::vector<GetValueRequest>& requests) const override {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ return handleRequests(__func__, callback, requests, &mGetValueRequests,
+ &mGetValueResponses);
}
DumpResult dump(const std::vector<std::string>&) override {
@@ -94,20 +140,316 @@
mPropertyConfigs = configs;
}
+ void addGetValueResponses(const std::vector<GetValueResult>& responses) {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ mGetValueResponses.push_back(responses);
+ }
+
+ void addSetValueResponses(const std::vector<SetValueResult>& responses) {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ mSetValueResponses.push_back(responses);
+ }
+
+ std::vector<GetValueRequest> nextGetValueRequests() {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ std::optional<std::vector<GetValueRequest>> request = pop(mGetValueRequests);
+ if (!request.has_value()) {
+ return std::vector<GetValueRequest>();
+ }
+ return std::move(request.value());
+ }
+
+ std::vector<SetValueRequest> nextSetValueRequests() {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ std::optional<std::vector<SetValueRequest>> request = pop(mSetValueRequests);
+ if (!request.has_value()) {
+ return std::vector<SetValueRequest>();
+ }
+ return std::move(request.value());
+ }
+
+ void setStatus(const char* functionName, StatusCode status) {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ mStatusByFunctions[functionName] = status;
+ }
+
+ void setSleepTime(int64_t timeInNano) {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ mSleepTime = timeInNano;
+ }
+
private:
mutable std::mutex mLock;
std::vector<VehiclePropConfig> mPropertyConfigs GUARDED_BY(mLock);
+ mutable std::list<std::vector<GetValueRequest>> mGetValueRequests GUARDED_BY(mLock);
+ mutable std::list<std::vector<GetValueResult>> mGetValueResponses GUARDED_BY(mLock);
+ mutable std::list<std::vector<SetValueRequest>> mSetValueRequests GUARDED_BY(mLock);
+ mutable std::list<std::vector<SetValueResult>> mSetValueResponses GUARDED_BY(mLock);
+ std::unordered_map<const char*, StatusCode> mStatusByFunctions GUARDED_BY(mLock);
+ int64_t mSleepTime GUARDED_BY(mLock) = 0;
+ mutable std::vector<std::thread> mThreads GUARDED_BY(mLock);
+
+ template <class ResultType>
+ StatusCode returnResponse(
+ std::shared_ptr<const std::function<void(std::vector<ResultType>)>> callback,
+ std::list<std::vector<ResultType>>* storedResponses) const;
+
+ template <class RequestType, class ResultType>
+ StatusCode handleRequests(
+ const char* functionName,
+ std::shared_ptr<const std::function<void(std::vector<ResultType>)>> callback,
+ const std::vector<RequestType>& requests,
+ std::list<std::vector<RequestType>>* storedRequests,
+ std::list<std::vector<ResultType>>* storedResponses) const REQUIRES(mLock);
};
+template <class ResultType>
+StatusCode MockVehicleHardware::returnResponse(
+ std::shared_ptr<const std::function<void(std::vector<ResultType>)>> callback,
+ std::list<std::vector<ResultType>>* storedResponses) const {
+ if (storedResponses->size() > 0) {
+ (*callback)(std::move(storedResponses->front()));
+ storedResponses->pop_front();
+ return StatusCode::OK;
+ } else {
+ ALOGE("no more response");
+ return StatusCode::INTERNAL_ERROR;
+ }
+}
+
+template StatusCode MockVehicleHardware::returnResponse<GetValueResult>(
+ std::shared_ptr<const std::function<void(std::vector<GetValueResult>)>> callback,
+ std::list<std::vector<GetValueResult>>* storedResponses) const;
+
+template StatusCode MockVehicleHardware::returnResponse<SetValueResult>(
+ std::shared_ptr<const std::function<void(std::vector<SetValueResult>)>> callback,
+ std::list<std::vector<SetValueResult>>* storedResponses) const;
+
+template <class RequestType, class ResultType>
+StatusCode MockVehicleHardware::handleRequests(
+ const char* functionName,
+ std::shared_ptr<const std::function<void(std::vector<ResultType>)>> callback,
+ const std::vector<RequestType>& requests,
+ std::list<std::vector<RequestType>>* storedRequests,
+ std::list<std::vector<ResultType>>* storedResponses) const {
+ storedRequests->push_back(requests);
+ if (auto it = mStatusByFunctions.find(functionName); it != mStatusByFunctions.end()) {
+ if (StatusCode status = it->second; status != StatusCode::OK) {
+ return status;
+ }
+ }
+
+ if (mSleepTime != 0) {
+ int64_t sleepTime = mSleepTime;
+ mThreads.emplace_back([this, callback, sleepTime, storedResponses]() {
+ std::this_thread::sleep_for(std::chrono::nanoseconds(sleepTime));
+ returnResponse(callback, storedResponses);
+ });
+ return StatusCode::OK;
+
+ } else {
+ return returnResponse(callback, storedResponses);
+ }
+}
+
+template StatusCode MockVehicleHardware::handleRequests<GetValueRequest, GetValueResult>(
+ const char* functionName,
+ std::shared_ptr<const std::function<void(std::vector<GetValueResult>)>> callback,
+ const std::vector<GetValueRequest>& requests,
+ std::list<std::vector<GetValueRequest>>* storedRequests,
+ std::list<std::vector<GetValueResult>>* storedResponses) const;
+
+template StatusCode MockVehicleHardware::handleRequests<SetValueRequest, SetValueResult>(
+ const char* functionName,
+ std::shared_ptr<const std::function<void(std::vector<SetValueResult>)>> callback,
+ const std::vector<SetValueRequest>& requests,
+ std::list<std::vector<SetValueRequest>>* storedRequests,
+ std::list<std::vector<SetValueResult>>* storedResponses) const;
+
struct PropConfigCmp {
bool operator()(const VehiclePropConfig& a, const VehiclePropConfig& b) const {
return (a.prop < b.prop);
}
} propConfigCmp;
+struct SetValuesInvalidRequestTestCase {
+ std::string name;
+ VehiclePropValue request;
+ StatusCode expectedStatus;
+};
+
+std::vector<SetValuesInvalidRequestTestCase> getSetValuesInvalidRequestTestCases() {
+ return {{
+ .name = "config_not_found",
+ .request =
+ {
+ // No config for INVALID_PROP_ID.
+ .prop = INVALID_PROP_ID,
+ },
+ .expectedStatus = StatusCode::INVALID_ARG,
+ },
+ {
+ .name = "invalid_prop_value",
+ .request =
+ {
+ .prop = testInt32VecProp(0),
+ // No int32Values for INT32_VEC property.
+ .value.int32Values = {},
+ },
+ .expectedStatus = StatusCode::INVALID_ARG,
+ },
+ {
+ .name = "value_out_of_range",
+ .request =
+ {
+ .prop = testInt32VecProp(0),
+ // We configured the range to be 0-100.
+ .value.int32Values = {0, -1},
+ },
+ .expectedStatus = StatusCode::INVALID_ARG,
+ },
+ {
+ .name = "invalid_area",
+ .request =
+ {
+ .prop = INT32_WINDOW_PROP,
+ .value.int32Values = {0},
+ // Only ROW_1_LEFT is allowed.
+ .areaId = toInt(VehicleAreaWindow::ROW_1_RIGHT),
+ },
+ .expectedStatus = StatusCode::INVALID_ARG,
+ }};
+}
+
} // namespace
-TEST(DefaultVehicleHalTest, testGetAllPropConfigsSmall) {
+class DefaultVehicleHalTest : public ::testing::Test {
+ public:
+ void SetUp() override {
+ auto hardware = std::make_unique<MockVehicleHardware>();
+ std::vector<VehiclePropConfig> testConfigs;
+ for (size_t i = 0; i < 10000; i++) {
+ testConfigs.push_back(VehiclePropConfig{
+ .prop = testInt32VecProp(i),
+ .areaConfigs =
+ {
+ {
+ .areaId = 0,
+ .minInt32Value = 0,
+ .maxInt32Value = 100,
+ },
+ },
+ });
+ }
+ testConfigs.push_back(
+ VehiclePropConfig{.prop = INT32_WINDOW_PROP,
+ .areaConfigs = {{
+ .areaId = toInt(VehicleAreaWindow::ROW_1_LEFT),
+ .minInt32Value = 0,
+ .maxInt32Value = 100,
+ }}});
+ hardware->setPropertyConfigs(testConfigs);
+ mHardwarePtr = hardware.get();
+ mVhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
+ mVhalClient = IVehicle::fromBinder(mVhal->asBinder());
+ mCallback = ndk::SharedRefBase::make<MockVehicleCallback>();
+ mCallbackClient = IVehicleCallback::fromBinder(mCallback->asBinder());
+ }
+
+ MockVehicleHardware* getHardware() { return mHardwarePtr; }
+
+ std::shared_ptr<IVehicle> getClient() { return mVhal; }
+
+ std::shared_ptr<IVehicleCallback> getCallbackClient() { return mCallbackClient; }
+
+ MockVehicleCallback* getCallback() { return mCallback.get(); }
+
+ static Result<void> getValuesTestCases(size_t size, GetValueRequests& requests,
+ std::vector<GetValueResult>& expectedResults,
+ std::vector<GetValueRequest>& expectedHardwareRequests) {
+ expectedHardwareRequests.clear();
+ for (size_t i = 0; i < size; i++) {
+ int64_t requestId = static_cast<int64_t>(i);
+ int32_t propId = testInt32VecProp(i);
+ expectedHardwareRequests.push_back(GetValueRequest{
+ .prop =
+ VehiclePropValue{
+ .prop = propId,
+ },
+ .requestId = requestId,
+ });
+ expectedResults.push_back(GetValueResult{
+ .requestId = requestId,
+ .status = StatusCode::OK,
+ .prop =
+ VehiclePropValue{
+ .prop = propId,
+ .value.int32Values = {1, 2, 3, 4},
+ },
+ });
+ }
+
+ auto result = LargeParcelableBase::parcelableVectorToStableLargeParcelable(
+ expectedHardwareRequests);
+ if (!result.ok()) {
+ return result.error();
+ }
+ if (result.value() == nullptr) {
+ requests.payloads = expectedHardwareRequests;
+ } else {
+ requests.sharedMemoryFd = std::move(*result.value());
+ }
+ return {};
+ }
+
+ static Result<void> setValuesTestCases(size_t size, SetValueRequests& requests,
+ std::vector<SetValueResult>& expectedResults,
+ std::vector<SetValueRequest>& expectedHardwareRequests) {
+ expectedHardwareRequests.clear();
+ for (size_t i = 0; i < size; i++) {
+ int64_t requestId = static_cast<int64_t>(i);
+ int32_t propId = testInt32VecProp(i);
+ expectedHardwareRequests.push_back(SetValueRequest{
+ .value =
+ VehiclePropValue{
+ .prop = propId,
+ .value.int32Values = {1, 2, 3, 4},
+ },
+ .requestId = requestId,
+ });
+ expectedResults.push_back(SetValueResult{
+ .requestId = requestId,
+ .status = StatusCode::OK,
+ });
+ }
+
+ auto result = LargeParcelableBase::parcelableVectorToStableLargeParcelable(
+ expectedHardwareRequests);
+ if (!result.ok()) {
+ return result.error();
+ }
+ if (result.value() == nullptr) {
+ requests.payloads = expectedHardwareRequests;
+ } else {
+ requests.sharedMemoryFd = std::move(*result.value());
+ }
+ return {};
+ }
+
+ size_t countClients() {
+ std::scoped_lock<std::mutex> lockGuard(mVhal->mLock);
+ return mVhal->mGetValuesClients.size() + mVhal->mSetValuesClients.size();
+ }
+
+ private:
+ std::shared_ptr<DefaultVehicleHal> mVhal;
+ std::shared_ptr<IVehicle> mVhalClient;
+ MockVehicleHardware* mHardwarePtr;
+ std::shared_ptr<MockVehicleCallback> mCallback;
+ std::shared_ptr<IVehicleCallback> mCallbackClient;
+};
+
+TEST_F(DefaultVehicleHalTest, testGetAllPropConfigsSmall) {
auto testConfigs = std::vector<VehiclePropConfig>({
VehiclePropConfig{
.prop = 1,
@@ -125,14 +467,14 @@
VehiclePropConfigs output;
auto status = client->getAllPropConfigs(&output);
- ASSERT_TRUE(status.isOk());
+ ASSERT_TRUE(status.isOk()) << "getAllPropConfigs failed: " << status.getMessage();
ASSERT_THAT(output.payloads, WhenSortedBy(propConfigCmp, Eq(testConfigs)));
}
-TEST(DefaultVehicleHalTest, testGetAllPropConfigsLarge) {
+TEST_F(DefaultVehicleHalTest, testGetAllPropConfigsLarge) {
std::vector<VehiclePropConfig> testConfigs;
- // 10000 VehiclePropConfig exceeds 4k memory limit, so it would be sent through shared memory.
- for (size_t i = 0; i < 10000; i++) {
+ // 5000 VehiclePropConfig exceeds 4k memory limit, so it would be sent through shared memory.
+ for (size_t i = 0; i < 5000; i++) {
testConfigs.push_back(VehiclePropConfig{
.prop = static_cast<int32_t>(i),
});
@@ -146,16 +488,202 @@
VehiclePropConfigs output;
auto status = client->getAllPropConfigs(&output);
- ASSERT_TRUE(status.isOk());
+ ASSERT_TRUE(status.isOk()) << "getAllPropConfigs failed: " << status.getMessage();
ASSERT_TRUE(output.payloads.empty());
Result<std::optional<std::vector<VehiclePropConfig>>> result =
LargeParcelableBase::stableLargeParcelableToParcelableVector<VehiclePropConfig>(
output.sharedMemoryFd);
- ASSERT_TRUE(result.ok());
- ASSERT_TRUE(result.value().has_value());
+ ASSERT_TRUE(result.ok()) << "failed to parse result shared memory file: "
+ << result.error().message();
+ ASSERT_TRUE(result.value().has_value()) << "empty parsed value";
ASSERT_EQ(result.value().value(), testConfigs);
}
+TEST_F(DefaultVehicleHalTest, testGetValuesSmall) {
+ GetValueRequests requests;
+ std::vector<GetValueResult> expectedResults;
+ std::vector<GetValueRequest> expectedHardwareRequests;
+
+ ASSERT_TRUE(getValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
+
+ getHardware()->addGetValueResponses(expectedResults);
+
+ auto status = getClient()->getValues(getCallbackClient(), requests);
+
+ ASSERT_TRUE(status.isOk()) << "getValues failed: " << status.getMessage();
+
+ EXPECT_EQ(getHardware()->nextGetValueRequests(), expectedHardwareRequests)
+ << "requests to hardware mismatch";
+
+ auto maybeGetValueResults = getCallback()->nextGetValueResults();
+ ASSERT_TRUE(maybeGetValueResults.has_value()) << "no results in callback";
+ EXPECT_EQ(maybeGetValueResults.value().payloads, expectedResults) << "results mismatch";
+ EXPECT_EQ(countClients(), static_cast<size_t>(1));
+}
+
+TEST_F(DefaultVehicleHalTest, testGetValuesLarge) {
+ GetValueRequests requests;
+ std::vector<GetValueResult> expectedResults;
+ std::vector<GetValueRequest> expectedHardwareRequests;
+
+ ASSERT_TRUE(getValuesTestCases(5000, requests, expectedResults, expectedHardwareRequests).ok())
+ << "requests to hardware mismatch";
+ ;
+
+ getHardware()->addGetValueResponses(expectedResults);
+
+ auto status = getClient()->getValues(getCallbackClient(), requests);
+
+ ASSERT_TRUE(status.isOk()) << "getValues failed: " << status.getMessage();
+
+ EXPECT_EQ(getHardware()->nextGetValueRequests(), expectedHardwareRequests);
+
+ auto maybeGetValueResults = getCallback()->nextGetValueResults();
+ ASSERT_TRUE(maybeGetValueResults.has_value()) << "no results in callback";
+ const GetValueResults& getValueResults = maybeGetValueResults.value();
+ ASSERT_TRUE(getValueResults.payloads.empty())
+ << "payload should be empty, shared memory file should be used";
+
+ auto result = LargeParcelableBase::stableLargeParcelableToParcelableVector<GetValueResult>(
+ getValueResults.sharedMemoryFd);
+ ASSERT_TRUE(result.ok()) << "failed to parse shared memory file";
+ ASSERT_TRUE(result.value().has_value()) << "no parsed value";
+ ASSERT_EQ(result.value().value(), expectedResults) << "results mismatch";
+ EXPECT_EQ(countClients(), static_cast<size_t>(1));
+}
+
+TEST_F(DefaultVehicleHalTest, testGetValuesErrorFromHardware) {
+ GetValueRequests requests;
+ std::vector<GetValueResult> expectedResults;
+ std::vector<GetValueRequest> expectedHardwareRequests;
+
+ ASSERT_TRUE(getValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
+
+ getHardware()->setStatus("getValues", StatusCode::INTERNAL_ERROR);
+
+ auto status = getClient()->getValues(getCallbackClient(), requests);
+
+ ASSERT_FALSE(status.isOk()) << "expect getValues to fail when hardware returns error";
+ ASSERT_EQ(status.getServiceSpecificError(), toInt(StatusCode::INTERNAL_ERROR));
+}
+
+TEST_F(DefaultVehicleHalTest, testGetValuesInvalidLargeParcelableInput) {
+ GetValueRequests requests;
+ requests.sharedMemoryFd = ScopedFileDescriptor(0);
+
+ auto status = getClient()->getValues(getCallbackClient(), requests);
+
+ ASSERT_FALSE(status.isOk()) << "expect getValues to fail when input parcelable is not valid";
+ ASSERT_EQ(status.getServiceSpecificError(), toInt(StatusCode::INVALID_ARG));
+}
+
+TEST_F(DefaultVehicleHalTest, testSetValuesSmall) {
+ SetValueRequests requests;
+ std::vector<SetValueResult> expectedResults;
+ std::vector<SetValueRequest> expectedHardwareRequests;
+
+ ASSERT_TRUE(setValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
+
+ getHardware()->addSetValueResponses(expectedResults);
+
+ auto status = getClient()->setValues(getCallbackClient(), requests);
+
+ ASSERT_TRUE(status.isOk()) << "setValues failed: " << status.getMessage();
+
+ EXPECT_EQ(getHardware()->nextSetValueRequests(), expectedHardwareRequests)
+ << "requests to hardware mismatch";
+
+ auto maybeSetValueResults = getCallback()->nextSetValueResults();
+ ASSERT_TRUE(maybeSetValueResults.has_value()) << "no results in callback";
+ ASSERT_EQ(maybeSetValueResults.value().payloads, expectedResults) << "results mismatch";
+ EXPECT_EQ(countClients(), static_cast<size_t>(1));
+}
+
+TEST_F(DefaultVehicleHalTest, testSetValuesLarge) {
+ SetValueRequests requests;
+ std::vector<SetValueResult> expectedResults;
+ std::vector<SetValueRequest> expectedHardwareRequests;
+
+ ASSERT_TRUE(setValuesTestCases(5000, requests, expectedResults, expectedHardwareRequests).ok());
+
+ getHardware()->addSetValueResponses(expectedResults);
+
+ auto status = getClient()->setValues(getCallbackClient(), requests);
+
+ ASSERT_TRUE(status.isOk()) << "setValues failed: " << status.getMessage();
+
+ EXPECT_EQ(getHardware()->nextSetValueRequests(), expectedHardwareRequests)
+ << "requests to hardware mismatch";
+
+ auto maybeSetValueResults = getCallback()->nextSetValueResults();
+ ASSERT_TRUE(maybeSetValueResults.has_value()) << "no results in callback";
+ const SetValueResults& setValueResults = maybeSetValueResults.value();
+ ASSERT_TRUE(setValueResults.payloads.empty())
+ << "payload should be empty, shared memory file should be used";
+
+ auto result = LargeParcelableBase::stableLargeParcelableToParcelableVector<SetValueResult>(
+ setValueResults.sharedMemoryFd);
+ ASSERT_TRUE(result.ok()) << "failed to parse shared memory file";
+ ASSERT_TRUE(result.value().has_value()) << "no parsed value";
+ ASSERT_EQ(result.value().value(), expectedResults) << "results mismatch";
+ EXPECT_EQ(countClients(), static_cast<size_t>(1));
+}
+
+class SetValuesInvalidRequestTest
+ : public DefaultVehicleHalTest,
+ public testing::WithParamInterface<SetValuesInvalidRequestTestCase> {};
+
+INSTANTIATE_TEST_SUITE_P(
+ SetValuesInvalidRequestTests, SetValuesInvalidRequestTest,
+ ::testing::ValuesIn(getSetValuesInvalidRequestTestCases()),
+ [](const testing::TestParamInfo<SetValuesInvalidRequestTest::ParamType>& info) {
+ return info.param.name;
+ });
+
+TEST_P(SetValuesInvalidRequestTest, testSetValuesInvalidRequest) {
+ SetValuesInvalidRequestTestCase tc = GetParam();
+ std::vector<SetValueResult> expectedHardwareResults{
+ SetValueResult{
+ .requestId = 1,
+ .status = StatusCode::OK,
+ },
+ };
+ getHardware()->addSetValueResponses(expectedHardwareResults);
+
+ SetValueRequests requests;
+ SetValueRequest invalidRequest{
+ .requestId = 0,
+ .value = tc.request,
+ };
+ SetValueRequest normalRequest{.requestId = 1,
+ .value = {
+ .prop = testInt32VecProp(0),
+ .value.int32Values = {0},
+ }};
+ requests.payloads = {invalidRequest, normalRequest};
+ auto status = getClient()->setValues(getCallbackClient(), requests);
+
+ ASSERT_TRUE(status.isOk()) << "setValues failed: " << status.getMessage();
+
+ EXPECT_EQ(getHardware()->nextSetValueRequests(), std::vector<SetValueRequest>({normalRequest}))
+ << "requests to hardware mismatch";
+
+ auto maybeSetValueResults = getCallback()->nextSetValueResults();
+ ASSERT_TRUE(maybeSetValueResults.has_value()) << "no results in callback";
+ EXPECT_EQ(maybeSetValueResults.value().payloads, std::vector<SetValueResult>({
+ {
+ .requestId = 0,
+ .status = tc.expectedStatus,
+ },
+ }))
+ << "invalid argument result mismatch";
+
+ maybeSetValueResults = getCallback()->nextSetValueResults();
+ ASSERT_TRUE(maybeSetValueResults.has_value()) << "no results from hardware in callback";
+ EXPECT_EQ(maybeSetValueResults.value().payloads, expectedHardwareResults)
+ << "results from hardware mismatch";
+}
+
} // namespace vehicle
} // namespace automotive
} // namespace hardware
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp
index 9435311..490a436 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp
@@ -233,7 +233,7 @@
LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
sessionType == V2_1::SessionType::
LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
- std::vector<LeAudioCodecCapabilitiesPair> db_codec_capabilities =
+ std::vector<LeAudioCodecCapabilitiesSetting> db_codec_capabilities =
android::bluetooth::audio::GetLeAudioOffloadCodecCapabilities(
sessionType);
if (db_codec_capabilities.size()) {
diff --git a/bluetooth/audio/2.2/types.hal b/bluetooth/audio/2.2/types.hal
index 8ec3660..6755899 100644
--- a/bluetooth/audio/2.2/types.hal
+++ b/bluetooth/audio/2.2/types.hal
@@ -83,23 +83,22 @@
safe_union AudioCapabilities {
PcmParameters pcmCapabilities;
CodecCapabilities codecCapabilities;
- LeAudioCodecCapabilitiesPair leAudioCapabilities;
+ LeAudioCodecCapabilitiesSetting leAudioCapabilities;
};
/**
- * Used to specify th le audio capabilities pair of the Hardware offload encode and decode.
+ * Used to specify the le audio capabilities for unicast and broadcast hardware offload.
*/
-struct LeAudioCodecCapabilitiesPair{
- LeAudioMode mode;
- LeAudioCodecCapability encodeCapability;
- LeAudioCodecCapability decodeCapability;
+struct LeAudioCodecCapabilitiesSetting{
+ UnicastCapability unicastEncodeCapability;
+ UnicastCapability unicastDecodeCapability;
+ BroadcastCapability broadcastCapability;
};
/**
- * Used to specify the le audio capabilities of the codecs supported by Hardware offload
- * for encode or decode.
+ * Used to specify the le audio unicast codec capabilities for hardware offload.
*/
-struct LeAudioCodecCapability {
+struct UnicastCapability {
CodecType codecType;
AudioLocation supportedChannel;
@@ -112,3 +111,17 @@
// Should use safe union when there is more than one codec
Lc3Parameters capabilities;
};
+
+/**
+ * Used to specify the le audio broadcast codec capabilities for hardware offload.
+ */
+struct BroadcastCapability {
+ CodecType codecType;
+ AudioLocation supportedChannel;
+
+ // Supported channel count for each stream
+ uint8_t channelCountPerStream;
+
+ // Should use safe union when there is more than one codec
+ vec<Lc3Parameters> capabilities;
+};
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp
index 34cfd7e..4c99b0f 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp
+++ b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp
@@ -30,16 +30,20 @@
using ::android::hardware::bluetooth::audio::V2_1::Lc3Parameters;
using ::android::hardware::bluetooth::audio::V2_1::SampleRate;
using ::android::hardware::bluetooth::audio::V2_2::AudioLocation;
-using ::android::hardware::bluetooth::audio::V2_2::LeAudioCodecCapabilitiesPair;
-using ::android::hardware::bluetooth::audio::V2_2::LeAudioCodecCapability;
-using ::android::hardware::bluetooth::audio::V2_2::LeAudioMode;
+using ::android::hardware::bluetooth::audio::V2_2::BroadcastCapability;
+using ::android::hardware::bluetooth::audio::V2_2::
+ LeAudioCodecCapabilitiesSetting;
+using ::android::hardware::bluetooth::audio::V2_2::UnicastCapability;
using SessionType_2_1 =
::android::hardware::bluetooth::audio::V2_1::SessionType;
// Stores the list of offload supported capability
-std::vector<LeAudioCodecCapabilitiesPair> kDefaultOffloadLeAudioCapabilities;
+std::vector<LeAudioCodecCapabilitiesSetting> kDefaultOffloadLeAudioCapabilities;
-static const LeAudioCodecCapability kInvalidLc3Capability = {
+static const UnicastCapability kInvalidUnicastCapability = {
+ .codecType = CodecType::UNKNOWN};
+
+static const BroadcastCapability kInvalidBroadcastCapability = {
.codecType = CodecType::UNKNOWN};
// Default Supported Codecs
@@ -94,53 +98,53 @@
return true;
}
-LeAudioCodecCapability composeLc3Capability(AudioLocation audioLocation,
- uint8_t deviceCnt,
- uint8_t channelCount,
- Lc3Parameters capability) {
- return LeAudioCodecCapability{.codecType = CodecType::LC3,
- .supportedChannel = audioLocation,
- .deviceCount = deviceCnt,
- .channelCountPerDevice = channelCount,
- .capabilities = capability};
+UnicastCapability composeUnicastLc3Capability(AudioLocation audioLocation,
+ uint8_t deviceCnt,
+ uint8_t channelCount,
+ Lc3Parameters capability) {
+ return UnicastCapability{.codecType = CodecType::LC3,
+ .supportedChannel = audioLocation,
+ .deviceCount = deviceCnt,
+ .channelCountPerDevice = channelCount,
+ .capabilities = capability};
}
-std::vector<LeAudioCodecCapabilitiesPair> GetLeAudioOffloadCodecCapabilities(
+std::vector<LeAudioCodecCapabilitiesSetting> GetLeAudioOffloadCodecCapabilities(
const SessionType_2_1& session_type) {
if (session_type !=
SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
session_type !=
SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
- return std::vector<LeAudioCodecCapabilitiesPair>(0);
+ return std::vector<LeAudioCodecCapabilitiesSetting>(0);
}
if (kDefaultOffloadLeAudioCapabilities.empty()) {
for (auto [audioLocation, deviceCnt, channelCount] :
supportedDeviceSetting) {
for (auto capability : supportedLc3CapabilityList) {
- LeAudioCodecCapability lc3Capability = composeLc3Capability(
+ UnicastCapability lc3Capability = composeUnicastLc3Capability(
audioLocation, deviceCnt, channelCount, capability);
- LeAudioCodecCapability lc3MonoCapability =
- composeLc3Capability(monoAudio, 1, 1, capability);
+ UnicastCapability lc3MonoDecodeCapability =
+ composeUnicastLc3Capability(monoAudio, 1, 1, capability);
// Adds the capability for encode only
kDefaultOffloadLeAudioCapabilities.push_back(
- {.mode = LeAudioMode::UNICAST,
- .encodeCapability = lc3Capability,
- .decodeCapability = kInvalidLc3Capability});
+ {.unicastEncodeCapability = lc3Capability,
+ .unicastDecodeCapability = kInvalidUnicastCapability,
+ .broadcastCapability = kInvalidBroadcastCapability});
// Adds the capability for decode only
kDefaultOffloadLeAudioCapabilities.push_back(
- {.mode = LeAudioMode::UNICAST,
- .encodeCapability = kInvalidLc3Capability,
- .decodeCapability = lc3Capability});
+ {.unicastEncodeCapability = kInvalidUnicastCapability,
+ .unicastDecodeCapability = lc3Capability,
+ .broadcastCapability = kInvalidBroadcastCapability});
// Adds the capability for the case that encode and decode exist at the
// same time
kDefaultOffloadLeAudioCapabilities.push_back(
- {.mode = LeAudioMode::UNICAST,
- .encodeCapability = lc3Capability,
- .decodeCapability = lc3MonoCapability});
+ {.unicastEncodeCapability = lc3Capability,
+ .unicastDecodeCapability = lc3MonoDecodeCapability,
+ .broadcastCapability = kInvalidBroadcastCapability});
}
}
}
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h
index 89da6a3..34bba5f 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h
@@ -31,7 +31,7 @@
const ::android::hardware::bluetooth::audio::V2_2::LeAudioConfiguration&
le_audio_codec_config);
-std::vector<hardware::bluetooth::audio::V2_2::LeAudioCodecCapabilitiesPair>
+std::vector<hardware::bluetooth::audio::V2_2::LeAudioCodecCapabilitiesSetting>
GetLeAudioOffloadCodecCapabilities(
const ::android::hardware::bluetooth::audio::V2_1::SessionType&
session_type);
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index c847ea3..cf85688 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -209,6 +209,18 @@
<instance>default</instance>
</interface>
</hal>
+ <hal format="aidl" optional="true">
+ <name>android.hardware.drm</name>
+ <version>1</version>
+ <interface>
+ <name>ICryptoFactory</name>
+ <regex-instance>.*</regex-instance>
+ </interface>
+ <interface>
+ <name>IDrmFactory</name>
+ <regex-instance>.*</regex-instance>
+ </interface>
+ </hal>
<hal format="hidl" optional="true">
<name>android.hardware.drm</name>
<version>1.3-4</version>
@@ -393,6 +405,7 @@
<interface>
<name>IRemotelyProvisionedComponent</name>
<instance>default</instance>
+ <instance>strongbox</instance>
</interface>
</hal>
<hal format="aidl" optional="true">
diff --git a/drm/aidl/Android.bp b/drm/aidl/Android.bp
new file mode 100644
index 0000000..d8500ec
--- /dev/null
+++ b/drm/aidl/Android.bp
@@ -0,0 +1,32 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+aidl_interface {
+ name: "android.hardware.drm",
+ vendor_available: true,
+ srcs: ["android/hardware/drm/*.aidl"],
+ stability: "vintf",
+ imports: [
+ "android.hardware.common-V2",
+ ],
+ backend: {
+ cpp: {
+ enabled: false,
+ },
+ java: {
+ sdk_version: "module_current",
+ },
+ ndk: {
+ vndk: {
+ enabled: true,
+ },
+ min_sdk_version: "current",
+ },
+ },
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/BufferType.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/BufferType.aidl
new file mode 100644
index 0000000..b6ec34d
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/BufferType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@Backing(type="int") @VintfStability
+enum BufferType {
+ SHARED_MEMORY = 0,
+ NATIVE_HANDLE = 1,
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DecryptResult.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DecryptResult.aidl
new file mode 100644
index 0000000..d2b48d2
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DecryptResult.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+parcelable DecryptResult {
+ int bytesWritten;
+ String detailedError;
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DestinationBuffer.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DestinationBuffer.aidl
new file mode 100644
index 0000000..4f2d133
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DestinationBuffer.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+parcelable DestinationBuffer {
+ android.hardware.drm.BufferType type;
+ android.hardware.drm.SharedBuffer nonsecureMemory;
+ android.hardware.common.NativeHandle secureMemory;
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetric.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetric.aidl
new file mode 100644
index 0000000..c78dff0
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetric.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+parcelable DrmMetric {
+ String name;
+ List<android.hardware.drm.DrmMetricNamedValue> attributes;
+ List<android.hardware.drm.DrmMetricNamedValue> values;
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricGroup.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricGroup.aidl
new file mode 100644
index 0000000..4128eaa
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricGroup.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+parcelable DrmMetricGroup {
+ List<android.hardware.drm.DrmMetric> metrics;
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricNamedValue.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricNamedValue.aidl
new file mode 100644
index 0000000..76ec35c
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricNamedValue.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+parcelable DrmMetricNamedValue {
+ String name;
+ android.hardware.drm.DrmMetricValue value;
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricValue.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricValue.aidl
new file mode 100644
index 0000000..8064913
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricValue.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+union DrmMetricValue {
+ long int64Value;
+ double doubleValue;
+ String stringValue;
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/EventType.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/EventType.aidl
new file mode 100644
index 0000000..80ebb28
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/EventType.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@Backing(type="int") @VintfStability
+enum EventType {
+ PROVISION_REQUIRED = 0,
+ KEY_NEEDED = 1,
+ KEY_EXPIRED = 2,
+ VENDOR_DEFINED = 3,
+ SESSION_RECLAIMED = 4,
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevel.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevel.aidl
new file mode 100644
index 0000000..5704fb0
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevel.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@Backing(type="int") @VintfStability
+enum HdcpLevel {
+ HDCP_UNKNOWN = 0,
+ HDCP_NONE = 1,
+ HDCP_V1 = 2,
+ HDCP_V2 = 3,
+ HDCP_V2_1 = 4,
+ HDCP_V2_2 = 5,
+ HDCP_NO_OUTPUT = 6,
+ HDCP_V2_3 = 7,
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevels.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevels.aidl
new file mode 100644
index 0000000..a6f86ac
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevels.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+parcelable HdcpLevels {
+ android.hardware.drm.HdcpLevel connectedLevel;
+ android.hardware.drm.HdcpLevel maxLevel;
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ICryptoFactory.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ICryptoFactory.aidl
new file mode 100644
index 0000000..0d4296e
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ICryptoFactory.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+interface ICryptoFactory {
+ @nullable android.hardware.drm.ICryptoPlugin createPlugin(in android.hardware.drm.Uuid uuid, in byte[] initData);
+ boolean isCryptoSchemeSupported(in android.hardware.drm.Uuid uuid);
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ICryptoPlugin.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ICryptoPlugin.aidl
new file mode 100644
index 0000000..2224795
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ICryptoPlugin.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+interface ICryptoPlugin {
+ android.hardware.drm.DecryptResult decrypt(in boolean secure, in byte[] keyId, in byte[] iv, in android.hardware.drm.Mode mode, in android.hardware.drm.Pattern pattern, in android.hardware.drm.SubSample[] subSamples, in android.hardware.drm.SharedBuffer source, in long offset, in android.hardware.drm.DestinationBuffer destination);
+ List<android.hardware.drm.LogMessage> getLogMessages();
+ void notifyResolution(in int width, in int height);
+ boolean requiresSecureDecoderComponent(in String mime);
+ void setMediaDrmSession(in byte[] sessionId);
+ void setSharedBufferBase(in android.hardware.common.Ashmem base, in int bufferId);
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmFactory.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmFactory.aidl
new file mode 100644
index 0000000..af48737
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmFactory.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+interface IDrmFactory {
+ @nullable android.hardware.drm.IDrmPlugin createPlugin(in android.hardware.drm.Uuid uuid, in String appPackageName);
+ List<android.hardware.drm.Uuid> getSupportedCryptoSchemes();
+ boolean isContentTypeSupported(in String mimeType);
+ boolean isCryptoSchemeSupported(in android.hardware.drm.Uuid uuid, in String mimeType, in android.hardware.drm.SecurityLevel securityLevel);
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmPlugin.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmPlugin.aidl
new file mode 100644
index 0000000..5f839d7
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmPlugin.aidl
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+interface IDrmPlugin {
+ void closeSession(in byte[] sessionId);
+ byte[] decrypt(in byte[] sessionId, in byte[] keyId, in byte[] input, in byte[] iv);
+ byte[] encrypt(in byte[] sessionId, in byte[] keyId, in byte[] input, in byte[] iv);
+ android.hardware.drm.HdcpLevels getHdcpLevels();
+ android.hardware.drm.KeyRequest getKeyRequest(in byte[] scope, in byte[] initData, in String mimeType, in android.hardware.drm.KeyType keyType, in android.hardware.drm.KeyValue[] optionalParameters);
+ List<android.hardware.drm.LogMessage> getLogMessages();
+ List<android.hardware.drm.DrmMetricGroup> getMetrics();
+ android.hardware.drm.NumberOfSessions getNumberOfSessions();
+ List<android.hardware.drm.KeySetId> getOfflineLicenseKeySetIds();
+ android.hardware.drm.OfflineLicenseState getOfflineLicenseState(in android.hardware.drm.KeySetId keySetId);
+ byte[] getPropertyByteArray(in String propertyName);
+ String getPropertyString(in String propertyName);
+ android.hardware.drm.ProvisionRequest getProvisionRequest(in String certificateType, in String certificateAuthority);
+ android.hardware.drm.SecureStop getSecureStop(in android.hardware.drm.SecureStopId secureStopId);
+ List<android.hardware.drm.SecureStopId> getSecureStopIds();
+ List<android.hardware.drm.SecureStop> getSecureStops();
+ android.hardware.drm.SecurityLevel getSecurityLevel(in byte[] sessionId);
+ byte[] openSession(in android.hardware.drm.SecurityLevel securityLevel);
+ android.hardware.drm.KeySetId provideKeyResponse(in byte[] scope, in byte[] response);
+ android.hardware.drm.ProvideProvisionResponseResult provideProvisionResponse(in byte[] response);
+ List<android.hardware.drm.KeyValue> queryKeyStatus(in byte[] sessionId);
+ void releaseAllSecureStops();
+ void releaseSecureStop(in android.hardware.drm.SecureStopId secureStopId);
+ void releaseSecureStops(in android.hardware.drm.OpaqueData ssRelease);
+ void removeAllSecureStops();
+ void removeKeys(in byte[] sessionId);
+ void removeOfflineLicense(in android.hardware.drm.KeySetId keySetId);
+ void removeSecureStop(in android.hardware.drm.SecureStopId secureStopId);
+ boolean requiresSecureDecoder(in String mime, in android.hardware.drm.SecurityLevel level);
+ boolean requiresSecureDecoderDefault(in String mime);
+ void restoreKeys(in byte[] sessionId, in android.hardware.drm.KeySetId keySetId);
+ void setCipherAlgorithm(in byte[] sessionId, in String algorithm);
+ void setListener(in android.hardware.drm.IDrmPluginListener listener);
+ void setMacAlgorithm(in byte[] sessionId, in String algorithm);
+ void setPlaybackId(in byte[] sessionId, in String playbackId);
+ void setPropertyByteArray(in String propertyName, in byte[] value);
+ void setPropertyString(in String propertyName, in String value);
+ byte[] sign(in byte[] sessionId, in byte[] keyId, in byte[] message);
+ byte[] signRSA(in byte[] sessionId, in String algorithm, in byte[] message, in byte[] wrappedkey);
+ boolean verify(in byte[] sessionId, in byte[] keyId, in byte[] message, in byte[] signature);
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmPluginListener.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmPluginListener.aidl
new file mode 100644
index 0000000..0a4b4b7
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmPluginListener.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+interface IDrmPluginListener {
+ oneway void onEvent(in android.hardware.drm.EventType eventType, in byte[] sessionId, in byte[] data);
+ oneway void onExpirationUpdate(in byte[] sessionId, in long expiryTimeInMS);
+ oneway void onKeysChange(in byte[] sessionId, in android.hardware.drm.KeyStatus[] keyStatusList, in boolean hasNewUsableKey);
+ oneway void onSessionLostState(in byte[] sessionId);
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequest.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequest.aidl
new file mode 100644
index 0000000..267f532
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequest.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+parcelable KeyRequest {
+ byte[] request;
+ android.hardware.drm.KeyRequestType requestType;
+ String defaultUrl;
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequestType.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequestType.aidl
new file mode 100644
index 0000000..34b9615
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequestType.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@Backing(type="int") @VintfStability
+enum KeyRequestType {
+ INITIAL = 0,
+ RENEWAL = 1,
+ RELEASE = 2,
+ UNKNOWN = 3,
+ NONE = 4,
+ UPDATE = 5,
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeySetId.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeySetId.aidl
new file mode 100644
index 0000000..58dfe1a
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeySetId.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+parcelable KeySetId {
+ byte[] keySetId;
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatus.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatus.aidl
new file mode 100644
index 0000000..53ab70f
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatus.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+parcelable KeyStatus {
+ byte[] keyId;
+ android.hardware.drm.KeyStatusType type;
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatusType.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatusType.aidl
new file mode 100644
index 0000000..e88d388
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatusType.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@Backing(type="int") @VintfStability
+enum KeyStatusType {
+ USABLE = 0,
+ EXPIRED = 1,
+ OUTPUTNOTALLOWED = 2,
+ STATUSPENDING = 3,
+ INTERNALERROR = 4,
+ USABLEINFUTURE = 5,
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyType.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyType.aidl
new file mode 100644
index 0000000..7a9d633
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@Backing(type="int") @VintfStability
+enum KeyType {
+ OFFLINE = 0,
+ STREAMING = 1,
+ RELEASE = 2,
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyValue.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyValue.aidl
new file mode 100644
index 0000000..35d7b77
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyValue.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+parcelable KeyValue {
+ String key;
+ String value;
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogMessage.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogMessage.aidl
new file mode 100644
index 0000000..93f76e1
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogMessage.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+parcelable LogMessage {
+ long timeMs;
+ android.hardware.drm.LogPriority priority;
+ String message;
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogPriority.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogPriority.aidl
new file mode 100644
index 0000000..83362c3
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogPriority.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@Backing(type="int") @VintfStability
+enum LogPriority {
+ UNKNOWN = 0,
+ DEFAULT = 1,
+ VERBOSE = 2,
+ DEBUG = 3,
+ INFO = 4,
+ WARN = 5,
+ ERROR = 6,
+ FATAL = 7,
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Mode.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Mode.aidl
new file mode 100644
index 0000000..7379774
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Mode.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@Backing(type="int") @VintfStability
+enum Mode {
+ UNENCRYPTED = 0,
+ AES_CTR = 1,
+ AES_CBC_CTS = 2,
+ AES_CBC = 3,
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/NumberOfSessions.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/NumberOfSessions.aidl
new file mode 100644
index 0000000..a421125
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/NumberOfSessions.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+parcelable NumberOfSessions {
+ int currentSessions;
+ int maxSessions;
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OfflineLicenseState.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OfflineLicenseState.aidl
new file mode 100644
index 0000000..629564d
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OfflineLicenseState.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@Backing(type="int") @VintfStability
+enum OfflineLicenseState {
+ UNKNOWN = 0,
+ USABLE = 1,
+ INACTIVE = 2,
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OpaqueData.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OpaqueData.aidl
new file mode 100644
index 0000000..3085889
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OpaqueData.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+parcelable OpaqueData {
+ byte[] opaqueData;
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Pattern.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Pattern.aidl
new file mode 100644
index 0000000..b01562e
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Pattern.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+parcelable Pattern {
+ int encryptBlocks;
+ int skipBlocks;
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ProvideProvisionResponseResult.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ProvideProvisionResponseResult.aidl
new file mode 100644
index 0000000..827de59
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ProvideProvisionResponseResult.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+parcelable ProvideProvisionResponseResult {
+ byte[] certificate;
+ byte[] wrappedKey;
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ProvisionRequest.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ProvisionRequest.aidl
new file mode 100644
index 0000000..84c5662
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ProvisionRequest.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+parcelable ProvisionRequest {
+ byte[] request;
+ String defaultUrl;
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecureStop.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecureStop.aidl
new file mode 100644
index 0000000..81d2dfe
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecureStop.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+parcelable SecureStop {
+ byte[] opaqueData;
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecureStopId.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecureStopId.aidl
new file mode 100644
index 0000000..2b904c8
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecureStopId.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+parcelable SecureStopId {
+ byte[] secureStopId;
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecurityLevel.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecurityLevel.aidl
new file mode 100644
index 0000000..65b2b9d
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecurityLevel.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@Backing(type="int") @VintfStability
+enum SecurityLevel {
+ UNKNOWN = 0,
+ SW_SECURE_CRYPTO = 1,
+ SW_SECURE_DECODE = 2,
+ HW_SECURE_CRYPTO = 3,
+ HW_SECURE_DECODE = 4,
+ HW_SECURE_ALL = 5,
+ DEFAULT = 6,
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SharedBuffer.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SharedBuffer.aidl
new file mode 100644
index 0000000..973ef0d
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SharedBuffer.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+parcelable SharedBuffer {
+ int bufferId;
+ long offset;
+ long size;
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Status.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Status.aidl
new file mode 100644
index 0000000..c640689
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Status.aidl
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@Backing(type="int") @VintfStability
+enum Status {
+ OK = 0,
+ ERROR_DRM_NO_LICENSE = 1,
+ ERROR_DRM_LICENSE_EXPIRED = 2,
+ ERROR_DRM_SESSION_NOT_OPENED = 3,
+ ERROR_DRM_CANNOT_HANDLE = 4,
+ ERROR_DRM_INVALID_STATE = 5,
+ BAD_VALUE = 6,
+ ERROR_DRM_NOT_PROVISIONED = 7,
+ ERROR_DRM_RESOURCE_BUSY = 8,
+ ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION = 9,
+ ERROR_DRM_DEVICE_REVOKED = 10,
+ ERROR_DRM_DECRYPT = 11,
+ ERROR_DRM_UNKNOWN = 12,
+ ERROR_DRM_INSUFFICIENT_SECURITY = 13,
+ ERROR_DRM_FRAME_TOO_LARGE = 14,
+ ERROR_DRM_SESSION_LOST_STATE = 15,
+ ERROR_DRM_RESOURCE_CONTENTION = 16,
+ CANNOT_DECRYPT_ZERO_SUBSAMPLES = 17,
+ CRYPTO_LIBRARY_ERROR = 18,
+ GENERAL_OEM_ERROR = 19,
+ GENERAL_PLUGIN_ERROR = 20,
+ INIT_DATA_INVALID = 21,
+ KEY_NOT_LOADED = 22,
+ LICENSE_PARSE_ERROR = 23,
+ LICENSE_POLICY_ERROR = 24,
+ LICENSE_RELEASE_ERROR = 25,
+ LICENSE_REQUEST_REJECTED = 26,
+ LICENSE_RESTORE_ERROR = 27,
+ LICENSE_STATE_ERROR = 28,
+ MALFORMED_CERTIFICATE = 29,
+ MEDIA_FRAMEWORK_ERROR = 30,
+ MISSING_CERTIFICATE = 31,
+ PROVISIONING_CERTIFICATE_ERROR = 32,
+ PROVISIONING_CONFIGURATION_ERROR = 33,
+ PROVISIONING_PARSE_ERROR = 34,
+ PROVISIONING_REQUEST_REJECTED = 35,
+ RETRYABLE_PROVISIONING_ERROR = 36,
+ SECURE_STOP_RELEASE_ERROR = 37,
+ STORAGE_READ_FAILURE = 38,
+ STORAGE_WRITE_FAILURE = 39,
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SubSample.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SubSample.aidl
new file mode 100644
index 0000000..57d815e
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SubSample.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+parcelable SubSample {
+ int numBytesOfClearData;
+ int numBytesOfEncryptedData;
+}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Uuid.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Uuid.aidl
new file mode 100644
index 0000000..ec2eb16
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Uuid.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.drm;
+@VintfStability
+parcelable Uuid {
+ byte[] uuid;
+}
diff --git a/drm/aidl/android/hardware/drm/BufferType.aidl b/drm/aidl/android/hardware/drm/BufferType.aidl
new file mode 100644
index 0000000..089c950
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/BufferType.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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;
+
+@VintfStability
+@Backing(type="int")
+enum BufferType {
+ SHARED_MEMORY = 0,
+ NATIVE_HANDLE = 1,
+}
diff --git a/drm/aidl/android/hardware/drm/DecryptResult.aidl b/drm/aidl/android/hardware/drm/DecryptResult.aidl
new file mode 100644
index 0000000..17e939b
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/DecryptResult.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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;
+
+/**
+ * The DecryptResult parcelable contains the result of
+ * ICryptoPlugin decrypt method.
+ */
+@VintfStability
+parcelable DecryptResult {
+ /** The number of decrypted bytes. */
+ int bytesWritten;
+
+ /**
+ * Vendor-specific error message if provided by the vendor's
+ * crypto HAL.
+ */
+ String detailedError;
+}
diff --git a/drm/aidl/android/hardware/drm/DestinationBuffer.aidl b/drm/aidl/android/hardware/drm/DestinationBuffer.aidl
new file mode 100644
index 0000000..0f1e3f5
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/DestinationBuffer.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.drm;
+
+import android.hardware.common.NativeHandle;
+import android.hardware.drm.BufferType;
+import android.hardware.drm.SharedBuffer;
+
+/**
+ * A decrypt destination buffer can be either normal user-space shared
+ * memory for the non-secure decrypt case, or it can be a secure buffer
+ * which is referenced by a native-handle. The native handle is allocated
+ * by the vendor's buffer allocator.
+ */
+@VintfStability
+parcelable DestinationBuffer {
+ /**
+ * The type of the buffer
+ */
+ BufferType type;
+ /**
+ * If type == SHARED_MEMORY, the decrypted data must be written
+ * to user-space non-secure shared memory.
+ */
+ SharedBuffer nonsecureMemory;
+ /**
+ * If type == NATIVE_HANDLE, the decrypted data must be written
+ * to secure memory referenced by the vendor's buffer allocator.
+ */
+ NativeHandle secureMemory;
+}
diff --git a/drm/aidl/android/hardware/drm/DrmMetric.aidl b/drm/aidl/android/hardware/drm/DrmMetric.aidl
new file mode 100644
index 0000000..6199af6
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/DrmMetric.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+import android.hardware.drm.DrmMetricNamedValue;
+
+/**
+ * The metric being captured.
+ *
+ * A metric must have a name and at least one value. A metric may have 0 or
+ * more attributes. The fields of a Metric are opaque to the framework.
+ */
+@VintfStability
+parcelable DrmMetric {
+ String name;
+
+ /**
+ * Detail(s) about the metric being captured.
+ *
+ * The fields of an Attribute are opaque to the framework.
+ */
+ List<DrmMetricNamedValue> attributes;
+
+ /**
+ * Value(s) of the metric.
+ *
+ * A metric may have multiple values. The component name may be left empty
+ * if there is only supposed to be one value for the given metric. The
+ * fields of the Value are opaque to the framework.
+ */
+ List<DrmMetricNamedValue> values;
+}
diff --git a/drm/aidl/android/hardware/drm/DrmMetricGroup.aidl b/drm/aidl/android/hardware/drm/DrmMetricGroup.aidl
new file mode 100644
index 0000000..3b1f3c9
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/DrmMetricGroup.aidl
@@ -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.
+ */
+
+package android.hardware.drm;
+
+import android.hardware.drm.DrmMetric;
+
+/**
+ * This message contains plugin-specific metrics made available to the client.
+ * The message is used for making vendor-specific metrics available to an
+ * application. The framework is not consuming any of the information.
+ *
+ * Metrics are grouped in instances of DrmMetricGroup. Each group contains
+ * multiple instances of Metric.
+ *
+ * Example:
+ *
+ * Capture the timing information of a buffer copy event, "buf_copy", broken
+ * out by the "size" of the buffer.
+ *
+ * DrmMetricGroup {
+ * metrics[0] {
+ * name: "buf_copy"
+ * attributes[0] {
+ * name: "size"
+ * type: INT64_TYPE
+ * int64Value: 1024
+ * }
+ * values[0] {
+ * componentName: "operation_count"
+ * type: INT64_TYPE
+ * int64Value: 75
+ * }
+ * values[1] {
+ * component_name: "average_time_seconds"
+ * type: DOUBLE_TYPE
+ * doubleValue: 0.00000042
+ * }
+ * }
+ * }
+ */
+@VintfStability
+parcelable DrmMetricGroup {
+ /**
+ * The list of metrics to be captured.
+ */
+ List<DrmMetric> metrics;
+}
diff --git a/drm/aidl/android/hardware/drm/DrmMetricNamedValue.aidl b/drm/aidl/android/hardware/drm/DrmMetricNamedValue.aidl
new file mode 100644
index 0000000..5bb17a6
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/DrmMetricNamedValue.aidl
@@ -0,0 +1,28 @@
+/*
+ * 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;
+
+import android.hardware.drm.DrmMetricValue;
+
+/**
+ * A name-value pair used in drm metrics.
+ */
+@VintfStability
+parcelable DrmMetricNamedValue {
+ String name;
+ DrmMetricValue value;
+}
diff --git a/drm/aidl/android/hardware/drm/DrmMetricValue.aidl b/drm/aidl/android/hardware/drm/DrmMetricValue.aidl
new file mode 100644
index 0000000..0203f3f
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/DrmMetricValue.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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;
+
+/**
+ * The value of a metric or a metric's attribute.
+ */
+@VintfStability
+union DrmMetricValue {
+ long int64Value;
+ double doubleValue;
+ String stringValue;
+}
diff --git a/drm/aidl/android/hardware/drm/EventType.aidl b/drm/aidl/android/hardware/drm/EventType.aidl
new file mode 100644
index 0000000..7a06eb0
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/EventType.aidl
@@ -0,0 +1,51 @@
+/*
+ * 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;
+
+/**
+ * EventType enumerates the events that can be delivered by sendEvent
+ */
+@VintfStability
+@Backing(type="int")
+enum EventType {
+ /**
+ * This event type indicates that the app needs to request a certificate
+ * from the provisioning server. The request message data is obtained using
+ * getProvisionRequest().
+ */
+ PROVISION_REQUIRED,
+ /**
+ * This event type indicates that the app needs to request keys from a
+ * license server. The request message data is obtained using getKeyRequest.
+ */
+ KEY_NEEDED,
+ /**
+ * This event type indicates that the licensed usage duration for keys in a
+ * session has expired. The keys are no longer valid.
+ */
+ KEY_EXPIRED,
+ /**
+ * This event may indicate some specific vendor-defined condition, see your
+ * DRM provider documentation for details.
+ */
+ VENDOR_DEFINED,
+ /**
+ * This event indicates that a session opened by the app has been reclaimed
+ * by the resource manager.
+ */
+ SESSION_RECLAIMED,
+}
diff --git a/drm/aidl/android/hardware/drm/HdcpLevel.aidl b/drm/aidl/android/hardware/drm/HdcpLevel.aidl
new file mode 100644
index 0000000..3497b78
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/HdcpLevel.aidl
@@ -0,0 +1,59 @@
+/*
+ * 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;
+
+/**
+ * HDCP specifications are defined by Digital Content Protection LLC (DCP).
+ * "HDCP Specification Rev. 2.3 Interface Independent Adaptation"
+ * "HDCP 2.3 on HDMI Specification"
+ */
+@VintfStability
+@Backing(type="int")
+enum HdcpLevel {
+ /**
+ * Unable to determine the HDCP level
+ */
+ HDCP_UNKNOWN,
+ /**
+ * No HDCP, output is unprotected
+ */
+ HDCP_NONE,
+ /**
+ * HDCP version 1.0
+ */
+ HDCP_V1,
+ /**
+ * HDCP version 2.0 Type 1.
+ */
+ HDCP_V2,
+ /**
+ * HDCP version 2.1 Type 1.
+ */
+ HDCP_V2_1,
+ /**
+ * HDCP version 2.2 Type 1.
+ */
+ HDCP_V2_2,
+ /**
+ * No digital output, implicitly secure
+ */
+ HDCP_NO_OUTPUT,
+ /**
+ * HDCP version 2.3 Type 1.
+ */
+ HDCP_V2_3,
+}
diff --git a/drm/aidl/android/hardware/drm/HdcpLevels.aidl b/drm/aidl/android/hardware/drm/HdcpLevels.aidl
new file mode 100644
index 0000000..cd4642b
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/HdcpLevels.aidl
@@ -0,0 +1,28 @@
+/*
+ * 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;
+
+import android.hardware.drm.HdcpLevel;
+
+@VintfStability
+parcelable HdcpLevels {
+ /** The lowest HDCP level for any connected displays. */
+ HdcpLevel connectedLevel;
+
+ /** The highest HDCP level that can be supported by the device. */
+ HdcpLevel maxLevel;
+}
diff --git a/drm/aidl/android/hardware/drm/ICryptoFactory.aidl b/drm/aidl/android/hardware/drm/ICryptoFactory.aidl
new file mode 100644
index 0000000..202bd3d
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/ICryptoFactory.aidl
@@ -0,0 +1,51 @@
+/*
+ * 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;
+
+import android.hardware.drm.Uuid;
+
+/**
+ * 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.
+ */
+@VintfStability
+interface ICryptoFactory {
+ /**
+ * Create a crypto plugin for the specified uuid and scheme-specific
+ * initialization data.
+ *
+ * @param uuid uniquely identifies the drm scheme. See
+ * http://dashif.org/identifiers/protection for uuid assignments
+ *
+ * @param initData scheme-specific init data.
+ *
+ * @return A crypto plugin instance if successful, or null if not created.
+ */
+ @nullable android.hardware.drm.ICryptoPlugin createPlugin(
+ in Uuid uuid, in byte[] initData);
+
+ /**
+ * Determine if a crypto scheme is supported by this HAL.
+ *
+ * @param uuid identifies the crypto scheme in question
+ * @return must be true only if the scheme is supported
+ */
+ boolean isCryptoSchemeSupported(in Uuid uuid);
+}
diff --git a/drm/aidl/android/hardware/drm/ICryptoPlugin.aidl b/drm/aidl/android/hardware/drm/ICryptoPlugin.aidl
new file mode 100644
index 0000000..80a63df
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/ICryptoPlugin.aidl
@@ -0,0 +1,138 @@
+/*
+ * 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;
+
+import android.hardware.common.Ashmem;
+import android.hardware.drm.DecryptResult;
+import android.hardware.drm.DestinationBuffer;
+import android.hardware.drm.LogMessage;
+import android.hardware.drm.Mode;
+import android.hardware.drm.Pattern;
+import android.hardware.drm.SharedBuffer;
+import android.hardware.drm.Status;
+import android.hardware.drm.SubSample;
+
+/**
+ * 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.
+ */
+@VintfStability
+interface ICryptoPlugin {
+ /**
+ * Decrypt an array of subsamples from the source memory buffer to the
+ * destination memory buffer.
+ *
+ * @param secure a flag to indicate if a secure decoder is being used.
+ * This enables the plugin to configure buffer modes to work
+ * consistently with a secure decoder.
+ * @param the keyId for the key that is used to do the decryption. The
+ * keyId refers to a key in the associated MediaDrm instance.
+ * @param iv the initialization vector to use
+ * @param mode the crypto mode to use
+ * @param pattern the crypto pattern to use
+ * @param subSamples a vector of subsamples indicating the number
+ * of clear and encrypted bytes to process. This allows the decrypt
+ * call to operate on a range of subsamples in a single call
+ * @param source the input buffer for the decryption
+ * @param offset the offset of the first byte of encrypted data from
+ * the base of the source buffer
+ * @param destination the output buffer for the decryption
+ *
+ * @return DecryptResult parcelable
+ * Implicit error codes:
+ * + ERROR_DRM_CANNOT_HANDLE in other failure cases
+ * + ERROR_DRM_DECRYPT if the decrypt operation fails
+ * + ERROR_DRM_FRAME_TOO_LARGE if the frame being decrypted into
+ * the secure output buffer exceeds the size of the buffer
+ * + ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION if required output
+ * protections are not active
+ * + ERROR_DRM_INSUFFICIENT_SECURITY if the security level of the
+ * device is not sufficient to meet the requirements in
+ * the license policy
+ * + ERROR_DRM_INVALID_STATE if the device is in a state where it
+ * is not able to perform decryption
+ * + ERROR_DRM_LICENSE_EXPIRED if the license keys have expired
+ * + ERROR_DRM_NO_LICENSE if no license keys have been loaded
+ * + ERROR_DRM_RESOURCE_BUSY if the resources required to perform
+ * the decryption are not available
+ * + ERROR_DRM_SESSION_NOT_OPENED if the decrypt session is not
+ * opened
+ */
+ DecryptResult decrypt(in boolean secure, in byte[] keyId, in byte[] iv, in Mode mode,
+ in Pattern pattern, in SubSample[] subSamples, in SharedBuffer source, in long offset,
+ in DestinationBuffer destination);
+
+ /**
+ * Get OEMCrypto or plugin error messages.
+ *
+ * @return LogMessages
+ * Implicit error codes:
+ * + GENERAL_OEM_ERROR on OEM-provided, low-level component failures;
+ * + GENERAL_PLUGIN_ERROR on unexpected plugin-level errors.
+ */
+ List<LogMessage> getLogMessages();
+
+ /**
+ * Notify a plugin of the currently configured resolution.
+ *
+ * @param width - the display resolutions's width
+ * @param height - the display resolution's height
+ */
+ void notifyResolution(in int width, in int height);
+
+ /**
+ * Check if the specified mime-type requires a secure decoder
+ * component.
+ *
+ * @param mime The content mime-type
+ * @return must be true only if a secure decoder is required
+ * for the specified mime-type
+ */
+ boolean requiresSecureDecoderComponent(in String mime);
+
+ /**
+ * Associate a mediadrm session with this crypto session.
+ *
+ * @param sessionId the MediaDrm session ID to associate with
+ * this crypto session
+ * @return (implicit) the status of the call, status can be:
+ * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened, or
+ * ERROR_DRM_CANNOT_HANDLE if the operation is not supported by
+ * the drm scheme
+ */
+ void setMediaDrmSession(in byte[] sessionId);
+
+ /**
+ * Set a shared memory base for subsequent decrypt operations.
+ * The buffer base is mmaped from a ParcelFileDesciptor in Ashmem
+ * which maps shared memory in the HAL module.
+ * After the shared buffer base is established, the decrypt() method
+ * receives SharedBuffer instances which specify the buffer address range
+ * for decrypt source and destination addresses.
+ *
+ * There can be multiple shared buffers per crypto plugin. The buffers
+ * are distinguished by the bufferId.
+ *
+ * @param base the base of the memory buffer identified by
+ * bufferId
+ * @param bufferId identifies the specific shared buffer for which
+ * the base is being set.
+ */
+ void setSharedBufferBase(in Ashmem base, in int bufferId);
+}
diff --git a/drm/aidl/android/hardware/drm/IDrmFactory.aidl b/drm/aidl/android/hardware/drm/IDrmFactory.aidl
new file mode 100644
index 0000000..b9622a4
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/IDrmFactory.aidl
@@ -0,0 +1,76 @@
+/*
+ * 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;
+
+import android.hardware.drm.SecurityLevel;
+import android.hardware.drm.Uuid;
+
+/**
+ * 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.
+ */
+@VintfStability
+interface IDrmFactory {
+ /**
+ * Create a drm plugin instance for the specified uuid and
+ * scheme-specific initialization data.
+ *
+ * @param uuid uniquely identifies the drm scheme. See
+ * http://dashif.org/identifiers/protection for uuid assignments
+ * @param appPackageName identifies the package name of the calling
+ * application.
+ *
+ * @return A DRM plugin instance if successful, or null if not created.
+ * Implicit error codes:
+ * + ERROR_DRM_CANNOT_HANDLE if the plugin cannot be created.
+ */
+ @nullable android.hardware.drm.IDrmPlugin createPlugin(
+ in Uuid uuid, in String appPackageName);
+
+ /**
+ * Return vector of uuids identifying crypto schemes supported by
+ * this HAL.
+ *
+ * @return List of uuids for which isCryptoSchemeSupported is true;
+ * each uuid can be used as input to createPlugin.
+ */
+ List<Uuid> getSupportedCryptoSchemes();
+
+ /**
+ * Determine if the HAL factory is able to construct plugins that
+ * support a given media container format specified by mimeType
+ *
+ * @param mimeType identifies the mime type in question
+ *
+ * @return must be true only if the scheme is supported
+ */
+ boolean isContentTypeSupported(in String mimeType);
+
+ /**
+ * Determine if a specific security level is supported by the device.
+ *
+ * @param uuid identifies the crypto scheme in question
+ * @param mimeType identifies the mime type in question
+ * @param securityLevel specifies the security level required
+ *
+ * @return must be true only if the scheme is supported
+ */
+ boolean isCryptoSchemeSupported(
+ in Uuid uuid, in String mimeType, in SecurityLevel securityLevel);
+}
diff --git a/drm/aidl/android/hardware/drm/IDrmPlugin.aidl b/drm/aidl/android/hardware/drm/IDrmPlugin.aidl
new file mode 100644
index 0000000..e649f26
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/IDrmPlugin.aidl
@@ -0,0 +1,755 @@
+/*
+ * 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;
+
+import android.hardware.drm.DrmMetricGroup;
+import android.hardware.drm.HdcpLevels;
+import android.hardware.drm.IDrmPluginListener;
+import android.hardware.drm.KeySetId;
+import android.hardware.drm.KeyRequest;
+import android.hardware.drm.KeyStatus;
+import android.hardware.drm.KeyType;
+import android.hardware.drm.KeyValue;
+import android.hardware.drm.LogMessage;
+import android.hardware.drm.NumberOfSessions;
+import android.hardware.drm.OfflineLicenseState;
+import android.hardware.drm.OpaqueData;
+import android.hardware.drm.ProvideProvisionResponseResult;
+import android.hardware.drm.ProvisionRequest;
+import android.hardware.drm.SecureStop;
+import android.hardware.drm.SecureStopId;
+import android.hardware.drm.SecurityLevel;
+
+/**
+ * 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.
+ */
+@VintfStability
+interface IDrmPlugin {
+ /**
+ * Close a session on the DrmPlugin object
+ *
+ * @param sessionId the session id the call applies to
+ *
+ * @return (implicit) the status of the call:
+ * BAD_VALUE if the sessionId is invalid
+ * ERROR_DRM_INVALID_STATE if the HAL is in a state where
+ * the session cannot be closed.
+ * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+ */
+ void closeSession(in byte[] sessionId);
+
+ /**
+ * Decrypt the provided input buffer with the cipher algorithm
+ * specified by setCipherAlgorithm and the key selected by keyId,
+ * and return the decrypted data.
+ *
+ * @param sessionId the session id the call applies to
+ * @param keyId the ID of the key to use for decryption
+ * @param input the input data to decrypt
+ * @param iv the initialization vector to use for decryption
+ *
+ * @return decrypted output buffer
+ * Implicit error codes:
+ * + BAD_VALUE if the sessionId is invalid
+ * + ERROR_DRM_INVALID_STATE if the HAL is in a state where
+ * the decrypt operation cannot be performed.
+ * + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+ */
+ byte[] decrypt(in byte[] sessionId, in byte[] keyId, in byte[] input, in byte[] iv);
+
+ /**
+ * Encrypt the provided input buffer with the cipher algorithm specified by
+ * setCipherAlgorithm and the key selected by keyId, and return the
+ * encrypted data.
+ *
+ * @param sessionId the session id the call applies to
+ * @param keyId the ID of the key to use for encryption
+ * @param input the input data to encrypt
+ * @param iv the initialization vector to use for encryption
+ *
+ * @return encrypted output buffer
+ * Implicit error codes:
+ * + BAD_VALUE if the sessionId is invalid
+ * + ERROR_DRM_INVALID_STATE if the HAL is in a state where
+ * the encrypt operation cannot be performed.
+ * + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+ */
+ byte[] encrypt(in byte[] sessionId, in byte[] keyId, in byte[] input, in byte[] iv);
+
+ /**
+ * Return the currently negotiated and max supported HDCP levels.
+ *
+ * The current level is based on the display(s) the device is connected to.
+ * If multiple HDCP-capable displays are simultaneously connected to
+ * separate interfaces, this method returns the lowest negotiated HDCP level
+ * of all interfaces.
+ *
+ * The maximum HDCP level is the highest level that can potentially be
+ * negotiated. It is a constant for any device, i.e. it does not depend on
+ * downstream receiving devices that could be connected. For example, if
+ * the device has HDCP 1.x keys and is capable of negotiating HDCP 1.x, but
+ * does not have HDCP 2.x keys, then the maximum HDCP capability would be
+ * reported as 1.x. If multiple HDCP-capable interfaces are present, it
+ * indicates the highest of the maximum HDCP levels of all interfaces.
+ *
+ * This method should only be used for informational purposes, not for
+ * enforcing compliance with HDCP requirements. Trusted enforcement of HDCP
+ * policies must be handled by the DRM system.
+ *
+ * @return HdcpLevels parcelable
+ * Implicit error codes:
+ * + ERROR_DRM_INVALID_STATE if the HAL is in a state where
+ * the HDCP level cannot be queried
+ */
+ HdcpLevels getHdcpLevels();
+
+ /**
+ * A key request/response exchange occurs between the app and a License
+ * Server to obtain the keys required to decrypt the content.
+ * getKeyRequest() is used to obtain an opaque key request blob that is
+ * delivered to the license server.
+ *
+ * @param scope either a sessionId or a keySetId, depending on the
+ * specified keyType. When the keyType is OFFLINE or STREAMING, scope
+ * must be set to the sessionId the keys will be provided to. When the
+ * keyType is RELEASE, scope must be set to the keySetId of the keys
+ * being released.
+ * @param initData container-specific data, its meaning is interpreted
+ * based on the mime type provided in the mimeType parameter. It could
+ * contain, for example, the content ID, key ID or other data obtained
+ * from the content metadata that is required to generate the key
+ * request. initData must be empty when keyType is RELEASE.
+ * @param mimeType identifies the mime type of the content
+ * @param keyType specifies if the keys are to be used for streaming,
+ * offline or a release
+ * @param optionalParameters included in the key request message to
+ * allow a client application to provide additional message parameters
+ * to the server.
+ *
+ * @return KeyRequest parcelable
+ * Implicit error codes:
+ * + BAD_VALUE if any parameters are invalid
+ * + ERROR_DRM_CANNOT_HANDLE if getKeyRequest is not supported at
+ * the time of the call
+ * + ERROR_DRM_INVALID_STATE if the HAL is in a state where
+ * a key request cannot be generated
+ * + ERROR_DRM_NOT_PROVISIONED if the device requires provisioning
+ * before it is able to generate a key request
+ * + ERROR_DRM_RESOURCE_CONTENTION if client applications using the
+ * hal are temporarily exceeding the available crypto resources
+ * such that a retry of the operation is likely to succeed
+ * + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+ */
+ KeyRequest getKeyRequest(in byte[] scope, in byte[] initData, in String mimeType,
+ in KeyType keyType, in KeyValue[] optionalParameters);
+
+ /**
+ * Get Plugin error messages.
+ *
+ * @return LogMessages
+ * Implicit error codes:
+ * + GENERAL_OEM_ERROR on OEM-provided, low-level component failures;
+ * + GENERAL_PLUGIN_ERROR on unexpected plugin-level errors.
+ */
+ List<LogMessage> getLogMessages();
+
+ /**
+ * Returns the plugin-specific metrics. Multiple metric groups may be
+ * returned in one call to getMetrics(). The scope and definition of the
+ * metrics is defined by the plugin.
+ *
+ * @return collection of metric groups provided by the plugin
+ * Implicit error codes:
+ * + ERROR_DRM_INVALID_STATE if the metrics are not available to be
+ * returned.
+ */
+ List<DrmMetricGroup> getMetrics();
+
+ /**
+ * Return the current number of open sessions and the maximum number of
+ * sessions that may be opened simultaneously among all DRM instances
+ * for the active DRM scheme.
+ *
+ * @return NumberOfSessions parcelable
+ * Implicit error codes:
+ * + ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+ * number of sessions cannot be queried
+ */
+ NumberOfSessions getNumberOfSessions();
+
+ /**
+ * The keys in an offline license allow protected content to be
+ * played even if the device is not connected to a network.
+ * Offline licenses are stored on the device after a key
+ * request/response exchange when the key request KeyType is
+ * OFFLINE. Normally each app is responsible for keeping track of
+ * the KeySetIds it has created. In some situations however, it
+ * will be necessary to request the list of stored offline license
+ * KeySetIds. If an app loses the KeySetId for any stored licenses
+ * that it created, for example, it must be able to recover the
+ * stored KeySetIds so those licenses will be removed when they
+ * expire or when the app is uninstalled.
+ *
+ * This method returns a list of the KeySetIds for all offline
+ * licenses. The offline license KeySetId allows an app to query
+ * the status of an offline license or remove it.
+ *
+ * @return list of keySetIds
+ * Implicit error codes:
+ * + ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+ * KeySetIds can't be returned
+ */
+ List<KeySetId> getOfflineLicenseKeySetIds();
+
+ /**
+ * Request the state of an offline license. An offline license must
+ * be usable or inactive. The keys in a usable offline license are
+ * available for decryption. When the offline license state is
+ * inactive, the keys have been marked for release using
+ * getKeyRequest with KeyType RELEASE but the key response has not
+ * been received. The keys in an inactive offline license are not
+ * usable for decryption.
+ *
+ * @param keySetId the id of the offline license
+ *
+ * @return The offline license state, UNKNOWN, USABLE or INACTIVE.
+ * Implicit error codes:
+ * + BAD_VALUE if the license is not found
+ * + ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+ * offline license state can't be queried
+ */
+ OfflineLicenseState getOfflineLicenseState(in KeySetId keySetId);
+
+ /**
+ * Read a byte array property value given the property name.
+ * See getPropertyString.
+ *
+ * @param propertyName the name of the property
+ *
+ * @return property value bye array
+ * Implicit error codes:
+ * + BAD_VALUE if the property name is invalid
+ * + ERROR_DRM_CANNOT_HANDLE if the property is not supported
+ * + ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+ * property cannot be obtained
+ */
+ byte[] getPropertyByteArray(in String propertyName);
+
+ /**
+ * A drm scheme can have properties that are settable and readable
+ * by an app. There are a few forms of property access methods,
+ * depending on the data type of the property.
+ *
+ * Property values defined by the public API are:
+ * "vendor" [string] identifies the maker of the drm scheme
+ * "version" [string] identifies the version of the drm scheme
+ * "description" [string] describes the drm scheme
+ * 'deviceUniqueId' [byte array] The device unique identifier is
+ * established during device provisioning and provides a means of
+ * uniquely identifying each device.
+ *
+ * Since drm scheme properties may vary, additional field names may be
+ * defined by each DRM vendor. Refer to your DRM provider documentation
+ * for definitions of its additional field names.
+ *
+ * Read a string property value given the property name.
+ *
+ * @param propertyName the name of the property
+ *
+ * @return the property value string.
+ * Implicit error codes:
+ * + BAD_VALUE if the property name is invalid
+ * + ERROR_DRM_CANNOT_HANDLE if the property is not supported
+ * + ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+ * property cannot be obtained
+ */
+ String getPropertyString(in String propertyName);
+
+ /**
+ * A provision request/response exchange occurs between the app
+ * and a provisioning server to retrieve a device certificate.
+ * getProvisionRequest is used to obtain an opaque provisioning
+ * request blob that is delivered to the provisioning server.
+ *
+ * @param certificateType the type of certificate requested, e.g. "X.509"
+ * @param certificateAuthority identifies the certificate authority.
+ * A certificate authority (CA) is an entity which issues digital
+ * certificates for use by other parties. It is an example of a
+ * trusted third party.
+ *
+ * @return ProvisionRequest parcelable
+ * Implicit error codes:
+ * + ERROR_DRM_CANNOT_HANDLE if the drm scheme does not require
+ * provisioning
+ * + ERROR_DRM_INVALID_STATE if the HAL is in a state where
+ * the provision request cannot be generated
+ * + ERROR_DRM_RESOURCE_CONTENTION if client applications using
+ * the hal are temporarily exceeding the available crypto
+ * resources such that a retry of the operation is likely
+ * to succeed
+ */
+ ProvisionRequest getProvisionRequest(
+ in String certificateType, in String certificateAuthority);
+
+ /**
+ * Get all secure stops by secure stop ID
+ *
+ * @param secureStopId the ID of the secure stop to return.
+ * The secure stop ID is delivered by the key server
+ * as part of the key response and must also be known by the app.
+ *
+ * @return secure stop opaque object.
+ * Implicit error codes:
+ * + BAD_VALUE if the secureStopId is invalid
+ * + ERROR_DRM_INVALID_STATE if the HAL is in a state where
+ * the secure stop cannot be returned
+ */
+ SecureStop getSecureStop(in SecureStopId secureStopId);
+
+ /**
+ * Get the IDs of all secure stops on the device
+ *
+ * @return list of secure stops IDs.
+ * Implicit error codes:
+ * + ERROR_DRM_INVALID_STATE if the HAL is in a state where
+ * the secure stop IDs list cannot be returned
+ */
+ List<SecureStopId> getSecureStopIds();
+
+ /**
+ * SecureStop is a way of enforcing the concurrent stream limit per
+ * subscriber.
+ *
+ * It can securely monitor the lifetime of sessions across device reboots
+ * by periodically persisting the session lifetime status in secure
+ * storage.
+ *
+ * A signed version of the sessionID is written to persistent storage on the
+ * device when each MediaCrypto object is created and periodically during
+ * playback. The sessionID is signed by the device private key to prevent
+ * tampering.
+ *
+ * When playback is completed the session is destroyed, and the secure
+ * stops are queried by the app. The app then delivers the secure stop
+ * message to a server which verifies the signature to confirm that the
+ * session and its keys have been removed from the device. The persisted
+ * record on the device is removed after receiving and verifying the
+ * signed response from the server.
+ *
+ * Get all secure stops on the device
+ *
+ * @return list of the opaque secure stop objects.
+ * Implicit error codes:
+ * + ERROR_DRM_INVALID_STATE if the HAL is in a state where
+ * the secure stops cannot be returned
+ */
+ List<SecureStop> getSecureStops();
+
+ /**
+ * Return the current security level of a session. A session has an initial
+ * security level determined by the robustness of the DRM system's
+ * implementation on the device.
+ *
+ * @param sessionId the session id the call applies to
+ *
+ * @return the current security level for the session.
+ * Implicit error codes:
+ * + BAD_VALUE if the sessionId is invalid
+ * + ERROR_DRM_INVALID_STATE if the HAL is in a state where
+ * the security level cannot be queried
+ * + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+ */
+ SecurityLevel getSecurityLevel(in byte[] sessionId);
+
+ /**
+ * Open a new session at a requested security level. The security level
+ * represents the robustness of the device's DRM implementation. By default,
+ * sessions are opened at the native security level of the device which is
+ * the maximum level that can be supported. Overriding the security level is
+ * necessary when the decrypted frames need to be manipulated, such as for
+ * image compositing. The security level parameter must be equal to or lower
+ * than the native level. If the requested level is not supported, the next
+ * lower supported security level must be set. The level can be queried
+ * using {@link #getSecurityLevel}. A session ID is returned.
+ *
+ * @param level the requested security level
+ *
+ * @return sessionId
+ */
+ byte[] openSession(in SecurityLevel securityLevel);
+
+ /**
+ * After a key response is received by the app, it is provided to the
+ * Drm plugin using provideKeyResponse.
+ *
+ * @param scope may be a sessionId or a keySetId depending on the
+ * type of the response. Scope should be set to the sessionId
+ * when the response is for either streaming or offline key requests.
+ * Scope should be set to the keySetId when the response is for
+ * a release request.
+ * @param response the response from the key server that is being
+ * provided to the drm HAL.
+ *
+ * @return a keySetId that can be used to later restore the keys to a new
+ * session with the method restoreKeys when the response is for an
+ * offline key request.
+ * Implicit error codes:
+ * + BAD_VALUE if any parameters are invalid
+ * + ERROR_DRM_CANNOT_HANDLE if provideKeyResponse is not supported
+ * at the time of the call
+ * + ERROR_DRM_DEVICE_REVOKED if the device has been disabled by
+ * the license policy
+ * + ERROR_DRM_INVALID_STATE if the HAL is in a state where
+ * a key response cannot be handled.
+ * + ERROR_DRM_NOT_PROVISIONED if the device requires provisioning
+ * before it can handle the key response
+ * + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+ */
+ KeySetId provideKeyResponse(in byte[] scope, in byte[] response);
+
+ /**
+ * After a provision response is received by the app from a provisioning
+ * server, it is provided to the Drm HAL using provideProvisionResponse.
+ * The HAL implementation must receive the provision request and
+ * store the provisioned credentials.
+ *
+ * @param response the opaque provisioning response received by the
+ * app from a provisioning server.
+ *
+ * @return ProvideProvisionResponseResult parcelable, which contains
+ * the public certificate and encrypted private key that can be
+ * used by signRSA to compute an RSA signature on a message.
+ * Implicit error codes:
+ * + BAD_VALUE if any parameters are invalid
+ * + ERROR_DRM_DEVICE_REVOKED if the device has been disabled by
+ * the license policy
+ * + ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+ * provision response cannot be handled
+ */
+ ProvideProvisionResponseResult provideProvisionResponse(in byte[] response);
+
+ /**
+ * Request an informative description of the license for the session.
+ * The status is in the form of {name, value} pairs. Since DRM license
+ * policies vary by vendor, the specific status field names are
+ * determined by each DRM vendor. Refer to your DRM provider
+ * documentation for definitions of the field names for a particular
+ * drm scheme.
+ *
+ * @param sessionId the session id the call applies to
+ *
+ * @return a list of name value pairs describing the license.
+ * Implicit error codes:
+ * + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+ * + BAD_VALUE if any parameters are invalid
+ * + ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+ * key status cannot be queried.
+ */
+ List<KeyValue> queryKeyStatus(in byte[] sessionId);
+
+ /**
+ * Release all secure stops on the device
+ *
+ * @return (implicit) the status of the call:
+ * ERROR_DRM_INVALID_STATE if the HAL is in a state where
+ * the secure stops cannot be released.
+ */
+ void releaseAllSecureStops();
+
+ /**
+ * Release a secure stop by secure stop ID
+ *
+ * @param secureStopId the ID of the secure stop to release.
+ * The secure stop ID is delivered by the key server as
+ * part of the key response and must also be known by the app.
+ *
+ * @return (implicit) the status of the call:
+ * BAD_VALUE if the secureStopId is invalid
+ * ERROR_DRM_INVALID_STATE if the HAL is in a state where
+ * the secure stop cannot be released.
+ */
+ void releaseSecureStop(in SecureStopId secureStopId);
+
+ /**
+ * Release secure stops given a release message from the key server
+ *
+ * @param ssRelease the secure stop release message identifying
+ * one or more secure stops to release. ssRelease is opaque,
+ * it is passed directly from a DRM license server through
+ * the app and media framework to the vendor HAL module.
+ * The format and content of ssRelease must be defined by the
+ * DRM scheme being implemented according to this HAL.
+ * The DRM scheme can be identified by its UUID which
+ * can be queried using IDrmFactory::isCryptoSchemeSupported.
+ *
+ * @return (implicit) the status of the call:
+ * BAD_VALUE if ssRelease is invalid
+ * ERROR_DRM_INVALID_STATE if the HAL is in a state wherei
+ * the secure stop cannot be released.
+ */
+ void releaseSecureStops(in OpaqueData ssRelease);
+
+ /**
+ * Remove all secure stops on the device without requiring a secure
+ * stop release response message from the key server.
+ *
+ * @return (implicit) the status of the call:
+ * ERROR_DRM_INVALID_STATE if the HAL is in a state where
+ * the secure stops cannot be removed.
+ */
+ void removeAllSecureStops();
+
+ /**
+ * Remove the current keys from a session
+ *
+ * @param sessionId the session id the call applies to
+ *
+ * @return (implicit) the status of the call:
+ * BAD_VALUE if the sessionId is invalid
+ * ERROR_DRM_INVALID_STATE if the HAL is in a state where
+ * the keys cannot be removed.
+ * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+ */
+ void removeKeys(in byte[] sessionId);
+
+ /**
+ * Normally offline licenses are released using a key
+ * request/response exchange using getKeyRequest where the KeyType
+ * is RELEASE, followed by provideKeyResponse. This allows the
+ * server to cryptographically confirm that the license has been
+ * removed and then adjust the count of offline licenses allocated
+ * to the device.
+ * <p>
+ * In some exceptional situations it will be necessary to directly
+ * remove offline licenses without notifying the server, which is
+ * performed by this method.
+ *
+ * @param keySetId the id of the offline license to remove
+ *
+ * @return (implicit) the status of the call:
+ * BAD_VALUE if the license is not found
+ * ERROR_DRM_INVALID_STATE if the HAL is in a state where
+ * the KeySetIds can't be removed.
+ */
+ void removeOfflineLicense(in KeySetId keySetId);
+
+ /**
+ * Remove a secure stop given its secure stop ID, without requiring
+ * a secure stop release response message from the key server.
+ *
+ * @param secureStopId the ID of the secure stop to release.
+ *
+ * @return the status of the call:
+ * BAD_VALUE if the secureStopId is invalid
+ * ERROR_DRM_INVALID_STATE if the HAL is in a state where
+ * the secure stop cannot be removed.
+ */
+ void removeSecureStop(in SecureStopId secureStopId);
+
+ /**
+ * 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 must be true if and only if a secure decoder is
+ * required for the specified mime-type & security level
+ */
+ boolean requiresSecureDecoder(in String mime, in SecurityLevel level);
+
+ /**
+ * 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 must be true if and only if a secure decoder is required
+ * for the specified mime-type
+ */
+ boolean requiresSecureDecoderDefault(in String mime);
+
+ /**
+ * Restore persisted offline keys into a new session
+ *
+ * @param sessionId the session id the call applies to
+ * @param keySetId identifies the keys to load, obtained from
+ * a prior call to provideKeyResponse().
+ *
+ * @return (implicit) the status of the call:
+ * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+ * BAD_VALUE if any parameters are invalid
+ * ERROR_DRM_INVALID_STATE if the HAL is in a state where
+ * keys cannot be restored.
+ */
+ void restoreKeys(in byte[] sessionId, in KeySetId keySetId);
+
+ /**
+ * The following methods implement operations on a CryptoSession to support
+ * encrypt, decrypt, sign verify operations on operator-provided
+ * session keys.
+ *
+ *
+ * Set the cipher algorithm to be used for the specified session.
+ *
+ * @param sessionId the session id the call applies to
+ * @param algorithm the algorithm to use. The string conforms to JCA
+ * Standard Names for Cipher Transforms and is case insensitive. An
+ * example algorithm is "AES/CBC/PKCS5Padding".
+ *
+ * @return (implicit) the status of the call:
+ * BAD_VALUE if any parameters are invalid
+ * ERROR_DRM_INVALID_STATE if the HAL is in a state where
+ * the algorithm cannot be set.
+ * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened`
+ */
+ void setCipherAlgorithm(in byte[] sessionId, in String algorithm);
+
+ /**
+ * Plugins call the following methods to deliver events to the
+ * java app.
+ *
+ *
+ * Set a listener for a drm session. This allows the drm HAL to
+ * make asynchronous calls back to the client of IDrm.
+ *
+ * @param listener instance of IDrmPluginListener to receive the events
+ */
+ void setListener(in IDrmPluginListener listener);
+
+ /**
+ * Set the MAC algorithm to be used for computing hashes in a session.
+ *
+ * @param sessionId the session id the call applies to
+ * @param algorithm the algorithm to use. The string conforms to JCA
+ * Standard Names for Mac Algorithms and is case insensitive. An example MAC
+ * algorithm string is "HmacSHA256".
+ *
+ * @return (implicit) the status of the call:
+ * BAD_VALUE if any parameters are invalid
+ * ERROR_DRM_INVALID_STATE if the HAL is in a state where
+ * the algorithm cannot be set.
+ * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened`
+ */
+ void setMacAlgorithm(in byte[] sessionId, in String algorithm);
+
+ /**
+ * Set playback id of a drm session. The playback id can be used to join drm session metrics
+ * with metrics from other low level media components, e.g. codecs, or metrics from the high
+ * level player.
+ *
+ * @param sessionId drm session id
+ * @param playbackId high level playback id
+ *
+ * @return (implicit) the status of the call:
+ * ERROR_DRM_SESSION_NOT_OPENED if the drm session cannot be found
+ */
+ void setPlaybackId(in byte[] sessionId, in String playbackId);
+
+ /**
+ * Write a property byte array value given the property name
+ *
+ * @param propertyName the name of the property
+ * @param value the value to write
+ *
+ * @return (implicit) the status of the call:
+ * BAD_VALUE if the property name is invalid
+ * ERROR_DRM_CANNOT_HANDLE if the property is not supported
+ * ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+ * property cannot be set
+ */
+ void setPropertyByteArray(in String propertyName, in byte[] value);
+
+ /**
+ * Write a property string value given the property name
+ *
+ * @param propertyName the name of the property
+ * @param value the value to write
+ *
+ * @return (implicit) status of the call:
+ * BAD_VALUE if the property name is invalid
+ * ERROR_DRM_CANNOT_HANDLE if the property is not supported
+ * ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+ * property cannot be set
+ */
+ void setPropertyString(in String propertyName, in String value);
+
+ /**
+ * Compute a signature over the provided message using the mac algorithm
+ * specified by setMacAlgorithm and the key selected by keyId and return
+ * the signature.
+ *
+ * @param sessionId the session id the call applies to
+ * @param keyId the ID of the key to use for decryption
+ * @param message the message to compute a signature over
+ *
+ * @return signature computed over the message
+ * Implicit error codes:
+ * + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+ * + BAD_VALUE if any parameters are invalid
+ * + ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+ * sign operation cannot be performed.
+ */
+ byte[] sign(in byte[] sessionId, in byte[] keyId, in byte[] message);
+
+ /**
+ * Compute an RSA signature on the provided message using the specified
+ * algorithm.
+ *
+ * @param sessionId the session id the call applies to
+ * @param algorithm the signing algorithm, such as "RSASSA-PSS-SHA1"
+ * or "PKCS1-BlockType1"
+ * @param message the message to compute the signature on
+ * @param wrappedKey the private key returned during provisioning as
+ * returned by provideProvisionResponse.
+ *
+ * @return signature computed over the message
+ * Implicit error codes:
+ * + BAD_VALUE if any parameters are invalid
+ * + ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+ * signRSA operation operation cannot be performed
+ * + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+ */
+ byte[] signRSA(
+ in byte[] sessionId, in String algorithm, in byte[] message,
+ in byte[] wrappedkey);
+
+ /**
+ * Compute a hash of the provided message using the mac algorithm specified
+ * by setMacAlgorithm and the key selected by keyId, and compare with the
+ * expected result.
+ *
+ * @param sessionId the session id the call applies to
+ * @param keyId the ID of the key to use for decryption
+ * @param message the message to compute a hash of
+ * @param signature the signature to verify
+ *
+ * @return true if the signature is verified positively, false otherwise.
+ * Implicit error codes:
+ * + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+ * + BAD_VALUE if any parameters are invalid
+ * + ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+ * verify operation cannot be performed.
+ */
+ boolean verify(
+ in byte[] sessionId, in byte[] keyId, in byte[] message,
+ in byte[] signature);
+}
diff --git a/drm/aidl/android/hardware/drm/IDrmPluginListener.aidl b/drm/aidl/android/hardware/drm/IDrmPluginListener.aidl
new file mode 100644
index 0000000..d52da66
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/IDrmPluginListener.aidl
@@ -0,0 +1,76 @@
+/*
+ * 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;
+
+import android.hardware.drm.EventType;
+import android.hardware.drm.KeyStatus;
+
+/**
+ * IDrmPluginListener is a listener interface for Drm events sent from an
+ * IDrmPlugin instance.
+ */
+@VintfStability
+interface IDrmPluginListener {
+ /**
+ * Legacy event sending method, it sends events of various types using a
+ * single overloaded set of parameters. This form is deprecated.
+ *
+ * @param eventType the type of the event
+ * @param sessionId identifies the session the event originated from
+ * @param data event-specific data blob
+ */
+ oneway void onEvent(in EventType eventType, in byte[] sessionId, in byte[] data);
+
+ /**
+ * Send a license expiration update to the listener. The expiration
+ * update indicates how long the current keys are valid before they
+ * need to be renewed.
+ *
+ * @param sessionId identifies the session the event originated from
+ * @param expiryTimeInMS the time when the keys need to be renewed.
+ * The time is in milliseconds, relative to the Unix epoch. A time
+ * of 0 indicates that the keys never expire.
+ */
+ oneway void onExpirationUpdate(in byte[] sessionId, in long expiryTimeInMS);
+
+ /**
+ * Send a keys change event to the listener. The keys change event
+ * indicates the status of each key in the session. Keys can be
+ * indicated as being usable, expired, outputnotallowed or statuspending.
+ *
+ * @param sessionId identifies the session the event originated from
+ * @param keyStatusList indicates the status for each key ID in the
+ * session.
+ * @param hasNewUsableKey indicates if the event includes at least one
+ * key that has become usable.
+ */
+ oneway void onKeysChange(
+ in byte[] sessionId, in KeyStatus[] keyStatusList, in boolean hasNewUsableKey);
+
+ /**
+ * Some device crypto hardware is incapable of retaining crypto
+ * session state across suspend and resume cycles. A
+ * SessionLostState event must be signaled when a session has
+ * become invalid for this reason. This event must not be used to
+ * indicate a failure in the crypto system. Closing the session
+ * and opening a new one must allow the application to resume
+ * normal use of the drm hal module.
+ *
+ * @param sessionId identifies the session that has been invalidated
+ */
+ oneway void onSessionLostState(in byte[] sessionId);
+}
diff --git a/drm/aidl/android/hardware/drm/KeyRequest.aidl b/drm/aidl/android/hardware/drm/KeyRequest.aidl
new file mode 100644
index 0000000..0c73205
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/KeyRequest.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+import android.hardware.drm.KeyRequestType;
+
+@VintfStability
+parcelable KeyRequest {
+ /** The opaque key request blob. */
+ byte[] request;
+
+ /**
+ * Enumerated type:
+ * INITIAL - the first key request for a license
+ * NONE - indicates that no request is needed because the keys
+ * are already loaded
+ * RENEWAL - is a subsequent key request used to refresh the
+ * keys in a license
+ * RELEASE - indicates keys are being released
+ * UPDATE - indicates that the keys need to be refetched after
+ * the initial license request
+ */
+ KeyRequestType requestType;
+
+ /**
+ * The URL that the request may be sent to,
+ * if provided by the drm HAL. The app can choose to
+ * override this URL. If the HAL implementation does not provide
+ * a defaultUrl, the returned string must be empty.
+ */
+ String defaultUrl;
+}
diff --git a/drm/aidl/android/hardware/drm/KeyRequestType.aidl b/drm/aidl/android/hardware/drm/KeyRequestType.aidl
new file mode 100644
index 0000000..3a603ff
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/KeyRequestType.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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;
+
+/**
+ * An app determines the type of a key request returned from getKeyRequest.
+ */
+@VintfStability
+@Backing(type="int")
+enum KeyRequestType {
+ /**
+ * Key request type is for an initial license request
+ */
+ INITIAL,
+ /**
+ * Key request type is for license renewal. Renewal requests are used
+ * to extend the validity period for streaming keys.
+ */
+ RENEWAL,
+ /**
+ * Key request type is a release. A key release causes offline keys
+ * to become available for streaming.
+ */
+ RELEASE,
+ /**
+ * Key request type is unknown due to some error condition.
+ */
+ UNKNOWN,
+ /**
+ * Keys are already loaded. No key request is needed.
+ */
+ NONE,
+ /**
+ * Keys have previously been loaded. An additional (non-renewal) license
+ * request is needed.
+ */
+ UPDATE,
+}
diff --git a/drm/aidl/android/hardware/drm/KeySetId.aidl b/drm/aidl/android/hardware/drm/KeySetId.aidl
new file mode 100644
index 0000000..be0ce0e
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/KeySetId.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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;
+
+@VintfStability
+parcelable KeySetId {
+ byte[] keySetId;
+}
diff --git a/drm/aidl/android/hardware/drm/KeyStatus.aidl b/drm/aidl/android/hardware/drm/KeyStatus.aidl
new file mode 100644
index 0000000..16e042a
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/KeyStatus.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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;
+
+import android.hardware.drm.KeyStatusType;
+
+/**
+ * Used by sendKeysChange to report the usability status of each key
+ * to the app.
+ */
+@VintfStability
+parcelable KeyStatus {
+ byte[] keyId;
+ KeyStatusType type;
+}
diff --git a/drm/aidl/android/hardware/drm/KeyStatusType.aidl b/drm/aidl/android/hardware/drm/KeyStatusType.aidl
new file mode 100644
index 0000000..6902d87
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/KeyStatusType.aidl
@@ -0,0 +1,51 @@
+/*
+ * 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;
+
+@VintfStability
+@Backing(type="int")
+enum KeyStatusType {
+ /**
+ * The key is currently usable to decrypt media data.
+ */
+ USABLE,
+ /**
+ * The key is no longer usable to decrypt media data because its expiration
+ * time has passed.
+ */
+ EXPIRED,
+ /**
+ * The key is not currently usable to decrypt media data because its output
+ * requirements cannot currently be met.
+ */
+ OUTPUTNOTALLOWED,
+ /**
+ * The status of the key is not yet known and is being determined.
+ */
+ STATUSPENDING,
+ /**
+ * The key is not currently usable to decrypt media data because of an
+ * internal error in processing unrelated to input parameters.
+ */
+ INTERNALERROR,
+ /**
+ * The key is not yet usable to decrypt media because the start
+ * time is in the future. The key must become usable when
+ * its start time is reached.
+ */
+ USABLEINFUTURE,
+}
diff --git a/drm/aidl/android/hardware/drm/KeyType.aidl b/drm/aidl/android/hardware/drm/KeyType.aidl
new file mode 100644
index 0000000..78b4d83
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/KeyType.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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;
+
+@VintfStability
+@Backing(type="int")
+enum KeyType {
+ /**
+ * Drm keys can be for offline content or for online streaming.
+ * Offline keys are persisted on the device and may be used when the device
+ * is disconnected from the network.
+ */
+ OFFLINE,
+ /**
+ * Keys for streaming are not persisted and require the device to be
+ * connected to the network for periodic renewal.
+ */
+ STREAMING,
+ /**
+ * The Release type is used to request that offline keys be no longer
+ * restricted to offline use.
+ */
+ RELEASE,
+}
diff --git a/drm/aidl/android/hardware/drm/KeyValue.aidl b/drm/aidl/android/hardware/drm/KeyValue.aidl
new file mode 100644
index 0000000..e26781b
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/KeyValue.aidl
@@ -0,0 +1,23 @@
+/*
+ * 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;
+
+@VintfStability
+parcelable KeyValue {
+ String key;
+ String value;
+}
diff --git a/drm/aidl/android/hardware/drm/LogMessage.aidl b/drm/aidl/android/hardware/drm/LogMessage.aidl
new file mode 100644
index 0000000..8ac1ced
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/LogMessage.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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;
+
+import android.hardware.drm.LogPriority;
+
+/**
+ * Returned by getLogMessages to report error diagnostics to the
+ * app.
+ *
+ * The |message| field is for informational purposes only, and
+ * NOT meant to be parsed programmatically when handling errors.
+ * For programmatic error handling, please check the return |Status|
+ * of APIs instead.
+ */
+@VintfStability
+parcelable LogMessage {
+ /**
+ * Epoch time in milliseconds.
+ */
+ long timeMs;
+ LogPriority priority;
+ String message;
+}
diff --git a/drm/aidl/android/hardware/drm/LogPriority.aidl b/drm/aidl/android/hardware/drm/LogPriority.aidl
new file mode 100644
index 0000000..4db3b40
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/LogPriority.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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;
+
+@VintfStability
+@Backing(type="int")
+enum LogPriority {
+ UNKNOWN,
+ DEFAULT,
+ VERBOSE,
+ DEBUG,
+ INFO,
+ WARN,
+ ERROR,
+ FATAL,
+}
diff --git a/drm/aidl/android/hardware/drm/Mode.aidl b/drm/aidl/android/hardware/drm/Mode.aidl
new file mode 100644
index 0000000..6fc0065
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/Mode.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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;
+
+/**
+ * Enumerate the supported crypto modes
+ */
+@VintfStability
+@Backing(type="int")
+enum Mode {
+ UNENCRYPTED = 0,
+ AES_CTR = 1,
+ AES_CBC_CTS = 2,
+ AES_CBC = 3,
+}
diff --git a/drm/aidl/android/hardware/drm/NumberOfSessions.aidl b/drm/aidl/android/hardware/drm/NumberOfSessions.aidl
new file mode 100644
index 0000000..75b7c2e
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/NumberOfSessions.aidl
@@ -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;
+
+@VintfStability
+parcelable NumberOfSessions {
+ /** The number of currently opened sessions. */
+ int currentSessions;
+
+ /** The maximum number of sessions that the device can support. */
+ int maxSessions;
+}
diff --git a/drm/aidl/android/hardware/drm/OfflineLicenseState.aidl b/drm/aidl/android/hardware/drm/OfflineLicenseState.aidl
new file mode 100644
index 0000000..0f447db
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/OfflineLicenseState.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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;
+
+@VintfStability
+@Backing(type="int")
+enum OfflineLicenseState {
+ /**
+ * Offline license state is unknown
+ */
+ UNKNOWN,
+ /**
+ * Offline license state is usable, the keys are usable for decryption.
+ */
+ USABLE,
+ /**
+ * Offline license state is inactive, the keys have been marked for
+ * release using {@link #getKeyRequest} with KEY_TYPE_RELEASE but the
+ * key response has not been received.
+ */
+ INACTIVE,
+}
diff --git a/drm/aidl/android/hardware/drm/OpaqueData.aidl b/drm/aidl/android/hardware/drm/OpaqueData.aidl
new file mode 100644
index 0000000..6b2a2e7
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/OpaqueData.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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;
+
+@VintfStability
+parcelable OpaqueData {
+ byte[] opaqueData;
+}
diff --git a/drm/aidl/android/hardware/drm/Pattern.aidl b/drm/aidl/android/hardware/drm/Pattern.aidl
new file mode 100644
index 0000000..88d22cf
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/Pattern.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.drm;
+
+/**
+ * A crypto Pattern is a repeating sequence of encrypted and clear blocks
+ * occurring within the bytes indicated by mNumBytesOfEncryptedDatad bytes
+ * of a subsample. Patterns are used to reduce the CPU overhead of
+ * decrypting samples. As an example, HLS uses 1:9 patterns where every
+ * 10th block is encrypted.
+ */
+@VintfStability
+parcelable Pattern {
+ /**
+ * The number of blocks to be encrypted in the pattern. If zero,
+ * pattern encryption is inoperative.
+ */
+ int encryptBlocks;
+
+ /**
+ * The number of blocks to be skipped (left clear) in the pattern. If
+ * zero, pattern encryption is inoperative.
+ */
+ int skipBlocks;
+}
diff --git a/drm/aidl/android/hardware/drm/ProvideProvisionResponseResult.aidl b/drm/aidl/android/hardware/drm/ProvideProvisionResponseResult.aidl
new file mode 100644
index 0000000..e9f1e2b
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/ProvideProvisionResponseResult.aidl
@@ -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;
+
+@VintfStability
+parcelable ProvideProvisionResponseResult {
+ /**
+ * The public certificate resulting from the provisioning
+ * operation, if any. An empty vector indicates that no
+ * certificate was returned.
+ */
+ byte[] certificate;
+
+ /**
+ * An opaque object containing encrypted private key material
+ * to be used by signRSA when computing an RSA signature on a
+ * message, see the signRSA method.
+ */
+ byte[] wrappedKey;
+}
diff --git a/drm/aidl/android/hardware/drm/ProvisionRequest.aidl b/drm/aidl/android/hardware/drm/ProvisionRequest.aidl
new file mode 100644
index 0000000..eb42d32
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/ProvisionRequest.aidl
@@ -0,0 +1,31 @@
+/*
+ * 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;
+
+@VintfStability
+parcelable ProvisionRequest {
+ /** The opaque certificate request blob. */
+ byte[] request;
+
+ /**
+ * The URL that the provisioning request may be sent to,
+ * if known by the HAL implementation. An app can choose to
+ * override this URL. If the HAL implementation does not provide
+ * a defaultUrl, the returned string must be empty.
+ */
+ String defaultUrl;
+}
diff --git a/drm/aidl/android/hardware/drm/SecureStop.aidl b/drm/aidl/android/hardware/drm/SecureStop.aidl
new file mode 100644
index 0000000..37cfbd3
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/SecureStop.aidl
@@ -0,0 +1,25 @@
+/*
+ * 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;
+
+/**
+ * Encapsulates a secure stop opaque object.
+ */
+@VintfStability
+parcelable SecureStop {
+ byte[] opaqueData;
+}
diff --git a/drm/aidl/android/hardware/drm/SecureStopId.aidl b/drm/aidl/android/hardware/drm/SecureStopId.aidl
new file mode 100644
index 0000000..775e60b
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/SecureStopId.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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;
+
+@VintfStability
+parcelable SecureStopId {
+ byte[] secureStopId;
+}
diff --git a/drm/aidl/android/hardware/drm/SecurityLevel.aidl b/drm/aidl/android/hardware/drm/SecurityLevel.aidl
new file mode 100644
index 0000000..aac1b68
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/SecurityLevel.aidl
@@ -0,0 +1,55 @@
+/*
+ * 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;
+
+@VintfStability
+@Backing(type="int")
+enum SecurityLevel {
+ /**
+ * Unable to determine the security level
+ */
+ UNKNOWN,
+ /**
+ * Software-based whitebox crypto
+ */
+ SW_SECURE_CRYPTO,
+ /**
+ * Software-based whitebox crypto and an obfuscated decoder
+ */
+ SW_SECURE_DECODE,
+ /**
+ * DRM key management and crypto operations are performed within a
+ * hardware backed trusted execution environment
+ */
+ HW_SECURE_CRYPTO,
+ /**
+ * DRM key management, crypto operations and decoding of content
+ * are performed within a hardware backed trusted execution environment
+ */
+ HW_SECURE_DECODE,
+ /**
+ * DRM key management, crypto operations, decoding of content and all
+ * handling of the media (compressed and uncompressed) is handled within
+ * a hardware backed trusted execution environment.
+ */
+ HW_SECURE_ALL,
+ /**
+ * The default security level is defined as the highest security level
+ * supported on the device.
+ */
+ DEFAULT,
+}
diff --git a/drm/aidl/android/hardware/drm/SharedBuffer.aidl b/drm/aidl/android/hardware/drm/SharedBuffer.aidl
new file mode 100644
index 0000000..6977284
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/SharedBuffer.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.drm;
+
+/**
+ * SharedBuffer describes a decrypt buffer which is defined by a bufferId, an
+ * offset and a size. The offset is relative to the shared memory base for the
+ * memory region identified by bufferId, which is established by
+ * setSharedMemoryBase().
+ */
+@VintfStability
+parcelable SharedBuffer {
+ /**
+ * The unique buffer identifier
+ */
+ int bufferId;
+ /**
+ * The offset from the shared memory base
+ */
+ long offset;
+ /**
+ * The size of the shared buffer in bytes
+ */
+ long size;
+}
diff --git a/drm/aidl/android/hardware/drm/Status.aidl b/drm/aidl/android/hardware/drm/Status.aidl
new file mode 100644
index 0000000..ee57d64
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/Status.aidl
@@ -0,0 +1,221 @@
+/*
+ * 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;
+
+@VintfStability
+@Backing(type="int")
+enum Status {
+ /**
+ * The DRM plugin must return OK when an operation completes without any
+ * errors.
+ */
+ OK,
+ /**
+ * The DRM plugin must return ERROR_DRM_NO_LICENSE, when decryption is
+ * attempted and no license keys have been provided.
+ */
+ ERROR_DRM_NO_LICENSE,
+ /**
+ * ERROR_DRM_LICENSE_EXPIRED must be returned when an attempt is made
+ * to use a license and the keys in that license have expired.
+ */
+ ERROR_DRM_LICENSE_EXPIRED,
+ /**
+ * The DRM plugin must return ERROR_DRM_SESSION_NOT_OPENED when an
+ * attempt is made to use a session that has not been opened.
+ */
+ ERROR_DRM_SESSION_NOT_OPENED,
+ /**
+ * The DRM plugin must return ERROR_DRM_CANNOT_HANDLE when an unsupported
+ * data format or operation is attempted.
+ */
+ ERROR_DRM_CANNOT_HANDLE,
+ /**
+ * ERROR_DRM_INVALID_STATE must be returned when the device is in a state
+ * where it is not able to perform decryption.
+ */
+ ERROR_DRM_INVALID_STATE,
+ /**
+ * The DRM plugin must return BAD_VALUE whenever an illegal parameter is
+ * passed to one of the interface functions.
+ */
+ BAD_VALUE,
+ /**
+ * The DRM plugin must return ERROR_DRM_NOT_PROVISIONED from getKeyRequest,
+ * openSession or provideKeyResponse when the device has not yet been
+ * provisioned.
+ */
+ ERROR_DRM_NOT_PROVISIONED,
+ /**
+ * ERROR_DRM_RESOURCE_BUSY must be returned when resources, such as drm
+ * sessions or secure buffers are not available to perform a requested
+ * operation because they are already in use.
+ */
+ ERROR_DRM_RESOURCE_BUSY,
+ /**
+ * The DRM Plugin must return ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION
+ * when the output protection level enabled on the device is not
+ * sufficient to meet the requirements in the license policy. HDCP is an
+ * example of a form of output protection.
+ */
+ ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION,
+ /**
+ * The DRM Plugin must return ERROR_DRM_DEVICE_REVOKED from
+ * provideProvisionResponse and provideKeyResponse if the response indicates
+ * that the device has been revoked. Device revocation means that the device
+ * is no longer permitted to play content.
+ */
+ ERROR_DRM_DEVICE_REVOKED,
+ /**
+ * The DRM Plugin must return ERROR_DRM_DECRYPT if the CryptoPlugin
+ * decrypt operation fails.
+ */
+ ERROR_DRM_DECRYPT,
+ /**
+ * ERROR_DRM_UNKNOWN must be returned when a fatal failure occurs and no
+ * other defined error is appropriate.
+ */
+ ERROR_DRM_UNKNOWN,
+ /**
+ * The drm HAL module must return ERROR_DRM_INSUFFICIENT_SECURITY
+ * from the crypto plugin decrypt method when the security level
+ * of the device is not sufficient to meet the requirements in the
+ * license policy.
+ */
+ ERROR_DRM_INSUFFICIENT_SECURITY,
+ /**
+ * The drm HAL module must return ERROR_FRAME_TOO_LARGE from the
+ * decrypt method when the frame being decrypted into the secure
+ * output buffer exceeds the size of the buffer.
+ */
+ ERROR_DRM_FRAME_TOO_LARGE,
+ /**
+ * This error must be returned from any session method when an
+ * attempt is made to use the session after the crypto hardware
+ * state has been invalidated. Some devices are not able to
+ * retain crypto session state across device suspend/resume which
+ * results in invalid session state.
+ */
+ ERROR_DRM_SESSION_LOST_STATE,
+ /**
+ * The drm HAL module must return this error if client
+ * applications using the hal are temporarily exceeding the
+ * capacity of available crypto resources such that a retry of
+ * the operation is likely to succeed.
+ */
+ ERROR_DRM_RESOURCE_CONTENTION,
+ /**
+ * queueSecureInput buffer called with 0 subsamples.
+ */
+ CANNOT_DECRYPT_ZERO_SUBSAMPLES,
+ /**
+ * An error happened within the crypto library used by the drm plugin.
+ */
+ CRYPTO_LIBRARY_ERROR,
+ /**
+ * Non-specific error reported by the device OEM subsystem.
+ */
+ GENERAL_OEM_ERROR,
+ /**
+ * Unexpected internal failure in the drm/crypto plugin.
+ */
+ GENERAL_PLUGIN_ERROR,
+ /**
+ * The init data parameter passed to getKeyRequest is empty or invalid.
+ */
+ INIT_DATA_INVALID,
+ /**
+ * Either the key was not loaded from the license before attempting the
+ * operation, or the key ID parameter provided by the app is incorrect.
+ */
+ KEY_NOT_LOADED,
+ /**
+ * The license response was empty, fields are missing or otherwise unable
+ * to be parsed.
+ */
+ LICENSE_PARSE_ERROR,
+ /**
+ * The operation (e.g. to renew or persist a license) is prohibited by the
+ * license policy.
+ */
+ LICENSE_POLICY_ERROR,
+ /**
+ * Failed to generate a release request because a field in the stored
+ * license is empty or malformed.
+ */
+ LICENSE_RELEASE_ERROR,
+ /**
+ * The license server detected an error in the license request.
+ */
+ LICENSE_REQUEST_REJECTED,
+ /**
+ * Failed to restore an offline license because a field is empty or
+ * malformed.
+ */
+ LICENSE_RESTORE_ERROR,
+ /**
+ * License is in an invalid state for the attempted operation.
+ */
+ LICENSE_STATE_ERROR,
+ /**
+ * Certificate is malformed or is of the wrong type.
+ */
+ MALFORMED_CERTIFICATE,
+ /**
+ * Failure in the media framework.
+ */
+ MEDIA_FRAMEWORK_ERROR,
+ /**
+ * Certificate has not been set.
+ */
+ MISSING_CERTIFICATE,
+ /**
+ * There was an error loading the provisioned certificate.
+ */
+ PROVISIONING_CERTIFICATE_ERROR,
+ /**
+ * Required steps where not performed before provisioning was attempted.
+ */
+ PROVISIONING_CONFIGURATION_ERROR,
+ /**
+ * The provisioning response was empty, fields are missing or otherwise
+ * unable to be parsed.
+ */
+ PROVISIONING_PARSE_ERROR,
+ /**
+ * The provisioning server detected an error in the provisioning request.
+ */
+ PROVISIONING_REQUEST_REJECTED,
+ /**
+ * Provisioning failed in a way that is likely to succeed on a subsequent
+ * attempt.
+ */
+ RETRYABLE_PROVISIONING_ERROR,
+ /**
+ * Failed to generate a secure stop request because a field in the stored
+ * license is empty or malformed.
+ */
+ SECURE_STOP_RELEASE_ERROR,
+ /**
+ * The plugin was unable to read data from the filesystem.
+ */
+ STORAGE_READ_FAILURE,
+ /**
+ * The plugin was unable to write data to the filesystem.
+ */
+ STORAGE_WRITE_FAILURE,
+}
diff --git a/drm/aidl/android/hardware/drm/SubSample.aidl b/drm/aidl/android/hardware/drm/SubSample.aidl
new file mode 100644
index 0000000..68a8fb1
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/SubSample.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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;
+
+/**
+ * A subsample consists of some number of bytes of clear (unencrypted)
+ * data followed by a number of bytes of encrypted data.
+ */
+@VintfStability
+parcelable SubSample {
+ int numBytesOfClearData;
+ int numBytesOfEncryptedData;
+}
diff --git a/drm/aidl/android/hardware/drm/Uuid.aidl b/drm/aidl/android/hardware/drm/Uuid.aidl
new file mode 100644
index 0000000..b36c409
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/Uuid.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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;
+
+@VintfStability
+parcelable Uuid {
+ byte[] uuid;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnss.aidl
index f02e08c..1a69f33 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnss.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnss.aidl
@@ -37,8 +37,8 @@
void setCallback(in android.hardware.gnss.IAGnssCallback callback);
void dataConnClosed();
void dataConnFailed();
- void setServer(in android.hardware.gnss.IAGnssCallback.AGnssType type, in String hostname, in int port);
- void dataConnOpen(in long networkHandle, in String apn, in android.hardware.gnss.IAGnss.ApnIpType apnIpType);
+ void setServer(in android.hardware.gnss.IAGnssCallback.AGnssType type, in @utf8InCpp String hostname, in int port);
+ void dataConnOpen(in long networkHandle, in @utf8InCpp String apn, in android.hardware.gnss.IAGnss.ApnIpType apnIpType);
@Backing(type="int") @VintfStability
enum ApnIpType {
INVALID = 0,
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 3477380..1b4c581 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
@@ -46,7 +46,41 @@
android.hardware.gnss.IAGnss getExtensionAGnss();
android.hardware.gnss.IGnssDebug getExtensionGnssDebug();
android.hardware.gnss.visibility_control.IGnssVisibilityControl getExtensionGnssVisibilityControl();
+ void start();
+ void stop();
+ void injectTime(in long timeMs, in long timeReferenceMs, in int uncertaintyMs);
+ void injectLocation(in android.hardware.gnss.GnssLocation location);
+ void injectBestLocation(in android.hardware.gnss.GnssLocation location);
+ void deleteAidingData(in android.hardware.gnss.IGnss.GnssAidingData aidingDataFlags);
+ void setPositionMode(in android.hardware.gnss.IGnss.GnssPositionMode mode, in android.hardware.gnss.IGnss.GnssPositionRecurrence recurrence, in int minIntervalMs, in int preferredAccuracyMeters, in int preferredTimeMs, in boolean lowPowerMode);
const int ERROR_INVALID_ARGUMENT = 1;
const int ERROR_ALREADY_INIT = 2;
const int ERROR_GENERIC = 3;
+ @Backing(type="int") @VintfStability
+ enum GnssPositionMode {
+ STANDALONE = 0,
+ MS_BASED = 1,
+ MS_ASSISTED = 2,
+ }
+ @Backing(type="int") @VintfStability
+ enum GnssPositionRecurrence {
+ RECURRENCE_PERIODIC = 0,
+ RECURRENCE_SINGLE = 1,
+ }
+ @Backing(type="int") @VintfStability
+ enum GnssAidingData {
+ DELETE_EPHEMERIS = 1,
+ DELETE_ALMANAC = 2,
+ DELETE_POSITION = 4,
+ DELETE_TIME = 8,
+ DELETE_IONO = 16,
+ DELETE_UTC = 32,
+ DELETE_HEALTH = 64,
+ DELETE_SVDIR = 128,
+ DELETE_SVSTEER = 256,
+ DELETE_SADATA = 512,
+ DELETE_RTI = 1024,
+ DELETE_CELLDB_INFO = 32768,
+ DELETE_ALL = 65535,
+ }
}
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 fb0931c..957a75f 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
@@ -35,8 +35,60 @@
@VintfStability
interface IGnssCallback {
void gnssSetCapabilitiesCb(in int capabilities);
+ void gnssStatusCb(in android.hardware.gnss.IGnssCallback.GnssStatusValue status);
+ void gnssSvStatusCb(in android.hardware.gnss.IGnssCallback.GnssSvInfo[] svInfoList);
+ void gnssLocationCb(in android.hardware.gnss.GnssLocation location);
+ void gnssNmeaCb(in long timestamp, in @utf8InCpp String nmea);
+ void gnssAcquireWakelockCb();
+ void gnssReleaseWakelockCb();
+ void gnssSetSystemInfoCb(in android.hardware.gnss.IGnssCallback.GnssSystemInfo info);
+ void gnssRequestTimeCb();
+ void gnssRequestLocationCb(in boolean independentFromGnss, in boolean isUserEmergency);
+ const int CAPABILITY_SCHEDULING = 1;
+ const int CAPABILITY_MSB = 2;
+ const int CAPABILITY_MSA = 4;
+ const int CAPABILITY_SINGLE_SHOT = 8;
+ const int CAPABILITY_ON_DEMAND_TIME = 16;
+ const int CAPABILITY_GEOFENCING = 32;
+ const int CAPABILITY_MEASUREMENTS = 64;
+ const int CAPABILITY_NAV_MESSAGES = 128;
+ const int CAPABILITY_LOW_POWER_MODE = 256;
const int CAPABILITY_SATELLITE_BLOCKLIST = 512;
+ const int CAPABILITY_MEASUREMENT_CORRECTIONS = 1024;
+ const int CAPABILITY_ANTENNA_INFO = 2048;
const int CAPABILITY_CORRELATION_VECTOR = 4096;
const int CAPABILITY_SATELLITE_PVT = 8192;
const int CAPABILITY_MEASUREMENT_CORRECTIONS_FOR_DRIVING = 16384;
+ @Backing(type="int") @VintfStability
+ enum GnssStatusValue {
+ NONE = 0,
+ SESSION_BEGIN = 1,
+ SESSION_END = 2,
+ ENGINE_ON = 3,
+ ENGINE_OFF = 4,
+ }
+ @Backing(type="int") @VintfStability
+ enum GnssSvFlags {
+ NONE = 0,
+ HAS_EPHEMERIS_DATA = 1,
+ HAS_ALMANAC_DATA = 2,
+ USED_IN_FIX = 4,
+ HAS_CARRIER_FREQUENCY = 8,
+ }
+ @VintfStability
+ parcelable GnssSvInfo {
+ int svid;
+ android.hardware.gnss.GnssConstellationType constellation;
+ float cN0Dbhz;
+ float basebandCN0DbHz;
+ float elevationDegrees;
+ float azimuthDegrees;
+ long carrierFrequencyHz;
+ int svFlag;
+ }
+ @VintfStability
+ parcelable GnssSystemInfo {
+ int yearOfHw;
+ @utf8InCpp String name;
+ }
}
diff --git a/gnss/aidl/android/hardware/gnss/IAGnss.aidl b/gnss/aidl/android/hardware/gnss/IAGnss.aidl
index 3e256e2..30b2167 100644
--- a/gnss/aidl/android/hardware/gnss/IAGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IAGnss.aidl
@@ -60,7 +60,7 @@
* @param hostname Hostname of the AGNSS server.
* @param port Port number associated with the server.
*/
- void setServer(in AGnssType type, in String hostname, in int port);
+ void setServer(in AGnssType type, in @utf8InCpp String hostname, in int port);
/**
* Notifies GNSS that a data connection is available and sets the network handle,
@@ -75,5 +75,6 @@
* @param apn Access Point Name (follows regular APN naming convention).
* @param apnIpType Specifies IP type of APN.
*/
- void dataConnOpen(in long networkHandle, in String apn, in ApnIpType apnIpType);
+ void dataConnOpen(
+ in long networkHandle, in @utf8InCpp String apn, in ApnIpType apnIpType);
}
diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl
index 1351f59..4ddc6a6 100644
--- a/gnss/aidl/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl
@@ -16,6 +16,7 @@
package android.hardware.gnss;
+import android.hardware.gnss.GnssLocation;
import android.hardware.gnss.IAGnss;
import android.hardware.gnss.IGnssBatching;
import android.hardware.gnss.IGnssCallback;
@@ -45,6 +46,53 @@
/** Any other error. */
const int ERROR_GENERIC = 3;
+ /** Requested operational mode for GNSS operation. */
+ @VintfStability
+ @Backing(type="int")
+ enum GnssPositionMode {
+ /** Mode for running GNSS standalone (no assistance). */
+ STANDALONE = 0,
+ /** AGNSS MS-Based mode. */
+ MS_BASED = 1,
+ /**
+ * AGNSS MS-Assisted mode. This mode is not maintained by the platform anymore.
+ * It is strongly recommended to use MS_BASED instead.
+ */
+ MS_ASSISTED = 2,
+ }
+
+ /** Requested recurrence mode for GNSS operation. */
+ @VintfStability
+ @Backing(type="int")
+ enum GnssPositionRecurrence {
+ /** Receive GNSS fixes on a recurring basis at a specified period. */
+ RECURRENCE_PERIODIC = 0,
+ /** Request a single shot GNSS fix. */
+ RECURRENCE_SINGLE = 1,
+ }
+
+ /**
+ * Flags used to specify which aiding data to delete when calling
+ * deleteAidingData().
+ */
+ @VintfStability
+ @Backing(type="int")
+ enum GnssAidingData {
+ DELETE_EPHEMERIS = 0x0001,
+ DELETE_ALMANAC = 0x0002,
+ DELETE_POSITION = 0x0004,
+ DELETE_TIME = 0x0008,
+ DELETE_IONO = 0x0010,
+ DELETE_UTC = 0x0020,
+ DELETE_HEALTH = 0x0040,
+ DELETE_SVDIR = 0x0080,
+ DELETE_SVSTEER = 0x0100,
+ DELETE_SADATA = 0x0200,
+ DELETE_RTI = 0x0400,
+ DELETE_CELLDB_INFO = 0x8000,
+ DELETE_ALL = 0xFFFF
+ }
+
/**
* Opens the interface and provides the callback routines to the implementation of this
* interface.
@@ -152,4 +200,81 @@
* @return Handle to the IGnssVisibilityControl.
*/
IGnssVisibilityControl getExtensionGnssVisibilityControl();
+
+ /**
+ * Starts a location output stream using the IGnssCallback gnssLocationCb(), following the
+ * settings from the most recent call to setPositionMode().
+ *
+ * This output must operate independently of any GNSS location batching operations,
+ * see the IGnssBatching for details.
+ */
+ void start();
+
+ /**
+ * Stops the location output stream.
+ */
+ void stop();
+
+ /**
+ * Injects the current time.
+ *
+ * @param timeMs This is the UTC time received from the NTP server, its value is given in
+ * milliseconds since January 1, 1970.
+ * @param timeReferenceMs The corresponding value of SystemClock.elapsedRealtime() from the
+ * device when the NTP response was received in milliseconds.
+ * @param uncertaintyMs Uncertainty associated with the value represented by time. Represented
+ * in milliseconds.
+ */
+ void injectTime(in long timeMs, in long timeReferenceMs, in int uncertaintyMs);
+
+ /**
+ * Injects current location from another (typically network) location provider.
+ *
+ * @param location Current location from the location provider
+ */
+ void injectLocation(in GnssLocation location);
+
+ /**
+ * Injects current location from the best available location provider.
+ *
+ * Unlike injectLocation, this method may inject a recent GNSS location from the HAL
+ * implementation, if that is the best available location known to the framework.
+ *
+ * @param location Location information from the best available location provider.
+ */
+ void injectBestLocation(in GnssLocation location);
+
+ /**
+ * Specifies that the next call to start will not use the information defined in the flags.
+ * GnssAidingData value of DELETE_ALL is passed for a cold start.
+ *
+ * @param aidingDataFlags Flags specifying the aiding data to be deleted.
+ */
+ void deleteAidingData(in GnssAidingData aidingDataFlags);
+
+ /**
+ * Sets the GnssPositionMode parameter, its associated recurrence value, the time between fixes,
+ * requested fix accuracy, time to first fix.
+ *
+ * @param mode Parameter must be one of MS_BASED or STANDALONE. It is allowed by the platform
+ * (and it is recommended) to fallback to MS_BASED if MS_ASSISTED is passed in, and MS_BASED
+ * is supported.
+ * @param recurrence GNSS position recurrence value, either periodic or single.
+ * @param minIntervalMs Represents the time between fixes in milliseconds.
+ * @param preferredAccuracyMeters Represents the requested fix accuracy in meters.
+ * @param preferredTimeMs Represents the requested time to first fix in milliseconds.
+ * @param lowPowerMode When true, and IGnss is the only client to the GNSS hardware, the GNSS
+ * hardware must make strong tradeoffs to substantially restrict power use. Specifically, in
+ * the case of a several second long minIntervalMs, the GNSS hardware must not, on average,
+ * run power hungry operations like RF and signal searches for more than one second per
+ * interval, and must make exactly one call to gnssSvStatusCb(), and either zero or one call
+ * to GnssLocationCb() at each interval. When false, HAL must operate in the nominal mode
+ * and is expected to make power and performance tradoffs such as duty-cycling when signal
+ * conditions are good and more active searches to reacquire GNSS signals when no signals
+ * are present. When there are additional clients using the GNSS hardware other than IGnss,
+ * the GNSS hardware may operate in a higher power mode, on behalf of those clients.
+ */
+ void setPositionMode(in GnssPositionMode mode, in GnssPositionRecurrence recurrence,
+ in int minIntervalMs, in int preferredAccuracyMeters, in int preferredTimeMs,
+ in boolean lowPowerMode);
}
diff --git a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
index aad09ef..157c912 100644
--- a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
@@ -16,6 +16,8 @@
package android.hardware.gnss;
+import android.hardware.gnss.GnssConstellationType;
+import android.hardware.gnss.GnssLocation;
import android.hardware.gnss.IGnssConfiguration;
import android.hardware.gnss.IGnssPsds;
@@ -26,9 +28,48 @@
*/
@VintfStability
interface IGnssCallback {
+ /**
+ * Capability bit mask indicating that GNSS supports scheduling fixes for RECURRENCE_PERIODIC
+ * mode.
+ *
+ * If this is not set, then the framework will use 1000ms for minInterval and will call start()
+ * and stop() to schedule the GNSS.
+ */
+ const int CAPABILITY_SCHEDULING = 1 << 0;
+
+ /** Capability bit mask indicating that GNSS supports MS-Based AGNSS mode */
+ const int CAPABILITY_MSB = 1 << 1;
+
+ /** Capability bit mask indicating that GNSS supports MS-Assisted AGNSS mode */
+ const int CAPABILITY_MSA = 1 << 2;
+
+ /** Capability bit mask indicating that GNSS supports single-shot fixes */
+ const int CAPABILITY_SINGLE_SHOT = 1 << 3;
+
+ /** Capability bit mask indicating that GNSS supports on demand time injection */
+ const int CAPABILITY_ON_DEMAND_TIME = 1 << 4;
+
+ /** Capability bit mask indicating that GNSS supports Geofencing */
+ const int CAPABILITY_GEOFENCING = 1 << 5;
+
+ /** Capability bit mask indicating that GNSS supports Measurements. */
+ const int CAPABILITY_MEASUREMENTS = 1 << 6;
+
+ /** Capability bit mask indicating that GNSS supports Navigation Messages */
+ const int CAPABILITY_NAV_MESSAGES = 1 << 7;
+
+ /** Capability bit mask indicating that GNSS supports low power mode */
+ const int CAPABILITY_LOW_POWER_MODE = 1 << 8;
+
/** Capability bit mask indicating that GNSS supports blocklisting satellites */
const int CAPABILITY_SATELLITE_BLOCKLIST = 1 << 9;
+ /** Capability bit mask indicating that GNSS supports measurement corrections */
+ const int CAPABILITY_MEASUREMENT_CORRECTIONS = 1 << 10;
+
+ /** Capability bit mask indicating that GNSS supports measurement corrections */
+ const int CAPABILITY_ANTENNA_INFO = 1 << 11;
+
/** Capability bit mask indicating that GNSS supports correlation vector */
const int CAPABILITY_CORRELATION_VECTOR = 1 << 12;
@@ -44,4 +85,221 @@
* @param capabilities Capability parameter is a bit field of the Capability bit masks.
*/
void gnssSetCapabilitiesCb(in int capabilities);
+
+ /** GNSS status event values. */
+ @VintfStability
+ @Backing(type="int")
+ enum GnssStatusValue {
+ /** GNSS status unknown. */
+ NONE = 0,
+ /** GNSS has begun navigating. */
+ SESSION_BEGIN = 1,
+ /** GNSS has stopped navigating. */
+ SESSION_END = 2,
+ /** GNSS has powered on but is not navigating. */
+ ENGINE_ON = 3,
+ /** GNSS is powered off. */
+ ENGINE_OFF = 4
+ }
+
+ /**
+ * Flags that indicate information about the satellite
+ */
+ @VintfStability
+ @Backing(type="int")
+ enum GnssSvFlags {
+ NONE = 0,
+ HAS_EPHEMERIS_DATA = 1 << 0,
+ HAS_ALMANAC_DATA = 1 << 1,
+ USED_IN_FIX = 1 << 2,
+ HAS_CARRIER_FREQUENCY = 1 << 3,
+ }
+
+ @VintfStability
+ parcelable GnssSvInfo {
+ /**
+ * Pseudo-random or satellite ID number for the satellite, a.k.a. Space Vehicle (SV), or
+ * FCN/OSN number for Glonass. The distinction is made by looking at constellation field.
+ * Values must be in the range of:
+ *
+ * - GNSS: 1-32
+ * - SBAS: 120-151, 183-192
+ * - GLONASS: 1-24, the orbital slot number (OSN), if known. Or, if not:
+ * 93-106, the frequency channel number (FCN) (-7 to +6) offset by
+ * + 100
+ * i.e. report an FCN of -7 as 93, FCN of 0 as 100, and FCN of +6
+ * as 106.
+ * - QZSS: 193-200
+ * - Galileo: 1-36
+ * - Beidou: 1-37
+ * - IRNSS: 1-14
+ */
+ int svid;
+
+ /**
+ * Defines the constellation of the given SV.
+ */
+ GnssConstellationType constellation;
+
+ /**
+ * Carrier-to-noise density in dB-Hz, typically in the range [0, 63].
+ * It contains the measured C/N0 value for the signal at the antenna port.
+ *
+ * This is a mandatory field.
+ */
+ float cN0Dbhz;
+
+ /**
+ * Baseband Carrier-to-noise density in dB-Hz, typically in the range [0, 63]. It contains
+ * the measured C/N0 value for the signal measured at the baseband.
+ *
+ * This is typically a few dB weaker than the value estimated for C/N0 at the antenna port,
+ * which is reported in cN0DbHz.
+ *
+ * If a signal has separate components (e.g. Pilot and Data channels) and the receiver only
+ * processes one of the components, then the reported basebandCN0DbHz reflects only the
+ * component that is processed.
+ *
+ * This field is mandatory. Like cN0DbHz, it may be reported as 0 for satellites being
+ * reported that may be searched for, but not yet tracked.
+ */
+ float basebandCN0DbHz;
+
+ /** Elevation of SV in degrees. */
+ float elevationDegrees;
+
+ /** Azimuth of SV in degrees. */
+ float azimuthDegrees;
+
+ /**
+ * Carrier frequency of the signal tracked, for example it can be the
+ * GPS central frequency for L1 = 1575.45 MHz, or L2 = 1227.60 MHz, L5 =
+ * 1176.45 MHz, varying GLO channels, etc. If the field is zero, it is
+ * the primary common use central frequency, e.g. L1 = 1575.45 MHz for
+ * GPS.
+ *
+ * For an L1, L5 receiver tracking a satellite on L1 and L5 at the same
+ * time, two GnssSvInfo structs must be reported for this same
+ * satellite, in one of the structs, all the values related
+ * to L1 must be filled, and in the other all of the values related to
+ * L5 must be filled.
+ *
+ * If the data is available, svFlag must contain HAS_CARRIER_FREQUENCY.
+ */
+ long carrierFrequencyHz;
+
+ /** A bit field of the GnssSvFlags. */
+ int svFlag;
+ }
+
+ /**
+ * Called to communicate the status of the GNSS engine.
+ *
+ * @param status Status information from HAL.
+ */
+ void gnssStatusCb(in GnssStatusValue status);
+
+ /**
+ * Callback for the HAL to pass a vector of GnssSvInfo back to the client.
+ *
+ * @param svInfo SV status information from HAL.
+ */
+ void gnssSvStatusCb(in GnssSvInfo[] svInfoList);
+
+ /**
+ * Called when a GNSS location is available.
+ *
+ * @param location Location information from HAL.
+ */
+ void gnssLocationCb(in GnssLocation location);
+
+ /**
+ * Callback for reporting NMEA sentences. Called when NMEA data is available.
+ *
+ * @param timestamp Marks the instance of reporting.
+ * @param nmea Follows standard NMEA 0183. Each sentence begins with a '$'
+ * and ends with a carriage return/line feed sequence and can be no longer
+ * than 80 characters of visible text (plus the line terminators). The data
+ * is contained within this single line with data items separated by commas.
+ * The data itself is just ascii text and may extend over multiple sentences
+ * in certain specialized instances but is normally fully contained in one
+ * variable length sentence. The data may vary in the amount of precision
+ * contained in the message. For example time might be indicated to decimal
+ * parts of a second or location may be shown with 3 or even 4 digits after
+ * the decimal point. Programs that read the data must only use the commas
+ * to determine the field boundaries and not depend on column positions.
+ * There is a provision for a checksum at the end of each sentence which may
+ * or may not be checked by the unit that reads the data. The checksum field
+ * consists of a '*' and two hex digits representing an 8 bit exclusive OR
+ * of all characters between, but not including, the '$' and '*'.
+ */
+ void gnssNmeaCb(in long timestamp, in @utf8InCpp String nmea);
+
+ /**
+ * Callback utility for acquiring the GNSS wakelock. This can be used to prevent
+ * the CPU from suspending while handling GNSS events.
+ */
+ void gnssAcquireWakelockCb();
+
+ /** Callback utility for releasing the GNSS wakelock. */
+ void gnssReleaseWakelockCb();
+
+ /**
+ * Provides information about how new the underlying GPS/GNSS hardware and software is.
+ */
+ @VintfStability
+ parcelable GnssSystemInfo {
+ /**
+ * The year in which the last update was made to the underlying hardware/firmware used to
+ * capture GNSS signals, e.g. 2016.
+ */
+ int yearOfHw;
+
+ /**
+ * The name of the GNSS HAL implementation model and version name.
+ *
+ * This is a user-visible string that identifies the model and version of the GNSS HAL.
+ * For example "ABC Co., Baseband Part 1234, RF Part 567, Software version 3.14.159"
+ *
+ * For privacy reasons, this string must not contain any device-specific serial number or
+ * other identifier that uniquely identifies an individual device.
+ */
+ @utf8InCpp String name;
+ }
+
+ /**
+ * Callback to inform the framework of the GNSS system information.
+ *
+ * This must be called in response to IGnss::setCallback
+ *
+ * @param info GnssSystemInfo about the GPS/GNSS hardware.
+ */
+ void gnssSetSystemInfoCb(in GnssSystemInfo info);
+
+ /** Callback for requesting NTP time */
+ void gnssRequestTimeCb();
+
+ /**
+ * Callback for requesting Location.
+ *
+ * HAL implementation must call this when it wants the framework to provide locations to assist
+ * with GNSS HAL operation, for example, to assist with time to first fix, error recovery, or to
+ * supplement GNSS location for other clients of the GNSS HAL.
+ *
+ * If a request is made with independentFromGnss set to true, the framework must avoid
+ * providing locations derived from GNSS locations (such as "fused" location), to help improve
+ * information independence for situations such as error recovery.
+ *
+ * In response to this method call, GNSS HAL can expect zero, one, or more calls to
+ * IGnss::injectLocation or IGnss::injectBestLocation, dependent on availability of location
+ * from other sources, which may happen at some arbitrary delay. Generally speaking, HAL
+ * implementations must be able to handle calls to IGnss::injectLocation or
+ * IGnss::injectBestLocation at any time.
+ *
+ * @param independentFromGnss True if requesting a location that is independent from GNSS.
+ * @param isUserEmergency True if the location request is for delivery of this location to an
+ * emergency services endpoint, during a user-initiated emergency session (e.g.
+ * during-call to E911, or up to 5 minutes after end-of-call or text to E911).
+ */
+ void gnssRequestLocationCb(in boolean independentFromGnss, in boolean isUserEmergency);
}
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index afb7b95..e296351 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "GnssAidl"
#include "Gnss.h"
+#include <inttypes.h>
#include <log/log.h>
#include "AGnss.h"
#include "GnssBatching.h"
@@ -27,16 +28,24 @@
#include "GnssNavigationMessageInterface.h"
#include "GnssPsds.h"
#include "GnssVisibilityControl.h"
+#include "Utils.h"
namespace aidl::android::hardware::gnss {
+using ::android::hardware::gnss::common::Utils;
+using ndk::ScopedAStatus;
+using GnssSvInfo = IGnssCallback::GnssSvInfo;
+
+constexpr int TTFF_MILLIS = 2200;
std::shared_ptr<IGnssCallback> Gnss::sGnssCallback = nullptr;
-ndk::ScopedAStatus Gnss::setCallback(const std::shared_ptr<IGnssCallback>& callback) {
- ALOGD("Gnss::setCallback");
+Gnss::Gnss() : mMinIntervalMs(1000), mFirstFixReceived(false) {}
+
+ScopedAStatus Gnss::setCallback(const std::shared_ptr<IGnssCallback>& callback) {
+ ALOGD("setCallback");
if (callback == nullptr) {
ALOGE("%s: Null callback ignored", __func__);
- return ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+ return ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
}
sGnssCallback = callback;
@@ -50,13 +59,99 @@
ALOGE("%s: Unable to invoke callback.gnssSetCapabilities", __func__);
}
- return ndk::ScopedAStatus::ok();
+ return ScopedAStatus::ok();
}
-ndk::ScopedAStatus Gnss::close() {
- ALOGD("Gnss::close");
+ScopedAStatus Gnss::start() {
+ ALOGD("start()");
+ if (mIsActive) {
+ ALOGW("Gnss has started. Restarting...");
+ stop();
+ }
+
+ mIsActive = true;
+ this->reportGnssStatusValue(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
+ mThread = std::thread([this]() {
+ auto svStatus = filterBlocklistedSatellites(Utils::getMockSvInfoList());
+ this->reportSvStatus(svStatus);
+ if (!mFirstFixReceived) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(TTFF_MILLIS));
+ mFirstFixReceived = true;
+ }
+ while (mIsActive == true) {
+ auto svStatus = filterBlocklistedSatellites(Utils::getMockSvInfoList());
+ this->reportSvStatus(svStatus);
+
+ mGnssPowerIndication->notePowerConsumption();
+ const auto location = Utils::getMockLocation();
+ this->reportLocation(location);
+ std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
+ }
+ });
+ return ScopedAStatus::ok();
+}
+
+void Gnss::reportLocation(const GnssLocation& location) const {
+ std::unique_lock<std::mutex> lock(mMutex);
+ if (sGnssCallback == nullptr) {
+ ALOGE("%s: GnssCallback is null.", __func__);
+ return;
+ }
+ auto status = sGnssCallback->gnssLocationCb(location);
+ if (!status.isOk()) {
+ ALOGE("%s: Unable to invoke gnssLocationCb", __func__);
+ }
+ return;
+}
+
+void Gnss::reportSvStatus(const std::vector<GnssSvInfo>& svInfoList) const {
+ std::unique_lock<std::mutex> lock(mMutex);
+ if (sGnssCallback == nullptr) {
+ ALOGE("%s: sGnssCallback is null.", __func__);
+ return;
+ }
+ auto status = sGnssCallback->gnssSvStatusCb(svInfoList);
+ if (!status.isOk()) {
+ ALOGE("%s: Unable to invoke callback", __func__);
+ }
+}
+
+std::vector<GnssSvInfo> Gnss::filterBlocklistedSatellites(std::vector<GnssSvInfo> gnssSvInfoList) {
+ ALOGD("filterBlocklistedSatellites");
+ for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) {
+ if (mGnssConfiguration->isBlocklisted(gnssSvInfoList[i])) {
+ gnssSvInfoList[i].svFlag &= ~(uint32_t)IGnssCallback::GnssSvFlags::USED_IN_FIX;
+ }
+ }
+ return gnssSvInfoList;
+}
+
+void Gnss::reportGnssStatusValue(const IGnssCallback::GnssStatusValue gnssStatusValue) const {
+ std::unique_lock<std::mutex> lock(mMutex);
+ if (sGnssCallback == nullptr) {
+ ALOGE("%s: sGnssCallback is null.", __func__);
+ return;
+ }
+ auto status = sGnssCallback->gnssStatusCb(gnssStatusValue);
+ if (!status.isOk()) {
+ ALOGE("%s: Unable to invoke gnssStatusCb", __func__);
+ }
+}
+
+ScopedAStatus Gnss::stop() {
+ ALOGD("stop");
+ mIsActive = false;
+ this->reportGnssStatusValue(IGnssCallback::GnssStatusValue::SESSION_END);
+ if (mThread.joinable()) {
+ mThread.join();
+ }
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus Gnss::close() {
+ ALOGD("close");
sGnssCallback = nullptr;
- return ndk::ScopedAStatus::ok();
+ return ScopedAStatus::ok();
}
ndk::ScopedAStatus Gnss::getExtensionAGnss(std::shared_ptr<IAGnss>* iAGnss) {
@@ -65,61 +160,93 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus Gnss::getExtensionPsds(std::shared_ptr<IGnssPsds>* iGnssPsds) {
- ALOGD("Gnss::getExtensionPsds");
- *iGnssPsds = SharedRefBase::make<GnssPsds>();
- return ndk::ScopedAStatus::ok();
+ScopedAStatus Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs, int uncertaintyMs) {
+ ALOGD("injectTime. timeMs:%" PRId64 ", timeReferenceMs:%" PRId64 ", uncertaintyMs:%d", timeMs,
+ timeReferenceMs, uncertaintyMs);
+ return ScopedAStatus::ok();
}
-ndk::ScopedAStatus Gnss::getExtensionGnssConfiguration(
+ScopedAStatus Gnss::injectLocation(const GnssLocation& location) {
+ ALOGD("injectLocation. lat:%lf, lng:%lf, acc:%f", location.latitudeDegrees,
+ location.longitudeDegrees, location.horizontalAccuracyMeters);
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus Gnss::injectBestLocation(const GnssLocation& location) {
+ ALOGD("injectBestLocation. lat:%lf, lng:%lf, acc:%f", location.latitudeDegrees,
+ location.longitudeDegrees, location.horizontalAccuracyMeters);
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus Gnss::deleteAidingData(GnssAidingData aidingDataFlags) {
+ ALOGD("deleteAidingData. flags:%d", (int)aidingDataFlags);
+ mFirstFixReceived = false;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus Gnss::setPositionMode(GnssPositionMode, GnssPositionRecurrence, int minIntervalMs,
+ int /* preferredAccuracyMeters */, int /* preferredTimeMs */,
+ bool lowPowerMode) {
+ ALOGD("setPositionMode. minIntervalMs:%d, lowPowerMode:%d", minIntervalMs, (int)lowPowerMode);
+ mMinIntervalMs = minIntervalMs;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus Gnss::getExtensionPsds(std::shared_ptr<IGnssPsds>* iGnssPsds) {
+ ALOGD("getExtensionPsds");
+ *iGnssPsds = SharedRefBase::make<GnssPsds>();
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus Gnss::getExtensionGnssConfiguration(
std::shared_ptr<IGnssConfiguration>* iGnssConfiguration) {
- ALOGD("Gnss::getExtensionGnssConfiguration");
+ ALOGD("getExtensionGnssConfiguration");
if (mGnssConfiguration == nullptr) {
mGnssConfiguration = SharedRefBase::make<GnssConfiguration>();
}
*iGnssConfiguration = mGnssConfiguration;
- return ndk::ScopedAStatus::ok();
+ return ScopedAStatus::ok();
}
-ndk::ScopedAStatus Gnss::getExtensionGnssPowerIndication(
+ScopedAStatus Gnss::getExtensionGnssPowerIndication(
std::shared_ptr<IGnssPowerIndication>* iGnssPowerIndication) {
- ALOGD("Gnss::getExtensionGnssPowerIndication");
+ ALOGD("getExtensionGnssPowerIndication");
if (mGnssPowerIndication == nullptr) {
mGnssPowerIndication = SharedRefBase::make<GnssPowerIndication>();
}
*iGnssPowerIndication = mGnssPowerIndication;
- return ndk::ScopedAStatus::ok();
+ return ScopedAStatus::ok();
}
-ndk::ScopedAStatus Gnss::getExtensionGnssMeasurement(
+ScopedAStatus Gnss::getExtensionGnssMeasurement(
std::shared_ptr<IGnssMeasurementInterface>* iGnssMeasurement) {
- ALOGD("Gnss::getExtensionGnssMeasurement");
+ ALOGD("getExtensionGnssMeasurement");
*iGnssMeasurement = SharedRefBase::make<GnssMeasurementInterface>();
- return ndk::ScopedAStatus::ok();
+ return ScopedAStatus::ok();
}
-ndk::ScopedAStatus Gnss::getExtensionGnssBatching(std::shared_ptr<IGnssBatching>* iGnssBatching) {
- ALOGD("Gnss::getExtensionGnssBatching");
+ScopedAStatus Gnss::getExtensionGnssBatching(std::shared_ptr<IGnssBatching>* iGnssBatching) {
+ ALOGD("getExtensionGnssBatching");
*iGnssBatching = SharedRefBase::make<GnssBatching>();
- return ndk::ScopedAStatus::ok();
+ return ScopedAStatus::ok();
}
-ndk::ScopedAStatus Gnss::getExtensionGnssGeofence(std::shared_ptr<IGnssGeofence>* iGnssGeofence) {
- ALOGD("Gnss::getExtensionGnssGeofence");
+ScopedAStatus Gnss::getExtensionGnssGeofence(std::shared_ptr<IGnssGeofence>* iGnssGeofence) {
+ ALOGD("getExtensionGnssGeofence");
*iGnssGeofence = SharedRefBase::make<GnssGeofence>();
- return ndk::ScopedAStatus::ok();
+ return ScopedAStatus::ok();
}
-ndk::ScopedAStatus Gnss::getExtensionGnssNavigationMessage(
+ScopedAStatus Gnss::getExtensionGnssNavigationMessage(
std::shared_ptr<IGnssNavigationMessageInterface>* iGnssNavigationMessage) {
- ALOGD("Gnss::getExtensionGnssNavigationMessage");
+ ALOGD("getExtensionGnssNavigationMessage");
*iGnssNavigationMessage = SharedRefBase::make<GnssNavigationMessageInterface>();
- return ndk::ScopedAStatus::ok();
+ return ScopedAStatus::ok();
}
ndk::ScopedAStatus Gnss::getExtensionGnssDebug(std::shared_ptr<IGnssDebug>* iGnssDebug) {
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
index 67fef94..384c862 100644
--- a/gnss/aidl/default/Gnss.h
+++ b/gnss/aidl/default/Gnss.h
@@ -25,6 +25,9 @@
#include <aidl/android/hardware/gnss/BnGnssPowerIndication.h>
#include <aidl/android/hardware/gnss/BnGnssPsds.h>
#include <aidl/android/hardware/gnss/visibility_control/BnGnssVisibilityControl.h>
+#include <atomic>
+#include <mutex>
+#include <thread>
#include "GnssConfiguration.h"
#include "GnssPowerIndication.h"
@@ -32,8 +35,22 @@
class Gnss : public BnGnss {
public:
+ Gnss();
+ ~Gnss() { stop(); };
ndk::ScopedAStatus setCallback(const std::shared_ptr<IGnssCallback>& callback) override;
+ ndk::ScopedAStatus start() override;
+ ndk::ScopedAStatus stop() override;
ndk::ScopedAStatus close() override;
+
+ ndk::ScopedAStatus injectTime(int64_t timeMs, int64_t timeReferenceMs,
+ int uncertaintyMs) override;
+ ndk::ScopedAStatus injectLocation(const GnssLocation& location) override;
+ ndk::ScopedAStatus injectBestLocation(const GnssLocation& location) override;
+ ndk::ScopedAStatus deleteAidingData(GnssAidingData aidingDataFlags) override;
+ ndk::ScopedAStatus setPositionMode(GnssPositionMode mode, GnssPositionRecurrence recurrence,
+ int minIntervalMs, int preferredAccuracyMeters,
+ int preferredTimeMs, bool lowPowerMode) override;
+
ndk::ScopedAStatus getExtensionPsds(std::shared_ptr<IGnssPsds>* iGnssPsds) override;
ndk::ScopedAStatus getExtensionGnssConfiguration(
std::shared_ptr<IGnssConfiguration>* iGnssConfiguration) override;
@@ -57,7 +74,20 @@
std::shared_ptr<GnssPowerIndication> mGnssPowerIndication;
private:
+ void reportLocation(const GnssLocation&) const;
+ void reportSvStatus(const std::vector<IGnssCallback::GnssSvInfo>& svInfoList) const;
+ std::vector<IGnssCallback::GnssSvInfo> filterBlocklistedSatellites(
+ std::vector<IGnssCallback::GnssSvInfo> gnssSvInfoList);
+ void reportGnssStatusValue(const IGnssCallback::GnssStatusValue gnssStatusValue) const;
+
static std::shared_ptr<IGnssCallback> sGnssCallback;
+
+ std::atomic<long> mMinIntervalMs;
+ std::atomic<bool> mIsActive;
+ std::atomic<bool> mFirstFixReceived;
+ std::thread mThread;
+
+ mutable std::mutex mMutex;
};
} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssConfiguration.cpp b/gnss/aidl/default/GnssConfiguration.cpp
index 30e0d8c..96a1aa2 100644
--- a/gnss/aidl/default/GnssConfiguration.cpp
+++ b/gnss/aidl/default/GnssConfiguration.cpp
@@ -49,4 +49,14 @@
return (mBlocklistedSourceSet.find(source) != mBlocklistedSourceSet.end());
}
+bool GnssConfiguration::isBlocklisted(const IGnssCallback::GnssSvInfo& gnssSvInfo) const {
+ std::unique_lock<std::recursive_mutex> lock(mMutex);
+ if (mBlocklistedConstellationSet.find(gnssSvInfo.constellation) !=
+ mBlocklistedConstellationSet.end()) {
+ return true;
+ }
+ BlocklistedSource source = {.constellation = gnssSvInfo.constellation, .svid = gnssSvInfo.svid};
+ return (mBlocklistedSourceSet.find(source) != mBlocklistedSourceSet.end());
+}
+
} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssConfiguration.h b/gnss/aidl/default/GnssConfiguration.h
index 491733c..3c77f32 100644
--- a/gnss/aidl/default/GnssConfiguration.h
+++ b/gnss/aidl/default/GnssConfiguration.h
@@ -16,6 +16,7 @@
#pragma once
+#include <aidl/android/hardware/gnss/BnGnssCallback.h>
#include <aidl/android/hardware/gnss/BnGnssConfiguration.h>
#include <android/hardware/gnss/2.1/IGnssCallback.h>
#include <mutex>
@@ -62,6 +63,7 @@
ndk::ScopedAStatus setBlocklist(const vector<BlocklistedSource>& blocklist) override;
bool isBlocklistedV2_1(const GnssSvInfoV2_1& gnssSvInfo) const;
+ bool isBlocklisted(const IGnssCallback::GnssSvInfo& gnssSvInfo) const;
private:
BlocklistedSourceSet mBlocklistedSourceSet;
diff --git a/gnss/aidl/vts/GnssBatchingCallback.cpp b/gnss/aidl/vts/GnssBatchingCallback.cpp
index 2da3b12..d4eb0a5 100644
--- a/gnss/aidl/vts/GnssBatchingCallback.cpp
+++ b/gnss/aidl/vts/GnssBatchingCallback.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#define LOG_TAG "GnssBatchingCallbackAidl"
+
#include "GnssBatchingCallback.h"
#include <inttypes.h>
#include <log/log.h>
diff --git a/gnss/aidl/vts/GnssCallbackAidl.cpp b/gnss/aidl/vts/GnssCallbackAidl.cpp
index f5c745b..77a2506 100644
--- a/gnss/aidl/vts/GnssCallbackAidl.cpp
+++ b/gnss/aidl/vts/GnssCallbackAidl.cpp
@@ -14,11 +14,62 @@
* limitations under the License.
*/
+#define LOG_TAG "GnssCallbackAidl"
+
#include "GnssCallbackAidl.h"
#include <log/log.h>
-android::binder::Status GnssCallbackAidl::gnssSetCapabilitiesCb(const int capabilities) {
- ALOGI("Capabilities received %d", capabilities);
+using android::binder::Status;
+using android::hardware::gnss::GnssLocation;
+using GnssSvInfo = android::hardware::gnss::IGnssCallback::GnssSvInfo;
+using GnssSystemInfo = android::hardware::gnss::IGnssCallback::GnssSystemInfo;
+
+Status GnssCallbackAidl::gnssSetCapabilitiesCb(const int capabilities) {
+ ALOGI("Capabilities received %#08x", capabilities);
capabilities_cbq_.store(capabilities);
- return android::binder::Status::ok();
+ return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssStatusCb(const GnssStatusValue /* status */) {
+ ALOGI("gnssSvStatusCb");
+ return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssSvStatusCb(const std::vector<GnssSvInfo>& svInfoList) {
+ ALOGI("gnssSvStatusCb. Size = %d", (int)svInfoList.size());
+ sv_info_list_cbq_.store(svInfoList);
+ return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssLocationCb(const GnssLocation& location) {
+ ALOGI("Location received");
+ location_cbq_.store(location);
+ return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssNmeaCb(const int64_t /* timestamp */, const std::string& /* nmea */) {
+ return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssAcquireWakelockCb() {
+ return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssReleaseWakelockCb() {
+ return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssSetSystemInfoCb(const GnssSystemInfo& info) {
+ ALOGI("gnssSetSystemInfoCb, year=%d, name=%s", info.yearOfHw, info.name.c_str());
+ info_cbq_.store(info);
+ return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssRequestTimeCb() {
+ return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssRequestLocationCb(const bool /* independentFromGnss */,
+ const bool /* isUserEmergency */) {
+ return Status::ok();
}
diff --git a/gnss/aidl/vts/GnssCallbackAidl.h b/gnss/aidl/vts/GnssCallbackAidl.h
index 7f802ea..209728d 100644
--- a/gnss/aidl/vts/GnssCallbackAidl.h
+++ b/gnss/aidl/vts/GnssCallbackAidl.h
@@ -22,11 +22,37 @@
/* Callback class for data & Event. */
class GnssCallbackAidl : public android::hardware::gnss::BnGnssCallback {
public:
- GnssCallbackAidl() : capabilities_cbq_("capabilities"){};
+ GnssCallbackAidl()
+ : capabilities_cbq_("capabilities"),
+ info_cbq_("system_info"),
+ location_cbq_("location"),
+ sv_info_list_cbq_("sv_info"){};
~GnssCallbackAidl(){};
android::binder::Status gnssSetCapabilitiesCb(const int capabilities) override;
+ android::binder::Status gnssStatusCb(const GnssStatusValue status) override;
+ android::binder::Status gnssSvStatusCb(const std::vector<GnssSvInfo>& svInfoList) override;
+ android::binder::Status gnssLocationCb(
+ const android::hardware::gnss::GnssLocation& location) override;
+ android::binder::Status gnssNmeaCb(const int64_t timestamp, const std::string& nmea) override;
+ android::binder::Status gnssAcquireWakelockCb() override;
+ android::binder::Status gnssReleaseWakelockCb() override;
+ android::binder::Status gnssSetSystemInfoCb(const GnssSystemInfo& info) override;
+ android::binder::Status gnssRequestTimeCb() override;
+ android::binder::Status gnssRequestLocationCb(const bool independentFromGnss,
+ const bool isUserEmergency) override;
int last_capabilities_;
+ android::hardware::gnss::IGnssCallback::GnssSystemInfo last_info_;
+ android::hardware::gnss::GnssLocation last_location_;
+
android::hardware::gnss::common::GnssCallbackEventQueue<int> capabilities_cbq_;
+ android::hardware::gnss::common::GnssCallbackEventQueue<
+ android::hardware::gnss::IGnssCallback::GnssSystemInfo>
+ info_cbq_;
+ android::hardware::gnss::common::GnssCallbackEventQueue<android::hardware::gnss::GnssLocation>
+ location_cbq_;
+ android::hardware::gnss::common::GnssCallbackEventQueue<
+ std::vector<android::hardware::gnss::IGnssCallback::GnssSvInfo>>
+ sv_info_list_cbq_;
};
\ No newline at end of file
diff --git a/gnss/aidl/vts/gnss_hal_test.cpp b/gnss/aidl/vts/gnss_hal_test.cpp
index 2447bf8..13c32ee 100644
--- a/gnss/aidl/vts/gnss_hal_test.cpp
+++ b/gnss/aidl/vts/gnss_hal_test.cpp
@@ -14,20 +14,31 @@
* limitations under the License.
*/
+#define LOG_TAG "GnssHalTest"
+
#include "gnss_hal_test.h"
#include <hidl/ServiceManagement.h>
+#include "Utils.h"
-using GnssConstellationTypeAidl = android::hardware::gnss::GnssConstellationType;
+using android::hardware::gnss::GnssConstellationType;
+using android::hardware::gnss::GnssLocation;
+using android::hardware::gnss::IGnss;
+using android::hardware::gnss::IGnssCallback;
+using android::hardware::gnss::common::Utils;
+using GnssConstellationTypeV2_0 = android::hardware::gnss::V2_0::GnssConstellationType;
void GnssHalTest::SetUp() {
// Get AIDL handle
aidl_gnss_hal_ = android::waitForDeclaredService<IGnssAidl>(String16(GetParam().c_str()));
ASSERT_NE(aidl_gnss_hal_, nullptr);
+ ALOGD("AIDL Interface Version = %d", aidl_gnss_hal_->getInterfaceVersion());
- const auto& hidlInstanceNames = android::hardware::getAllHalInstanceNames(
- android::hardware::gnss::V2_1::IGnss::descriptor);
- gnss_hal_ = IGnss_V2_1::getService(hidlInstanceNames[0]);
- ASSERT_NE(gnss_hal_, nullptr);
+ if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+ const auto& hidlInstanceNames = android::hardware::getAllHalInstanceNames(
+ android::hardware::gnss::V2_1::IGnss::descriptor);
+ gnss_hal_ = IGnss_V2_1::getService(hidlInstanceNames[0]);
+ ASSERT_NE(gnss_hal_, nullptr);
+ }
SetUpGnssCallback();
}
@@ -40,7 +51,6 @@
if (!status.isOk()) {
ALOGE("Failed to setCallback");
}
-
ASSERT_TRUE(status.isOk());
/*
@@ -48,9 +58,243 @@
*/
EXPECT_TRUE(aidl_gnss_cb_->capabilities_cbq_.retrieve(aidl_gnss_cb_->last_capabilities_,
TIMEOUT_SEC));
-
EXPECT_EQ(aidl_gnss_cb_->capabilities_cbq_.calledCount(), 1);
- // Invoke the super method.
- GnssHalTestTemplate<IGnss_V2_1>::SetUpGnssCallback();
+ if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+ // Invoke the super method.
+ GnssHalTestTemplate<IGnss_V2_1>::SetUpGnssCallback();
+ }
+}
+
+void GnssHalTest::CheckLocation(const GnssLocation& location, bool check_speed) {
+ Utils::checkLocation(location, check_speed, /* check_more_accuracies= */ true);
+}
+
+void GnssHalTest::SetPositionMode(const int min_interval_msec, const bool low_power_mode) {
+ if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+ // Invoke the super method.
+ return GnssHalTestTemplate<IGnss_V2_1>::SetPositionMode(min_interval_msec, low_power_mode);
+ }
+
+ const int kPreferredAccuracy = 0; // Ideally perfect (matches GnssLocationProvider)
+ const int kPreferredTimeMsec = 0; // Ideally immediate
+
+ auto status = aidl_gnss_hal_->setPositionMode(
+ IGnss::GnssPositionMode::MS_BASED, IGnss::GnssPositionRecurrence::RECURRENCE_PERIODIC,
+ min_interval_msec, kPreferredAccuracy, kPreferredTimeMsec, low_power_mode);
+
+ ASSERT_TRUE(status.isOk());
+}
+
+bool GnssHalTest::StartAndCheckFirstLocation(const int min_interval_msec,
+ const bool low_power_mode) {
+ if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+ // Invoke the super method.
+ return GnssHalTestTemplate<IGnss_V2_1>::StartAndCheckFirstLocation(min_interval_msec,
+ low_power_mode);
+ }
+
+ SetPositionMode(min_interval_msec, low_power_mode);
+ auto result = aidl_gnss_hal_->start();
+
+ EXPECT_TRUE(result.isOk());
+
+ /*
+ * GnssLocationProvider support of AGPS SUPL & XtraDownloader is not available in VTS,
+ * so allow time to demodulate ephemeris over the air.
+ */
+ const int kFirstGnssLocationTimeoutSeconds = 75;
+
+ EXPECT_TRUE(aidl_gnss_cb_->location_cbq_.retrieve(aidl_gnss_cb_->last_location_,
+ kFirstGnssLocationTimeoutSeconds));
+ int locationCalledCount = aidl_gnss_cb_->location_cbq_.calledCount();
+ EXPECT_EQ(locationCalledCount, 1);
+
+ if (locationCalledCount > 0) {
+ // don't require speed on first fix
+ CheckLocation(aidl_gnss_cb_->last_location_, false);
+ return true;
+ }
+ return false;
+}
+
+void GnssHalTest::StopAndClearLocations() {
+ ALOGD("StopAndClearLocations");
+ if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+ // Invoke the super method.
+ return GnssHalTestTemplate<IGnss_V2_1>::StopAndClearLocations();
+ }
+
+ auto status = aidl_gnss_hal_->stop();
+ EXPECT_TRUE(status.isOk());
+
+ /*
+ * Clear notify/waiting counter, allowing up till the timeout after
+ * the last reply for final startup messages to arrive (esp. system
+ * info.)
+ */
+ while (aidl_gnss_cb_->location_cbq_.retrieve(aidl_gnss_cb_->last_location_, TIMEOUT_SEC)) {
+ }
+ aidl_gnss_cb_->location_cbq_.reset();
+}
+
+void GnssHalTest::StartAndCheckLocations(int count) {
+ if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+ // Invoke the super method.
+ return GnssHalTestTemplate<IGnss_V2_1>::StartAndCheckLocations(count);
+ }
+ const int kMinIntervalMsec = 500;
+ const int kLocationTimeoutSubsequentSec = 2;
+ const bool kLowPowerMode = false;
+
+ EXPECT_TRUE(StartAndCheckFirstLocation(kMinIntervalMsec, kLowPowerMode));
+
+ for (int i = 1; i < count; i++) {
+ EXPECT_TRUE(aidl_gnss_cb_->location_cbq_.retrieve(aidl_gnss_cb_->last_location_,
+ kLocationTimeoutSubsequentSec));
+ int locationCalledCount = aidl_gnss_cb_->location_cbq_.calledCount();
+ EXPECT_EQ(locationCalledCount, i + 1);
+ // Don't cause confusion by checking details if no location yet
+ if (locationCalledCount > 0) {
+ // Should be more than 1 location by now, but if not, still don't check first fix speed
+ CheckLocation(aidl_gnss_cb_->last_location_, locationCalledCount > 1);
+ }
+ }
+}
+
+std::list<std::vector<IGnssCallback::GnssSvInfo>> GnssHalTest::convertToAidl(
+ const std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>>& sv_info_list) {
+ std::list<std::vector<IGnssCallback::GnssSvInfo>> aidl_sv_info_list;
+ for (const auto& sv_info_vec : sv_info_list) {
+ std::vector<IGnssCallback::GnssSvInfo> aidl_sv_info_vec;
+ for (const auto& sv_info : sv_info_vec) {
+ IGnssCallback::GnssSvInfo aidl_sv_info;
+ aidl_sv_info.svid = sv_info.v2_0.v1_0.svid;
+ aidl_sv_info.constellation =
+ static_cast<GnssConstellationType>(sv_info.v2_0.constellation);
+ aidl_sv_info.cN0Dbhz = sv_info.v2_0.v1_0.cN0Dbhz;
+ aidl_sv_info.basebandCN0DbHz = sv_info.basebandCN0DbHz;
+ aidl_sv_info.elevationDegrees = sv_info.v2_0.v1_0.elevationDegrees;
+ aidl_sv_info.azimuthDegrees = sv_info.v2_0.v1_0.azimuthDegrees;
+ aidl_sv_info.carrierFrequencyHz = (int64_t)sv_info.v2_0.v1_0.carrierFrequencyHz;
+ aidl_sv_info.svFlag = (int)sv_info.v2_0.v1_0.svFlag;
+ aidl_sv_info_vec.push_back(aidl_sv_info);
+ }
+ aidl_sv_info_list.push_back(aidl_sv_info_vec);
+ }
+ return aidl_sv_info_list;
+}
+
+/*
+ * FindStrongFrequentNonGpsSource:
+ *
+ * Search through a GnssSvStatus list for the strongest non-GPS satellite observed enough times
+ *
+ * returns the strongest source,
+ * or a source with constellation == UNKNOWN if none are found sufficient times
+ */
+BlocklistedSource GnssHalTest::FindStrongFrequentNonGpsSource(
+ const std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_list,
+ const int min_observations) {
+ return FindStrongFrequentNonGpsSource(convertToAidl(sv_info_list), min_observations);
+}
+
+BlocklistedSource GnssHalTest::FindStrongFrequentNonGpsSource(
+ const std::list<std::vector<IGnssCallback::GnssSvInfo>> sv_info_list,
+ const int min_observations) {
+ std::map<ComparableBlocklistedSource, SignalCounts> mapSignals;
+
+ for (const auto& sv_info_vec : sv_info_list) {
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ if ((gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX) &&
+ (gnss_sv.constellation != GnssConstellationType::GPS)) {
+ ComparableBlocklistedSource source;
+ source.id.svid = gnss_sv.svid;
+ source.id.constellation = gnss_sv.constellation;
+
+ const auto& itSignal = mapSignals.find(source);
+ if (itSignal == mapSignals.end()) {
+ SignalCounts counts;
+ counts.observations = 1;
+ counts.max_cn0_dbhz = gnss_sv.cN0Dbhz;
+ mapSignals.insert(
+ std::pair<ComparableBlocklistedSource, SignalCounts>(source, counts));
+ } else {
+ itSignal->second.observations++;
+ if (itSignal->second.max_cn0_dbhz < gnss_sv.cN0Dbhz) {
+ itSignal->second.max_cn0_dbhz = gnss_sv.cN0Dbhz;
+ }
+ }
+ }
+ }
+ }
+
+ float max_cn0_dbhz_with_sufficient_count = 0.;
+ int total_observation_count = 0;
+ int blocklisted_source_count_observation = 0;
+
+ ComparableBlocklistedSource source_to_blocklist; // initializes to zero = UNKNOWN constellation
+ for (auto const& pairSignal : mapSignals) {
+ total_observation_count += pairSignal.second.observations;
+ if ((pairSignal.second.observations >= min_observations) &&
+ (pairSignal.second.max_cn0_dbhz > max_cn0_dbhz_with_sufficient_count)) {
+ source_to_blocklist = pairSignal.first;
+ blocklisted_source_count_observation = pairSignal.second.observations;
+ max_cn0_dbhz_with_sufficient_count = pairSignal.second.max_cn0_dbhz;
+ }
+ }
+ ALOGD("Among %d observations, chose svid %d, constellation %d, "
+ "with %d observations at %.1f max CNo",
+ total_observation_count, source_to_blocklist.id.svid,
+ (int)source_to_blocklist.id.constellation, blocklisted_source_count_observation,
+ max_cn0_dbhz_with_sufficient_count);
+
+ return source_to_blocklist.id;
+}
+
+GnssConstellationType GnssHalTest::startLocationAndGetNonGpsConstellation(
+ const int locations_to_await, const int gnss_sv_info_list_timeout) {
+ if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+ return static_cast<GnssConstellationType>(
+ GnssHalTestTemplate<IGnss_V2_1>::startLocationAndGetNonGpsConstellation(
+ locations_to_await, gnss_sv_info_list_timeout));
+ }
+ aidl_gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(locations_to_await);
+ const int location_called_count = aidl_gnss_cb_->location_cbq_.calledCount();
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ int sv_info_list_cbq_size = aidl_gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, locations_to_await);
+ ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
+ sv_info_list_cbq_size, locations_to_await, location_called_count);
+
+ // Find first non-GPS constellation to blocklist
+ GnssConstellationType constellation_to_blocklist = GnssConstellationType::UNKNOWN;
+ for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+ std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
+ aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, gnss_sv_info_list_timeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ auto& gnss_sv = sv_info_vec[iSv];
+ if ((gnss_sv.svFlag & (uint32_t)IGnssCallback::GnssSvFlags::USED_IN_FIX) &&
+ (gnss_sv.constellation != GnssConstellationType::UNKNOWN) &&
+ (gnss_sv.constellation != GnssConstellationType::GPS)) {
+ // found a non-GPS constellation
+ constellation_to_blocklist = gnss_sv.constellation;
+ break;
+ }
+ }
+ if (constellation_to_blocklist != GnssConstellationType::UNKNOWN) {
+ break;
+ }
+ }
+
+ if (constellation_to_blocklist == GnssConstellationType::UNKNOWN) {
+ ALOGI("No non-GPS constellations found, constellation blocklist test less effective.");
+ // Proceed functionally to blocklist something.
+ constellation_to_blocklist = GnssConstellationType::GLONASS;
+ }
+
+ return constellation_to_blocklist;
}
diff --git a/gnss/aidl/vts/gnss_hal_test.h b/gnss/aidl/vts/gnss_hal_test.h
index e3ecbed..d479af3 100644
--- a/gnss/aidl/vts/gnss_hal_test.h
+++ b/gnss/aidl/vts/gnss_hal_test.h
@@ -41,9 +41,50 @@
public:
GnssHalTest(){};
~GnssHalTest(){};
+
+ struct ComparableBlocklistedSource {
+ android::hardware::gnss::BlocklistedSource id;
+
+ ComparableBlocklistedSource() {
+ id.constellation = android::hardware::gnss::GnssConstellationType::UNKNOWN;
+ id.svid = 0;
+ }
+
+ bool operator<(const ComparableBlocklistedSource& compare) const {
+ return ((id.svid < compare.id.svid) || ((id.svid == compare.id.svid) &&
+ (id.constellation < compare.id.constellation)));
+ }
+ };
+
+ struct SignalCounts {
+ int observations;
+ float max_cn0_dbhz;
+ };
+
virtual void SetUp() override;
virtual void SetUpGnssCallback() override;
+ void CheckLocation(const android::hardware::gnss::GnssLocation& location,
+ const bool check_speed);
+ void SetPositionMode(const int min_interval_msec, const bool low_power_mode);
+ bool StartAndCheckFirstLocation(const int min_interval_msec, const bool low_power_mode);
+ void StopAndClearLocations();
+ void StartAndCheckLocations(int count);
+
+ android::hardware::gnss::GnssConstellationType startLocationAndGetNonGpsConstellation(
+ const int locations_to_await, const int gnss_sv_info_list_timeout);
+ std::list<std::vector<android::hardware::gnss::IGnssCallback::GnssSvInfo>> convertToAidl(
+ const std::list<hidl_vec<android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo>>&
+ sv_info_list);
+ android::hardware::gnss::BlocklistedSource FindStrongFrequentNonGpsSource(
+ const std::list<hidl_vec<android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo>>
+ sv_info_list,
+ const int min_observations);
+ android::hardware::gnss::BlocklistedSource FindStrongFrequentNonGpsSource(
+ const std::list<std::vector<android::hardware::gnss::IGnssCallback::GnssSvInfo>>
+ sv_info_list,
+ const int min_observations);
+
sp<IGnssAidl> aidl_gnss_hal_;
sp<GnssCallbackAidl> aidl_gnss_cb_; // Primary callback interface
};
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index d3cb0a0..9acef8b 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -46,6 +46,7 @@
using android::hardware::gnss::IGnss;
using android::hardware::gnss::IGnssBatching;
using android::hardware::gnss::IGnssBatchingCallback;
+using android::hardware::gnss::IGnssCallback;
using android::hardware::gnss::IGnssConfiguration;
using android::hardware::gnss::IGnssDebug;
using android::hardware::gnss::IGnssGeofence;
@@ -59,6 +60,7 @@
using android::hardware::gnss::SatellitePvt;
using android::hardware::gnss::visibility_control::IGnssVisibilityControl;
+using GnssConstellationTypeV2_0 = android::hardware::gnss::V2_0::GnssConstellationType;
using GnssConstellationTypeAidl = android::hardware::gnss::GnssConstellationType;
static bool IsAutomotiveDevice() {
@@ -324,7 +326,11 @@
auto powerStats1 = gnssPowerIndicationCallback->last_gnss_power_stats_;
// Get a location and request another GnssPowerStats
- gnss_cb_->location_cbq_.reset();
+ if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+ gnss_cb_->location_cbq_.reset();
+ } else {
+ aidl_gnss_cb_->location_cbq_.reset();
+ }
StartAndCheckFirstLocation(/* min_interval_msec= */ 1000, /* low_power_mode= */ false);
// Request and verify the 2nd GnssPowerStats has larger values than the 1st one
@@ -375,88 +381,6 @@
}
/*
- * FindStrongFrequentNonGpsSource:
- *
- * Search through a GnssSvStatus list for the strongest non-GPS satellite observed enough times
- *
- * returns the strongest source,
- * or a source with constellation == UNKNOWN if none are found sufficient times
- */
-BlocklistedSource FindStrongFrequentNonGpsSource(
- const std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_list,
- const int min_observations) {
- struct ComparableBlocklistedSource {
- BlocklistedSource id;
-
- ComparableBlocklistedSource() {
- id.constellation = GnssConstellationTypeAidl::UNKNOWN;
- id.svid = 0;
- }
-
- bool operator<(const ComparableBlocklistedSource& compare) const {
- return ((id.svid < compare.id.svid) || ((id.svid == compare.id.svid) &&
- (id.constellation < compare.id.constellation)));
- }
- };
-
- struct SignalCounts {
- int observations;
- float max_cn0_dbhz;
- };
-
- std::map<ComparableBlocklistedSource, SignalCounts> mapSignals;
-
- for (const auto& sv_info_vec : sv_info_list) {
- for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
- const auto& gnss_sv = sv_info_vec[iSv];
- if ((gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX) &&
- (gnss_sv.v2_0.constellation != GnssConstellationType::GPS)) {
- ComparableBlocklistedSource source;
- source.id.svid = gnss_sv.v2_0.v1_0.svid;
- source.id.constellation =
- static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation);
-
- const auto& itSignal = mapSignals.find(source);
- if (itSignal == mapSignals.end()) {
- SignalCounts counts;
- counts.observations = 1;
- counts.max_cn0_dbhz = gnss_sv.v2_0.v1_0.cN0Dbhz;
- mapSignals.insert(
- std::pair<ComparableBlocklistedSource, SignalCounts>(source, counts));
- } else {
- itSignal->second.observations++;
- if (itSignal->second.max_cn0_dbhz < gnss_sv.v2_0.v1_0.cN0Dbhz) {
- itSignal->second.max_cn0_dbhz = gnss_sv.v2_0.v1_0.cN0Dbhz;
- }
- }
- }
- }
- }
-
- float max_cn0_dbhz_with_sufficient_count = 0.;
- int total_observation_count = 0;
- int blocklisted_source_count_observation = 0;
-
- ComparableBlocklistedSource source_to_blocklist; // initializes to zero = UNKNOWN constellation
- for (auto const& pairSignal : mapSignals) {
- total_observation_count += pairSignal.second.observations;
- if ((pairSignal.second.observations >= min_observations) &&
- (pairSignal.second.max_cn0_dbhz > max_cn0_dbhz_with_sufficient_count)) {
- source_to_blocklist = pairSignal.first;
- blocklisted_source_count_observation = pairSignal.second.observations;
- max_cn0_dbhz_with_sufficient_count = pairSignal.second.max_cn0_dbhz;
- }
- }
- ALOGD("Among %d observations, chose svid %d, constellation %d, "
- "with %d observations at %.1f max CNo",
- total_observation_count, source_to_blocklist.id.svid,
- (int)source_to_blocklist.id.constellation, blocklisted_source_count_observation,
- max_cn0_dbhz_with_sufficient_count);
-
- return source_to_blocklist.id;
-}
-
-/*
* BlocklistIndividualSatellites:
*
* 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
@@ -481,12 +405,20 @@
const int kLocationsToAwait = 3;
const int kRetriesToUnBlocklist = 10;
- gnss_cb_->location_cbq_.reset();
+ if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+ gnss_cb_->location_cbq_.reset();
+ } else {
+ aidl_gnss_cb_->location_cbq_.reset();
+ }
StartAndCheckLocations(kLocationsToAwait);
- int location_called_count = gnss_cb_->location_cbq_.calledCount();
+ int location_called_count = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+ ? gnss_cb_->location_cbq_.calledCount()
+ : aidl_gnss_cb_->location_cbq_.calledCount();
// Tolerate 1 less sv status to handle edge cases in reporting.
- int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ int sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+ ? gnss_cb_->sv_info_list_cbq_.size()
+ : aidl_gnss_cb_->sv_info_list_cbq_.size();
EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
@@ -498,14 +430,22 @@
*/
const int kGnssSvInfoListTimeout = 2;
- std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_vec_list;
- int count = gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec_list, sv_info_list_cbq_size,
- kGnssSvInfoListTimeout);
-
- ASSERT_EQ(count, sv_info_list_cbq_size);
-
- BlocklistedSource source_to_blocklist =
- FindStrongFrequentNonGpsSource(sv_info_vec_list, kLocationsToAwait - 1);
+ BlocklistedSource source_to_blocklist;
+ if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+ std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_vec_list;
+ int count = gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec_list, sv_info_list_cbq_size,
+ kGnssSvInfoListTimeout);
+ ASSERT_EQ(count, sv_info_list_cbq_size);
+ source_to_blocklist =
+ FindStrongFrequentNonGpsSource(sv_info_vec_list, kLocationsToAwait - 1);
+ } else {
+ std::list<std::vector<IGnssCallback::GnssSvInfo>> sv_info_vec_list;
+ int count = aidl_gnss_cb_->sv_info_list_cbq_.retrieve(
+ sv_info_vec_list, sv_info_list_cbq_size, kGnssSvInfoListTimeout);
+ ASSERT_EQ(count, sv_info_list_cbq_size);
+ source_to_blocklist =
+ FindStrongFrequentNonGpsSource(sv_info_vec_list, kLocationsToAwait - 1);
+ }
if (source_to_blocklist.constellation == GnssConstellationTypeAidl::UNKNOWN) {
// Cannot find a non-GPS satellite. Let the test pass.
@@ -529,32 +469,53 @@
ASSERT_TRUE(status.isOk());
// retry and ensure satellite not used
- gnss_cb_->sv_info_list_cbq_.reset();
+ if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+ gnss_cb_->sv_info_list_cbq_.reset();
+ gnss_cb_->location_cbq_.reset();
+ } else {
+ aidl_gnss_cb_->sv_info_list_cbq_.reset();
+ aidl_gnss_cb_->location_cbq_.reset();
+ }
- gnss_cb_->location_cbq_.reset();
StartAndCheckLocations(kLocationsToAwait);
// early exit if test is being run with insufficient signal
- location_called_count = gnss_cb_->location_cbq_.calledCount();
+ location_called_count = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+ ? gnss_cb_->location_cbq_.calledCount()
+ : aidl_gnss_cb_->location_cbq_.calledCount();
if (location_called_count == 0) {
ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
}
ASSERT_TRUE(location_called_count > 0);
// Tolerate 1 less sv status to handle edge cases in reporting.
- sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+ ? gnss_cb_->sv_info_list_cbq_.size()
+ : aidl_gnss_cb_->sv_info_list_cbq_.size();
EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
for (int i = 0; i < sv_info_list_cbq_size; ++i) {
- hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
- gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
- for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
- const auto& gnss_sv = sv_info_vec[iSv];
- EXPECT_FALSE((gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
- (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
- source_to_blocklist.constellation) &&
- (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+ hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ auto& gnss_sv = sv_info_vec[iSv];
+ EXPECT_FALSE(
+ (gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
+ (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+ source_to_blocklist.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ }
+ } else {
+ std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
+ aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ auto& gnss_sv = sv_info_vec[iSv];
+ EXPECT_FALSE((gnss_sv.svid == source_to_blocklist.svid) &&
+ (gnss_sv.constellation == source_to_blocklist.constellation) &&
+ (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
+ }
}
}
@@ -569,36 +530,59 @@
int unblocklist_loops_remaining = kRetriesToUnBlocklist;
while (!strongest_sv_is_reobserved && (unblocklist_loops_remaining-- > 0)) {
StopAndClearLocations();
- gnss_cb_->sv_info_list_cbq_.reset();
- gnss_cb_->location_cbq_.reset();
+ if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+ gnss_cb_->sv_info_list_cbq_.reset();
+ gnss_cb_->location_cbq_.reset();
+ } else {
+ aidl_gnss_cb_->sv_info_list_cbq_.reset();
+ aidl_gnss_cb_->location_cbq_.reset();
+ }
StartAndCheckLocations(kLocationsToAwait);
// early exit loop if test is being run with insufficient signal
- location_called_count = gnss_cb_->location_cbq_.calledCount();
+ location_called_count = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+ ? gnss_cb_->location_cbq_.calledCount()
+ : aidl_gnss_cb_->location_cbq_.calledCount();
if (location_called_count == 0) {
ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
}
ASSERT_TRUE(location_called_count > 0);
// Tolerate 1 less sv status to handle edge cases in reporting.
- sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+ ? gnss_cb_->sv_info_list_cbq_.size()
+ : aidl_gnss_cb_->sv_info_list_cbq_.size();
EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
ALOGD("Clear blocklist, observed %d GnssSvInfo, while awaiting %d Locations"
", tries remaining %d",
sv_info_list_cbq_size, kLocationsToAwait, unblocklist_loops_remaining);
for (int i = 0; i < sv_info_list_cbq_size; ++i) {
- hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
- gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
- for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
- const auto& gnss_sv = sv_info_vec[iSv];
- if ((gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
- (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
- source_to_blocklist.constellation) &&
- (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)) {
- strongest_sv_is_reobserved = true;
- break;
+ if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+ hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ auto& gnss_sv = sv_info_vec[iSv];
+ if ((gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
+ (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+ source_to_blocklist.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)) {
+ strongest_sv_is_reobserved = true;
+ break;
+ }
+ }
+ } else {
+ std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
+ aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ auto& gnss_sv = sv_info_vec[iSv];
+ if ((gnss_sv.svid == source_to_blocklist.svid) &&
+ (gnss_sv.constellation == source_to_blocklist.constellation) &&
+ (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX)) {
+ strongest_sv_is_reobserved = true;
+ break;
+ }
}
}
if (strongest_sv_is_reobserved) break;
@@ -660,27 +644,47 @@
ASSERT_TRUE(status.isOk());
// retry and ensure constellation not used
- gnss_cb_->sv_info_list_cbq_.reset();
-
- gnss_cb_->location_cbq_.reset();
+ if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+ gnss_cb_->sv_info_list_cbq_.reset();
+ gnss_cb_->location_cbq_.reset();
+ } else {
+ aidl_gnss_cb_->sv_info_list_cbq_.reset();
+ aidl_gnss_cb_->location_cbq_.reset();
+ }
StartAndCheckLocations(kLocationsToAwait);
// Tolerate 1 less sv status to handle edge cases in reporting.
- int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ int sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+ ? gnss_cb_->sv_info_list_cbq_.size()
+ : aidl_gnss_cb_->sv_info_list_cbq_.size();
EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations", sv_info_list_cbq_size,
kLocationsToAwait);
for (int i = 0; i < sv_info_list_cbq_size; ++i) {
- hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
- gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
- for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
- const auto& gnss_sv = sv_info_vec[iSv];
- EXPECT_FALSE((static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
- source_to_blocklist_1.constellation) &&
- (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
- EXPECT_FALSE((static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
- source_to_blocklist_2.constellation) &&
- (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+ hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ EXPECT_FALSE(
+ (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+ source_to_blocklist_1.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ EXPECT_FALSE(
+ (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+ source_to_blocklist_2.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ }
+ } else {
+ std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
+ aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ EXPECT_FALSE((gnss_sv.constellation == source_to_blocklist_1.constellation) &&
+ (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
+ EXPECT_FALSE((gnss_sv.constellation == source_to_blocklist_2.constellation) &&
+ (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
+ }
}
}
@@ -743,27 +747,47 @@
StopAndClearLocations();
// retry and ensure constellation not used
- gnss_cb_->sv_info_list_cbq_.reset();
-
- gnss_cb_->location_cbq_.reset();
+ if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+ gnss_cb_->sv_info_list_cbq_.reset();
+ gnss_cb_->location_cbq_.reset();
+ } else {
+ aidl_gnss_cb_->sv_info_list_cbq_.reset();
+ aidl_gnss_cb_->location_cbq_.reset();
+ }
StartAndCheckLocations(kLocationsToAwait);
// Tolerate 1 less sv status to handle edge cases in reporting.
- int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ int sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+ ? gnss_cb_->sv_info_list_cbq_.size()
+ : aidl_gnss_cb_->sv_info_list_cbq_.size();
EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations", sv_info_list_cbq_size,
kLocationsToAwait);
for (int i = 0; i < sv_info_list_cbq_size; ++i) {
- hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
- gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
- for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
- const auto& gnss_sv = sv_info_vec[iSv];
- EXPECT_FALSE((static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
- source_to_blocklist_1.constellation) &&
- (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
- EXPECT_FALSE((static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
- source_to_blocklist_2.constellation) &&
- (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+ hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ EXPECT_FALSE(
+ (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+ source_to_blocklist_1.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ EXPECT_FALSE(
+ (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+ source_to_blocklist_2.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ }
+ } else {
+ std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
+ aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ EXPECT_FALSE((gnss_sv.constellation == source_to_blocklist_1.constellation) &&
+ (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
+ EXPECT_FALSE((gnss_sv.constellation == source_to_blocklist_2.constellation) &&
+ (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
+ }
}
}
@@ -829,7 +853,7 @@
ASSERT_TRUE(status.isOk());
// Set SUPL server host/port
- status = iAGnss->setServer(AGnssType::SUPL, String16("supl.google.com"), 7275);
+ status = iAGnss->setServer(AGnssType::SUPL, std::string("supl.google.com"), 7275);
ASSERT_TRUE(status.isOk());
}
@@ -845,7 +869,7 @@
auto status = aidl_gnss_hal_->getExtensionGnssDebug(&iGnssDebug);
ASSERT_TRUE(status.isOk());
- if (!IsAutomotiveDevice() && gnss_cb_->info_cbq_.calledCount() > 0) {
+ if (!IsAutomotiveDevice()) {
ASSERT_TRUE(iGnssDebug != nullptr);
IGnssDebug::DebugData data;
diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp
index c339e72..563c6d5 100644
--- a/gnss/common/utils/default/Utils.cpp
+++ b/gnss/common/utils/default/Utils.cpp
@@ -27,14 +27,17 @@
using aidl::android::hardware::gnss::ElapsedRealtime;
using aidl::android::hardware::gnss::GnssClock;
+using aidl::android::hardware::gnss::GnssConstellationType;
using aidl::android::hardware::gnss::GnssData;
using aidl::android::hardware::gnss::GnssLocation;
using aidl::android::hardware::gnss::GnssMeasurement;
using aidl::android::hardware::gnss::IGnss;
using aidl::android::hardware::gnss::IGnssMeasurementCallback;
using aidl::android::hardware::gnss::SatellitePvt;
+using GnssSvInfo = aidl::android::hardware::gnss::IGnssCallback::GnssSvInfo;
+using GnssSvFlags = aidl::android::hardware::gnss::IGnssCallback::GnssSvFlags;
-using GnssSvFlags = V1_0::IGnssCallback::GnssSvFlags;
+using GnssSvFlagsV1_0 = V1_0::IGnssCallback::GnssSvFlags;
using GnssMeasurementFlagsV1_0 = V1_0::IGnssMeasurementCallback::GnssMeasurementFlags;
using GnssMeasurementFlagsV2_1 = V2_1::IGnssMeasurementCallback::GnssMeasurementFlags;
using GnssMeasurementStateV2_0 = V2_0::IGnssMeasurementCallback::GnssMeasurementState;
@@ -144,7 +147,7 @@
GnssData Utils::getMockMeasurement(const bool enableCorrVecOutputs) {
aidl::android::hardware::gnss::GnssSignalType signalType = {
- .constellation = aidl::android::hardware::gnss::GnssConstellationType::GLONASS,
+ .constellation = GnssConstellationType::GLONASS,
.carrierFrequencyHz = 1.59975e+09,
.codeType = aidl::android::hardware::gnss::GnssSignalType::CODE_TYPE_C,
};
@@ -289,6 +292,40 @@
return location;
}
+namespace {
+GnssSvInfo getMockSvInfo(int svid, GnssConstellationType type, float cN0DbHz, float basebandCN0DbHz,
+ float elevationDegrees, float azimuthDegrees, long carrierFrequencyHz) {
+ GnssSvInfo svInfo = {
+ .svid = svid,
+ .constellation = type,
+ .cN0Dbhz = cN0DbHz,
+ .basebandCN0DbHz = basebandCN0DbHz,
+ .elevationDegrees = elevationDegrees,
+ .azimuthDegrees = azimuthDegrees,
+ .carrierFrequencyHz = carrierFrequencyHz,
+ .svFlag = (int)GnssSvFlags::USED_IN_FIX | (int)GnssSvFlags::HAS_EPHEMERIS_DATA |
+ (int)GnssSvFlags::HAS_ALMANAC_DATA | (int)GnssSvFlags::HAS_CARRIER_FREQUENCY};
+ return svInfo;
+}
+} // anonymous namespace
+
+std::vector<GnssSvInfo> Utils::getMockSvInfoList() {
+ std::vector<GnssSvInfo> gnssSvInfoList = {
+ getMockSvInfo(3, GnssConstellationType::GPS, 32.5, 27.5, 59.1, 166.5, kGpsL1FreqHz),
+ getMockSvInfo(5, GnssConstellationType::GPS, 27.0, 22.0, 29.0, 56.5, kGpsL1FreqHz),
+ getMockSvInfo(17, GnssConstellationType::GPS, 30.5, 25.5, 71.0, 77.0, kGpsL5FreqHz),
+ getMockSvInfo(26, GnssConstellationType::GPS, 24.1, 19.1, 28.0, 253.0, kGpsL5FreqHz),
+ getMockSvInfo(5, GnssConstellationType::GLONASS, 20.5, 15.5, 11.5, 116.0, kGloG1FreqHz),
+ getMockSvInfo(17, GnssConstellationType::GLONASS, 21.5, 16.5, 28.5, 186.0,
+ kGloG1FreqHz),
+ getMockSvInfo(18, GnssConstellationType::GLONASS, 28.3, 25.3, 38.8, 69.0, kGloG1FreqHz),
+ getMockSvInfo(10, GnssConstellationType::GLONASS, 25.0, 20.0, 66.0, 247.0,
+ kGloG1FreqHz),
+ getMockSvInfo(3, GnssConstellationType::IRNSS, 22.0, 19.7, 35.0, 112.0, kIrnssL5FreqHz),
+ };
+ return gnssSvInfoList;
+}
+
hidl_vec<GnssSvInfoV2_1> Utils::getMockSvInfoListV2_1() {
GnssSvInfoV1_0 gnssSvInfoV1_0 = Utils::getMockSvInfoV1_0(3, V1_0::GnssConstellationType::GPS,
32.5, 59.1, 166.5, kGpsL1FreqHz);
@@ -360,15 +397,15 @@
GnssSvInfoV1_0 Utils::getMockSvInfoV1_0(int16_t svid, V1_0::GnssConstellationType type,
float cN0DbHz, float elevationDegrees, float azimuthDegrees,
float carrierFrequencyHz) {
- GnssSvInfoV1_0 svInfo = {.svid = svid,
- .constellation = type,
- .cN0Dbhz = cN0DbHz,
- .elevationDegrees = elevationDegrees,
- .azimuthDegrees = azimuthDegrees,
- .carrierFrequencyHz = carrierFrequencyHz,
- .svFlag = GnssSvFlags::USED_IN_FIX | GnssSvFlags::HAS_EPHEMERIS_DATA |
- GnssSvFlags::HAS_ALMANAC_DATA |
- GnssSvFlags::HAS_CARRIER_FREQUENCY};
+ GnssSvInfoV1_0 svInfo = {
+ .svid = svid,
+ .constellation = type,
+ .cN0Dbhz = cN0DbHz,
+ .elevationDegrees = elevationDegrees,
+ .azimuthDegrees = azimuthDegrees,
+ .carrierFrequencyHz = carrierFrequencyHz,
+ .svFlag = GnssSvFlagsV1_0::USED_IN_FIX | GnssSvFlagsV1_0::HAS_EPHEMERIS_DATA |
+ GnssSvFlagsV1_0::HAS_ALMANAC_DATA | GnssSvFlagsV1_0::HAS_CARRIER_FREQUENCY};
return svInfo;
}
diff --git a/gnss/common/utils/default/include/Utils.h b/gnss/common/utils/default/include/Utils.h
index 4500ee6..7065a6fb 100644
--- a/gnss/common/utils/default/include/Utils.h
+++ b/gnss/common/utils/default/include/Utils.h
@@ -35,9 +35,13 @@
const bool enableCorrVecOutputs);
static V2_0::IGnssMeasurementCallback::GnssData getMockMeasurementV2_0();
static V2_1::IGnssMeasurementCallback::GnssData getMockMeasurementV2_1();
+
static aidl::android::hardware::gnss::GnssLocation getMockLocation();
static V2_0::GnssLocation getMockLocationV2_0();
static V1_0::GnssLocation getMockLocationV1_0();
+
+ static std::vector<aidl::android::hardware::gnss::IGnssCallback::GnssSvInfo>
+ getMockSvInfoList();
static hidl_vec<V2_1::IGnssCallback::GnssSvInfo> getMockSvInfoListV2_1();
static V2_1::IGnssCallback::GnssSvInfo getMockSvInfoV2_1(
V2_0::IGnssCallback::GnssSvInfo gnssSvInfoV2_0, float basebandCN0DbHz);
@@ -48,6 +52,7 @@
float cN0DbHz, float elevationDegrees,
float azimuthDegrees,
float carrierFrequencyHz);
+
static hidl_vec<V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo> getMockAntennaInfos();
};
diff --git a/gnss/common/utils/vts/Android.bp b/gnss/common/utils/vts/Android.bp
index 47eff2e..f92e609 100644
--- a/gnss/common/utils/vts/Android.bp
+++ b/gnss/common/utils/vts/Android.bp
@@ -44,6 +44,7 @@
"android.hardware.gnss@2.1",
"android.hardware.gnss.measurement_corrections@1.0",
"android.hardware.gnss.measurement_corrections@1.1",
+ "android.hardware.gnss-V2-cpp",
],
static_libs: [
"libgtest",
diff --git a/gnss/common/utils/vts/Utils.cpp b/gnss/common/utils/vts/Utils.cpp
index be22ff6..06bce9d 100644
--- a/gnss/common/utils/vts/Utils.cpp
+++ b/gnss/common/utils/vts/Utils.cpp
@@ -15,6 +15,7 @@
*/
#include <Utils.h>
+#include <android/hardware/gnss/IGnss.h>
#include "gtest/gtest.h"
#include <cutils/properties.h>
@@ -27,71 +28,14 @@
using namespace measurement_corrections::V1_0;
using V1_0::GnssLocationFlags;
-void Utils::checkLocation(const V1_0::GnssLocation& location, bool check_speed,
- bool check_more_accuracies) {
- EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG);
- EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE);
- if (check_speed) {
- EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED);
- }
- EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY);
- // New uncertainties available in O must be provided,
- // at least when paired with modern hardware (2017+)
- if (check_more_accuracies) {
- EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY);
- if (check_speed) {
- EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY);
- if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
- EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY);
- }
- }
- }
- EXPECT_GE(location.latitudeDegrees, -90.0);
- EXPECT_LE(location.latitudeDegrees, 90.0);
- EXPECT_GE(location.longitudeDegrees, -180.0);
- EXPECT_LE(location.longitudeDegrees, 180.0);
- EXPECT_GE(location.altitudeMeters, -1000.0);
- EXPECT_LE(location.altitudeMeters, 30000.0);
- if (check_speed) {
- EXPECT_GE(location.speedMetersPerSec, 0.0);
- EXPECT_LE(location.speedMetersPerSec, 5.0); // VTS tests are stationary.
+template <>
+int64_t Utils::getLocationTimestampMillis(const android::hardware::gnss::GnssLocation& location) {
+ return location.timestampMillis;
+}
- // Non-zero speeds must be reported with an associated bearing
- if (location.speedMetersPerSec > 0.0) {
- EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING);
- }
- }
-
- /*
- * Tolerating some especially high values for accuracy estimate, in case of
- * first fix with especially poor geometry (happens occasionally)
- */
- EXPECT_GT(location.horizontalAccuracyMeters, 0.0);
- EXPECT_LE(location.horizontalAccuracyMeters, 250.0);
-
- /*
- * Some devices may define bearing as -180 to +180, others as 0 to 360.
- * Both are okay & understandable.
- */
- if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
- EXPECT_GE(location.bearingDegrees, -180.0);
- EXPECT_LE(location.bearingDegrees, 360.0);
- }
- if (location.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
- EXPECT_GT(location.verticalAccuracyMeters, 0.0);
- EXPECT_LE(location.verticalAccuracyMeters, 500.0);
- }
- if (location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
- EXPECT_GT(location.speedAccuracyMetersPerSecond, 0.0);
- EXPECT_LE(location.speedAccuracyMetersPerSecond, 50.0);
- }
- if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
- EXPECT_GT(location.bearingAccuracyDegrees, 0.0);
- EXPECT_LE(location.bearingAccuracyDegrees, 360.0);
- }
-
- // Check timestamp > 1.48e12 (47 years in msec - 1970->2017+)
- EXPECT_GT(location.timestamp, 1.48e12);
+template <>
+int64_t Utils::getLocationTimestampMillis(const V1_0::GnssLocation& location) {
+ return location.timestamp;
}
const MeasurementCorrections Utils::getMockMeasurementCorrections() {
diff --git a/gnss/common/utils/vts/include/Utils.h b/gnss/common/utils/vts/include/Utils.h
index 91c1167..40f31d2 100644
--- a/gnss/common/utils/vts/include/Utils.h
+++ b/gnss/common/utils/vts/include/Utils.h
@@ -21,6 +21,7 @@
#include <android/hardware/gnss/2.0/IGnss.h>
#include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
#include <android/hardware/gnss/measurement_corrections/1.1/IMeasurementCorrections.h>
+#include <gtest/gtest.h>
namespace android {
namespace hardware {
@@ -28,8 +29,9 @@
namespace common {
struct Utils {
- static void checkLocation(const V1_0::GnssLocation& location, bool check_speed,
- bool check_more_accuracies);
+ public:
+ template <class T>
+ static void checkLocation(const T& location, bool check_speed, bool check_more_accuracies);
static const measurement_corrections::V1_0::MeasurementCorrections
getMockMeasurementCorrections();
static const measurement_corrections::V1_1::MeasurementCorrections
@@ -39,8 +41,80 @@
V2_0::GnssConstellationType constellation);
static bool isAutomotiveDevice();
+
+ private:
+ template <class T>
+ static int64_t getLocationTimestampMillis(const T&);
};
+template <class T>
+void Utils::checkLocation(const T& location, bool check_speed, bool check_more_accuracies) {
+ EXPECT_TRUE(location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_LAT_LONG);
+ EXPECT_TRUE(location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_ALTITUDE);
+ if (check_speed) {
+ EXPECT_TRUE(location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_SPEED);
+ }
+ EXPECT_TRUE(location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_HORIZONTAL_ACCURACY);
+ // New uncertainties available in O must be provided,
+ // at least when paired with modern hardware (2017+)
+ if (check_more_accuracies) {
+ EXPECT_TRUE(location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_VERTICAL_ACCURACY);
+ if (check_speed) {
+ EXPECT_TRUE(location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_SPEED_ACCURACY);
+ if (location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_BEARING) {
+ EXPECT_TRUE(location.gnssLocationFlags &
+ V1_0::GnssLocationFlags::HAS_BEARING_ACCURACY);
+ }
+ }
+ }
+ EXPECT_GE(location.latitudeDegrees, -90.0);
+ EXPECT_LE(location.latitudeDegrees, 90.0);
+ EXPECT_GE(location.longitudeDegrees, -180.0);
+ EXPECT_LE(location.longitudeDegrees, 180.0);
+ EXPECT_GE(location.altitudeMeters, -1000.0);
+ EXPECT_LE(location.altitudeMeters, 30000.0);
+ if (check_speed) {
+ EXPECT_GE(location.speedMetersPerSec, 0.0);
+ EXPECT_LE(location.speedMetersPerSec, 5.0); // VTS tests are stationary.
+
+ // Non-zero speeds must be reported with an associated bearing
+ if (location.speedMetersPerSec > 0.0) {
+ EXPECT_TRUE(location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_BEARING);
+ }
+ }
+
+ /*
+ * Tolerating some especially high values for accuracy estimate, in case of
+ * first fix with especially poor geometry (happens occasionally)
+ */
+ EXPECT_GT(location.horizontalAccuracyMeters, 0.0);
+ EXPECT_LE(location.horizontalAccuracyMeters, 250.0);
+
+ /*
+ * Some devices may define bearing as -180 to +180, others as 0 to 360.
+ * Both are okay & understandable.
+ */
+ if (location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_BEARING) {
+ EXPECT_GE(location.bearingDegrees, -180.0);
+ EXPECT_LE(location.bearingDegrees, 360.0);
+ }
+ if (location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
+ EXPECT_GT(location.verticalAccuracyMeters, 0.0);
+ EXPECT_LE(location.verticalAccuracyMeters, 500.0);
+ }
+ if (location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_SPEED_ACCURACY) {
+ EXPECT_GT(location.speedAccuracyMetersPerSecond, 0.0);
+ EXPECT_LE(location.speedAccuracyMetersPerSecond, 50.0);
+ }
+ if (location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_BEARING_ACCURACY) {
+ EXPECT_GT(location.bearingAccuracyDegrees, 0.0);
+ EXPECT_LE(location.bearingAccuracyDegrees, 360.0);
+ }
+
+ // Check timestamp > 1.48e12 (47 years in msec - 1970->2017+)
+ EXPECT_GT(getLocationTimestampMillis(location), 1.48e12);
+}
+
} // namespace common
} // namespace gnss
} // namespace hardware
diff --git a/gnss/common/utils/vts/include/v2_1/GnssCallback.h b/gnss/common/utils/vts/include/v2_1/GnssCallback.h
index ab1375d..09a67de 100644
--- a/gnss/common/utils/vts/include/v2_1/GnssCallback.h
+++ b/gnss/common/utils/vts/include/v2_1/GnssCallback.h
@@ -28,7 +28,6 @@
using android::hardware::gnss::common::GnssCallbackEventQueue;
using android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrectionsCallback;
using android::hardware::gnss::V1_0::GnssLocationFlags;
-using android::hardware::gnss::V2_0::GnssConstellationType;
using GnssLocation_1_0 = android::hardware::gnss::V1_0::GnssLocation;
using GnssLocation_2_0 = android::hardware::gnss::V2_0::GnssLocation;
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl
index 9f5342e..fdf1100 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl
@@ -41,4 +41,5 @@
PROTECTED_CONTENTS = 4,
AUTO_LOW_LATENCY_MODE = 5,
SUSPEND = 6,
+ DISPLAY_DECORATION = 7,
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl
index eacf106..249fed0 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl
@@ -75,4 +75,8 @@
* PowerMode.ON_SUSPEND and PowerMode.DOZE_SUSPEND must be supported.
*/
SUSPEND = 6,
+ /**
+ * Indicates that the display supports Composition.DISPLAY_DECORATION.
+ */
+ DISPLAY_DECORATION = 7,
}
diff --git a/health/aidl/default/Android.bp b/health/aidl/default/Android.bp
index 8aa7638..8eab997 100644
--- a/health/aidl/default/Android.bp
+++ b/health/aidl/default/Android.bp
@@ -120,6 +120,15 @@
},
}
+// Users of libhealth_aidl_impl should use this defaults.
+cc_defaults {
+ name: "libhealth_aidl_impl_user",
+ defaults: [
+ "libhealth_aidl_common_defaults",
+ "libhealth_aidl_charger_defaults",
+ ],
+}
+
// AIDL version of android.hardware.health@2.1-service.
// Default binder service of the health HAL.
cc_defaults {
@@ -127,8 +136,7 @@
relative_install_path: "hw",
vintf_fragments: ["android.hardware.health-service.example.xml"],
defaults: [
- "libhealth_aidl_common_defaults",
- "libhealth_aidl_charger_defaults",
+ "libhealth_aidl_impl_user",
],
static_libs: [
"libhealth_aidl_impl",
diff --git a/ir/aidl/Android.bp b/ir/aidl/Android.bp
index 6dacb85..a623491 100644
--- a/ir/aidl/Android.bp
+++ b/ir/aidl/Android.bp
@@ -12,6 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
aidl_interface {
name: "android.hardware.ir",
vendor_available: true,
diff --git a/ir/aidl/default/Android.bp b/ir/aidl/default/Android.bp
index 6519664..a4fb439 100644
--- a/ir/aidl/default/Android.bp
+++ b/ir/aidl/default/Android.bp
@@ -13,6 +13,15 @@
// limitations under the License.
// Example binder service of the ir HAL.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
cc_binary {
name: "android.hardware.ir-service.example",
relative_install_path: "hw",
diff --git a/neuralnetworks/OWNERS b/neuralnetworks/OWNERS
index def3ea9..04c5d72 100644
--- a/neuralnetworks/OWNERS
+++ b/neuralnetworks/OWNERS
@@ -1,10 +1,2 @@
# Bug component: 195575
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-galarragas@google.com
-ianhua@google.com
-jeanluc@google.com
-miaowang@google.com
-pszczepaniak@google.com
-xusongw@google.com
+include platform/packages/modules/NeuralNetworks:/NNAPI_OWNERS # Neuralnetworks team
diff --git a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
index a1c3c27..b5cf633 100644
--- a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
+++ b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
@@ -42,7 +42,13 @@
*/
String eid;
/**
- * PortInfo contains the ICCID, logical slot ID, and port state
+ * PortInfo contains the ICCID, logical slot ID, and port state.
+ * Cardstate has no relationship with whether the slot is active or inactive. Should always
+ * report up at least 1 port otherwise the logicalSlotIndex and portActive info will be lost.
+ * For example, the pSIM can be removed, but the slot can still be active. In that case, the
+ * SIM_STATUS reported for the corresponding logical stack will show CARDSTATE_ABSENT.
+ * Similarly, even if there is no profile enabled on the eSIM, that port can still be the
+ * active port in the slot mapping.
*/
SimPortInfo[] portInfo;
}
diff --git a/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl b/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
index c731caf..7923b14 100644
--- a/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
+++ b/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
@@ -205,6 +205,12 @@
* Open a new logical channel and select the given application. This command
* reflects TS 27.007 "open logical channel" operation (+CCHO).
*
+ * For MEP-A(Multiple enabled profile), only dedicated port 0 is ISDR selectable.
+ * e.g., Port0 - for ISDR access and Port1/Port2 - the currently active ports/subscriptions.
+ * Port 0 should be transparent to AP and iccLogicalChannel API should remain the same.
+ * Even if the ISDR request comes over port1 or port2, Modem would just internally convert the
+ * portID to port0 and add the real port index as the payload of MANAGE_CHANNEL command.
+ *
* @param serial Serial number of request.
* @param aid AID value, See ETSI 102.221 and 101.220.
* @param p2 P2 value, described in ISO 7816-4. Ignore if equal to RadioConst:P2_CONSTANT_NO_P2
diff --git a/radio/aidl/compat/libradiocompat/RadioResponse.cpp b/radio/aidl/compat/libradiocompat/RadioResponse.cpp
index dbeb68a..dab70cc 100644
--- a/radio/aidl/compat/libradiocompat/RadioResponse.cpp
+++ b/radio/aidl/compat/libradiocompat/RadioResponse.cpp
@@ -26,7 +26,10 @@
Return<void> RadioResponse::acknowledgeRequest(int32_t serial) {
LOG_CALL << serial;
- // TODO(b/203699028): send to correct requestor or confirm if spam is not a problem
+ /* We send ACKs to all callbacks instead of the one requested it to make implementation simpler.
+ * If it turns out to be a problem, we would have to track where serials come from and make sure
+ * this tracking data (e.g. a map) doesn't grow indefinitely.
+ */
if (mDataCb) mDataCb.get()->acknowledgeRequest(serial);
if (mMessagingCb) mMessagingCb.get()->acknowledgeRequest(serial);
if (mModemCb) mModemCb.get()->acknowledgeRequest(serial);
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp b/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
index 5b22dbe..b450418 100644
--- a/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
@@ -20,6 +20,8 @@
#include "debug.h"
#include "structs.h"
+#include "collections.h"
+
#define RADIO_MODULE "Config"
namespace android::hardware::radio::compat {
diff --git a/radio/aidl/compat/libradiocompat/config/structs.cpp b/radio/aidl/compat/libradiocompat/config/structs.cpp
index 9ba5623..39ad944 100644
--- a/radio/aidl/compat/libradiocompat/config/structs.cpp
+++ b/radio/aidl/compat/libradiocompat/config/structs.cpp
@@ -24,14 +24,11 @@
namespace aidl = ::aidl::android::hardware::radio::config;
-hidl_vec<uint32_t> toHidl(const std::vector<aidl::SlotPortMapping>& slotMap) {
- hidl_vec<uint32_t> out(slotMap.size());
- for (const auto& el : slotMap) {
- CHECK_GE(el.portId, 0);
- CHECK_LT(static_cast<size_t>(el.portId), out.size());
- out[el.portId] = el.physicalSlotId;
+uint32_t toHidl(const aidl::SlotPortMapping& slotPortMapping) {
+ if (slotPortMapping.portId != 0) {
+ LOG(ERROR) << "Port ID " << slotPortMapping.portId << " != 0 not supported by HIDL HAL";
}
- return out;
+ return slotPortMapping.physicalSlotId;
}
aidl::SimSlotStatus toAidl(const config::V1_0::SimSlotStatus& sst) {
diff --git a/radio/aidl/compat/libradiocompat/config/structs.h b/radio/aidl/compat/libradiocompat/config/structs.h
index b8a0385..6ea4e4a 100644
--- a/radio/aidl/compat/libradiocompat/config/structs.h
+++ b/radio/aidl/compat/libradiocompat/config/structs.h
@@ -23,8 +23,7 @@
namespace android::hardware::radio::compat {
-hidl_vec<uint32_t> //
-toHidl(const std::vector<aidl::android::hardware::radio::config::SlotPortMapping>& slotMap);
+uint32_t toHidl(const aidl::android::hardware::radio::config::SlotPortMapping& slotPortMapping);
aidl::android::hardware::radio::config::SimSlotStatus //
toAidl(const config::V1_0::SimSlotStatus& sst);
diff --git a/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
index d3b6002..22b9ede 100644
--- a/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
+++ b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
@@ -254,7 +254,13 @@
ScopedAStatus RadioNetwork::setSignalStrengthReportingCriteria(
int32_t serial, const std::vector<aidl::SignalThresholdInfo>& infos) {
LOG_CALL << serial;
- // TODO(b/203699028): how about other infos?
+ if (infos.size() == 0) {
+ LOG(ERROR) << "Threshold info array is empty - dropping setSignalStrengthReportingCriteria";
+ return ok();
+ }
+ if (infos.size() > 1) {
+ LOG(WARNING) << "Multi-element reporting criteria are not supported with HIDL HAL";
+ }
mHal1_5->setSignalStrengthReportingCriteria_1_5(serial, toHidl(infos[0]),
V1_5::AccessNetwork(infos[0].ran));
return ok();
@@ -291,18 +297,17 @@
return ok();
}
-// TODO(b/210498497): is there a cleaner way to send a response back to Android, even though these
-// methods must never be called?
-ScopedAStatus RadioNetwork::setUsageSetting(
- int32_t ser, ::aidl::android::hardware::radio::network::UsageSetting) {
- LOG_CALL << ser;
+ScopedAStatus RadioNetwork::setUsageSetting(int32_t serial, aidl::UsageSetting) {
+ LOG_CALL << serial;
LOG(ERROR) << "setUsageSetting is unsupported by HIDL HALs";
+ respond()->setUsageSettingResponse(notSupported(serial));
return ok();
}
-ScopedAStatus RadioNetwork::getUsageSetting(int32_t ser) {
- LOG_CALL << ser;
+ScopedAStatus RadioNetwork::getUsageSetting(int32_t serial) {
+ LOG_CALL << serial;
LOG(ERROR) << "getUsageSetting is unsupported by HIDL HALs";
+ respond()->getUsageSettingResponse(notSupported(serial), {}); // {} = neither voice nor data
return ok();
}
diff --git a/radio/aidl/compat/libradiocompat/sim/structs.cpp b/radio/aidl/compat/libradiocompat/sim/structs.cpp
index 97a21a1..bfbff02 100644
--- a/radio/aidl/compat/libradiocompat/sim/structs.cpp
+++ b/radio/aidl/compat/libradiocompat/sim/structs.cpp
@@ -173,7 +173,6 @@
.atr = status.base.base.atr,
.iccid = status.base.base.iccid,
.eid = status.base.eid,
- // TODO(b/203699028): we don't know portId here (but we can get it from RadioConfig)
.slotMap = {static_cast<int32_t>(status.base.base.physicalSlotId), 0},
};
}
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 3695f1e..02462fc 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -537,6 +537,9 @@
Status result;
if (!output) return ErrorCode::UNEXPECTED_NULL_POINTER;
+ EXPECT_NE(op_, nullptr);
+ if (!op_) return ErrorCode::UNEXPECTED_NULL_POINTER;
+
std::vector<uint8_t> o_put;
result = op_->update(vector<uint8_t>(input.begin(), input.end()), {}, {}, &o_put);
diff --git a/wifi/1.5/default/Android.bp b/wifi/1.5/default/Android.bp
new file mode 100644
index 0000000..6333b6e
--- /dev/null
+++ b/wifi/1.5/default/Android.bp
@@ -0,0 +1,105 @@
+// 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 {
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+filegroup {
+ name: "android.hardware.wifi@1.0-service_srcs",
+ srcs: ["service.cpp"],
+}
+
+cc_defaults {
+ name: "android.hardware.wifi@1.0-service_default",
+ srcs: [":android.hardware.wifi@1.0-service_srcs"],
+ relative_install_path: "hw",
+ soc_specific: true,
+ shared_libs: [
+ "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",
+ "libbase",
+ "libcutils",
+ "libhidlbase",
+ "liblog",
+ "libnl",
+ "libutils",
+ "libwifi-system-iface",
+ "libxml2",
+ ],
+ cppflags: [
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ ],
+}
+
+filegroup {
+ name: "android.hardware.wifi@1.0-service-lib_srcs",
+ srcs: [
+ "hidl_struct_util.cpp",
+ "hidl_sync_util.cpp",
+ "ringbuffer.cpp",
+ "wifi.cpp",
+ "wifi_ap_iface.cpp",
+ "wifi_chip.cpp",
+ "wifi_feature_flags.cpp",
+ "wifi_iface_util.cpp",
+ "wifi_legacy_hal.cpp",
+ "wifi_legacy_hal_factory.cpp",
+ "wifi_legacy_hal_stubs.cpp",
+ "wifi_mode_controller.cpp",
+ "wifi_nan_iface.cpp",
+ "wifi_p2p_iface.cpp",
+ "wifi_rtt_controller.cpp",
+ "wifi_sta_iface.cpp",
+ "wifi_status_util.cpp",
+ ],
+}
+
+cc_defaults {
+ name: "android.hardware.wifi@1.0-service-lib_defaults",
+ srcs: [":android.hardware.wifi@1.0-service-lib_srcs"],
+ relative_install_path: "hw",
+ soc_specific: true,
+ shared_libs: [
+ "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",
+ "libbase",
+ "libcutils",
+ "libhidlbase",
+ "liblog",
+ "libnl",
+ "libutils",
+ "libwifi-system-iface",
+ "libxml2",
+ ],
+ // Generated by building android.hardware.wifi@1.0-service-lib and printing LOCAL_CPPFLAGS.
+ cppflags: [
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ "-DWIFI_HIDL_FEATURE_DUAL_INTERFACE",
+ ],
+ export_include_dirs: ["."],
+ include_dirs: ["external/libxml2/include"],
+}
diff --git a/wifi/supplicant/aidl/Android.bp b/wifi/supplicant/aidl/Android.bp
index c97a6f9..d00dd21 100644
--- a/wifi/supplicant/aidl/Android.bp
+++ b/wifi/supplicant/aidl/Android.bp
@@ -12,6 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
aidl_interface {
name: "android.hardware.wifi.supplicant",
vendor_available: true,