diff options
620 files changed, 27011 insertions, 7160 deletions
diff --git a/atrace/1.0/default/android.hardware.atrace@1.0-service.rc b/atrace/1.0/default/android.hardware.atrace@1.0-service.rc index 7110b45c9f..31459b4916 100644 --- a/atrace/1.0/default/android.hardware.atrace@1.0-service.rc +++ b/atrace/1.0/default/android.hardware.atrace@1.0-service.rc @@ -14,4 +14,4 @@ service vendor.atrace-hal-1-0 /vendor/bin/hw/android.hardware.atrace@1.0-service interface android.hardware.atrace@1.0::IAtraceDevice default class early_hal user system - group system + group system readtracefs diff --git a/automotive/evs/OWNERS b/automotive/evs/OWNERS index 6fc50248c7..b973e912bf 100644 --- a/automotive/evs/OWNERS +++ b/automotive/evs/OWNERS @@ -1,3 +1,3 @@ +ankitarora@google.com changyeon@google.com -garysungang@google.com -haoxiangl@google.com +jwhpryor@google.com diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp index f8df6e62d1..970d044d43 100644 --- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp +++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp @@ -154,7 +154,7 @@ class FakeVehicleHardwareTest : public ::testing::Test { return toInt(result.error()); } - void onSetValues(const std::vector<SetValueResult> results) { + void onSetValues(std::vector<SetValueResult> results) { for (auto& result : results) { mSetValueResults.push_back(result); } @@ -162,7 +162,7 @@ class FakeVehicleHardwareTest : public ::testing::Test { const std::vector<SetValueResult>& getSetValueResults() { return mSetValueResults; } - void onGetValues(const std::vector<GetValueResult> results) { + void onGetValues(std::vector<GetValueResult> results) { for (auto& result : results) { mGetValueResults.push_back(result); } @@ -170,7 +170,7 @@ class FakeVehicleHardwareTest : public ::testing::Test { const std::vector<GetValueResult>& getGetValueResults() { return mGetValueResults; } - void onPropertyChangeEvent(const std::vector<VehiclePropValue>& values) { + void onPropertyChangeEvent(std::vector<VehiclePropValue> values) { for (auto& value : values) { mChangedProperties.push_back(value); } diff --git a/automotive/vehicle/aidl/impl/vhal/Android.bp b/automotive/vehicle/aidl/impl/vhal/Android.bp index 454fea5050..a54ab4bbe9 100644 --- a/automotive/vehicle/aidl/impl/vhal/Android.bp +++ b/automotive/vehicle/aidl/impl/vhal/Android.bp @@ -56,6 +56,7 @@ cc_library { srcs: [ "src/ConnectedClient.cpp", "src/DefaultVehicleHal.cpp", + "src/PendingRequestPool.cpp", ], static_libs: [ "VehicleHalUtils", diff --git a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h index 4ee3ee93d8..f6f7d80002 100644 --- a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h +++ b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h @@ -88,12 +88,17 @@ class DefaultVehicleHal final : public ::aidl::android::hardware::automotive::ve GetSetValuesClient<::aidl::android::hardware::automotive::vehicle::SetValueResult, ::aidl::android::hardware::automotive::vehicle::SetValueResults>; + // The default timeout of get or set value requests is 30s. + // TODO(b/214605968): define TIMEOUT_IN_NANO in IVehicle and allow getValues/setValues/subscribe + // to specify custom timeouts. + static constexpr int64_t TIMEOUT_IN_NANO = 30'000'000'000; 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; + // Only modified in constructor, so thread-safe. std::unique_ptr<::ndk::ScopedFileDescriptor> mConfigFile; std::mutex mLock; diff --git a/automotive/vehicle/aidl/impl/vhal/include/ParcelableUtils.h b/automotive/vehicle/aidl/impl/vhal/include/ParcelableUtils.h index dcb15b9c63..4b7c2f3221 100644 --- a/automotive/vehicle/aidl/impl/vhal/include/ParcelableUtils.h +++ b/automotive/vehicle/aidl/impl/vhal/include/ParcelableUtils.h @@ -31,19 +31,18 @@ namespace vehicle { template <class T1, class T2> ::ndk::ScopedAStatus vectorToStableLargeParcelable(std::vector<T1>&& values, T2* output) { + output->payloads = std::move(values); auto result = ::android::automotive::car_binder_lib::LargeParcelableBase:: - parcelableVectorToStableLargeParcelable(values); + parcelableToStableLargeParcelable(*output); if (!result.ok()) { return toScopedAStatus( result, ::aidl::android::hardware::automotive::vehicle::StatusCode::INTERNAL_ERROR); } auto& fd = result.value(); - if (fd == nullptr) { - // If we no longer needs values, move it inside the payloads to avoid copying. - output->payloads = std::move(values); - } else { + if (fd != nullptr) { // Move the returned ScopedFileDescriptor pointer to ScopedFileDescriptor value in // 'sharedMemoryFd' field. + output->payloads.clear(); output->sharedMemoryFd = std::move(*fd); } return ::ndk::ScopedAStatus::ok(); @@ -57,12 +56,13 @@ template <class T1, class T2> return vectorToStableLargeParcelable(std::move(valuesCopy), output); } -template <class T1, class T2> -::android::base::expected<std::vector<T1>, ::ndk::ScopedAStatus> stableLargeParcelableToVector( - const T2& largeParcelable) { - ::android::base::Result<std::optional<std::vector<T1>>> result = - ::android::automotive::car_binder_lib::LargeParcelableBase:: - stableLargeParcelableToParcelableVector<T1>(largeParcelable.sharedMemoryFd); +template <class T> +::android::base::expected< + ::android::automotive::car_binder_lib::LargeParcelableBase::BorrowedOwnedObject<T>, + ::ndk::ScopedAStatus> +fromStableLargeParcelable(const T& largeParcelable) { + auto result = ::android::automotive::car_binder_lib::LargeParcelableBase:: + stableLargeParcelableToParcelable(largeParcelable); if (!result.ok()) { return ::android::base::unexpected(toScopedAStatus( @@ -70,15 +70,7 @@ template <class T1, class T2> "failed to parse large parcelable")); } - if (!result.value().has_value()) { - return ::android::base::unexpected( - ::ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( - toInt(::aidl::android::hardware::automotive::vehicle::StatusCode:: - INVALID_ARG), - "empty request")); - } - - return std::move(result.value().value()); + return std::move(result.value()); } } // namespace vehicle diff --git a/automotive/vehicle/aidl/impl/vhal/include/PendingRequestPool.h b/automotive/vehicle/aidl/impl/vhal/include/PendingRequestPool.h new file mode 100644 index 0000000000..6dcfaff5fa --- /dev/null +++ b/automotive/vehicle/aidl/impl/vhal/include/PendingRequestPool.h @@ -0,0 +1,100 @@ +/* + * 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. + */ + +#ifndef android_hardware_automotive_vehicle_aidl_impl_vhal_include_PendingRequestPool_H_ +#define android_hardware_automotive_vehicle_aidl_impl_vhal_include_PendingRequestPool_H_ + +#include <android-base/result.h> +#include <android-base/thread_annotations.h> + +#include <atomic> +#include <list> +#include <mutex> +#include <thread> +#include <unordered_map> +#include <unordered_set> + +namespace android { +namespace hardware { +namespace automotive { +namespace vehicle { + +// A thread-safe pending request pool that tracks whether each request has timed-out. +class PendingRequestPool final { + public: + using TimeoutCallbackFunc = std::function<void(const std::unordered_set<int64_t>&)>; + + explicit PendingRequestPool(int64_t timeoutInSec); + + ~PendingRequestPool(); + + // Adds a list of requests to the request pool. + // The clientId is the key for all the requests. It could be a number or an address to a data + // structure that represents a client. The caller must maintain this data structure. + // All the request IDs must be unique for one client, if any of the requestIds is duplicate with + // any pending request IDs for the client, this function returns error and no requests would be + // added. Otherwise, they would be added to the request pool. + // The callback would be called if requests are not finished within {@code mTimeoutInNano} + // seconds. + android::base::Result<void> addRequests(const void* clientId, + const std::unordered_set<int64_t>& requestIds, + std::shared_ptr<TimeoutCallbackFunc> callback); + + // Checks whether the request is currently pending. + bool isRequestPending(const void* clientId, int64_t requestId) const; + + // Tries to mark the requests as finished and remove them from the pool if the request is + // currently pending. Returns the list of request that is pending and has been finished + // successfully. This function would try to finish any valid requestIds even though some of the + // requestIds are not valid. + std::unordered_set<int64_t> tryFinishRequests(const void* clientId, + const std::unordered_set<int64_t>& requestIds); + + // Returns how many pending requests in the pool, for testing purpose. + size_t countPendingRequests(const void* clientId) const; + + private: + // The maximum number of pending requests allowed per client. If exceeds this number, adding + // more requests would fail. This is to prevent spamming from client. + static constexpr size_t MAX_PENDING_REQUEST_PER_CLIENT = 10000; + + struct PendingRequest { + std::unordered_set<int64_t> requestIds; + int64_t timeoutTimestamp; + std::shared_ptr<TimeoutCallbackFunc> callback; + }; + + int64_t mTimeoutInNano; + mutable std::mutex mLock; + std::unordered_map<const void*, std::list<PendingRequest>> mPendingRequestsByClient + GUARDED_BY(mLock); + std::thread mThread; + std::atomic<bool> mThreadStop = false; + std::condition_variable mCv; + std::mutex mCvLock; + + bool isRequestPendingLocked(const void* clientId, int64_t requestId) const REQUIRES(mLock); + + // Checks whether the requests in the pool has timed-out, run periodically in a separate thread. + void checkTimeout(); +}; + +} // namespace vehicle +} // namespace automotive +} // namespace hardware +} // namespace android + +#endif // android_hardware_automotive_vehicle_aidl_impl_vhal_include_PendingRequestPool_H_ diff --git a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp index e98f02112e..7f09a59fbb 100644 --- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp +++ b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp @@ -57,7 +57,9 @@ DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware) for (auto& config : configs) { mConfigsByPropId[config.prop] = config; } - auto result = LargeParcelableBase::parcelableVectorToStableLargeParcelable(configs); + VehiclePropConfigs vehiclePropConfigs; + vehiclePropConfigs.payloads = std::move(configs); + auto result = LargeParcelableBase::parcelableToStableLargeParcelable(vehiclePropConfigs); if (!result.ok()) { ALOGE("failed to convert configs to shared memory file, error: %s, code: %d", getErrorMsg(result).c_str(), getIntErrorCode(result)); @@ -71,6 +73,7 @@ DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware) ScopedAStatus DefaultVehicleHal::getAllPropConfigs(VehiclePropConfigs* output) { if (mConfigFile != nullptr) { + output->payloads.clear(); output->sharedMemoryFd.set(dup(mConfigFile->get())); return ScopedAStatus::ok(); } @@ -131,20 +134,14 @@ 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(); + expected<LargeParcelableBase::BorrowedOwnedObject<GetValueRequests>, ScopedAStatus> + deserializedResults = fromStableLargeParcelable(requests); + if (!deserializedResults.ok()) { + ALOGE("getValues: failed to parse getValues requests"); + return std::move(deserializedResults.error()); } + const std::vector<GetValueRequest>& getValueRequests = + deserializedResults.value().getObject()->payloads; std::shared_ptr<GetValuesClient> client; { @@ -153,7 +150,7 @@ ScopedAStatus DefaultVehicleHal::getValues(const CallbackType& callback, } if (StatusCode status = - mVehicleHardware->getValues(client->getResultCallback(), *getValueRequests); + mVehicleHardware->getValues(client->getResultCallback(), getValueRequests); status != StatusCode::OK) { return ScopedAStatus::fromServiceSpecificErrorWithMessage( toInt(status), "failed to get value from VehicleHardware"); @@ -166,27 +163,21 @@ 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(); + expected<LargeParcelableBase::BorrowedOwnedObject<SetValueRequests>, ScopedAStatus> + deserializedResults = fromStableLargeParcelable(requests); + if (!deserializedResults.ok()) { + ALOGE("setValues: failed to parse setValues requests"); + return std::move(deserializedResults.error()); } + const std::vector<SetValueRequest>& setValueRequests = + deserializedResults.value().getObject()->payloads; // 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) { + 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()); diff --git a/automotive/vehicle/aidl/impl/vhal/src/PendingRequestPool.cpp b/automotive/vehicle/aidl/impl/vhal/src/PendingRequestPool.cpp new file mode 100644 index 0000000000..c2d6f89c2d --- /dev/null +++ b/automotive/vehicle/aidl/impl/vhal/src/PendingRequestPool.cpp @@ -0,0 +1,220 @@ +/* + * 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 "PendingRequestPool.h" + +#include <VehicleHalTypes.h> +#include <VehicleUtils.h> + +#include <utils/Log.h> +#include <utils/SystemClock.h> + +#include <vector> + +namespace android { +namespace hardware { +namespace automotive { +namespace vehicle { + +namespace { + +using ::aidl::android::hardware::automotive::vehicle::StatusCode; +using ::android::base::Error; +using ::android::base::Result; + +// At least check every 1s. +constexpr int64_t CHECK_TIME_IN_NANO = 1000000000; + +} // namespace + +PendingRequestPool::PendingRequestPool(int64_t timeoutInNano) + : mTimeoutInNano(timeoutInNano), mThread([this] { + // [this] must be alive within this thread because destructor would wait for this thread + // to exit. + int64_t sleepTime = std::min(mTimeoutInNano, static_cast<int64_t>(CHECK_TIME_IN_NANO)); + std::unique_lock<std::mutex> lk(mCvLock); + while (!mCv.wait_for(lk, std::chrono::nanoseconds(sleepTime), + [this] { return mThreadStop.load(); })) { + checkTimeout(); + } + }) {} + +PendingRequestPool::~PendingRequestPool() { + mThreadStop = true; + mCv.notify_all(); + if (mThread.joinable()) { + mThread.join(); + } + + // If this pool is being destructed, send out all pending requests as timeout. + { + std::scoped_lock<std::mutex> lockGuard(mLock); + + for (auto& [_, pendingRequests] : mPendingRequestsByClient) { + for (const auto& request : pendingRequests) { + (*request.callback)(request.requestIds); + } + } + mPendingRequestsByClient.clear(); + } +} + +Result<void> PendingRequestPool::addRequests(const void* clientId, + const std::unordered_set<int64_t>& requestIds, + std::shared_ptr<TimeoutCallbackFunc> callback) { + std::scoped_lock<std::mutex> lockGuard(mLock); + std::list<PendingRequest>* pendingRequests; + size_t pendingRequestCount = 0; + if (mPendingRequestsByClient.find(clientId) != mPendingRequestsByClient.end()) { + pendingRequests = &mPendingRequestsByClient[clientId]; + for (const auto& pendingRequest : *pendingRequests) { + const auto& pendingRequestIds = pendingRequest.requestIds; + for (int64_t requestId : requestIds) { + if (pendingRequestIds.find(requestId) != pendingRequestIds.end()) { + return Error(toInt(StatusCode::INVALID_ARG)) + << "duplicate request ID: " << requestId; + } + } + pendingRequestCount += pendingRequestIds.size(); + } + } else { + // Create a new empty list for this client. + pendingRequests = &mPendingRequestsByClient[clientId]; + } + + if (requestIds.size() > MAX_PENDING_REQUEST_PER_CLIENT - pendingRequestCount) { + return Error(toInt(StatusCode::TRY_AGAIN)) << "too many pending requests"; + } + + int64_t currentTime = elapsedRealtimeNano(); + int64_t timeoutTimestamp = currentTime + mTimeoutInNano; + + pendingRequests->push_back({ + .requestIds = std::unordered_set<int64_t>(requestIds.begin(), requestIds.end()), + .timeoutTimestamp = timeoutTimestamp, + .callback = callback, + }); + + return {}; +} + +bool PendingRequestPool::isRequestPending(const void* clientId, int64_t requestId) const { + std::scoped_lock<std::mutex> lockGuard(mLock); + + return isRequestPendingLocked(clientId, requestId); +} + +size_t PendingRequestPool::countPendingRequests(const void* clientId) const { + std::scoped_lock<std::mutex> lockGuard(mLock); + + auto it = mPendingRequestsByClient.find(clientId); + if (it == mPendingRequestsByClient.end()) { + return 0; + } + + size_t count = 0; + for (const auto& pendingRequest : it->second) { + count += pendingRequest.requestIds.size(); + } + + return count; +} + +bool PendingRequestPool::isRequestPendingLocked(const void* clientId, int64_t requestId) const { + auto it = mPendingRequestsByClient.find(clientId); + if (it == mPendingRequestsByClient.end()) { + return false; + } + for (const auto& pendingRequest : it->second) { + const auto& requestIds = pendingRequest.requestIds; + if (requestIds.find(requestId) != requestIds.end()) { + return true; + } + } + return false; +} + +void PendingRequestPool::checkTimeout() { + std::vector<PendingRequest> timeoutRequests; + { + std::scoped_lock<std::mutex> lockGuard(mLock); + + int64_t currentTime = elapsedRealtimeNano(); + + std::vector<const void*> clientsWithEmptyRequests; + + for (auto& [clientId, pendingRequests] : mPendingRequestsByClient) { + auto it = pendingRequests.begin(); + while (it != pendingRequests.end()) { + if (it->timeoutTimestamp >= currentTime) { + break; + } + timeoutRequests.push_back(std::move(*it)); + it = pendingRequests.erase(it); + } + + if (pendingRequests.empty()) { + clientsWithEmptyRequests.push_back(clientId); + } + } + + for (const void* clientId : clientsWithEmptyRequests) { + mPendingRequestsByClient.erase(clientId); + } + } + + // Call the callback outside the lock. + for (const auto& request : timeoutRequests) { + (*request.callback)(request.requestIds); + } +} + +std::unordered_set<int64_t> PendingRequestPool::tryFinishRequests( + const void* clientId, const std::unordered_set<int64_t>& requestIds) { + std::scoped_lock<std::mutex> lockGuard(mLock); + + std::unordered_set<int64_t> foundIds; + + if (mPendingRequestsByClient.find(clientId) == mPendingRequestsByClient.end()) { + return foundIds; + } + + auto& pendingRequests = mPendingRequestsByClient[clientId]; + auto it = pendingRequests.begin(); + while (it != pendingRequests.end()) { + auto& pendingRequestIds = it->requestIds; + for (int64_t requestId : requestIds) { + auto idIt = pendingRequestIds.find(requestId); + if (idIt == pendingRequestIds.end()) { + continue; + } + pendingRequestIds.erase(idIt); + foundIds.insert(requestId); + } + if (pendingRequestIds.empty()) { + it = pendingRequests.erase(it); + continue; + } + it++; + } + + return foundIds; +} + +} // namespace vehicle +} // namespace automotive +} // namespace hardware +} // namespace android diff --git a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp index 8934a7b012..ffc08a71b8 100644 --- a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp +++ b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp @@ -389,15 +389,14 @@ class DefaultVehicleHalTest : public ::testing::Test { }); } - auto result = LargeParcelableBase::parcelableVectorToStableLargeParcelable( - expectedHardwareRequests); + requests.payloads = expectedHardwareRequests; + auto result = LargeParcelableBase::parcelableToStableLargeParcelable(requests); if (!result.ok()) { return result.error(); } - if (result.value() == nullptr) { - requests.payloads = expectedHardwareRequests; - } else { + if (result.value() != nullptr) { requests.sharedMemoryFd = std::move(*result.value()); + requests.payloads.clear(); } return {}; } @@ -423,14 +422,13 @@ class DefaultVehicleHalTest : public ::testing::Test { }); } - auto result = LargeParcelableBase::parcelableVectorToStableLargeParcelable( - expectedHardwareRequests); + requests.payloads = expectedHardwareRequests; + auto result = LargeParcelableBase::parcelableToStableLargeParcelable(requests); if (!result.ok()) { return result.error(); } - if (result.value() == nullptr) { - requests.payloads = expectedHardwareRequests; - } else { + if (result.value() != nullptr) { + requests.payloads.clear(); requests.sharedMemoryFd = std::move(*result.value()); } return {}; @@ -490,13 +488,10 @@ TEST_F(DefaultVehicleHalTest, testGetAllPropConfigsLarge) { 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); + auto result = LargeParcelableBase::stableLargeParcelableToParcelable(output); 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); + ASSERT_EQ(result.value().getObject()->payloads, testConfigs); } TEST_F(DefaultVehicleHalTest, testGetValuesSmall) { @@ -544,11 +539,9 @@ TEST_F(DefaultVehicleHalTest, testGetValuesLarge) { ASSERT_TRUE(getValueResults.payloads.empty()) << "payload should be empty, shared memory file should be used"; - auto result = LargeParcelableBase::stableLargeParcelableToParcelableVector<GetValueResult>( - getValueResults.sharedMemoryFd); + auto result = LargeParcelableBase::stableLargeParcelableToParcelable(getValueResults); 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"; + ASSERT_EQ(result.value().getObject()->payloads, expectedResults) << "results mismatch"; EXPECT_EQ(countClients(), static_cast<size_t>(1)); } @@ -621,11 +614,9 @@ TEST_F(DefaultVehicleHalTest, testSetValuesLarge) { ASSERT_TRUE(setValueResults.payloads.empty()) << "payload should be empty, shared memory file should be used"; - auto result = LargeParcelableBase::stableLargeParcelableToParcelableVector<SetValueResult>( - setValueResults.sharedMemoryFd); + auto result = LargeParcelableBase::stableLargeParcelableToParcelable(setValueResults); 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"; + ASSERT_EQ(result.value().getObject()->payloads, expectedResults) << "results mismatch"; EXPECT_EQ(countClients(), static_cast<size_t>(1)); } diff --git a/automotive/vehicle/aidl/impl/vhal/test/PendingRequestPoolTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/PendingRequestPoolTest.cpp new file mode 100644 index 0000000000..03d795beaa --- /dev/null +++ b/automotive/vehicle/aidl/impl/vhal/test/PendingRequestPoolTest.cpp @@ -0,0 +1,274 @@ +/* + * 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 "PendingRequestPool.h" + +#include <VehicleHalTypes.h> +#include <VehicleUtils.h> + +#include <gmock/gmock.h> +#include <gtest/gtest.h> + +#include <unordered_set> +#include <vector> + +namespace android { +namespace hardware { +namespace automotive { +namespace vehicle { + +using ::aidl::android::hardware::automotive::vehicle::StatusCode; + +using ::testing::ElementsAre; +using ::testing::UnorderedElementsAre; +using ::testing::WhenSorted; + +class PendingRequestPoolTest : public ::testing::Test { + public: + void SetUp() override { mPool = std::make_unique<PendingRequestPool>(TEST_TIMEOUT); } + + void TearDown() override { + if (mPool != nullptr) { + ASSERT_EQ(mPool->countPendingRequests(getTestClientId()), static_cast<size_t>(0)) + << "at least one pending request still exists in the pool when finish"; + } + } + + PendingRequestPool* getPool() { return mPool.get(); } + + void destroyPool() { mPool.reset(); } + + int64_t getTimeout() { return TEST_TIMEOUT; } + + void* getTestClientId() { return reinterpret_cast<void*>(0); } + + private: + // Test timeout is 0.1s. + static const int64_t TEST_TIMEOUT = 100000000; + + std::unique_ptr<PendingRequestPool> mPool; +}; + +TEST_F(PendingRequestPoolTest, testFinishAllRequests) { + std::mutex lock; + std::vector<int64_t> timeoutRequestIds; + + std::unordered_set<int64_t> requestIds; + for (int64_t i = 0; i < 10; i++) { + requestIds.insert(i); + } + + auto callback = std::make_shared<PendingRequestPool::TimeoutCallbackFunc>( + [&lock, &timeoutRequestIds](const std::unordered_set<int64_t>& requests) { + std::scoped_lock<std::mutex> lockGuard(lock); + for (int64_t request : requests) { + timeoutRequestIds.push_back(request); + } + }); + + ASSERT_RESULT_OK(getPool()->addRequests(getTestClientId(), requestIds, callback)); + + for (int64_t i = 0; i < 10; i++) { + ASSERT_TRUE(getPool()->isRequestPending(getTestClientId(), i)); + } + + for (int64_t i = 0; i < 10; i++) { + ASSERT_THAT(getPool()->tryFinishRequests(getTestClientId(), {i}), UnorderedElementsAre(i)); + } + + for (int64_t i = 0; i < 10; i++) { + ASSERT_FALSE(getPool()->isRequestPending(getTestClientId(), i)); + } +} + +TEST_F(PendingRequestPoolTest, testFinishHalfOfRequest) { + int64_t timeout = getTimeout(); + std::mutex lock; + std::vector<int64_t> timeoutRequestIds; + + std::unordered_set<int64_t> requestIds; + for (int64_t i = 0; i < 10; i++) { + requestIds.insert(i); + } + + auto callback = std::make_shared<PendingRequestPool::TimeoutCallbackFunc>( + [&lock, &timeoutRequestIds](const std::unordered_set<int64_t>& requests) { + std::scoped_lock<std::mutex> lockGuard(lock); + for (int64_t request : requests) { + timeoutRequestIds.push_back(request); + } + }); + + ASSERT_RESULT_OK(getPool()->addRequests(getTestClientId(), requestIds, callback)); + + for (int64_t i = 0; i < 10; i++) { + ASSERT_TRUE(getPool()->isRequestPending(getTestClientId(), i)); + } + + // Finish half of the requests. + requestIds.clear(); + for (int64_t i = 0; i < 5; i++) { + requestIds.insert(i); + } + + ASSERT_EQ(getPool()->tryFinishRequests(getTestClientId(), requestIds), requestIds); + + for (int64_t i = 0; i < 5; i++) { + ASSERT_FALSE(getPool()->isRequestPending(getTestClientId(), i)); + } + for (int64_t i = 5; i < 10; i++) { + ASSERT_TRUE(getPool()->isRequestPending(getTestClientId(), i)); + } + + // Wait until the unfinished requests timeout. The check interval is timeout, so at max we + // would wait an additional interval, which is 2 * timeout until the callback is called. + std::this_thread::sleep_for(2 * std::chrono::nanoseconds(timeout)); + + ASSERT_THAT(timeoutRequestIds, WhenSorted(ElementsAre(5, 6, 7, 8, 9))); +} + +TEST_F(PendingRequestPoolTest, testFinishRequestTwice) { + std::mutex lock; + std::vector<int64_t> timeoutRequestIds; + + auto callback = std::make_shared<PendingRequestPool::TimeoutCallbackFunc>( + [&lock, &timeoutRequestIds](const std::unordered_set<int64_t>& requests) { + std::scoped_lock<std::mutex> lockGuard(lock); + for (int64_t request : requests) { + timeoutRequestIds.push_back(request); + } + }); + + ASSERT_RESULT_OK(getPool()->addRequests(getTestClientId(), {0}, callback)); + + ASSERT_THAT(getPool()->tryFinishRequests(getTestClientId(), {0}), UnorderedElementsAre(0)) + << "failed to finish an added request"; + ASSERT_TRUE(getPool()->tryFinishRequests(getTestClientId(), {0}).empty()) + << "finish a request second time must return empty result"; +} + +TEST_F(PendingRequestPoolTest, testFinishRequestNonExistingId) { + std::mutex lock; + std::vector<int64_t> timeoutRequestIds; + + auto callback = std::make_shared<PendingRequestPool::TimeoutCallbackFunc>( + [&lock, &timeoutRequestIds](const std::unordered_set<int64_t>& requests) { + std::scoped_lock<std::mutex> lockGuard(lock); + for (int64_t request : requests) { + timeoutRequestIds.push_back(request); + } + }); + + ASSERT_RESULT_OK(getPool()->addRequests(getTestClientId(), {0, 1, 2}, callback)); + + ASSERT_THAT(getPool()->tryFinishRequests(getTestClientId(), {0, 1, 2, 3}), + UnorderedElementsAre(0, 1, 2)) + << "finished request IDs must not contain non-existing request ID"; + // Even though one of the request to finish does not exist, the rest of the requests should be + // finished. + ASSERT_EQ(getPool()->countPendingRequests(getTestClientId()), static_cast<size_t>(0)) + << "requests not being finished correctly"; +} + +TEST_F(PendingRequestPoolTest, testFinishAfterTimeout) { + std::mutex lock; + std::vector<int64_t> timeoutRequestIds; + + auto callback = std::make_shared<PendingRequestPool::TimeoutCallbackFunc>( + [&lock, &timeoutRequestIds](const std::unordered_set<int64_t>& requests) { + std::scoped_lock<std::mutex> lockGuard(lock); + for (int64_t request : requests) { + timeoutRequestIds.push_back(request); + } + }); + + ASSERT_RESULT_OK(getPool()->addRequests(getTestClientId(), {0}, callback)); + + std::this_thread::sleep_for(2 * std::chrono::nanoseconds(getTimeout())); + + ASSERT_TRUE(getPool()->tryFinishRequests(getTestClientId(), {0}).empty()) + << "finish a request after timeout must do nothing"; +} + +TEST_F(PendingRequestPoolTest, testDestroyWithPendingRequests) { + std::mutex lock; + std::vector<int64_t> timeoutRequestIds; + + auto callback = std::make_shared<PendingRequestPool::TimeoutCallbackFunc>( + [&lock, &timeoutRequestIds](const std::unordered_set<int64_t>& requests) { + std::scoped_lock<std::mutex> lockGuard(lock); + for (int64_t request : requests) { + timeoutRequestIds.push_back(request); + } + }); + + ASSERT_RESULT_OK(getPool()->addRequests(getTestClientId(), {0}, callback)); + + destroyPool(); + + // Before the pool is destroyed, the pending requests should be notified as timeout. + ASSERT_THAT(timeoutRequestIds, UnorderedElementsAre(0)) + << "timeout not triggered when the pool is destroyed"; +} + +TEST_F(PendingRequestPoolTest, testDuplicateRequestId) { + auto callback = std::make_shared<PendingRequestPool::TimeoutCallbackFunc>( + [](std::unordered_set<int64_t>) {}); + + ASSERT_RESULT_OK(getPool()->addRequests(getTestClientId(), {0}, callback)); + ASSERT_FALSE(getPool()->addRequests(getTestClientId(), {1, 2, 0}, callback).ok()) + << "adding duplicate request IDs must fail"; + + ASSERT_THAT(getPool()->tryFinishRequests(getTestClientId(), {0}), UnorderedElementsAre(0)); +} + +TEST_F(PendingRequestPoolTest, testSameRequestIdForDifferentClient) { + auto callback = std::make_shared<PendingRequestPool::TimeoutCallbackFunc>( + [](std::unordered_set<int64_t>) {}); + + ASSERT_RESULT_OK(getPool()->addRequests(reinterpret_cast<void*>(0), {0}, callback)); + ASSERT_RESULT_OK(getPool()->addRequests(reinterpret_cast<void*>(1), {1, 2, 0}, callback)); + + ASSERT_THAT(getPool()->tryFinishRequests(reinterpret_cast<void*>(0), {0}), + UnorderedElementsAre(0)); + ASSERT_THAT(getPool()->tryFinishRequests(reinterpret_cast<void*>(1), {1, 2, 0}), + UnorderedElementsAre(0, 1, 2)); +} + +TEST_F(PendingRequestPoolTest, testPendingRequestCountLimit) { + auto callback = std::make_shared<PendingRequestPool::TimeoutCallbackFunc>( + [](std::unordered_set<int64_t>) {}); + + std::unordered_set<int64_t> requests; + + // MAX_PENDING_REQUEST_PER_CLIENT = 10000 + for (size_t i = 0; i < 10000; i++) { + requests.insert(static_cast<int64_t>(i)); + } + ASSERT_RESULT_OK(getPool()->addRequests(reinterpret_cast<void*>(0), requests, callback)); + + auto result = getPool()->addRequests(reinterpret_cast<void*>(0), {static_cast<int64_t>(10000)}, + callback); + ASSERT_FALSE(result.ok()) << "adding more pending requests than limit must fail"; + ASSERT_EQ(result.error().code(), toInt(StatusCode::TRY_AGAIN)); + + getPool()->tryFinishRequests(reinterpret_cast<void*>(0), requests); +} + +} // namespace vehicle +} // namespace automotive +} // namespace hardware +} // namespace android diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl new file mode 100644 index 0000000000..3a6461ed91 --- /dev/null +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.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.biometrics.common; +@VintfStability +parcelable OperationContext { + int id = 0; + android.hardware.biometrics.common.OperationReason reason = android.hardware.biometrics.common.OperationReason.UNKNOWN; + boolean isAoD = false; + boolean isCrypto = false; +} diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationReason.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationReason.aidl new file mode 100644 index 0000000000..3da3a6ab0b --- /dev/null +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationReason.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.biometrics.common; +@Backing(type="byte") @VintfStability +enum OperationReason { + UNKNOWN = 0, + BIOMETRIC_PROMPT = 1, + KEYGUARD = 2, +} diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl new file mode 100644 index 0000000000..390e6985e4 --- /dev/null +++ b/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl @@ -0,0 +1,49 @@ +/* + * 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.biometrics.common; + +import android.hardware.biometrics.common.OperationReason; + +/** + * Additional context associated with an operation. + */ +@VintfStability +parcelable OperationContext { + /** + * An identifier for the logical action that the user is engaged in. These identifiers are + * not guaranteed to be unique. However, the framework will not reuse identifiers within + * short periods of time so they can be made unique, if needed, by appending a timestamp. + * + * Zero if the reason is OperationReason.UNKNOWN. + */ + int id = 0; + + /** + * A logical reason for this operation. + * + * This should be interpreted as a hint to enable optimizations or tracing. The + * framework may choose to use OperationReason.UNKNOWN at any time based on the device's + * policy. + */ + OperationReason reason = OperationReason.UNKNOWN; + + /* Flag indicating that the display is in AoD mode. */ + boolean isAoD = false; + + /** Flag indicating that crypto was requested. */ + boolean isCrypto = false; +} diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/OperationReason.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/OperationReason.aidl new file mode 100644 index 0000000000..abc25ed663 --- /dev/null +++ b/biometrics/common/aidl/android/hardware/biometrics/common/OperationReason.aidl @@ -0,0 +1,37 @@ +/* + * 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.biometrics.common; + +@VintfStability +@Backing(type="byte") +enum OperationReason { + /** + * A normal operation without an explicit reason. + */ + UNKNOWN, + + /** + * An operation associated with biometric prompt. This may be due to either application or + * system use, but it is not related to KEYGUARD device entry. + */ + BIOMETRIC_PROMPT, + + /** + * An operation associated with device entry. + */ + KEYGUARD, +} diff --git a/biometrics/face/aidl/Android.bp b/biometrics/face/aidl/Android.bp index 3f53fc8cdf..fff2c1d3d4 100644 --- a/biometrics/face/aidl/Android.bp +++ b/biometrics/face/aidl/Android.bp @@ -16,7 +16,7 @@ aidl_interface { imports: [ "android.hardware.biometrics.common", "android.hardware.common-V2", - "android.hardware.keymaster", + "android.hardware.keymaster-V3", ], stability: "vintf", backend: { diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl index 78178642cd..4b51bb17cc 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl @@ -48,4 +48,7 @@ interface ISession { void invalidateAuthenticatorId(); void resetLockout(in android.hardware.keymaster.HardwareAuthToken hat); void close(); + android.hardware.biometrics.common.ICancellationSignal authenticateWithContext(in long operationId, in android.hardware.biometrics.common.OperationContext context); + android.hardware.biometrics.common.ICancellationSignal enrollWithContext(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in @nullable android.hardware.common.NativeHandle previewSurface, in android.hardware.biometrics.common.OperationContext context); + android.hardware.biometrics.common.ICancellationSignal detectInteractionWithContext(in android.hardware.biometrics.common.OperationContext context); } diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl index 5f06b408e8..bbe3632b6b 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl @@ -17,6 +17,7 @@ package android.hardware.biometrics.face; import android.hardware.biometrics.common.ICancellationSignal; +import android.hardware.biometrics.common.OperationContext; import android.hardware.biometrics.face.EnrollmentStageConfig; import android.hardware.biometrics.face.EnrollmentType; import android.hardware.biometrics.face.Feature; @@ -441,4 +442,23 @@ interface ISession { * - ISessionCallback#onSessionClosed */ void close(); + + /** + * These are alternative methods for some operations to allow the HAL to make optional + * optimizations during execution. + * + * HALs may ignore the additional context and treat all *WithContext methods the same as + * the original methods. + */ + + /* See ISession#authenticateWithContext(long) */ + ICancellationSignal authenticateWithContext(in long operationId, in OperationContext context); + + /* See ISession#enroll(HardwareAuthToken, EnrollmentType, Feature[], NativeHandle) */ + ICancellationSignal enrollWithContext(in HardwareAuthToken hat, in EnrollmentType type, + in Feature[] features, in @nullable NativeHandle previewSurface, + in OperationContext context); + + /* See ISession#detectInteraction() */ + ICancellationSignal detectInteractionWithContext(in OperationContext context); } diff --git a/biometrics/face/aidl/default/Android.bp b/biometrics/face/aidl/default/Android.bp index 509231859d..7f66ecaf83 100644 --- a/biometrics/face/aidl/default/Android.bp +++ b/biometrics/face/aidl/default/Android.bp @@ -16,8 +16,8 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.biometrics.face-V1-ndk", - "android.hardware.biometrics.common-V1-ndk", + "android.hardware.biometrics.face-V2-ndk", + "android.hardware.biometrics.common-V2-ndk", ], srcs: [ "main.cpp", diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp index 01cb620b35..9e753e5c33 100644 --- a/biometrics/face/aidl/default/Session.cpp +++ b/biometrics/face/aidl/default/Session.cpp @@ -151,4 +151,25 @@ ndk::ScopedAStatus Session::close() { return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus Session::authenticateWithContext( + int64_t operationId, const common::OperationContext& /*context*/, + std::shared_ptr<common::ICancellationSignal>* out) { + return authenticate(operationId, out); +} + +ndk::ScopedAStatus Session::enrollWithContext(const keymaster::HardwareAuthToken& hat, + EnrollmentType enrollmentType, + const std::vector<Feature>& features, + const std::optional<NativeHandle>& previewSurface, + const common::OperationContext& /*context*/, + std::shared_ptr<common::ICancellationSignal>* out) { + return enroll(hat, enrollmentType, features, previewSurface, out); +} + +ndk::ScopedAStatus Session::detectInteractionWithContext( + const common::OperationContext& /*context*/, + std::shared_ptr<common::ICancellationSignal>* out) { + return detectInteraction(out); +} + } // namespace aidl::android::hardware::biometrics::face diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h index 4152909a49..0ce9e2060e 100644 --- a/biometrics/face/aidl/default/Session.h +++ b/biometrics/face/aidl/default/Session.h @@ -68,6 +68,20 @@ class Session : public BnSession { ndk::ScopedAStatus close() override; + ndk::ScopedAStatus authenticateWithContext( + int64_t operationId, const common::OperationContext& context, + std::shared_ptr<common::ICancellationSignal>* out) override; + + ndk::ScopedAStatus enrollWithContext( + const keymaster::HardwareAuthToken& hat, EnrollmentType enrollmentType, + const std::vector<Feature>& features, const std::optional<NativeHandle>& previewSurface, + const common::OperationContext& context, + std::shared_ptr<common::ICancellationSignal>* out) override; + + ndk::ScopedAStatus detectInteractionWithContext( + const common::OperationContext& context, + std::shared_ptr<common::ICancellationSignal>* out) override; + private: std::shared_ptr<ISessionCallback> cb_; std::mt19937 mRandom; diff --git a/biometrics/face/aidl/default/face-default.xml b/biometrics/face/aidl/default/face-default.xml index 6915ad0a4d..e6ef842734 100644 --- a/biometrics/face/aidl/default/face-default.xml +++ b/biometrics/face/aidl/default/face-default.xml @@ -1,6 +1,7 @@ <manifest version="1.0" type="device"> <hal format="aidl"> <name>android.hardware.biometrics.face</name> + <version>2</version> <fqname>IFace/default</fqname> </hal> </manifest> diff --git a/biometrics/face/aidl/vts/Android.bp b/biometrics/face/aidl/vts/Android.bp index 09ec4d06e3..4171ac3364 100644 --- a/biometrics/face/aidl/vts/Android.bp +++ b/biometrics/face/aidl/vts/Android.bp @@ -15,8 +15,8 @@ cc_test { ], srcs: ["VtsHalBiometricsFaceTargetTest.cpp"], static_libs: [ - "android.hardware.biometrics.common-V1-ndk", - "android.hardware.biometrics.face-V1-ndk", + "android.hardware.biometrics.common-V2-ndk", + "android.hardware.biometrics.face-V2-ndk", "android.hardware.common-V2-ndk", "android.hardware.keymaster-V3-ndk", ], diff --git a/biometrics/fingerprint/aidl/Android.bp b/biometrics/fingerprint/aidl/Android.bp index c46150ebe5..c3a056cc2b 100644 --- a/biometrics/fingerprint/aidl/Android.bp +++ b/biometrics/fingerprint/aidl/Android.bp @@ -15,7 +15,7 @@ aidl_interface { ], imports: [ "android.hardware.biometrics.common", - "android.hardware.keymaster", + "android.hardware.keymaster-V3", ], stability: "vintf", backend: { @@ -26,8 +26,5 @@ aidl_interface { enabled: false, }, }, - versions: [ - "1", - "2", - ], + versions: ["1"], } diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/.hash b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/.hash deleted file mode 100644 index 411cb751cb..0000000000 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/.hash +++ /dev/null @@ -1 +0,0 @@ -762eb38ce93ea3c7d39a680949cbdbd2371b3f06 diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl index 9934a763e7..4e7b3b451e 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl @@ -48,4 +48,9 @@ interface ISession { void onPointerDown(in int pointerId, in int x, in int y, in float minor, in float major); void onPointerUp(in int pointerId); void onUiReady(); + android.hardware.biometrics.common.ICancellationSignal authenticateWithContext(in long operationId, in android.hardware.biometrics.common.OperationContext context); + android.hardware.biometrics.common.ICancellationSignal enrollWithContext(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.common.OperationContext context); + android.hardware.biometrics.common.ICancellationSignal detectInteractionWithContext(in android.hardware.biometrics.common.OperationContext context); + void onPointerDownWithContext(in android.hardware.biometrics.fingerprint.PointerContext context); + void onPointerUpWithContext(in android.hardware.biometrics.fingerprint.PointerContext context); } diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/PointerContext.aidl index 295fde9f5f..e383330b69 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/PointerContext.aidl @@ -33,10 +33,11 @@ package android.hardware.biometrics.fingerprint; @VintfStability -parcelable SensorLocation { - int displayId; - int sensorLocationX; - int sensorLocationY; - int sensorRadius; - String display = ""; +parcelable PointerContext { + int pointerId = 0; + int x = 0; + int y = 0; + float minor = 0.000000f; + float major = 0.000000f; + boolean isAoD = false; } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl index f1d96d3039..ea8c6aa869 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl @@ -17,6 +17,8 @@ package android.hardware.biometrics.fingerprint; import android.hardware.biometrics.common.ICancellationSignal; +import android.hardware.biometrics.common.OperationContext; +import android.hardware.biometrics.fingerprint.PointerContext; import android.hardware.keymaster.HardwareAuthToken; /** @@ -140,7 +142,7 @@ interface ISession { * * @param hat See above documentation. * @return ICancellationSignal An object that can be used by the framework to cancel this - * operation. + * operation. */ ICancellationSignal enroll(in HardwareAuthToken hat); @@ -234,7 +236,7 @@ interface ISession { * - ISessionCallback#onAcquired * * @return ICancellationSignal An object that can be used by the framework to cancel this - * operation. + * operation. */ ICancellationSignal detectInteraction(); @@ -448,4 +450,27 @@ interface ISession { * HAL, the framework will invoke this operation to notify when the illumination is showing. */ void onUiReady(); + + /** + * These are alternative methods for some operations to allow the HAL to make optional + * optimizations during execution. + * + * HALs may ignore the additional context and treat all *WithContext methods the same as + * the original methods. + */ + + /** See ISession#authenticate(long) */ + ICancellationSignal authenticateWithContext(in long operationId, in OperationContext context); + + /** See ISession#enroll(HardwareAuthToken) */ + ICancellationSignal enrollWithContext(in HardwareAuthToken hat, in OperationContext context); + + /** See ISession#detectInteraction() */ + ICancellationSignal detectInteractionWithContext(in OperationContext context); + + /** See ISession#onPointerDown(int, int, int, float, float) */ + void onPointerDownWithContext(in PointerContext context); + + /** See ISession#onPointerUp(int) */ + void onPointerUpWithContext(in PointerContext context); } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/PointerContext.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/PointerContext.aidl new file mode 100644 index 0000000000..4975175d8c --- /dev/null +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/PointerContext.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. + */ + +package android.hardware.biometrics.fingerprint; + +/** + * Additional context associated with a pointer event. + */ +@VintfStability +parcelable PointerContext { + /* See android.view.MotionEvent#getPointerId. */ + int pointerId = 0; + + /* The distance in pixels from the left edge of the display. */ + int x = 0; + + /* The distance in pixels from the top edge of the display. */ + int y = 0; + + /* See android.view.MotionEvent#getTouchMinor. */ + float minor = 0f; + + /* See android.view.MotionEvent#getTouchMajor. */ + float major = 0f; + + /* Flag indicating that the display is in AoD mode. */ + boolean isAoD = false; +} diff --git a/biometrics/fingerprint/aidl/default/Android.bp b/biometrics/fingerprint/aidl/default/Android.bp index d4194a3afb..430bf3cd82 100644 --- a/biometrics/fingerprint/aidl/default/Android.bp +++ b/biometrics/fingerprint/aidl/default/Android.bp @@ -25,7 +25,7 @@ cc_binary { "libbase", "libbinder_ndk", "android.hardware.biometrics.fingerprint-V2-ndk", - "android.hardware.biometrics.common-V1-ndk", + "android.hardware.biometrics.common-V2-ndk", ], } diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp index ca481e7cf0..8cbcfc77c5 100644 --- a/biometrics/fingerprint/aidl/default/Session.cpp +++ b/biometrics/fingerprint/aidl/default/Session.cpp @@ -244,4 +244,30 @@ ndk::ScopedAStatus Session::onUiReady() { return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus Session::authenticateWithContext( + int64_t operationId, const common::OperationContext& /*context*/, + std::shared_ptr<common::ICancellationSignal>* out) { + return authenticate(operationId, out); +} + +ndk::ScopedAStatus Session::enrollWithContext(const keymaster::HardwareAuthToken& hat, + const common::OperationContext& /*context*/, + std::shared_ptr<common::ICancellationSignal>* out) { + return enroll(hat, out); +} + +ndk::ScopedAStatus Session::detectInteractionWithContext( + const common::OperationContext& /*context*/, + std::shared_ptr<common::ICancellationSignal>* out) { + return detectInteraction(out); +} + +ndk::ScopedAStatus Session::onPointerDownWithContext(const PointerContext& context) { + return onPointerDown(context.pointerId, context.x, context.y, context.minor, context.major); +} + +ndk::ScopedAStatus Session::onPointerUpWithContext(const PointerContext& context) { + return onPointerUp(context.pointerId); +} + } // namespace aidl::android::hardware::biometrics::fingerprint diff --git a/biometrics/fingerprint/aidl/default/include/Session.h b/biometrics/fingerprint/aidl/default/include/Session.h index 9e464229e1..584cb27b96 100644 --- a/biometrics/fingerprint/aidl/default/include/Session.h +++ b/biometrics/fingerprint/aidl/default/include/Session.h @@ -79,6 +79,22 @@ class Session : public BnSession { ndk::ScopedAStatus onUiReady() override; + ndk::ScopedAStatus authenticateWithContext( + int64_t operationId, const common::OperationContext& context, + std::shared_ptr<common::ICancellationSignal>* out) override; + + ndk::ScopedAStatus enrollWithContext( + const keymaster::HardwareAuthToken& hat, const common::OperationContext& context, + std::shared_ptr<common::ICancellationSignal>* out) override; + + ndk::ScopedAStatus detectInteractionWithContext( + const common::OperationContext& context, + std::shared_ptr<common::ICancellationSignal>* out) override; + + ndk::ScopedAStatus onPointerDownWithContext(const PointerContext& context) override; + + ndk::ScopedAStatus onPointerUpWithContext(const PointerContext& context) override; + bool isClosed(); private: diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp index 9435311b13..490a436b5e 100644 --- a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp +++ b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp @@ -233,7 +233,7 @@ Return<void> BluetoothAudioProvidersFactory::getProviderCapabilities_2_2( 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 8ec366060c..67558995f9 100644 --- a/bluetooth/audio/2.2/types.hal +++ b/bluetooth/audio/2.2/types.hal @@ -83,23 +83,22 @@ safe_union AudioConfiguration { 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 @@ struct LeAudioCodecCapability { // 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/aidl/Android.bp b/bluetooth/audio/aidl/Android.bp index 12eed55072..5107240957 100644 --- a/bluetooth/audio/aidl/Android.bp +++ b/bluetooth/audio/aidl/Android.bp @@ -43,6 +43,10 @@ aidl_interface { vndk: { enabled: true, }, + apex_available: [ + "//apex_available:platform", + "com.android.bluetooth", + ], }, }, } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl index ad44c26f59..899b8ca6db 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl @@ -34,9 +34,9 @@ package android.hardware.bluetooth.audio; @VintfStability parcelable AacCapabilities { - android.hardware.bluetooth.audio.AacObjectType objectType; + android.hardware.bluetooth.audio.AacObjectType[] objectType; int[] sampleRateHz; - android.hardware.bluetooth.audio.ChannelMode channelMode; + android.hardware.bluetooth.audio.ChannelMode[] channelMode; boolean variableBitRateSupported; byte[] bitsPerSample; } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl index c129c66b40..2148244d06 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl @@ -34,8 +34,8 @@ package android.hardware.bluetooth.audio; @Backing(type="byte") @VintfStability enum AacObjectType { - MPEG2_LC = 1, - MPEG4_LC = 2, - MPEG4_LTP = 4, - MPEG4_SCALABLE = 8, + MPEG2_LC = 0, + MPEG4_LC = 1, + MPEG4_LTP = 2, + MPEG4_SCALABLE = 3, } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl index 4767b696ec..08a38e26e1 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl @@ -35,6 +35,6 @@ package android.hardware.bluetooth.audio; @VintfStability parcelable AptxCapabilities { int[] sampleRateHz; - android.hardware.bluetooth.audio.ChannelMode channelMode; + android.hardware.bluetooth.audio.ChannelMode[] channelMode; byte[] bitsPerSample; } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl index 20a7731010..8ae716ff23 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl @@ -35,6 +35,6 @@ package android.hardware.bluetooth.audio; @VintfStability union AudioCapabilities { android.hardware.bluetooth.audio.PcmCapabilities pcmCapabilities; - android.hardware.bluetooth.audio.CodecCapabilities codecCapabilities; - android.hardware.bluetooth.audio.LeAudioCapabilities leAudioCapabilities; + android.hardware.bluetooth.audio.CodecCapabilities a2dpCapabilities; + android.hardware.bluetooth.audio.LeAudioCodecCapabilitiesSetting leAudioCapabilities; } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl index 34f7837967..50b54c30c0 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl @@ -35,6 +35,6 @@ package android.hardware.bluetooth.audio; @VintfStability union AudioConfiguration { android.hardware.bluetooth.audio.PcmConfiguration pcmConfig; - android.hardware.bluetooth.audio.CodecConfiguration codecConfig; + android.hardware.bluetooth.audio.CodecConfiguration a2dpConfig; android.hardware.bluetooth.audio.LeAudioConfiguration leAudioConfig; } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastCapability.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastCapability.aidl new file mode 100644 index 0000000000..58710effe7 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastCapability.aidl @@ -0,0 +1,50 @@ +/* + * Copyright 2022 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.bluetooth.audio; +@VintfStability +parcelable BroadcastCapability { + android.hardware.bluetooth.audio.CodecType codecType; + android.hardware.bluetooth.audio.AudioLocation supportedChannel; + int channelCountPerStream; + android.hardware.bluetooth.audio.BroadcastCapability.LeAudioCodecCapabilities leAudioCodecCapabilities; + @VintfStability + parcelable VendorCapabilities { + ParcelableHolder extension; + } + @VintfStability + union LeAudioCodecCapabilities { + @nullable android.hardware.bluetooth.audio.Lc3Capabilities[] lc3Capabilities; + @nullable android.hardware.bluetooth.audio.BroadcastCapability.VendorCapabilities[] vendorCapabillities; + } +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl index b3aa709ddd..5fa392631b 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl @@ -39,6 +39,6 @@ parcelable BroadcastConfiguration { parcelable BroadcastStreamMap { char streamHandle; int audioChannelAllocation; - android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCondecConfig; + android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCodecConfig; } } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl index 3ca93c3e03..c3bc7410e4 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl @@ -34,7 +34,7 @@ package android.hardware.bluetooth.audio; @Backing(type="byte") @VintfStability enum ChannelMode { - UNKNOWN = 1, - MONO = 2, - STEREO = 4, + UNKNOWN = 0, + MONO = 1, + STEREO = 2, } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl index b451880e05..e2a08a0e6d 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl @@ -42,5 +42,6 @@ parcelable CodecCapabilities { android.hardware.bluetooth.audio.AacCapabilities aacCapabilities; android.hardware.bluetooth.audio.LdacCapabilities ldacCapabilities; android.hardware.bluetooth.audio.AptxCapabilities aptxCapabilities; + android.hardware.bluetooth.audio.Lc3Capabilities lc3Capabilities; } } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl index 863aee244c..34ebd60530 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl @@ -45,5 +45,6 @@ parcelable CodecConfiguration { android.hardware.bluetooth.audio.AacConfiguration aacConfig; android.hardware.bluetooth.audio.LdacConfiguration ldacConfig; android.hardware.bluetooth.audio.AptxConfiguration aptxConfig; + android.hardware.bluetooth.audio.Lc3Configuration lc3Config; } } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl index e5e79cb1c4..0dcba2e818 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl @@ -38,4 +38,5 @@ interface IBluetoothAudioProvider { android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> startSession(in android.hardware.bluetooth.audio.IBluetoothAudioPort hostIf, in android.hardware.bluetooth.audio.AudioConfiguration audioConfig); void streamStarted(in android.hardware.bluetooth.audio.BluetoothAudioStatus status); void streamSuspended(in android.hardware.bluetooth.audio.BluetoothAudioStatus status); + void updateAudioConfiguration(in android.hardware.bluetooth.audio.AudioConfiguration audioConfig); } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl index 3c650da4f7..cc4449aea9 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl @@ -39,4 +39,5 @@ parcelable Lc3Capabilities { int[] frameDurationUs; int[] octetsPerFrame; byte[] blocksPerSdu; + android.hardware.bluetooth.audio.ChannelMode[] channelMode; } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl index ef77da7023..7e8dccff5f 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl @@ -39,4 +39,5 @@ parcelable Lc3Configuration { int frameDurationUs; int octetsPerFrame; byte blocksPerSdu; + android.hardware.bluetooth.audio.ChannelMode channelMode; } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl index 19e041a15c..aa4e4c8793 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl @@ -35,7 +35,7 @@ package android.hardware.bluetooth.audio; @VintfStability parcelable LdacCapabilities { int[] sampleRateHz; - android.hardware.bluetooth.audio.LdacChannelMode channelMode; - android.hardware.bluetooth.audio.LdacQualityIndex qualityIndex; + android.hardware.bluetooth.audio.LdacChannelMode[] channelMode; + android.hardware.bluetooth.audio.LdacQualityIndex[] qualityIndex; byte[] bitsPerSample; } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl index a9d6c5e14e..88d6faff53 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl @@ -34,8 +34,8 @@ package android.hardware.bluetooth.audio; @Backing(type="byte") @VintfStability enum LdacChannelMode { - UNKNOWN = 1, - STEREO = 2, - DUAL = 4, - MONO = 8, + UNKNOWN = 0, + STEREO = 1, + DUAL = 2, + MONO = 3, } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl index 693392fe51..35e435867e 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl @@ -34,8 +34,8 @@ package android.hardware.bluetooth.audio; @Backing(type="byte") @VintfStability enum LdacQualityIndex { - HIGH = 1, - MID = 2, - LOW = 4, - ABR = 8, + HIGH = 0, + MID = 1, + LOW = 2, + ABR = 3, } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl new file mode 100644 index 0000000000..9818d543ac --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl @@ -0,0 +1,40 @@ +/* + * Copyright 2022 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.bluetooth.audio; +@VintfStability +parcelable LeAudioCodecCapabilitiesSetting { + android.hardware.bluetooth.audio.UnicastCapability unicastEncodeCapability; + android.hardware.bluetooth.audio.UnicastCapability unicastDecodeCapability; + android.hardware.bluetooth.audio.BroadcastCapability broadcastCapability; +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl index 6cfe5cd78c..0c2f87d599 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl @@ -35,7 +35,7 @@ package android.hardware.bluetooth.audio; @VintfStability parcelable PcmCapabilities { int[] sampleRateHz; - android.hardware.bluetooth.audio.ChannelMode channelMode; + android.hardware.bluetooth.audio.ChannelMode[] channelMode; byte[] bitsPerSample; int[] dataIntervalUs; } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl index 5170f164a3..091f6d7246 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl @@ -34,6 +34,6 @@ package android.hardware.bluetooth.audio; @Backing(type="byte") @VintfStability enum SbcAllocMethod { - ALLOC_MD_S = 1, - ALLOC_MD_L = 2, + ALLOC_MD_S = 0, + ALLOC_MD_L = 1, } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl index ec3aa0f262..c8d7e7e74e 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl @@ -35,10 +35,10 @@ package android.hardware.bluetooth.audio; @VintfStability parcelable SbcCapabilities { int[] sampleRateHz; - android.hardware.bluetooth.audio.SbcChannelMode channelMode; + android.hardware.bluetooth.audio.SbcChannelMode[] channelMode; byte[] blockLength; byte[] numSubbands; - android.hardware.bluetooth.audio.SbcAllocMethod allocMethod; + android.hardware.bluetooth.audio.SbcAllocMethod[] allocMethod; byte[] bitsPerSample; int minBitpool; int maxBitpool; diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl index 88fca4aac4..6441a99877 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl @@ -34,9 +34,9 @@ package android.hardware.bluetooth.audio; @Backing(type="byte") @VintfStability enum SbcChannelMode { - UNKNOWN = 1, - JOINT_STEREO = 2, - STEREO = 4, - DUAL = 8, - MONO = 16, + UNKNOWN = 0, + JOINT_STEREO = 1, + STEREO = 2, + DUAL = 3, + MONO = 4, } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl index a7224ca5da..130fef971c 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl @@ -33,12 +33,12 @@ package android.hardware.bluetooth.audio; @VintfStability -parcelable LeAudioCapabilities { - android.hardware.bluetooth.audio.LeAudioMode mode; +parcelable UnicastCapability { android.hardware.bluetooth.audio.CodecType codecType; android.hardware.bluetooth.audio.AudioLocation supportedChannel; - int supportedChannelCount; - android.hardware.bluetooth.audio.LeAudioCapabilities.LeAudioCodecCapabilities leAudioCodecCapabilities; + int deviceCount; + int channelCountPerDevice; + android.hardware.bluetooth.audio.UnicastCapability.LeAudioCodecCapabilities leAudioCodecCapabilities; @VintfStability parcelable VendorCapabilities { ParcelableHolder extension; @@ -46,6 +46,6 @@ parcelable LeAudioCapabilities { @VintfStability union LeAudioCodecCapabilities { android.hardware.bluetooth.audio.Lc3Capabilities lc3Capabilities; - android.hardware.bluetooth.audio.LeAudioCapabilities.VendorCapabilities vendorCapabillities; + android.hardware.bluetooth.audio.UnicastCapability.VendorCapabilities vendorCapabillities; } } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl index 43038836aa..c4153e9ffd 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl @@ -24,11 +24,9 @@ import android.hardware.bluetooth.audio.ChannelMode; */ @VintfStability parcelable AacCapabilities { - /* bitfield */ - AacObjectType objectType; + AacObjectType[] objectType; int[] sampleRateHz; - /* bitfield */ - ChannelMode channelMode; + ChannelMode[] channelMode; boolean variableBitRateSupported; byte[] bitsPerSample; } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl index 480e422e1c..4e9958c855 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl @@ -22,17 +22,17 @@ enum AacObjectType { /** * MPEG-2 Low Complexity. Support is Mandatory. */ - MPEG2_LC = 1, + MPEG2_LC, /** * MPEG-4 Low Complexity. Support is Optional. */ - MPEG4_LC = 1 << 1, + MPEG4_LC, /** * MPEG-4 Long Term Prediction. Support is Optional. */ - MPEG4_LTP = 1 << 2, + MPEG4_LTP, /** * MPEG-4 Scalable. Support is Optional. */ - MPEG4_SCALABLE = 1 << 3, + MPEG4_SCALABLE, } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl index 6a37fc6a41..f5605d31fe 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl @@ -24,7 +24,6 @@ import android.hardware.bluetooth.audio.ChannelMode; @VintfStability parcelable AptxCapabilities { int[] sampleRateHz; - /* bitfield */ - ChannelMode channelMode; + ChannelMode[] channelMode; byte[] bitsPerSample; } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl index 6ed44722cc..a75c4457e9 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl @@ -17,7 +17,7 @@ package android.hardware.bluetooth.audio; import android.hardware.bluetooth.audio.CodecCapabilities; -import android.hardware.bluetooth.audio.LeAudioCapabilities; +import android.hardware.bluetooth.audio.LeAudioCodecCapabilitiesSetting; import android.hardware.bluetooth.audio.PcmCapabilities; /** @@ -26,6 +26,6 @@ import android.hardware.bluetooth.audio.PcmCapabilities; @VintfStability union AudioCapabilities { PcmCapabilities pcmCapabilities; - CodecCapabilities codecCapabilities; - LeAudioCapabilities leAudioCapabilities; + CodecCapabilities a2dpCapabilities; + LeAudioCodecCapabilitiesSetting leAudioCapabilities; } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl index ce515b5611..81b41dcf7f 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl @@ -26,6 +26,6 @@ import android.hardware.bluetooth.audio.PcmConfiguration; @VintfStability union AudioConfiguration { PcmConfiguration pcmConfig; - CodecConfiguration codecConfig; + CodecConfiguration a2dpConfig; LeAudioConfiguration leAudioConfig; } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastCapability.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastCapability.aidl new file mode 100644 index 0000000000..cb63f88ea9 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastCapability.aidl @@ -0,0 +1,43 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.bluetooth.audio; + +import android.hardware.bluetooth.audio.AudioLocation; +import android.hardware.bluetooth.audio.CodecType; +import android.hardware.bluetooth.audio.Lc3Capabilities; +import android.hardware.bluetooth.audio.LeAudioMode; + +/** + * Used to specify the le audio broadcast codec capabilities for hardware offload. + */ +@VintfStability +parcelable BroadcastCapability { + @VintfStability + parcelable VendorCapabilities { + ParcelableHolder extension; + } + @VintfStability + union LeAudioCodecCapabilities { + @nullable Lc3Capabilities[] lc3Capabilities; + @nullable VendorCapabilities[] vendorCapabillities; + } + CodecType codecType; + AudioLocation supportedChannel; + // Supported channel count for each stream + int channelCountPerStream; + LeAudioCodecCapabilities leAudioCodecCapabilities; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl index 07d05f1bd7..cfc9d3aa01 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl @@ -33,7 +33,7 @@ parcelable BroadcastConfiguration { * least significant bit to the most significant bit. */ int audioChannelAllocation; - LeAudioCodecConfiguration leAudioCondecConfig; + LeAudioCodecConfiguration leAudioCodecConfig; } BroadcastStreamMap[] streamMap; } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl index 2df879d837..66138724ae 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl @@ -19,7 +19,7 @@ package android.hardware.bluetooth.audio; @VintfStability @Backing(type="byte") enum ChannelMode { - UNKNOWN = 1, - MONO = 1 << 1, - STEREO = 1 << 2, + UNKNOWN, + MONO, + STEREO, } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl index 0eee8cb55b..5bf0252bf8 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl @@ -19,6 +19,7 @@ package android.hardware.bluetooth.audio; import android.hardware.bluetooth.audio.AacCapabilities; import android.hardware.bluetooth.audio.AptxCapabilities; import android.hardware.bluetooth.audio.CodecType; +import android.hardware.bluetooth.audio.Lc3Capabilities; import android.hardware.bluetooth.audio.LdacCapabilities; import android.hardware.bluetooth.audio.SbcCapabilities; @@ -34,6 +35,7 @@ parcelable CodecCapabilities { AacCapabilities aacCapabilities; LdacCapabilities ldacCapabilities; AptxCapabilities aptxCapabilities; + Lc3Capabilities lc3Capabilities; } CodecType codecType; Capabilities capabilities; diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl index fac90f065d..9e43f2244a 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl @@ -19,6 +19,7 @@ package android.hardware.bluetooth.audio; import android.hardware.bluetooth.audio.AacConfiguration; import android.hardware.bluetooth.audio.AptxConfiguration; import android.hardware.bluetooth.audio.CodecType; +import android.hardware.bluetooth.audio.Lc3Configuration; import android.hardware.bluetooth.audio.LdacConfiguration; import android.hardware.bluetooth.audio.SbcConfiguration; @@ -34,6 +35,7 @@ parcelable CodecConfiguration { AacConfiguration aacConfig; LdacConfiguration ldacConfig; AptxConfiguration aptxConfig; + Lc3Configuration lc3Config; } CodecType codecType; /** diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl index a2c5ae9a76..6f88f3041a 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl @@ -72,4 +72,14 @@ interface IBluetoothAudioProvider { * @param status true for SUCCESS or false for FAILURE */ void streamSuspended(in BluetoothAudioStatus status); + + /** + * Called when the audio configuration of the stream has been changed. + * + * @param audioConfig The audio configuration negotiated with the remote + * device. The PCM parameters are set if software based encoding, + * otherwise the correct codec configuration is used for hardware + * encoding. + */ + void updateAudioConfiguration(in AudioConfiguration audioConfig); } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl index 1aedefd2d5..fc2f382d18 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl @@ -16,6 +16,8 @@ package android.hardware.bluetooth.audio; +import android.hardware.bluetooth.audio.ChannelMode; + /** * Used for Hardware Encoding/Decoding LC3 codec capabilities. */ @@ -41,4 +43,8 @@ parcelable Lc3Capabilities { * Number of blocks of codec frames per single SDU (Service Data Unit) */ byte[] blocksPerSdu; + /* + * Channel mode used in A2DP special audio, ignored in standard LE Audio mode + */ + ChannelMode[] channelMode; } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl index 77c04c1b6e..e8a93b27d8 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl @@ -16,6 +16,8 @@ package android.hardware.bluetooth.audio; +import android.hardware.bluetooth.audio.ChannelMode; + /** * Used for Hardware Encoding/Decoding LC3 codec configuration. */ @@ -41,4 +43,8 @@ parcelable Lc3Configuration { * Number of blocks of codec frames per single SDU (Service Data Unit) */ byte blocksPerSdu; + /* + * Channel mode used in A2DP special audio, ignored in standard LE Audio mode + */ + ChannelMode channelMode; } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl index 44cca7e071..1dbec0896b 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl @@ -26,9 +26,7 @@ import android.hardware.bluetooth.audio.LdacQualityIndex; @VintfStability parcelable LdacCapabilities { int[] sampleRateHz; - /* bitfiled */ - LdacChannelMode channelMode; - /* bitfiled */ - LdacQualityIndex qualityIndex; + LdacChannelMode[] channelMode; + LdacQualityIndex[] qualityIndex; byte[] bitsPerSample; } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl index 3acca32fc2..3cc910f49c 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl @@ -22,8 +22,8 @@ package android.hardware.bluetooth.audio; @VintfStability @Backing(type="byte") enum LdacChannelMode { - UNKNOWN = 1, - STEREO = 1 << 1, - DUAL = 1 << 2, - MONO = 1 << 3, + UNKNOWN, + STEREO, + DUAL, + MONO, } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl index cb125839ef..9993b8b6d2 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl @@ -22,17 +22,17 @@ enum LdacQualityIndex { /** * 990kbps */ - HIGH = 1, + HIGH, /** * 660kbps */ - MID = 1 << 1, + MID, /** * 330kbps */ - LOW = 1 << 2, + LOW, /** * Adaptive Bit Rate mode */ - ABR = 1 << 3, + ABR, } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl new file mode 100644 index 0000000000..58dac06080 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl @@ -0,0 +1,30 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.bluetooth.audio; + +import android.hardware.bluetooth.audio.BroadcastCapability; +import android.hardware.bluetooth.audio.UnicastCapability; + +/** + * Used to specify the le audio capabilities for unicast and broadcast hardware offload. + */ +@VintfStability +parcelable LeAudioCodecCapabilitiesSetting { + UnicastCapability unicastEncodeCapability; + UnicastCapability unicastDecodeCapability; + BroadcastCapability broadcastCapability; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl index f5d699edf1..776b777f50 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl @@ -24,7 +24,7 @@ import android.hardware.bluetooth.audio.ChannelMode; @VintfStability parcelable PcmCapabilities { int[] sampleRateHz; - ChannelMode channelMode; + ChannelMode[] channelMode; byte[] bitsPerSample; /** * Data interval for data transfer diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl index 7047e346dc..1159f30374 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl @@ -22,9 +22,9 @@ enum SbcAllocMethod { /** * SNR */ - ALLOC_MD_S = 1, + ALLOC_MD_S, /** * Loudness */ - ALLOC_MD_L = 1 << 1, + ALLOC_MD_L, } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl index cf62ed4e5e..743a1f73e2 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl @@ -25,12 +25,10 @@ import android.hardware.bluetooth.audio.SbcChannelMode; @VintfStability parcelable SbcCapabilities { int[] sampleRateHz; - /* bitfield */ - SbcChannelMode channelMode; + SbcChannelMode[] channelMode; byte[] blockLength; byte[] numSubbands; - /* bitfield */ - SbcAllocMethod allocMethod; + SbcAllocMethod[] allocMethod; byte[] bitsPerSample; /* * range from 2 to 250. diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl index 7eb38cd9f7..68e32670e8 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl @@ -19,9 +19,9 @@ package android.hardware.bluetooth.audio; @VintfStability @Backing(type="byte") enum SbcChannelMode { - UNKNOWN = 1, - JOINT_STEREO = 1 << 1, - STEREO = 1 << 2, - DUAL = 1 << 3, - MONO = 1 << 4, + UNKNOWN, + JOINT_STEREO, + STEREO, + DUAL, + MONO, } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl index 732427f060..cd8a4c1971 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl @@ -22,10 +22,10 @@ import android.hardware.bluetooth.audio.Lc3Capabilities; import android.hardware.bluetooth.audio.LeAudioMode; /** - * Used to specify the capabilities of the LC3 codecs supported by Hardware Encoding. + * Used to specify the le audio unicast codec capabilities for hardware offload. */ @VintfStability -parcelable LeAudioCapabilities { +parcelable UnicastCapability { @VintfStability parcelable VendorCapabilities { ParcelableHolder extension; @@ -35,13 +35,11 @@ parcelable LeAudioCapabilities { Lc3Capabilities lc3Capabilities; VendorCapabilities vendorCapabillities; } - LeAudioMode mode; CodecType codecType; - /* - * This is bitfield, if bit N is set, HW Offloader supports N+1 channels at the same time. - * Example: 0x27 = 0b00100111: One, two, three or six channels supported. - */ AudioLocation supportedChannel; - int supportedChannelCount; + // The number of connected device + int deviceCount; + // Supported channel count for each device + int channelCountPerDevice; LeAudioCodecCapabilities leAudioCodecCapabilities; } diff --git a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp new file mode 100644 index 0000000000..fc8a911145 --- /dev/null +++ b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "BTAudioProviderA2dpHW" + +#include "A2dpOffloadAudioProvider.h" + +#include <BluetoothAudioCodecs.h> +#include <BluetoothAudioSessionReport.h> +#include <android-base/logging.h> + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +A2dpOffloadAudioProvider::A2dpOffloadAudioProvider() { + session_type_ = SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH; +} + +bool A2dpOffloadAudioProvider::isValid(const SessionType& session_type) { + return (session_type == session_type_); +} + +ndk::ScopedAStatus A2dpOffloadAudioProvider::startSession( + const std::shared_ptr<IBluetoothAudioPort>& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) { + if (audio_config.getTag() != AudioConfiguration::a2dpConfig) { + LOG(WARNING) << __func__ << " - Invalid Audio Configuration=" + << audio_config.toString(); + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + if (!BluetoothAudioCodecs::IsOffloadCodecConfigurationValid( + session_type_, audio_config.get<AudioConfiguration::a2dpConfig>())) { + LOG(WARNING) << __func__ << " - Invalid Audio Configuration=" + << audio_config.toString(); + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + return BluetoothAudioProvider::startSession(host_if, audio_config, + _aidl_return); +} + +ndk::ScopedAStatus A2dpOffloadAudioProvider::onSessionReady( + DataMQDesc* _aidl_return) { + *_aidl_return = DataMQDesc(); + BluetoothAudioSessionReport::OnSessionStarted(session_type_, stack_iface_, + nullptr, *audio_config_); + return ndk::ScopedAStatus::ok(); +} + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl
\ No newline at end of file diff --git a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h new file mode 100644 index 0000000000..5934f5b32d --- /dev/null +++ b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "BluetoothAudioProvider.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +class A2dpOffloadAudioProvider : public BluetoothAudioProvider { + public: + A2dpOffloadAudioProvider(); + + bool isValid(const SessionType& session_type) override; + + ndk::ScopedAStatus startSession( + const std::shared_ptr<IBluetoothAudioPort>& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return); + + private: + ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override; +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.cpp b/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.cpp new file mode 100644 index 0000000000..7e4907409e --- /dev/null +++ b/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "BTAudioProviderA2dpSW" + +#include "A2dpSoftwareAudioProvider.h" + +#include <BluetoothAudioCodecs.h> +#include <BluetoothAudioSessionReport.h> +#include <android-base/logging.h> + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +// Here the buffer size is based on SBC +static constexpr uint32_t kPcmFrameSize = 4; // 16 bits per sample / stereo +// SBC is 128, and here we choose the LCM of 16, 24, and 32 +static constexpr uint32_t kPcmFrameCount = 96; +static constexpr uint32_t kRtpFrameSize = kPcmFrameSize * kPcmFrameCount; +// The max counts by 1 tick (20ms) for SBC is about 7. Since using 96 for the +// PCM counts, here we just choose a greater number +static constexpr uint32_t kRtpFrameCount = 10; +static constexpr uint32_t kBufferSize = kRtpFrameSize * kRtpFrameCount; +static constexpr uint32_t kBufferCount = 2; // double buffer +static constexpr uint32_t kDataMqSize = kBufferSize * kBufferCount; + +A2dpSoftwareAudioProvider::A2dpSoftwareAudioProvider() + : BluetoothAudioProvider(), data_mq_(nullptr) { + LOG(INFO) << __func__ << " - size of audio buffer " << kDataMqSize + << " byte(s)"; + std::unique_ptr<DataMQ> data_mq( + new DataMQ(kDataMqSize, /* EventFlag */ true)); + if (data_mq && data_mq->isValid()) { + data_mq_ = std::move(data_mq); + session_type_ = SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH; + } else { + ALOGE_IF(!data_mq, "failed to allocate data MQ"); + ALOGE_IF(data_mq && !data_mq->isValid(), "data MQ is invalid"); + } +} + +bool A2dpSoftwareAudioProvider::isValid(const SessionType& sessionType) { + return (sessionType == session_type_ && data_mq_ && data_mq_->isValid()); +} + +ndk::ScopedAStatus A2dpSoftwareAudioProvider::startSession( + const std::shared_ptr<IBluetoothAudioPort>& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) { + if (audio_config.getTag() != AudioConfiguration::pcmConfig) { + LOG(WARNING) << __func__ << " - Invalid Audio Configuration=" + << audio_config.toString(); + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + const PcmConfiguration& pcm_config = + audio_config.get<AudioConfiguration::pcmConfig>(); + if (!BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid(pcm_config)) { + LOG(WARNING) << __func__ << " - Unsupported PCM Configuration=" + << pcm_config.toString(); + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + + return BluetoothAudioProvider::startSession(host_if, audio_config, + _aidl_return); +} + +ndk::ScopedAStatus A2dpSoftwareAudioProvider::onSessionReady( + DataMQDesc* _aidl_return) { + if (data_mq_ == nullptr || !data_mq_->isValid()) { + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + *_aidl_return = data_mq_->dupeDesc(); + BluetoothAudioSessionReport::OnSessionStarted(session_type_, stack_iface_, + _aidl_return, *audio_config_); + return ndk::ScopedAStatus::ok(); +} + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl
\ No newline at end of file diff --git a/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.h b/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.h new file mode 100644 index 0000000000..3bc0a135dd --- /dev/null +++ b/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "BluetoothAudioProvider.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +class A2dpSoftwareAudioProvider : public BluetoothAudioProvider { + public: + A2dpSoftwareAudioProvider(); + + bool isValid(const SessionType& sessionType) override; + + ndk::ScopedAStatus startSession( + const std::shared_ptr<IBluetoothAudioPort>& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return); + + private: + // audio data queue for software encoding + std::unique_ptr<DataMQ> data_mq_; + + ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override; +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/bluetooth/audio/aidl/default/Android.bp b/bluetooth/audio/aidl/default/Android.bp new file mode 100644 index 0000000000..846702fa0e --- /dev/null +++ b/bluetooth/audio/aidl/default/Android.bp @@ -0,0 +1,34 @@ +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_shared { + name: "android.hardware.bluetooth.audio-V1-impl", + vendor: true, + vintf_fragments: ["bluetooth_audio.xml"], + srcs: [ + "BluetoothAudioProvider.cpp", + "BluetoothAudioProviderFactory.cpp", + "A2dpOffloadAudioProvider.cpp", + "A2dpSoftwareAudioProvider.cpp", + "HearingAidAudioProvider.cpp", + "LeAudioOffloadAudioProvider.cpp", + "LeAudioSoftwareAudioProvider.cpp", + ], + export_include_dirs: ["."], + header_libs: ["libhardware_headers"], + shared_libs: [ + "libbase", + "libbinder_ndk", + "libcutils", + "libfmq", + "liblog", + "android.hardware.bluetooth.audio-V1-ndk", + "libbluetooth_audio_session_aidl", + ], +} diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp new file mode 100644 index 0000000000..c2ffa2efa2 --- /dev/null +++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "BTAudioProviderStub" + +#include "BluetoothAudioProvider.h" + +#include <BluetoothAudioSessionReport.h> +#include <android-base/logging.h> + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +BluetoothAudioProvider::BluetoothAudioProvider() { + death_recipient_ = ::ndk::ScopedAIBinder_DeathRecipient( + AIBinder_DeathRecipient_new(binderDiedCallbackAidl)); +} + +ndk::ScopedAStatus BluetoothAudioProvider::startSession( + const std::shared_ptr<IBluetoothAudioPort>& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) { + if (host_if == nullptr) { + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + audio_config_ = std::make_unique<AudioConfiguration>(audio_config); + stack_iface_ = host_if; + + AIBinder_linkToDeath(stack_iface_->asBinder().get(), death_recipient_.get(), + this); + + onSessionReady(_aidl_return); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus BluetoothAudioProvider::endSession() { + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_); + + if (stack_iface_ != nullptr) { + BluetoothAudioSessionReport::OnSessionEnded(session_type_); + + AIBinder_unlinkToDeath(stack_iface_->asBinder().get(), + death_recipient_.get(), this); + } else { + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) + << " has NO session"; + } + + stack_iface_ = nullptr; + audio_config_ = nullptr; + + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus BluetoothAudioProvider::streamStarted( + BluetoothAudioStatus status) { + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) + << ", status=" << toString(status); + + if (stack_iface_ != nullptr) { + BluetoothAudioSessionReport::ReportControlStatus(session_type_, true, + status); + } else { + LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) + << ", status=" << toString(status) << " has NO session"; + } + + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus BluetoothAudioProvider::streamSuspended( + BluetoothAudioStatus status) { + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) + << ", status=" << toString(status); + + if (stack_iface_ != nullptr) { + BluetoothAudioSessionReport::ReportControlStatus(session_type_, false, + status); + } else { + LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) + << ", status=" << toString(status) << " has NO session"; + } + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus BluetoothAudioProvider::updateAudioConfiguration( + const AudioConfiguration& audio_config) { + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_); + + if (stack_iface_ == nullptr || audio_config_ == nullptr) { + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) + << " has NO session"; + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + + if (audio_config.getTag() != audio_config_->getTag()) { + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) + << " audio config type is not match"; + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + + audio_config_ = std::make_unique<AudioConfiguration>(audio_config); + BluetoothAudioSessionReport::ReportAudioConfigChanged(session_type_, + *audio_config_); + return ndk::ScopedAStatus::ok(); +} + +void BluetoothAudioProvider::binderDiedCallbackAidl(void* ptr) { + LOG(ERROR) << __func__ << " - BluetoothAudio Service died"; + auto provider = static_cast<BluetoothAudioProvider*>(ptr); + if (provider == nullptr) { + LOG(ERROR) << __func__ << ": Null AudioProvider HAL died"; + return; + } + provider->endSession(); +} + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl
\ No newline at end of file diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h new file mode 100644 index 0000000000..f7acbdf7e3 --- /dev/null +++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include <aidl/android/hardware/bluetooth/audio/BnBluetoothAudioProvider.h> +#include <aidl/android/hardware/bluetooth/audio/SessionType.h> +#include <fmq/AidlMessageQueue.h> + +using ::aidl::android::hardware::common::fmq::MQDescriptor; +using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite; +using ::android::AidlMessageQueue; + +using MqDataType = int8_t; +using MqDataMode = SynchronizedReadWrite; +using DataMQ = AidlMessageQueue<MqDataType, MqDataMode>; +using DataMQDesc = MQDescriptor<MqDataType, MqDataMode>; + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +class BluetoothAudioProvider : public BnBluetoothAudioProvider { + public: + BluetoothAudioProvider(); + + ndk::ScopedAStatus startSession( + const std::shared_ptr<IBluetoothAudioPort>& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return); + ndk::ScopedAStatus endSession(); + ndk::ScopedAStatus streamStarted(BluetoothAudioStatus status); + ndk::ScopedAStatus streamSuspended(BluetoothAudioStatus status); + ndk::ScopedAStatus updateAudioConfiguration( + const AudioConfiguration& audio_config); + + virtual bool isValid(const SessionType& sessionType) = 0; + + protected: + virtual ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) = 0; + static void binderDiedCallbackAidl(void* cookie_ptr); + + ::ndk::ScopedAIBinder_DeathRecipient death_recipient_; + + std::shared_ptr<IBluetoothAudioPort> stack_iface_; + std::unique_ptr<AudioConfiguration> audio_config_ = nullptr; + SessionType session_type_; +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl
\ No newline at end of file diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp new file mode 100644 index 0000000000..8e6cee7b2f --- /dev/null +++ b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "BTAudioProvidersFactory" + +#include "BluetoothAudioProviderFactory.h" + +#include <BluetoothAudioCodecs.h> +#include <android-base/logging.h> + +#include "A2dpOffloadAudioProvider.h" +#include "A2dpSoftwareAudioProvider.h" +#include "BluetoothAudioProvider.h" +#include "HearingAidAudioProvider.h" +#include "LeAudioOffloadAudioProvider.h" +#include "LeAudioSoftwareAudioProvider.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +BluetoothAudioProviderFactory::BluetoothAudioProviderFactory() {} + +ndk::ScopedAStatus BluetoothAudioProviderFactory::openProvider( + const SessionType session_type, + std::shared_ptr<IBluetoothAudioProvider>* _aidl_return) { + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type); + std::shared_ptr<BluetoothAudioProvider> provider = nullptr; + + switch (session_type) { + case SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH: + provider = ndk::SharedRefBase::make<A2dpSoftwareAudioProvider>(); + break; + case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH: + provider = ndk::SharedRefBase::make<A2dpOffloadAudioProvider>(); + break; + case SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH: + provider = ndk::SharedRefBase::make<HearingAidAudioProvider>(); + break; + case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH: + provider = ndk::SharedRefBase::make<LeAudioSoftwareOutputAudioProvider>(); + break; + case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH: + provider = ndk::SharedRefBase::make<LeAudioOffloadOutputAudioProvider>(); + break; + case SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH: + provider = ndk::SharedRefBase::make<LeAudioSoftwareInputAudioProvider>(); + break; + case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH: + provider = ndk::SharedRefBase::make<LeAudioOffloadInputAudioProvider>(); + break; + default: + provider = nullptr; + break; + } + + if (provider == nullptr || !provider->isValid(session_type)) { + provider = nullptr; + LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + *_aidl_return = provider; + + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus BluetoothAudioProviderFactory::getProviderCapabilities( + const SessionType session_type, + std::vector<AudioCapabilities>* _aidl_return) { + if (session_type == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + auto codec_capabilities = + BluetoothAudioCodecs::GetA2dpOffloadCodecCapabilities(session_type); + _aidl_return->resize(codec_capabilities.size()); + for (int i = 0; i < codec_capabilities.size(); i++) { + _aidl_return->at(i).set<AudioCapabilities::a2dpCapabilities>( + codec_capabilities[i]); + } + } else if (session_type == + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH || + session_type == + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) { + std::vector<LeAudioCodecCapabilitiesSetting> db_codec_capabilities = + BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities(session_type); + if (db_codec_capabilities.size()) { + _aidl_return->resize(db_codec_capabilities.size()); + for (int i = 0; i < db_codec_capabilities.size(); ++i) { + _aidl_return->at(i).set<AudioCapabilities::leAudioCapabilities>( + db_codec_capabilities[i]); + } + } + } else if (session_type != SessionType::UNKNOWN) { + auto pcm_capabilities = BluetoothAudioCodecs::GetSoftwarePcmCapabilities(); + _aidl_return->resize(pcm_capabilities.size()); + for (int i = 0; i < pcm_capabilities.size(); i++) { + _aidl_return->at(i).set<AudioCapabilities::pcmCapabilities>( + pcm_capabilities[i]); + } + } + + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type) + << " supports " << _aidl_return->size() << " codecs"; + return ndk::ScopedAStatus::ok(); +} + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl
\ No newline at end of file diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.h b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.h new file mode 100644 index 0000000000..96d888c166 --- /dev/null +++ b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <aidl/android/hardware/bluetooth/audio/BnBluetoothAudioProviderFactory.h> + +#include "A2dpOffloadAudioProvider.h" +#include "A2dpSoftwareAudioProvider.h" +#include "BluetoothAudioProvider.h" +#include "HearingAidAudioProvider.h" +#include "LeAudioOffloadAudioProvider.h" +#include "LeAudioSoftwareAudioProvider.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +class BluetoothAudioProviderFactory : public BnBluetoothAudioProviderFactory { + public: + BluetoothAudioProviderFactory(); + + ndk::ScopedAStatus openProvider( + const SessionType session_type, + std::shared_ptr<IBluetoothAudioProvider>* _aidl_return) override; + + ndk::ScopedAStatus getProviderCapabilities( + const SessionType session_type, + std::vector<AudioCapabilities>* _aidl_return) override; +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/bluetooth/audio/aidl/default/HearingAidAudioProvider.cpp b/bluetooth/audio/aidl/default/HearingAidAudioProvider.cpp new file mode 100644 index 0000000000..a993059b65 --- /dev/null +++ b/bluetooth/audio/aidl/default/HearingAidAudioProvider.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "BTAudioProviderHearingAid" + +#include "HearingAidAudioProvider.h" + +#include <BluetoothAudioCodecs.h> +#include <BluetoothAudioSessionReport.h> +#include <android-base/logging.h> + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +static constexpr uint32_t kPcmFrameSize = 4; // 16 bits per sample / stereo +static constexpr uint32_t kPcmFrameCount = 128; +static constexpr uint32_t kRtpFrameSize = kPcmFrameSize * kPcmFrameCount; +static constexpr uint32_t kRtpFrameCount = 7; // max counts by 1 tick (20ms) +static constexpr uint32_t kBufferSize = kRtpFrameSize * kRtpFrameCount; +static constexpr uint32_t kBufferCount = 1; // single buffer +static constexpr uint32_t kDataMqSize = kBufferSize * kBufferCount; + +HearingAidAudioProvider::HearingAidAudioProvider() + : BluetoothAudioProvider(), data_mq_(nullptr) { + LOG(INFO) << __func__ << " - size of audio buffer " << kDataMqSize + << " byte(s)"; + std::unique_ptr<DataMQ> data_mq( + new DataMQ(kDataMqSize, /* EventFlag */ true)); + if (data_mq && data_mq->isValid()) { + data_mq_ = std::move(data_mq); + session_type_ = SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH; + } else { + ALOGE_IF(!data_mq, "failed to allocate data MQ"); + ALOGE_IF(data_mq && !data_mq->isValid(), "data MQ is invalid"); + } +} +bool HearingAidAudioProvider::isValid(const SessionType& sessionType) { + return (sessionType == session_type_ && data_mq_ && data_mq_->isValid()); +} + +ndk::ScopedAStatus HearingAidAudioProvider::startSession( + const std::shared_ptr<IBluetoothAudioPort>& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) { + if (audio_config.getTag() != AudioConfiguration::pcmConfig) { + LOG(WARNING) << __func__ << " - Invalid Audio Configuration=" + << audio_config.toString(); + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + const auto& pcm_config = audio_config.get<AudioConfiguration::pcmConfig>(); + if (!BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid(pcm_config)) { + LOG(WARNING) << __func__ << " - Unsupported PCM Configuration=" + << pcm_config.toString(); + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + + return BluetoothAudioProvider::startSession(host_if, audio_config, + _aidl_return); +} + +ndk::ScopedAStatus HearingAidAudioProvider::onSessionReady( + DataMQDesc* _aidl_return) { + if (data_mq_ == nullptr || !data_mq_->isValid()) { + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + auto desc = data_mq_->dupeDesc(); + BluetoothAudioSessionReport::OnSessionStarted(session_type_, stack_iface_, + &desc, *audio_config_); + *_aidl_return = data_mq_->dupeDesc(); + return ndk::ScopedAStatus::ok(); +} + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl
\ No newline at end of file diff --git a/bluetooth/audio/aidl/default/HearingAidAudioProvider.h b/bluetooth/audio/aidl/default/HearingAidAudioProvider.h new file mode 100644 index 0000000000..a7e19e982d --- /dev/null +++ b/bluetooth/audio/aidl/default/HearingAidAudioProvider.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "BluetoothAudioProvider.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +class HearingAidAudioProvider : public BluetoothAudioProvider { + public: + HearingAidAudioProvider(); + + bool isValid(const SessionType& sessionType) override; + + ndk::ScopedAStatus startSession( + const std::shared_ptr<IBluetoothAudioPort>& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return); + + private: + // audio data queue for software encoding + std::unique_ptr<DataMQ> data_mq_; + + ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override; +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp new file mode 100644 index 0000000000..4078783c99 --- /dev/null +++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "BTAudioProviderLeAudioSW" + +#include "LeAudioOffloadAudioProvider.h" + +#include <BluetoothAudioCodecs.h> +#include <BluetoothAudioSessionReport.h> +#include <android-base/logging.h> + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +LeAudioOffloadOutputAudioProvider::LeAudioOffloadOutputAudioProvider() + : LeAudioOffloadAudioProvider() { + session_type_ = SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH; +} + +LeAudioOffloadInputAudioProvider::LeAudioOffloadInputAudioProvider() + : LeAudioOffloadAudioProvider() { + session_type_ = SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH; +} + +LeAudioOffloadAudioProvider::LeAudioOffloadAudioProvider() + : BluetoothAudioProvider() {} + +bool LeAudioOffloadAudioProvider::isValid(const SessionType& sessionType) { + return (sessionType == session_type_); +} + +ndk::ScopedAStatus LeAudioOffloadAudioProvider::startSession( + const std::shared_ptr<IBluetoothAudioPort>& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) { + if (audio_config.getTag() != AudioConfiguration::leAudioConfig) { + LOG(WARNING) << __func__ << " - Invalid Audio Configuration=" + << audio_config.toString(); + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + const auto& le_audio_config = + audio_config.get<AudioConfiguration::leAudioConfig>(); + if (!BluetoothAudioCodecs::IsOffloadLeAudioConfigurationValid( + session_type_, le_audio_config)) { + LOG(WARNING) << __func__ << " - Unsupported LC3 Offloaded Configuration=" + << le_audio_config.toString(); + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + + return BluetoothAudioProvider::startSession(host_if, audio_config, + _aidl_return); +} + +ndk::ScopedAStatus LeAudioOffloadAudioProvider::onSessionReady( + DataMQDesc* _aidl_return) { + BluetoothAudioSessionReport::OnSessionStarted(session_type_, stack_iface_, + nullptr, *audio_config_); + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::ok(); +} + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl
\ No newline at end of file diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h new file mode 100644 index 0000000000..a27a2e71ce --- /dev/null +++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "BluetoothAudioProvider.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +class LeAudioOffloadAudioProvider : public BluetoothAudioProvider { + public: + LeAudioOffloadAudioProvider(); + + bool isValid(const SessionType& sessionType) override; + + ndk::ScopedAStatus startSession( + const std::shared_ptr<IBluetoothAudioPort>& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return); + + private: + ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override; +}; + +class LeAudioOffloadOutputAudioProvider : public LeAudioOffloadAudioProvider { + public: + LeAudioOffloadOutputAudioProvider(); +}; + +class LeAudioOffloadInputAudioProvider : public LeAudioOffloadAudioProvider { + public: + LeAudioOffloadInputAudioProvider(); +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp new file mode 100644 index 0000000000..f9962fd9d9 --- /dev/null +++ b/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "BTAudioProviderLeAudioHW" + +#include "LeAudioSoftwareAudioProvider.h" + +#include <BluetoothAudioCodecs.h> +#include <BluetoothAudioSessionReport.h> +#include <android-base/logging.h> + +#include <cstdint> + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +static constexpr uint32_t kBufferOutCount = 2; // two frame buffer +static constexpr uint32_t kBufferInCount = 2; // two frame buffer + +inline uint32_t channel_mode_to_channel_count(ChannelMode channel_mode) { + switch (channel_mode) { + case ChannelMode::MONO: + return 1; + case ChannelMode::STEREO: + return 2; + default: + return 0; + } + return 0; +} + +LeAudioSoftwareOutputAudioProvider::LeAudioSoftwareOutputAudioProvider() + : LeAudioSoftwareAudioProvider() { + session_type_ = SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH; +} + +LeAudioSoftwareInputAudioProvider::LeAudioSoftwareInputAudioProvider() + : LeAudioSoftwareAudioProvider() { + session_type_ = SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH; +} + +LeAudioSoftwareAudioProvider::LeAudioSoftwareAudioProvider() + : BluetoothAudioProvider(), data_mq_(nullptr) {} + +bool LeAudioSoftwareAudioProvider::isValid(const SessionType& sessionType) { + return (sessionType == session_type_); +} + +ndk::ScopedAStatus LeAudioSoftwareAudioProvider::startSession( + const std::shared_ptr<IBluetoothAudioPort>& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) { + if (audio_config.getTag() != AudioConfiguration::pcmConfig) { + LOG(WARNING) << __func__ << " - Invalid Audio Configuration=" + << audio_config.toString(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + const auto& pcm_config = audio_config.get<AudioConfiguration::pcmConfig>(); + if (!BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid(pcm_config)) { + LOG(WARNING) << __func__ << " - Unsupported PCM Configuration=" + << pcm_config.toString(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + + uint32_t buffer_modifier = 0; + if (session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH) + buffer_modifier = kBufferOutCount; + else if (session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH) + buffer_modifier = kBufferInCount; + + uint32_t data_mq_size = + (ceil(pcm_config.sampleRateHz) / 1000) * + channel_mode_to_channel_count(pcm_config.channelMode) * + (pcm_config.bitsPerSample / 8) * (pcm_config.dataIntervalUs / 1000) * + buffer_modifier; + + LOG(INFO) << __func__ << " - size of audio buffer " << data_mq_size + << " byte(s)"; + + std::unique_ptr<DataMQ> temp_data_mq( + new DataMQ(data_mq_size, /* EventFlag */ true)); + if (temp_data_mq == nullptr || !temp_data_mq->isValid()) { + ALOGE_IF(!temp_data_mq, "failed to allocate data MQ"); + ALOGE_IF(temp_data_mq && !temp_data_mq->isValid(), "data MQ is invalid"); + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + data_mq_ = std::move(temp_data_mq); + + return BluetoothAudioProvider::startSession(host_if, audio_config, + _aidl_return); +} + +ndk::ScopedAStatus LeAudioSoftwareAudioProvider::onSessionReady( + DataMQDesc* _aidl_return) { + if (data_mq_ == nullptr || !data_mq_->isValid()) { + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + *_aidl_return = data_mq_->dupeDesc(); + BluetoothAudioSessionReport::OnSessionStarted(session_type_, stack_iface_, + _aidl_return, *audio_config_); + return ndk::ScopedAStatus::ok(); +} + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl
\ No newline at end of file diff --git a/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.h b/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.h new file mode 100644 index 0000000000..fa581820c6 --- /dev/null +++ b/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "BluetoothAudioProvider.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +class LeAudioSoftwareAudioProvider : public BluetoothAudioProvider { + public: + LeAudioSoftwareAudioProvider(); + + bool isValid(const SessionType& sessionType) override; + + ndk::ScopedAStatus startSession( + const std::shared_ptr<IBluetoothAudioPort>& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return); + + private: + // audio data queue for software encoding + std::unique_ptr<DataMQ> data_mq_; + + ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override; +}; + +class LeAudioSoftwareOutputAudioProvider : public LeAudioSoftwareAudioProvider { + public: + LeAudioSoftwareOutputAudioProvider(); +}; + +class LeAudioSoftwareInputAudioProvider : public LeAudioSoftwareAudioProvider { + public: + LeAudioSoftwareInputAudioProvider(); +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl
\ No newline at end of file diff --git a/bluetooth/audio/aidl/default/bluetooth_audio.xml b/bluetooth/audio/aidl/default/bluetooth_audio.xml new file mode 100644 index 0000000000..1859a1a366 --- /dev/null +++ b/bluetooth/audio/aidl/default/bluetooth_audio.xml @@ -0,0 +1,6 @@ +<manifest version="1.0" type="device"> + <hal format="aidl"> + <name>android.hardware.bluetooth.audio</name> + <fqname>IBluetoothAudioProviderFactory/default</fqname> + </hal> +</manifest>
\ No newline at end of file diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp index 4f712bffab..974357e278 100644 --- a/bluetooth/audio/utils/Android.bp +++ b/bluetooth/audio/utils/Android.bp @@ -32,5 +32,30 @@ cc_library_shared { "libhidlbase", "liblog", "libutils", + "libbluetooth_audio_session_aidl", + ], +} + +cc_library_shared { + name: "libbluetooth_audio_session_aidl", + vendor: true, + srcs: [ + "aidl_session/BluetoothAudioCodecs.cpp", + "aidl_session/BluetoothAudioSession.cpp", + "aidl_session/HidlToAidlMiddleware.cpp", + ], + export_include_dirs: ["aidl_session/"], + header_libs: ["libhardware_headers"], + shared_libs: [ + "android.hardware.bluetooth.audio@2.0", + "android.hardware.bluetooth.audio@2.1", + "android.hardware.bluetooth.audio@2.2", + "libbase", + "libcutils", + "libbinder_ndk", + "libfmq", + "liblog", + "android.hardware.bluetooth.audio-V1-ndk", + "libhidlbase", ], } diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp new file mode 100644 index 0000000000..92cd0f5b14 --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp @@ -0,0 +1,489 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "BTAudioCodecsAidl" + +#include "BluetoothAudioCodecs.h" + +#include <aidl/android/hardware/bluetooth/audio/AacCapabilities.h> +#include <aidl/android/hardware/bluetooth/audio/AacObjectType.h> +#include <aidl/android/hardware/bluetooth/audio/AptxCapabilities.h> +#include <aidl/android/hardware/bluetooth/audio/ChannelMode.h> +#include <aidl/android/hardware/bluetooth/audio/LdacCapabilities.h> +#include <aidl/android/hardware/bluetooth/audio/LdacChannelMode.h> +#include <aidl/android/hardware/bluetooth/audio/LdacQualityIndex.h> +#include <aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.h> +#include <aidl/android/hardware/bluetooth/audio/SbcCapabilities.h> +#include <aidl/android/hardware/bluetooth/audio/SbcChannelMode.h> +#include <android-base/logging.h> + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +static const PcmCapabilities kDefaultSoftwarePcmCapabilities = { + .sampleRateHz = {16000, 24000, 44100, 48000, 88200, 96000}, + .channelMode = {ChannelMode::MONO, ChannelMode::STEREO}, + .bitsPerSample = {16, 24, 32}, + .dataIntervalUs = {}, +}; + +static const SbcCapabilities kDefaultOffloadSbcCapability = { + .sampleRateHz = {44100}, + .channelMode = {SbcChannelMode::MONO, SbcChannelMode::JOINT_STEREO}, + .blockLength = {4, 8, 12, 16}, + .numSubbands = {8}, + .allocMethod = {SbcAllocMethod::ALLOC_MD_L}, + .bitsPerSample = {16}, + .minBitpool = 2, + .maxBitpool = 53}; + +static const AacCapabilities kDefaultOffloadAacCapability = { + .objectType = {AacObjectType::MPEG2_LC}, + .sampleRateHz = {44100}, + .channelMode = {ChannelMode::STEREO}, + .variableBitRateSupported = true, + .bitsPerSample = {16}}; + +static const LdacCapabilities kDefaultOffloadLdacCapability = { + .sampleRateHz = {44100, 48000, 88200, 96000}, + .channelMode = {LdacChannelMode::DUAL, LdacChannelMode::STEREO}, + .qualityIndex = {LdacQualityIndex::HIGH}, + .bitsPerSample = {16, 24, 32}}; + +static const AptxCapabilities kDefaultOffloadAptxCapability = { + .sampleRateHz = {44100, 48000}, + .channelMode = {ChannelMode::STEREO}, + .bitsPerSample = {16}, +}; + +static const AptxCapabilities kDefaultOffloadAptxHdCapability = { + .sampleRateHz = {44100, 48000}, + .channelMode = {ChannelMode::STEREO}, + .bitsPerSample = {24}, +}; + +static const Lc3Capabilities kDefaultOffloadLc3Capability = { + .samplingFrequencyHz = {44100, 48000}, + .frameDurationUs = {7500, 10000}, + .channelMode = {ChannelMode::MONO, ChannelMode::STEREO}, +}; + +const std::vector<CodecCapabilities> kDefaultOffloadA2dpCodecCapabilities = { + {.codecType = CodecType::SBC, .capabilities = {}}, + {.codecType = CodecType::AAC, .capabilities = {}}, + {.codecType = CodecType::LDAC, .capabilities = {}}, + {.codecType = CodecType::APTX, .capabilities = {}}, + {.codecType = CodecType::APTX_HD, .capabilities = {}}, + {.codecType = CodecType::LC3, .capabilities = {}}}; + +std::vector<LeAudioCodecCapabilitiesSetting> kDefaultOffloadLeAudioCapabilities; + +static const UnicastCapability kInvalidUnicastCapability = { + .codecType = CodecType::UNKNOWN}; + +static const BroadcastCapability kInvalidBroadcastCapability = { + .codecType = CodecType::UNKNOWN}; + +// Default Supported Codecs +// LC3 16_1: sample rate: 16 kHz, frame duration: 7.5 ms, octets per frame: 30 +static const Lc3Capabilities kLc3Capability_16_1 = { + .samplingFrequencyHz = {16000}, + .frameDurationUs = {7500}, + .octetsPerFrame = {30}}; + +// Default Supported Codecs +// LC3 16_2: sample rate: 16 kHz, frame duration: 10 ms, octets per frame: 40 +static const Lc3Capabilities kLc3Capability_16_2 = { + .samplingFrequencyHz = {16000}, + .frameDurationUs = {10000}, + .octetsPerFrame = {40}}; + +// Default Supported Codecs +// LC3 48_4: sample rate: 48 kHz, frame duration: 10 ms, octets per frame: 120 +static const Lc3Capabilities kLc3Capability_48_4 = { + .samplingFrequencyHz = {48000}, + .frameDurationUs = {10000}, + .octetsPerFrame = {120}}; + +static const std::vector<Lc3Capabilities> supportedLc3CapabilityList = { + kLc3Capability_48_4, kLc3Capability_16_2, kLc3Capability_16_1}; + +static AudioLocation stereoAudio = static_cast<AudioLocation>( + static_cast<uint8_t>(AudioLocation::FRONT_LEFT) | + static_cast<uint8_t>(AudioLocation::FRONT_RIGHT)); +static AudioLocation monoAudio = AudioLocation::UNKNOWN; + +// Stores the supported setting of audio location, connected device, and the +// channel count for each device +std::vector<std::tuple<AudioLocation, uint8_t, uint8_t>> + supportedDeviceSetting = {std::make_tuple(stereoAudio, 2, 1), + std::make_tuple(monoAudio, 1, 2), + std::make_tuple(monoAudio, 1, 1)}; + +template <class T> +bool BluetoothAudioCodecs::ContainedInVector( + const std::vector<T>& vector, const typename identity<T>::type& target) { + return std::find(vector.begin(), vector.end(), target) != vector.end(); +} + +bool BluetoothAudioCodecs::IsOffloadSbcConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific) { + if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::sbcConfig) { + LOG(WARNING) << __func__ + << ": Invalid CodecSpecific=" << codec_specific.toString(); + return false; + } + const SbcConfiguration sbc_data = + codec_specific.get<CodecConfiguration::CodecSpecific::sbcConfig>(); + + if (ContainedInVector(kDefaultOffloadSbcCapability.sampleRateHz, + sbc_data.sampleRateHz) && + ContainedInVector(kDefaultOffloadSbcCapability.blockLength, + sbc_data.blockLength) && + ContainedInVector(kDefaultOffloadSbcCapability.numSubbands, + sbc_data.numSubbands) && + ContainedInVector(kDefaultOffloadSbcCapability.bitsPerSample, + sbc_data.bitsPerSample) && + ContainedInVector(kDefaultOffloadSbcCapability.channelMode, + sbc_data.channelMode) && + ContainedInVector(kDefaultOffloadSbcCapability.allocMethod, + sbc_data.allocMethod) && + sbc_data.minBitpool <= sbc_data.maxBitpool && + kDefaultOffloadSbcCapability.minBitpool <= sbc_data.minBitpool && + kDefaultOffloadSbcCapability.maxBitpool >= sbc_data.maxBitpool) { + return true; + } + LOG(WARNING) << __func__ + << ": Unsupported CodecSpecific=" << codec_specific.toString(); + return false; +} + +bool BluetoothAudioCodecs::IsOffloadAacConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific) { + if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::aacConfig) { + LOG(WARNING) << __func__ + << ": Invalid CodecSpecific=" << codec_specific.toString(); + return false; + } + const AacConfiguration aac_data = + codec_specific.get<CodecConfiguration::CodecSpecific::aacConfig>(); + + if (ContainedInVector(kDefaultOffloadAacCapability.sampleRateHz, + aac_data.sampleRateHz) && + ContainedInVector(kDefaultOffloadAacCapability.bitsPerSample, + aac_data.bitsPerSample) && + ContainedInVector(kDefaultOffloadAacCapability.channelMode, + aac_data.channelMode) && + ContainedInVector(kDefaultOffloadAacCapability.objectType, + aac_data.objectType) && + (!aac_data.variableBitRateEnabled || + kDefaultOffloadAacCapability.variableBitRateSupported)) { + return true; + } + LOG(WARNING) << __func__ + << ": Unsupported CodecSpecific=" << codec_specific.toString(); + return false; +} + +bool BluetoothAudioCodecs::IsOffloadLdacConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific) { + if (codec_specific.getTag() != + CodecConfiguration::CodecSpecific::ldacConfig) { + LOG(WARNING) << __func__ + << ": Invalid CodecSpecific=" << codec_specific.toString(); + return false; + } + const LdacConfiguration ldac_data = + codec_specific.get<CodecConfiguration::CodecSpecific::ldacConfig>(); + + if (ContainedInVector(kDefaultOffloadLdacCapability.sampleRateHz, + ldac_data.sampleRateHz) && + ContainedInVector(kDefaultOffloadLdacCapability.bitsPerSample, + ldac_data.bitsPerSample) && + ContainedInVector(kDefaultOffloadLdacCapability.channelMode, + ldac_data.channelMode) && + ContainedInVector(kDefaultOffloadLdacCapability.qualityIndex, + ldac_data.qualityIndex)) { + return true; + } + LOG(WARNING) << __func__ + << ": Unsupported CodecSpecific=" << codec_specific.toString(); + return false; +} + +bool BluetoothAudioCodecs::IsOffloadAptxConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific) { + if (codec_specific.getTag() != + CodecConfiguration::CodecSpecific::aptxConfig) { + LOG(WARNING) << __func__ + << ": Invalid CodecSpecific=" << codec_specific.toString(); + return false; + } + const AptxConfiguration aptx_data = + codec_specific.get<CodecConfiguration::CodecSpecific::aptxConfig>(); + + if (ContainedInVector(kDefaultOffloadAptxCapability.sampleRateHz, + aptx_data.sampleRateHz) && + ContainedInVector(kDefaultOffloadAptxCapability.bitsPerSample, + aptx_data.bitsPerSample) && + ContainedInVector(kDefaultOffloadAptxCapability.channelMode, + aptx_data.channelMode)) { + return true; + } + LOG(WARNING) << __func__ + << ": Unsupported CodecSpecific=" << codec_specific.toString(); + return false; +} + +bool BluetoothAudioCodecs::IsOffloadAptxHdConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific) { + if (codec_specific.getTag() != + CodecConfiguration::CodecSpecific::aptxConfig) { + LOG(WARNING) << __func__ + << ": Invalid CodecSpecific=" << codec_specific.toString(); + return false; + } + const AptxConfiguration aptx_data = + codec_specific.get<CodecConfiguration::CodecSpecific::aptxConfig>(); + + if (ContainedInVector(kDefaultOffloadAptxHdCapability.sampleRateHz, + aptx_data.sampleRateHz) && + ContainedInVector(kDefaultOffloadAptxHdCapability.bitsPerSample, + aptx_data.bitsPerSample) && + ContainedInVector(kDefaultOffloadAptxHdCapability.channelMode, + aptx_data.channelMode)) { + return true; + } + LOG(WARNING) << __func__ + << ": Unsupported CodecSpecific=" << codec_specific.toString(); + return false; +} + +bool BluetoothAudioCodecs::IsOffloadLc3ConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific) { + if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::lc3Config) { + LOG(WARNING) << __func__ + << ": Invalid CodecSpecific=" << codec_specific.toString(); + return false; + } + const Lc3Configuration lc3_data = + codec_specific.get<CodecConfiguration::CodecSpecific::lc3Config>(); + + if (ContainedInVector(kDefaultOffloadLc3Capability.samplingFrequencyHz, + lc3_data.samplingFrequencyHz) && + ContainedInVector(kDefaultOffloadLc3Capability.frameDurationUs, + lc3_data.frameDurationUs) && + ContainedInVector(kDefaultOffloadLc3Capability.channelMode, + lc3_data.channelMode)) { + return true; + } + LOG(WARNING) << __func__ + << ": Unsupported CodecSpecific=" << codec_specific.toString(); + return false; +} + +bool BluetoothAudioCodecs::IsOffloadLeAudioConfigurationValid( + const SessionType& session_type, const LeAudioConfiguration&) { + if (session_type != + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH && + session_type != + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) { + return false; + } + return true; +} + +std::vector<PcmCapabilities> +BluetoothAudioCodecs::GetSoftwarePcmCapabilities() { + return {kDefaultSoftwarePcmCapabilities}; +} + +std::vector<CodecCapabilities> +BluetoothAudioCodecs::GetA2dpOffloadCodecCapabilities( + const SessionType& session_type) { + if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + return {}; + } + std::vector<CodecCapabilities> offload_a2dp_codec_capabilities = + kDefaultOffloadA2dpCodecCapabilities; + for (auto& codec_capability : offload_a2dp_codec_capabilities) { + switch (codec_capability.codecType) { + case CodecType::SBC: + codec_capability.capabilities + .set<CodecCapabilities::Capabilities::sbcCapabilities>( + kDefaultOffloadSbcCapability); + break; + case CodecType::AAC: + codec_capability.capabilities + .set<CodecCapabilities::Capabilities::aacCapabilities>( + kDefaultOffloadAacCapability); + break; + case CodecType::LDAC: + codec_capability.capabilities + .set<CodecCapabilities::Capabilities::ldacCapabilities>( + kDefaultOffloadLdacCapability); + break; + case CodecType::APTX: + codec_capability.capabilities + .set<CodecCapabilities::Capabilities::aptxCapabilities>( + kDefaultOffloadAptxCapability); + break; + case CodecType::APTX_HD: + codec_capability.capabilities + .set<CodecCapabilities::Capabilities::aptxCapabilities>( + kDefaultOffloadAptxHdCapability); + break; + case CodecType::LC3: + codec_capability.capabilities + .set<CodecCapabilities::Capabilities::lc3Capabilities>( + kDefaultOffloadLc3Capability); + break; + case CodecType::UNKNOWN: + codec_capability = {}; + break; + } + } + return offload_a2dp_codec_capabilities; +} + +bool BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid( + const PcmConfiguration& pcm_config) { + if (ContainedInVector(kDefaultSoftwarePcmCapabilities.sampleRateHz, + pcm_config.sampleRateHz) && + ContainedInVector(kDefaultSoftwarePcmCapabilities.bitsPerSample, + pcm_config.bitsPerSample) && + ContainedInVector(kDefaultSoftwarePcmCapabilities.channelMode, + pcm_config.channelMode) + // data interval is not checked for now + // && pcm_config.dataIntervalUs != 0 + ) { + return true; + } + LOG(WARNING) << __func__ + << ": Unsupported CodecSpecific=" << pcm_config.toString(); + return false; +} + +bool BluetoothAudioCodecs::IsOffloadCodecConfigurationValid( + const SessionType& session_type, const CodecConfiguration& codec_config) { + if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + LOG(ERROR) << __func__ + << ": Invalid SessionType=" << toString(session_type); + return false; + } + const CodecConfiguration::CodecSpecific& codec_specific = codec_config.config; + switch (codec_config.codecType) { + case CodecType::SBC: + if (IsOffloadSbcConfigurationValid(codec_specific)) { + return true; + } + break; + case CodecType::AAC: + if (IsOffloadAacConfigurationValid(codec_specific)) { + return true; + } + break; + case CodecType::LDAC: + if (IsOffloadLdacConfigurationValid(codec_specific)) { + return true; + } + break; + case CodecType::APTX: + if (IsOffloadAptxConfigurationValid(codec_specific)) { + return true; + } + break; + case CodecType::APTX_HD: + if (IsOffloadAptxHdConfigurationValid(codec_specific)) { + return true; + } + break; + case CodecType::LC3: + if (IsOffloadLc3ConfigurationValid(codec_specific)) { + return true; + } + break; + case CodecType::UNKNOWN: + break; + } + return false; +} + +UnicastCapability composeUnicastLc3Capability( + AudioLocation audioLocation, uint8_t deviceCnt, uint8_t channelCount, + const Lc3Capabilities& capability) { + return { + .codecType = CodecType::LC3, + .supportedChannel = audioLocation, + .deviceCount = deviceCnt, + .channelCountPerDevice = channelCount, + .leAudioCodecCapabilities = + UnicastCapability::LeAudioCodecCapabilities(capability), + }; +} + +std::vector<LeAudioCodecCapabilitiesSetting> +BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities( + const SessionType& session_type) { + if (session_type != + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH && + session_type != + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) { + return std::vector<LeAudioCodecCapabilitiesSetting>(0); + } + + if (kDefaultOffloadLeAudioCapabilities.empty()) { + for (auto [audioLocation, deviceCnt, channelCount] : + supportedDeviceSetting) { + for (auto capability : supportedLc3CapabilityList) { + UnicastCapability lc3Capability = composeUnicastLc3Capability( + audioLocation, deviceCnt, channelCount, capability); + UnicastCapability lc3MonoDecodeCapability = + composeUnicastLc3Capability(monoAudio, 1, 1, capability); + + // Adds the capability for encode only + kDefaultOffloadLeAudioCapabilities.push_back( + {.unicastEncodeCapability = lc3Capability, + .unicastDecodeCapability = kInvalidUnicastCapability, + .broadcastCapability = kInvalidBroadcastCapability}); + + // Adds the capability for decode only + kDefaultOffloadLeAudioCapabilities.push_back( + {.unicastEncodeCapability = kInvalidUnicastCapability, + .unicastDecodeCapability = lc3Capability, + .broadcastCapability = kInvalidBroadcastCapability}); + + // Adds the capability for the case that encode and decode exist at the + // same time + kDefaultOffloadLeAudioCapabilities.push_back( + {.unicastEncodeCapability = lc3Capability, + .unicastDecodeCapability = lc3MonoDecodeCapability, + .broadcastCapability = kInvalidBroadcastCapability}); + } + } + } + + return kDefaultOffloadLeAudioCapabilities; +} + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl
\ No newline at end of file diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h new file mode 100644 index 0000000000..c542ce5be7 --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <aidl/android/hardware/bluetooth/audio/CodecCapabilities.h> +#include <aidl/android/hardware/bluetooth/audio/CodecConfiguration.h> +#include <aidl/android/hardware/bluetooth/audio/Lc3Configuration.h> +#include <aidl/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.h> +#include <aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.h> +#include <aidl/android/hardware/bluetooth/audio/PcmCapabilities.h> +#include <aidl/android/hardware/bluetooth/audio/PcmConfiguration.h> +#include <aidl/android/hardware/bluetooth/audio/SessionType.h> + +#include <vector> + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +class BluetoothAudioCodecs { + public: + static std::vector<PcmCapabilities> GetSoftwarePcmCapabilities(); + static std::vector<CodecCapabilities> GetA2dpOffloadCodecCapabilities( + const SessionType& session_type); + + static bool IsSoftwarePcmConfigurationValid( + const PcmConfiguration& pcm_config); + static bool IsOffloadCodecConfigurationValid( + const SessionType& session_type, const CodecConfiguration& codec_config); + + static bool IsOffloadLeAudioConfigurationValid( + const SessionType& session_type, const Lc3Configuration& codec_config); + + static bool IsOffloadLeAudioConfigurationValid( + const SessionType& session_type, + const LeAudioConfiguration& codec_config); + + static std::vector<LeAudioCodecCapabilitiesSetting> + GetLeAudioOffloadCodecCapabilities(const SessionType& session_type); + + private: + template <typename T> + struct identity { + typedef T type; + }; + template <class T> + static bool ContainedInVector(const std::vector<T>& vector, + const typename identity<T>::type& target); + template <class T> + static bool ContainedInBitmask(const T& bitmask, const T& target); + static bool IsSingleBit(uint32_t bitmasks, uint32_t bitfield); + static bool IsOffloadSbcConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific); + static bool IsOffloadAacConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific); + static bool IsOffloadLdacConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific); + static bool IsOffloadAptxConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific); + static bool IsOffloadAptxHdConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific); + static bool IsOffloadLc3ConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific); + static bool IsOffloadLeAudioConfigurationValid( + const SessionType& session_type, const LeAudioCodecConfiguration&); +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp new file mode 100644 index 0000000000..95e473e5b9 --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp @@ -0,0 +1,581 @@ +/* + * Copyright (C) 2022 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 <sys/types.h> +#define LOG_TAG "BTAudioSessionAidl" + +#include <android-base/logging.h> +#include <android-base/stringprintf.h> +#include <android/binder_manager.h> + +#include "BluetoothAudioSession.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +static constexpr int kFmqSendTimeoutMs = 1000; // 1000 ms timeout for sending +static constexpr int kFmqReceiveTimeoutMs = + 1000; // 1000 ms timeout for receiving +static constexpr int kWritePollMs = 1; // polled non-blocking interval +static constexpr int kReadPollMs = 1; // polled non-blocking interval + +const CodecConfiguration BluetoothAudioSession::kInvalidCodecConfiguration = {}; +const LeAudioConfiguration kInvalidLeAudioConfiguration = {}; +AudioConfiguration BluetoothAudioSession::invalidSoftwareAudioConfiguration = + {}; +AudioConfiguration BluetoothAudioSession::invalidOffloadAudioConfiguration = {}; +AudioConfiguration BluetoothAudioSession::invalidLeOffloadAudioConfig = {}; + +BluetoothAudioSession::BluetoothAudioSession(const SessionType& session_type) + : session_type_(session_type), stack_iface_(nullptr), data_mq_(nullptr) { + invalidSoftwareAudioConfiguration.set<AudioConfiguration::pcmConfig>( + kInvalidPcmConfiguration); + invalidOffloadAudioConfiguration.set<AudioConfiguration::a2dpConfig>( + kInvalidCodecConfiguration); + invalidLeOffloadAudioConfig.set<AudioConfiguration::leAudioConfig>( + kInvalidLeAudioConfiguration); +} + +/*** + * + * Callback methods + * + ***/ + +void BluetoothAudioSession::OnSessionStarted( + const std::shared_ptr<IBluetoothAudioPort> stack_iface, + const DataMQDesc* mq_desc, const AudioConfiguration& audio_config) { + std::lock_guard<std::recursive_mutex> guard(mutex_); + if (stack_iface == nullptr) { + LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_) + << ", IBluetoothAudioPort Invalid"; + } else if (!UpdateAudioConfig(audio_config)) { + LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_) + << ", AudioConfiguration=" << audio_config.toString() + << " Invalid"; + } else if (!UpdateDataPath(mq_desc)) { + LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_) + << " MqDescriptor Invalid"; + if (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + audio_config_ = std::make_unique<AudioConfiguration>( + invalidOffloadAudioConfiguration); + } else { + audio_config_ = std::make_unique<AudioConfiguration>( + invalidSoftwareAudioConfiguration); + } + } else { + stack_iface_ = stack_iface; + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) + << ", AudioConfiguration=" << audio_config.toString(); + ReportSessionStatus(); + } +} + +void BluetoothAudioSession::OnSessionEnded() { + std::lock_guard<std::recursive_mutex> guard(mutex_); + bool toggled = IsSessionReady(); + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_); + if (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + audio_config_ = + std::make_unique<AudioConfiguration>(invalidOffloadAudioConfiguration); + } else { + audio_config_ = + std::make_unique<AudioConfiguration>(invalidSoftwareAudioConfiguration); + } + stack_iface_ = nullptr; + UpdateDataPath(nullptr); + if (toggled) { + ReportSessionStatus(); + } +} + +/*** + * + * Util methods + * + ***/ + +const AudioConfiguration& BluetoothAudioSession::GetAudioConfig() { + std::lock_guard<std::recursive_mutex> guard(mutex_); + if (!IsSessionReady()) { + if (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + return invalidOffloadAudioConfiguration; + } else { + return invalidSoftwareAudioConfiguration; + } + switch (session_type_) { + case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH: + return invalidOffloadAudioConfiguration; + case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH: + case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH: + return invalidLeOffloadAudioConfig; + default: + return invalidSoftwareAudioConfiguration; + } + } + return *audio_config_; +} + +void BluetoothAudioSession::ReportAudioConfigChanged( + const AudioConfiguration& audio_config) { + if (session_type_ != + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH && + session_type_ != + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) { + return; + } + std::lock_guard<std::recursive_mutex> guard(mutex_); + audio_config_ = std::make_unique<AudioConfiguration>(audio_config); + if (observers_.empty()) { + LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) + << " has NO port state observer"; + return; + } + for (auto& observer : observers_) { + uint16_t cookie = observer.first; + std::shared_ptr<struct PortStatusCallbacks> cb = observer.second; + LOG(INFO) << __func__ << " for SessionType=" << toString(session_type_) + << ", bluetooth_audio=0x" + << ::android::base::StringPrintf("%04x", cookie); + if (cb->audio_configuration_changed_cb_ != nullptr) { + cb->audio_configuration_changed_cb_(cookie); + } + } +} + +bool BluetoothAudioSession::IsSessionReady() { + std::lock_guard<std::recursive_mutex> guard(mutex_); + + bool is_mq_valid = + (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH || + session_type_ == + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH || + session_type_ == + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH || + (data_mq_ != nullptr && data_mq_->isValid())); + return stack_iface_ != nullptr && is_mq_valid; +} + +/*** + * + * Status callback methods + * + ***/ + +uint16_t BluetoothAudioSession::RegisterStatusCback( + const PortStatusCallbacks& callbacks) { + std::lock_guard<std::recursive_mutex> guard(mutex_); + uint16_t cookie = ObserversCookieGetInitValue(session_type_); + uint16_t cookie_upper_bound = ObserversCookieGetUpperBound(session_type_); + + while (cookie < cookie_upper_bound) { + if (observers_.find(cookie) == observers_.end()) { + break; + } + ++cookie; + } + if (cookie >= cookie_upper_bound) { + LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_) + << " has " << observers_.size() + << " observers already (No Resource)"; + return kObserversCookieUndefined; + } + std::shared_ptr<PortStatusCallbacks> cb = + std::make_shared<PortStatusCallbacks>(); + *cb = callbacks; + observers_[cookie] = cb; + return cookie; +} + +void BluetoothAudioSession::UnregisterStatusCback(uint16_t cookie) { + std::lock_guard<std::recursive_mutex> guard(mutex_); + if (observers_.erase(cookie) != 1) { + LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) + << " no such provider=0x" + << ::android::base::StringPrintf("%04x", cookie); + } +} + +/*** + * + * Stream methods + * + ***/ + +bool BluetoothAudioSession::StartStream() { + std::lock_guard<std::recursive_mutex> guard(mutex_); + if (!IsSessionReady()) { + LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) + << " has NO session"; + return false; + } + auto hal_retval = stack_iface_->startStream(); + if (!hal_retval.isOk()) { + LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" + << toString(session_type_) << " failed"; + return false; + } + return true; +} + +bool BluetoothAudioSession::SuspendStream() { + std::lock_guard<std::recursive_mutex> guard(mutex_); + if (!IsSessionReady()) { + LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) + << " has NO session"; + return false; + } + auto hal_retval = stack_iface_->suspendStream(); + if (!hal_retval.isOk()) { + LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" + << toString(session_type_) << " failed"; + return false; + } + return true; +} + +void BluetoothAudioSession::StopStream() { + std::lock_guard<std::recursive_mutex> guard(mutex_); + if (!IsSessionReady()) { + return; + } + auto hal_retval = stack_iface_->stopStream(); + if (!hal_retval.isOk()) { + LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" + << toString(session_type_) << " failed"; + } +} + +/*** + * + * Private methods + * + ***/ + +bool BluetoothAudioSession::UpdateDataPath(const DataMQDesc* mq_desc) { + if (mq_desc == nullptr) { + // usecase of reset by nullptr + data_mq_ = nullptr; + return true; + } + std::unique_ptr<DataMQ> temp_mq; + temp_mq.reset(new DataMQ(*mq_desc)); + if (!temp_mq || !temp_mq->isValid()) { + data_mq_ = nullptr; + return false; + } + data_mq_ = std::move(temp_mq); + return true; +} + +bool BluetoothAudioSession::UpdateAudioConfig( + const AudioConfiguration& audio_config) { + bool is_software_session = + (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH || + session_type_ == SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH || + session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH || + session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH); + bool is_offload_a2dp_session = + (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH); + bool is_offload_le_audio_session = + (session_type_ == + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH || + session_type_ == + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH); + auto audio_config_tag = audio_config.getTag(); + bool is_software_audio_config = + (is_software_session && + audio_config_tag == AudioConfiguration::pcmConfig); + bool is_a2dp_offload_audio_config = + (is_offload_a2dp_session && + audio_config_tag == AudioConfiguration::a2dpConfig); + bool is_le_audio_offload_audio_config = + (is_offload_le_audio_session && + audio_config_tag == AudioConfiguration::leAudioConfig); + if (!is_software_audio_config && !is_a2dp_offload_audio_config && + !is_le_audio_offload_audio_config) { + return false; + } + audio_config_ = std::make_unique<AudioConfiguration>(audio_config); + return true; +} + +void BluetoothAudioSession::ReportSessionStatus() { + // This is locked already by OnSessionStarted / OnSessionEnded + if (observers_.empty()) { + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) + << " has NO port state observer"; + return; + } + for (auto& observer : observers_) { + uint16_t cookie = observer.first; + std::shared_ptr<PortStatusCallbacks> callback = observer.second; + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) + << " notify to bluetooth_audio=0x" + << ::android::base::StringPrintf("%04x", cookie); + callback->session_changed_cb_(cookie); + } +} + +/*** + * + * PCM methods + * + ***/ + +size_t BluetoothAudioSession::OutWritePcmData(const void* buffer, + size_t bytes) { + if (buffer == nullptr || bytes <= 0) { + return 0; + } + size_t total_written = 0; + int timeout_ms = kFmqSendTimeoutMs; + do { + std::unique_lock<std::recursive_mutex> lock(mutex_); + if (!IsSessionReady()) { + break; + } + size_t num_bytes_to_write = data_mq_->availableToWrite(); + if (num_bytes_to_write) { + if (num_bytes_to_write > (bytes - total_written)) { + num_bytes_to_write = bytes - total_written; + } + + if (!data_mq_->write( + static_cast<const MQDataType*>(buffer) + total_written, + num_bytes_to_write)) { + LOG(ERROR) << "FMQ datapath writing " << total_written << "/" << bytes + << " failed"; + return total_written; + } + total_written += num_bytes_to_write; + } else if (timeout_ms >= kWritePollMs) { + lock.unlock(); + usleep(kWritePollMs * 1000); + timeout_ms -= kWritePollMs; + } else { + LOG(DEBUG) << "Data " << total_written << "/" << bytes << " overflow " + << (kFmqSendTimeoutMs - timeout_ms) << " ms"; + return total_written; + } + } while (total_written < bytes); + return total_written; +} + +size_t BluetoothAudioSession::InReadPcmData(void* buffer, size_t bytes) { + if (buffer == nullptr || bytes <= 0) { + return 0; + } + size_t total_read = 0; + int timeout_ms = kFmqReceiveTimeoutMs; + do { + std::unique_lock<std::recursive_mutex> lock(mutex_); + if (!IsSessionReady()) { + break; + } + size_t num_bytes_to_read = data_mq_->availableToRead(); + if (num_bytes_to_read) { + if (num_bytes_to_read > (bytes - total_read)) { + num_bytes_to_read = bytes - total_read; + } + if (!data_mq_->read(static_cast<MQDataType*>(buffer) + total_read, + num_bytes_to_read)) { + LOG(ERROR) << "FMQ datapath reading " << total_read << "/" << bytes + << " failed"; + return total_read; + } + total_read += num_bytes_to_read; + } else if (timeout_ms >= kReadPollMs) { + lock.unlock(); + usleep(kReadPollMs * 1000); + timeout_ms -= kReadPollMs; + continue; + } else { + LOG(DEBUG) << "Data " << total_read << "/" << bytes << " overflow " + << (kFmqReceiveTimeoutMs - timeout_ms) << " ms"; + return total_read; + } + } while (total_read < bytes); + return total_read; +} + +/*** + * + * Other methods + * + ***/ + +void BluetoothAudioSession::ReportControlStatus(bool start_resp, + BluetoothAudioStatus status) { + std::lock_guard<std::recursive_mutex> guard(mutex_); + if (observers_.empty()) { + LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) + << " has NO port state observer"; + return; + } + for (auto& observer : observers_) { + uint16_t cookie = observer.first; + std::shared_ptr<PortStatusCallbacks> callback = observer.second; + LOG(INFO) << __func__ << " - status=" << toString(status) + << " for SessionType=" << toString(session_type_) + << ", bluetooth_audio=0x" + << ::android::base::StringPrintf("%04x", cookie) + << (start_resp ? " started" : " suspended"); + callback->control_result_cb_(cookie, start_resp, status); + } +} + +bool BluetoothAudioSession::GetPresentationPosition( + PresentationPosition& presentation_position) { + std::lock_guard<std::recursive_mutex> guard(mutex_); + if (!IsSessionReady()) { + LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) + << " has NO session"; + return false; + } + bool retval = false; + + if (!stack_iface_->getPresentationPosition(&presentation_position).isOk()) { + LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" + << toString(session_type_) << " failed"; + return false; + } + return retval; +} + +void BluetoothAudioSession::UpdateSourceMetadata( + const struct source_metadata& source_metadata) { + std::lock_guard<std::recursive_mutex> guard(mutex_); + if (!IsSessionReady()) { + LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) + << " has NO session"; + return; + } + + ssize_t track_count = source_metadata.track_count; + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << "," + << track_count << " track(s)"; + if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH || + session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + return; + } + + SourceMetadata hal_source_metadata; + hal_source_metadata.tracks.resize(track_count); + for (int i = 0; i < track_count; i++) { + hal_source_metadata.tracks[i].usage = + static_cast<media::audio::common::AudioUsage>( + source_metadata.tracks[i].usage); + hal_source_metadata.tracks[i].contentType = + static_cast<media::audio::common::AudioContentType>( + source_metadata.tracks[i].content_type); + hal_source_metadata.tracks[i].gain = source_metadata.tracks[i].gain; + LOG(VERBOSE) << __func__ << " - SessionType=" << toString(session_type_) + << ", usage=" << toString(hal_source_metadata.tracks[i].usage) + << ", content=" + << toString(hal_source_metadata.tracks[i].contentType) + << ", gain=" << hal_source_metadata.tracks[i].gain; + } + + auto hal_retval = stack_iface_->updateSourceMetadata(hal_source_metadata); + if (!hal_retval.isOk()) { + LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" + << toString(session_type_) << " failed"; + } +} + +void BluetoothAudioSession::UpdateSinkMetadata( + const struct sink_metadata& sink_metadata) { + std::lock_guard<std::recursive_mutex> guard(mutex_); + if (!IsSessionReady()) { + LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) + << " has NO session"; + return; + } + + ssize_t track_count = sink_metadata.track_count; + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << "," + << track_count << " track(s)"; + if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH || + session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + return; + } + + SinkMetadata hal_sink_metadata; + hal_sink_metadata.tracks.resize(track_count); + for (int i = 0; i < track_count; i++) { + hal_sink_metadata.tracks[i].source = + static_cast<media::audio::common::AudioSource>( + sink_metadata.tracks[i].source); + hal_sink_metadata.tracks[i].gain = sink_metadata.tracks[i].gain; + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) + << ", source=" << sink_metadata.tracks[i].source + << ", dest_device=" << sink_metadata.tracks[i].dest_device + << ", gain=" << sink_metadata.tracks[i].gain + << ", dest_device_address=" + << sink_metadata.tracks[i].dest_device_address; + } + + auto hal_retval = stack_iface_->updateSinkMetadata(hal_sink_metadata); + if (!hal_retval.isOk()) { + LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" + << toString(session_type_) << " failed"; + } +} + +bool BluetoothAudioSession::IsAidlAvailable() { + if (is_aidl_checked) return is_aidl_available; + is_aidl_available = + (AServiceManager_checkService( + kDefaultAudioProviderFactoryInterface.c_str()) != nullptr); + is_aidl_checked = true; + return is_aidl_available; +} + +/*** + * + * BluetoothAudioSessionInstance + * + ***/ +std::mutex BluetoothAudioSessionInstance::mutex_; +std::unordered_map<SessionType, std::shared_ptr<BluetoothAudioSession>> + BluetoothAudioSessionInstance::sessions_map_; + +std::shared_ptr<BluetoothAudioSession> +BluetoothAudioSessionInstance::GetSessionInstance( + const SessionType& session_type) { + std::lock_guard<std::mutex> guard(mutex_); + + if (!sessions_map_.empty()) { + auto entry = sessions_map_.find(session_type); + if (entry != sessions_map_.end()) { + return entry->second; + } + } + std::shared_ptr<BluetoothAudioSession> session_ptr = + std::make_shared<BluetoothAudioSession>(session_type); + sessions_map_[session_type] = session_ptr; + return session_ptr; +} + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl
\ No newline at end of file diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h new file mode 100644 index 0000000000..85fd571f28 --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <aidl/android/hardware/audio/common/SinkMetadata.h> +#include <aidl/android/hardware/audio/common/SourceMetadata.h> +#include <aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.h> +#include <aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.h> +#include <aidl/android/hardware/bluetooth/audio/SessionType.h> +#include <fmq/AidlMessageQueue.h> +#include <hardware/audio.h> + +#include <mutex> +#include <unordered_map> + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +using ::aidl::android::hardware::common::fmq::MQDescriptor; +using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite; +using ::android::AidlMessageQueue; + +using ::aidl::android::hardware::audio::common::SinkMetadata; +using ::aidl::android::hardware::audio::common::SourceMetadata; + +using MQDataType = int8_t; +using MQDataMode = SynchronizedReadWrite; +using DataMQ = AidlMessageQueue<MQDataType, MQDataMode>; +using DataMQDesc = + ::aidl::android::hardware::common::fmq::MQDescriptor<MQDataType, + MQDataMode>; + +static constexpr uint16_t kObserversCookieSize = 0x0010; // 0x0000 ~ 0x000f +static constexpr uint16_t kObserversCookieUndefined = + (static_cast<uint16_t>(SessionType::UNKNOWN) << 8 & 0xff00); +inline SessionType ObserversCookieGetSessionType(uint16_t cookie) { + return static_cast<SessionType>(cookie >> 8 & 0x00ff); +} +inline uint16_t ObserversCookieGetInitValue(SessionType session_type) { + return (static_cast<uint16_t>(session_type) << 8 & 0xff00); +} +inline uint16_t ObserversCookieGetUpperBound(SessionType session_type) { + return (static_cast<uint16_t>(session_type) << 8 & 0xff00) + + kObserversCookieSize; +} + +/*** + * This presents the callbacks of started / suspended and session changed, + * and the bluetooth_audio module uses to receive the status notification + ***/ +struct PortStatusCallbacks { + /*** + * control_result_cb_ - when the Bluetooth stack reports results of + * streamStarted or streamSuspended, the BluetoothAudioProvider will invoke + * this callback to report to the bluetooth_audio module. + * @param: cookie - indicates which bluetooth_audio output should handle + * @param: start_resp - this report is for startStream or not + * @param: status - the result of startStream + ***/ + std::function<void(uint16_t cookie, bool start_resp, + BluetoothAudioStatus status)> + control_result_cb_; + /*** + * session_changed_cb_ - when the Bluetooth stack start / end session, the + * BluetoothAudioProvider will invoke this callback to notify to the + * bluetooth_audio module. + * @param: cookie - indicates which bluetooth_audio output should handle + ***/ + std::function<void(uint16_t cookie)> session_changed_cb_; + /*** + * audio_configuration_changed_cb_ - when the Bluetooth stack change the audio + * configuration, the BluetoothAudioProvider will invoke this callback to + * notify to the bluetooth_audio module. + * @param: cookie - indicates which bluetooth_audio output should handle + ***/ + std::function<void(uint16_t cookie)> audio_configuration_changed_cb_; +}; + +class BluetoothAudioSession { + public: + BluetoothAudioSession(const SessionType& session_type); + + /*** + * The function helps to check if this session is ready or not + * @return: true if the Bluetooth stack has started the specified session + ***/ + bool IsSessionReady(); + + /*** + * The report function is used to report that the Bluetooth stack has started + * this session without any failure, and will invoke session_changed_cb_ to + * notify those registered bluetooth_audio outputs + ***/ + void OnSessionStarted(const std::shared_ptr<IBluetoothAudioPort> stack_iface, + const DataMQDesc* mq_desc, + const AudioConfiguration& audio_config); + + /*** + * The report function is used to report that the Bluetooth stack has ended + * the session, and will invoke session_changed_cb_ to notify registered + * bluetooth_audio outputs + ***/ + void OnSessionEnded(); + + /*** + * The report function is used to report that the Bluetooth stack has notified + * the result of startStream or suspendStream, and will invoke + * control_result_cb_ to notify registered bluetooth_audio outputs + ***/ + void ReportControlStatus(bool start_resp, BluetoothAudioStatus status); + + /*** + * The control function helps the bluetooth_audio module to register + * PortStatusCallbacks + * @return: cookie - the assigned number to this bluetooth_audio output + ***/ + uint16_t RegisterStatusCback(const PortStatusCallbacks& cbacks); + + /*** + * The control function helps the bluetooth_audio module to unregister + * PortStatusCallbacks + * @param: cookie - indicates which bluetooth_audio output is + ***/ + void UnregisterStatusCback(uint16_t cookie); + + /*** + * The control function is for the bluetooth_audio module to get the current + * AudioConfiguration + ***/ + const AudioConfiguration& GetAudioConfig(); + + /*** + * The report function is used to report that the Bluetooth stack has notified + * the audio configuration changed, and will invoke + * audio_configuration_changed_cb_ to notify registered bluetooth_audio + * outputs + ***/ + void ReportAudioConfigChanged(const AudioConfiguration& audio_config); + + /*** + * Those control functions are for the bluetooth_audio module to start, + * suspend, stop stream, to check position, and to update metadata. + ***/ + bool StartStream(); + bool SuspendStream(); + void StopStream(); + bool GetPresentationPosition(PresentationPosition& presentation_position); + void UpdateSourceMetadata(const struct source_metadata& source_metadata); + void UpdateSinkMetadata(const struct sink_metadata& sink_metadata); + + // The control function writes stream to FMQ + size_t OutWritePcmData(const void* buffer, size_t bytes); + // The control function read stream from FMQ + size_t InReadPcmData(void* buffer, size_t bytes); + + // Return if IBluetoothAudioProviderFactory implementation existed + static bool IsAidlAvailable(); + + static constexpr PcmConfiguration kInvalidPcmConfiguration = {}; + // can't be constexpr because of non-literal type + static const CodecConfiguration kInvalidCodecConfiguration; + + static AudioConfiguration invalidSoftwareAudioConfiguration; + static AudioConfiguration invalidOffloadAudioConfiguration; + static AudioConfiguration invalidLeOffloadAudioConfig; + + private: + // using recursive_mutex to allow hwbinder to re-enter again. + std::recursive_mutex mutex_; + SessionType session_type_; + + // audio control path to use for both software and offloading + std::shared_ptr<IBluetoothAudioPort> stack_iface_; + // audio data path (FMQ) for software encoding + std::unique_ptr<DataMQ> data_mq_; + // audio data configuration for both software and offloading + std::unique_ptr<AudioConfiguration> audio_config_; + + // saving those registered bluetooth_audio's callbacks + std::unordered_map<uint16_t, std::shared_ptr<struct PortStatusCallbacks>> + observers_; + + bool UpdateDataPath(const DataMQDesc* mq_desc); + bool UpdateAudioConfig(const AudioConfiguration& audio_config); + // invoking the registered session_changed_cb_ + void ReportSessionStatus(); + + static inline std::atomic<bool> is_aidl_checked = false; + static inline std::atomic<bool> is_aidl_available = false; + static inline const std::string kDefaultAudioProviderFactoryInterface = + std::string() + IBluetoothAudioProviderFactory::descriptor + "/default"; +}; + +class BluetoothAudioSessionInstance { + public: + // The API is to fetch the specified session of A2DP / Hearing Aid + static std::shared_ptr<BluetoothAudioSession> GetSessionInstance( + const SessionType& session_type); + + private: + static std::mutex mutex_; + static std::unordered_map<SessionType, std::shared_ptr<BluetoothAudioSession>> + sessions_map_; +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl
\ No newline at end of file diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h new file mode 100644 index 0000000000..a3ed42894c --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h @@ -0,0 +1,182 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "BluetoothAudioSession.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +class BluetoothAudioSessionControl { + public: + /*** + * The control API helps to check if session is ready or not + * @return: true if the Bluetooth stack has started th specified session + ***/ + static bool IsSessionReady(const SessionType& session_type) { + std::shared_ptr<BluetoothAudioSession> session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + return session_ptr->IsSessionReady(); + } + + return false; + } + + /*** + * The control API helps the bluetooth_audio module to register + * PortStatusCallbacks + * @return: cookie - the assigned number to this bluetooth_audio output + ***/ + static uint16_t RegisterControlResultCback( + const SessionType& session_type, const PortStatusCallbacks& cbacks) { + std::shared_ptr<BluetoothAudioSession> session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + return session_ptr->RegisterStatusCback(cbacks); + } + return kObserversCookieUndefined; + } + + /*** + * The control API helps the bluetooth_audio module to unregister + * PortStatusCallbacks + * @param: cookie - indicates which bluetooth_audio output is + ***/ + static void UnregisterControlResultCback(const SessionType& session_type, + uint16_t cookie) { + std::shared_ptr<BluetoothAudioSession> session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + session_ptr->UnregisterStatusCback(cookie); + } + } + + /*** + * The control API for the bluetooth_audio module to get current + * AudioConfiguration + ***/ + static const AudioConfiguration GetAudioConfig( + const SessionType& session_type) { + std::shared_ptr<BluetoothAudioSession> session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + return session_ptr->GetAudioConfig(); + } else if (session_type == + SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + return BluetoothAudioSession::invalidOffloadAudioConfiguration; + } else { + return BluetoothAudioSession::invalidSoftwareAudioConfiguration; + } + } + + /*** + * Those control APIs for the bluetooth_audio module to start / suspend / + stop + * stream, to check position, and to update metadata. + ***/ + static bool StartStream(const SessionType& session_type) { + std::shared_ptr<BluetoothAudioSession> session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + return session_ptr->StartStream(); + } + return false; + } + + static bool SuspendStream(const SessionType& session_type) { + std::shared_ptr<BluetoothAudioSession> session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + return session_ptr->SuspendStream(); + } + return false; + } + + static void StopStream(const SessionType& session_type) { + std::shared_ptr<BluetoothAudioSession> session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + session_ptr->StopStream(); + } + } + + static bool GetPresentationPosition( + const SessionType& session_type, + PresentationPosition& presentation_position) { + std::shared_ptr<BluetoothAudioSession> session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + return session_ptr->GetPresentationPosition(presentation_position); + } + return false; + } + + static void UpdateSourceMetadata( + const SessionType& session_type, + const struct source_metadata& source_metadata) { + std::shared_ptr<BluetoothAudioSession> session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + session_ptr->UpdateSourceMetadata(source_metadata); + } + } + + static void UpdateSinkMetadata(const SessionType& session_type, + const struct sink_metadata& sink_metadata) { + std::shared_ptr<BluetoothAudioSession> session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + session_ptr->UpdateSinkMetadata(sink_metadata); + } + } + + /*** + * The control API writes stream to FMQ + ***/ + static size_t OutWritePcmData(const SessionType& session_type, + const void* buffer, size_t bytes) { + std::shared_ptr<BluetoothAudioSession> session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + return session_ptr->OutWritePcmData(buffer, bytes); + } + return 0; + } + + /*** + * The control API reads stream from FMQ + ***/ + static size_t InReadPcmData(const SessionType& session_type, void* buffer, + size_t bytes) { + std::shared_ptr<BluetoothAudioSession> session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + return session_ptr->InReadPcmData(buffer, bytes); + } + return 0; + } +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl
\ No newline at end of file diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionReport.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionReport.h new file mode 100644 index 0000000000..18569c3827 --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionReport.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "BluetoothAudioSession.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +class BluetoothAudioSessionReport { + public: + /*** + * The API reports the Bluetooth stack has started the session, and will + * inform registered bluetooth_audio outputs + ***/ + static void OnSessionStarted( + const SessionType& session_type, + const std::shared_ptr<IBluetoothAudioPort> host_iface, + const DataMQDesc* data_mq, const AudioConfiguration& audio_config) { + std::shared_ptr<BluetoothAudioSession> session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + session_ptr->OnSessionStarted(host_iface, data_mq, audio_config); + } + } + + /*** + * The API reports the Bluetooth stack has ended the session, and will + * inform registered bluetooth_audio outputs + ***/ + static void OnSessionEnded(const SessionType& session_type) { + std::shared_ptr<BluetoothAudioSession> session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + session_ptr->OnSessionEnded(); + } + } + + /*** + * The API reports the Bluetooth stack has replied the result of startStream + * or suspendStream, and will inform registered bluetooth_audio outputs + ***/ + static void ReportControlStatus(const SessionType& session_type, + const bool& start_resp, + BluetoothAudioStatus status) { + std::shared_ptr<BluetoothAudioSession> session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + session_ptr->ReportControlStatus(start_resp, status); + } + } + /*** + * The API reports the Bluetooth stack has replied the changed of the audio + * configuration, and will inform registered bluetooth_audio outputs + ***/ + static void ReportAudioConfigChanged(const SessionType& session_type, + const AudioConfiguration& audio_config) { + std::shared_ptr<BluetoothAudioSession> session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + session_ptr->ReportAudioConfigChanged(audio_config); + } + } +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl
\ No newline at end of file diff --git a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp new file mode 100644 index 0000000000..91e0238783 --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp @@ -0,0 +1,775 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "BtAudioNakahara" + +#include <aidl/android/hardware/bluetooth/audio/AudioConfiguration.h> +#include <aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.h> +#include <aidl/android/hardware/bluetooth/audio/SessionType.h> +#include <android-base/logging.h> + +#include <functional> +#include <unordered_map> + +#include "../aidl_session/BluetoothAudioSession.h" +#include "../aidl_session/BluetoothAudioSessionControl.h" +#include "HidlToAidlMiddleware_2_0.h" +#include "HidlToAidlMiddleware_2_1.h" +#include "HidlToAidlMiddleware_2_2.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +using HidlStatus = ::android::hardware::bluetooth::audio::V2_0::Status; +using PcmConfig_2_0 = + ::android::hardware::bluetooth::audio::V2_0::PcmParameters; +using SampleRate_2_0 = ::android::hardware::bluetooth::audio::V2_0::SampleRate; +using ChannelMode_2_0 = + ::android::hardware::bluetooth::audio::V2_0::ChannelMode; +using BitsPerSample_2_0 = + ::android::hardware::bluetooth::audio::V2_0::BitsPerSample; +using CodecConfig_2_0 = + ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration; +using CodecType_2_0 = ::android::hardware::bluetooth::audio::V2_0::CodecType; +using SbcConfig_2_0 = + ::android::hardware::bluetooth::audio::V2_0::SbcParameters; +using AacConfig_2_0 = + ::android::hardware::bluetooth::audio::V2_0::AacParameters; +using LdacConfig_2_0 = + ::android::hardware::bluetooth::audio::V2_0::LdacParameters; +using AptxConfig_2_0 = + ::android::hardware::bluetooth::audio::V2_0::AptxParameters; +using SbcAllocMethod_2_0 = + ::android::hardware::bluetooth::audio::V2_0::SbcAllocMethod; +using SbcBlockLength_2_0 = + ::android::hardware::bluetooth::audio::V2_0::SbcBlockLength; +using SbcChannelMode_2_0 = + ::android::hardware::bluetooth::audio::V2_0::SbcChannelMode; +using SbcNumSubbands_2_0 = + ::android::hardware::bluetooth::audio::V2_0::SbcNumSubbands; +using AacObjectType_2_0 = + ::android::hardware::bluetooth::audio::V2_0::AacObjectType; +using AacVarBitRate_2_0 = + ::android::hardware::bluetooth::audio::V2_0::AacVariableBitRate; +using LdacChannelMode_2_0 = + ::android::hardware::bluetooth::audio::V2_0::LdacChannelMode; +using LdacQualityIndex_2_0 = + ::android::hardware::bluetooth::audio::V2_0::LdacQualityIndex; + +using PcmConfig_2_1 = + ::android::hardware::bluetooth::audio::V2_1::PcmParameters; +using SampleRate_2_1 = ::android::hardware::bluetooth::audio::V2_1::SampleRate; +using Lc3CodecConfig_2_1 = + ::android::hardware::bluetooth::audio::V2_1::Lc3CodecConfiguration; +using Lc3Config_2_1 = + ::android::hardware::bluetooth::audio::V2_1::Lc3Parameters; +using Lc3FrameDuration_2_1 = + ::android::hardware::bluetooth::audio::V2_1::Lc3FrameDuration; + +using LeAudioConfig_2_2 = + ::android::hardware::bluetooth::audio::V2_2::LeAudioConfiguration; +using LeAudioMode_2_2 = + ::android::hardware::bluetooth::audio::V2_2::LeAudioMode; + +std::mutex legacy_callback_lock; +std::unordered_map< + SessionType, + std::unordered_map<uint16_t, std::shared_ptr<PortStatusCallbacks_2_2>>> + legacy_callback_table; + +const static std::unordered_map<SessionType_2_0, SessionType> + session_type_2_0_to_aidl_map{ + {SessionType_2_0::A2DP_SOFTWARE_ENCODING_DATAPATH, + SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH}, + {SessionType_2_0::A2DP_HARDWARE_OFFLOAD_DATAPATH, + SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH}, + {SessionType_2_0::HEARING_AID_SOFTWARE_ENCODING_DATAPATH, + SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH}, + }; + +const static std::unordered_map<SessionType_2_1, SessionType> + session_type_2_1_to_aidl_map{ + {SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH, + SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH}, + {SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH, + SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH}, + {SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH, + SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH}, + {SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH, + SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH}, + {SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH, + SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH}, + {SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH, + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH}, + {SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH, + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH}, + }; + +const static std::unordered_map<int32_t, SampleRate_2_0> + sample_rate_to_hidl_2_0_map{ + {44100, SampleRate_2_0::RATE_44100}, + {48000, SampleRate_2_0::RATE_48000}, + {88200, SampleRate_2_0::RATE_88200}, + {96000, SampleRate_2_0::RATE_96000}, + {176400, SampleRate_2_0::RATE_176400}, + {192000, SampleRate_2_0::RATE_192000}, + {16000, SampleRate_2_0::RATE_16000}, + {24000, SampleRate_2_0::RATE_24000}, + }; + +const static std::unordered_map<int32_t, SampleRate_2_1> + sample_rate_to_hidl_2_1_map{ + {44100, SampleRate_2_1::RATE_44100}, + {48000, SampleRate_2_1::RATE_48000}, + {88200, SampleRate_2_1::RATE_88200}, + {96000, SampleRate_2_1::RATE_96000}, + {176400, SampleRate_2_1::RATE_176400}, + {192000, SampleRate_2_1::RATE_192000}, + {16000, SampleRate_2_1::RATE_16000}, + {24000, SampleRate_2_1::RATE_24000}, + {8000, SampleRate_2_1::RATE_8000}, + {32000, SampleRate_2_1::RATE_32000}, + }; + +const static std::unordered_map<CodecType, CodecType_2_0> + codec_type_to_hidl_2_0_map{ + {CodecType::UNKNOWN, CodecType_2_0::UNKNOWN}, + {CodecType::SBC, CodecType_2_0::SBC}, + {CodecType::AAC, CodecType_2_0::AAC}, + {CodecType::APTX, CodecType_2_0::APTX}, + {CodecType::APTX_HD, CodecType_2_0::APTX_HD}, + {CodecType::LDAC, CodecType_2_0::LDAC}, + {CodecType::LC3, CodecType_2_0::UNKNOWN}, + }; + +const static std::unordered_map<SbcChannelMode, SbcChannelMode_2_0> + sbc_channel_mode_to_hidl_2_0_map{ + {SbcChannelMode::UNKNOWN, SbcChannelMode_2_0::UNKNOWN}, + {SbcChannelMode::JOINT_STEREO, SbcChannelMode_2_0::JOINT_STEREO}, + {SbcChannelMode::STEREO, SbcChannelMode_2_0::STEREO}, + {SbcChannelMode::DUAL, SbcChannelMode_2_0::DUAL}, + {SbcChannelMode::MONO, SbcChannelMode_2_0::MONO}, + }; + +const static std::unordered_map<int8_t, SbcBlockLength_2_0> + sbc_block_length_to_hidl_map{ + {4, SbcBlockLength_2_0::BLOCKS_4}, + {8, SbcBlockLength_2_0::BLOCKS_8}, + {12, SbcBlockLength_2_0::BLOCKS_12}, + {16, SbcBlockLength_2_0::BLOCKS_16}, + }; + +const static std::unordered_map<int8_t, SbcNumSubbands_2_0> + sbc_subbands_to_hidl_map{ + {4, SbcNumSubbands_2_0::SUBBAND_4}, + {8, SbcNumSubbands_2_0::SUBBAND_8}, + }; + +const static std::unordered_map<SbcAllocMethod, SbcAllocMethod_2_0> + sbc_alloc_method_to_hidl_map{ + {SbcAllocMethod::ALLOC_MD_S, SbcAllocMethod_2_0::ALLOC_MD_S}, + {SbcAllocMethod::ALLOC_MD_L, SbcAllocMethod_2_0::ALLOC_MD_L}, + }; + +const static std::unordered_map<AacObjectType, AacObjectType_2_0> + aac_object_type_to_hidl_map{ + {AacObjectType::MPEG2_LC, AacObjectType_2_0::MPEG2_LC}, + {AacObjectType::MPEG4_LC, AacObjectType_2_0::MPEG4_LC}, + {AacObjectType::MPEG4_LTP, AacObjectType_2_0::MPEG4_LTP}, + {AacObjectType::MPEG4_SCALABLE, AacObjectType_2_0::MPEG4_SCALABLE}, + }; + +const static std::unordered_map<LdacChannelMode, LdacChannelMode_2_0> + ldac_channel_mode_to_hidl_map{ + {LdacChannelMode::UNKNOWN, LdacChannelMode_2_0::UNKNOWN}, + {LdacChannelMode::STEREO, LdacChannelMode_2_0::STEREO}, + {LdacChannelMode::DUAL, LdacChannelMode_2_0::DUAL}, + {LdacChannelMode::MONO, LdacChannelMode_2_0::MONO}, + }; + +const static std::unordered_map<LdacQualityIndex, LdacQualityIndex_2_0> + ldac_qindex_to_hidl_map{ + {LdacQualityIndex::HIGH, LdacQualityIndex_2_0::QUALITY_HIGH}, + {LdacQualityIndex::MID, LdacQualityIndex_2_0::QUALITY_MID}, + {LdacQualityIndex::LOW, LdacQualityIndex_2_0::QUALITY_LOW}, + {LdacQualityIndex::ABR, LdacQualityIndex_2_0::QUALITY_ABR}, + }; + +const static std::unordered_map<LeAudioMode, LeAudioMode_2_2> + leaudio_mode_to_hidl_map{ + {LeAudioMode::UNKNOWN, LeAudioMode_2_2::UNKNOWN}, + {LeAudioMode::UNICAST, LeAudioMode_2_2::UNICAST}, + {LeAudioMode::BROADCAST, LeAudioMode_2_2::BROADCAST}, + }; + +inline SessionType from_session_type_2_0( + const SessionType_2_0& session_type_hidl) { + auto it = session_type_2_0_to_aidl_map.find(session_type_hidl); + if (it != session_type_2_0_to_aidl_map.end()) return it->second; + return SessionType::UNKNOWN; +} + +inline SessionType from_session_type_2_1( + const SessionType_2_1& session_type_hidl) { + auto it = session_type_2_1_to_aidl_map.find(session_type_hidl); + if (it != session_type_2_1_to_aidl_map.end()) return it->second; + return SessionType::UNKNOWN; +} + +inline HidlStatus to_hidl_status(const BluetoothAudioStatus& status) { + switch (status) { + case BluetoothAudioStatus::SUCCESS: + return HidlStatus::SUCCESS; + case BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION: + return HidlStatus::UNSUPPORTED_CODEC_CONFIGURATION; + default: + return HidlStatus::FAILURE; + } +} + +inline SampleRate_2_0 to_hidl_sample_rate_2_0(const int32_t sample_rate_hz) { + auto it = sample_rate_to_hidl_2_0_map.find(sample_rate_hz); + if (it != sample_rate_to_hidl_2_0_map.end()) return it->second; + return SampleRate_2_0::RATE_UNKNOWN; +} + +inline SampleRate_2_1 to_hidl_sample_rate_2_1(const int32_t sample_rate_hz) { + auto it = sample_rate_to_hidl_2_1_map.find(sample_rate_hz); + if (it != sample_rate_to_hidl_2_1_map.end()) return it->second; + return SampleRate_2_1::RATE_UNKNOWN; +} + +inline BitsPerSample_2_0 to_hidl_bits_per_sample(const int8_t bit_per_sample) { + switch (bit_per_sample) { + case 16: + return BitsPerSample_2_0::BITS_16; + case 24: + return BitsPerSample_2_0::BITS_24; + case 32: + return BitsPerSample_2_0::BITS_32; + default: + return BitsPerSample_2_0::BITS_UNKNOWN; + } +} + +inline ChannelMode_2_0 to_hidl_channel_mode(const ChannelMode channel_mode) { + switch (channel_mode) { + case ChannelMode::MONO: + return ChannelMode_2_0::MONO; + case ChannelMode::STEREO: + return ChannelMode_2_0::STEREO; + default: + return ChannelMode_2_0::UNKNOWN; + } +} + +inline PcmConfig_2_0 to_hidl_pcm_config_2_0( + const PcmConfiguration& pcm_config) { + PcmConfig_2_0 hidl_pcm_config; + hidl_pcm_config.sampleRate = to_hidl_sample_rate_2_0(pcm_config.sampleRateHz); + hidl_pcm_config.channelMode = to_hidl_channel_mode(pcm_config.channelMode); + hidl_pcm_config.bitsPerSample = + to_hidl_bits_per_sample(pcm_config.bitsPerSample); + return hidl_pcm_config; +} + +inline CodecType_2_0 to_hidl_codec_type_2_0(const CodecType codec_type) { + auto it = codec_type_to_hidl_2_0_map.find(codec_type); + if (it != codec_type_to_hidl_2_0_map.end()) return it->second; + return CodecType_2_0::UNKNOWN; +} + +inline SbcConfig_2_0 to_hidl_sbc_config(const SbcConfiguration sbc_config) { + SbcConfig_2_0 hidl_sbc_config; + hidl_sbc_config.minBitpool = sbc_config.minBitpool; + hidl_sbc_config.maxBitpool = sbc_config.maxBitpool; + hidl_sbc_config.sampleRate = to_hidl_sample_rate_2_0(sbc_config.sampleRateHz); + hidl_sbc_config.bitsPerSample = + to_hidl_bits_per_sample(sbc_config.bitsPerSample); + if (sbc_channel_mode_to_hidl_2_0_map.find(sbc_config.channelMode) != + sbc_channel_mode_to_hidl_2_0_map.end()) { + hidl_sbc_config.channelMode = + sbc_channel_mode_to_hidl_2_0_map.at(sbc_config.channelMode); + } + if (sbc_block_length_to_hidl_map.find(sbc_config.blockLength) != + sbc_block_length_to_hidl_map.end()) { + hidl_sbc_config.blockLength = + sbc_block_length_to_hidl_map.at(sbc_config.blockLength); + } + if (sbc_subbands_to_hidl_map.find(sbc_config.numSubbands) != + sbc_subbands_to_hidl_map.end()) { + hidl_sbc_config.numSubbands = + sbc_subbands_to_hidl_map.at(sbc_config.numSubbands); + } + if (sbc_alloc_method_to_hidl_map.find(sbc_config.allocMethod) != + sbc_alloc_method_to_hidl_map.end()) { + hidl_sbc_config.allocMethod = + sbc_alloc_method_to_hidl_map.at(sbc_config.allocMethod); + } + return hidl_sbc_config; +} + +inline AacConfig_2_0 to_hidl_aac_config(const AacConfiguration aac_config) { + AacConfig_2_0 hidl_aac_config; + hidl_aac_config.sampleRate = to_hidl_sample_rate_2_0(aac_config.sampleRateHz); + hidl_aac_config.bitsPerSample = + to_hidl_bits_per_sample(aac_config.bitsPerSample); + hidl_aac_config.channelMode = to_hidl_channel_mode(aac_config.channelMode); + if (aac_object_type_to_hidl_map.find(aac_config.objectType) != + aac_object_type_to_hidl_map.end()) { + hidl_aac_config.objectType = + aac_object_type_to_hidl_map.at(aac_config.objectType); + } + hidl_aac_config.variableBitRateEnabled = aac_config.variableBitRateEnabled + ? AacVarBitRate_2_0::ENABLED + : AacVarBitRate_2_0::DISABLED; + return hidl_aac_config; +} + +inline LdacConfig_2_0 to_hidl_ldac_config(const LdacConfiguration ldac_config) { + LdacConfig_2_0 hidl_ldac_config; + hidl_ldac_config.sampleRate = + to_hidl_sample_rate_2_0(ldac_config.sampleRateHz); + hidl_ldac_config.bitsPerSample = + to_hidl_bits_per_sample(ldac_config.bitsPerSample); + if (ldac_channel_mode_to_hidl_map.find(ldac_config.channelMode) != + ldac_channel_mode_to_hidl_map.end()) { + hidl_ldac_config.channelMode = + ldac_channel_mode_to_hidl_map.at(ldac_config.channelMode); + } + if (ldac_qindex_to_hidl_map.find(ldac_config.qualityIndex) != + ldac_qindex_to_hidl_map.end()) { + hidl_ldac_config.qualityIndex = + ldac_qindex_to_hidl_map.at(ldac_config.qualityIndex); + } + return hidl_ldac_config; +} + +inline AptxConfig_2_0 to_hidl_aptx_config(const AptxConfiguration aptx_config) { + AptxConfig_2_0 hidl_aptx_config; + hidl_aptx_config.sampleRate = + to_hidl_sample_rate_2_0(aptx_config.sampleRateHz); + hidl_aptx_config.bitsPerSample = + to_hidl_bits_per_sample(aptx_config.bitsPerSample); + hidl_aptx_config.channelMode = to_hidl_channel_mode(aptx_config.channelMode); + return hidl_aptx_config; +} + +inline CodecConfig_2_0 to_hidl_codec_config_2_0( + const CodecConfiguration& codec_config) { + CodecConfig_2_0 hidl_codec_config; + hidl_codec_config.codecType = to_hidl_codec_type_2_0(codec_config.codecType); + hidl_codec_config.encodedAudioBitrate = + static_cast<uint32_t>(codec_config.encodedAudioBitrate); + hidl_codec_config.peerMtu = static_cast<uint32_t>(codec_config.peerMtu); + hidl_codec_config.isScmstEnabled = codec_config.isScmstEnabled; + switch (codec_config.config.getTag()) { + case CodecConfiguration::CodecSpecific::sbcConfig: + hidl_codec_config.config.sbcConfig(to_hidl_sbc_config( + codec_config.config + .get<CodecConfiguration::CodecSpecific::sbcConfig>())); + break; + case CodecConfiguration::CodecSpecific::aacConfig: + hidl_codec_config.config.aacConfig(to_hidl_aac_config( + codec_config.config + .get<CodecConfiguration::CodecSpecific::aacConfig>())); + break; + case CodecConfiguration::CodecSpecific::ldacConfig: + hidl_codec_config.config.ldacConfig(to_hidl_ldac_config( + codec_config.config + .get<CodecConfiguration::CodecSpecific::ldacConfig>())); + break; + case CodecConfiguration::CodecSpecific::aptxConfig: + hidl_codec_config.config.aptxConfig(to_hidl_aptx_config( + codec_config.config + .get<CodecConfiguration::CodecSpecific::aptxConfig>())); + break; + default: + break; + } + return hidl_codec_config; +} + +inline AudioConfig_2_0 to_hidl_audio_config_2_0( + const AudioConfiguration& audio_config) { + AudioConfig_2_0 hidl_audio_config; + if (audio_config.getTag() == AudioConfiguration::pcmConfig) { + hidl_audio_config.pcmConfig(to_hidl_pcm_config_2_0( + audio_config.get<AudioConfiguration::pcmConfig>())); + } else if (audio_config.getTag() == AudioConfiguration::a2dpConfig) { + hidl_audio_config.codecConfig(to_hidl_codec_config_2_0( + audio_config.get<AudioConfiguration::a2dpConfig>())); + } + return hidl_audio_config; +} + +inline PcmConfig_2_1 to_hidl_pcm_config_2_1( + const PcmConfiguration& pcm_config) { + PcmConfig_2_1 hidl_pcm_config; + hidl_pcm_config.sampleRate = to_hidl_sample_rate_2_1(pcm_config.sampleRateHz); + hidl_pcm_config.channelMode = to_hidl_channel_mode(pcm_config.channelMode); + hidl_pcm_config.bitsPerSample = + to_hidl_bits_per_sample(pcm_config.bitsPerSample); + hidl_pcm_config.dataIntervalUs = + static_cast<uint32_t>(pcm_config.dataIntervalUs); + return hidl_pcm_config; +} + +inline Lc3Config_2_1 to_hidl_lc3_config_2_1( + const Lc3Configuration& lc3_config) { + Lc3Config_2_1 hidl_lc3_config; + hidl_lc3_config.pcmBitDepth = to_hidl_bits_per_sample(lc3_config.pcmBitDepth); + hidl_lc3_config.samplingFrequency = + to_hidl_sample_rate_2_1(lc3_config.samplingFrequencyHz); + if (lc3_config.samplingFrequencyHz == 10000) + hidl_lc3_config.frameDuration = Lc3FrameDuration_2_1::DURATION_10000US; + else if (lc3_config.samplingFrequencyHz == 7500) + hidl_lc3_config.frameDuration = Lc3FrameDuration_2_1::DURATION_7500US; + hidl_lc3_config.octetsPerFrame = + static_cast<uint32_t>(lc3_config.octetsPerFrame); + hidl_lc3_config.blocksPerSdu = static_cast<uint32_t>(lc3_config.blocksPerSdu); + return hidl_lc3_config; +} + +inline Lc3CodecConfig_2_1 to_hidl_leaudio_config_2_1( + const LeAudioConfiguration& leaudio_config) { + auto& unicast_config = + leaudio_config.modeConfig + .get<LeAudioConfiguration::LeAudioModeConfig::unicastConfig>(); + + auto& le_codec_config = unicast_config.leAudioCodecConfig + .get<LeAudioCodecConfiguration::lc3Config>(); + + Lc3CodecConfig_2_1 hidl_lc3_codec_config; + hidl_lc3_codec_config.lc3Config = to_hidl_lc3_config_2_1(le_codec_config); + + hidl_lc3_codec_config.audioChannelAllocation = + unicast_config.streamMap.size(); + + return hidl_lc3_codec_config; +} + +inline LeAudioConfig_2_2 to_hidl_leaudio_config_2_2( + const LeAudioConfiguration& leaudio_config) { + LeAudioConfig_2_2 hidl_leaudio_config; + if (leaudio_mode_to_hidl_map.find(leaudio_config.mode) != + leaudio_mode_to_hidl_map.end()) { + hidl_leaudio_config.mode = leaudio_mode_to_hidl_map.at(leaudio_config.mode); + } + + if (leaudio_config.modeConfig.getTag() == + LeAudioConfiguration::LeAudioModeConfig::unicastConfig) { + auto& unicast_config = + leaudio_config.modeConfig + .get<LeAudioConfiguration::LeAudioModeConfig::unicastConfig>(); + ::android::hardware::bluetooth::audio::V2_2::UnicastConfig + hidl_unicast_config; + hidl_unicast_config.peerDelay = + static_cast<uint32_t>(unicast_config.peerDelay); + + auto& lc3_config = unicast_config.leAudioCodecConfig + .get<LeAudioCodecConfiguration::lc3Config>(); + hidl_unicast_config.lc3Config = to_hidl_lc3_config_2_1(lc3_config); + + hidl_unicast_config.streamMap.resize(unicast_config.streamMap.size()); + for (int i = 0; i < unicast_config.streamMap.size(); i++) { + hidl_unicast_config.streamMap[i].audioChannelAllocation = + static_cast<uint32_t>( + unicast_config.streamMap[i].audioChannelAllocation); + hidl_unicast_config.streamMap[i].streamHandle = + static_cast<uint16_t>(unicast_config.streamMap[i].streamHandle); + } + } else if (leaudio_config.modeConfig.getTag() == + LeAudioConfiguration::LeAudioModeConfig::broadcastConfig) { + auto bcast_config = + leaudio_config.modeConfig + .get<LeAudioConfiguration::LeAudioModeConfig::broadcastConfig>(); + ::android::hardware::bluetooth::audio::V2_2::BroadcastConfig + hidl_bcast_config; + hidl_bcast_config.streamMap.resize(bcast_config.streamMap.size()); + for (int i = 0; i < bcast_config.streamMap.size(); i++) { + hidl_bcast_config.streamMap[i].audioChannelAllocation = + static_cast<uint32_t>( + bcast_config.streamMap[i].audioChannelAllocation); + hidl_bcast_config.streamMap[i].streamHandle = + static_cast<uint16_t>(bcast_config.streamMap[i].streamHandle); + hidl_bcast_config.streamMap[i].lc3Config = to_hidl_lc3_config_2_1( + bcast_config.streamMap[i] + .leAudioCodecConfig.get<LeAudioCodecConfiguration::lc3Config>()); + } + } + return hidl_leaudio_config; +} + +inline AudioConfig_2_1 to_hidl_audio_config_2_1( + const AudioConfiguration& audio_config) { + AudioConfig_2_1 hidl_audio_config; + switch (audio_config.getTag()) { + case AudioConfiguration::pcmConfig: + hidl_audio_config.pcmConfig(to_hidl_pcm_config_2_1( + audio_config.get<AudioConfiguration::pcmConfig>())); + break; + case AudioConfiguration::a2dpConfig: + hidl_audio_config.codecConfig(to_hidl_codec_config_2_0( + audio_config.get<AudioConfiguration::a2dpConfig>())); + break; + case AudioConfiguration::leAudioConfig: + hidl_audio_config.leAudioCodecConfig(to_hidl_leaudio_config_2_1( + audio_config.get<AudioConfiguration::leAudioConfig>())); + break; + } + return hidl_audio_config; +} + +inline AudioConfig_2_2 to_hidl_audio_config_2_2( + const AudioConfiguration& audio_config) { + AudioConfig_2_2 hidl_audio_config; + switch (audio_config.getTag()) { + case AudioConfiguration::pcmConfig: + hidl_audio_config.pcmConfig(to_hidl_pcm_config_2_1( + audio_config.get<AudioConfiguration::pcmConfig>())); + break; + case AudioConfiguration::a2dpConfig: + hidl_audio_config.codecConfig(to_hidl_codec_config_2_0( + audio_config.get<AudioConfiguration::a2dpConfig>())); + break; + case AudioConfiguration::leAudioConfig: + hidl_audio_config.leAudioConfig(to_hidl_leaudio_config_2_2( + audio_config.get<AudioConfiguration::leAudioConfig>())); + break; + } + return hidl_audio_config; +} + +/*** + * + * 2.0 + * + ***/ + +bool HidlToAidlMiddleware_2_0::IsSessionReady( + const SessionType_2_0& session_type) { + return BluetoothAudioSessionControl::IsSessionReady( + from_session_type_2_0(session_type)); +} + +uint16_t HidlToAidlMiddleware_2_0::RegisterControlResultCback( + const SessionType_2_0& session_type, + const PortStatusCallbacks_2_0& cbacks) { + PortStatusCallbacks_2_2 callback_2_2{ + .control_result_cb_ = cbacks.control_result_cb_, + .session_changed_cb_ = cbacks.session_changed_cb_, + }; + return HidlToAidlMiddleware_2_2::RegisterControlResultCback( + static_cast<SessionType_2_1>(session_type), callback_2_2); +} + +void HidlToAidlMiddleware_2_0::UnregisterControlResultCback( + const SessionType_2_0& session_type, uint16_t cookie) { + HidlToAidlMiddleware_2_2::UnregisterControlResultCback( + static_cast<SessionType_2_1>(session_type), cookie); +} + +const AudioConfig_2_0 HidlToAidlMiddleware_2_0::GetAudioConfig( + const SessionType_2_0& session_type) { + return to_hidl_audio_config_2_0(BluetoothAudioSessionControl::GetAudioConfig( + from_session_type_2_0(session_type))); +} + +bool HidlToAidlMiddleware_2_0::StartStream( + const SessionType_2_0& session_type) { + return BluetoothAudioSessionControl::StartStream( + from_session_type_2_0(session_type)); +} + +void HidlToAidlMiddleware_2_0::StopStream(const SessionType_2_0& session_type) { + return BluetoothAudioSessionControl::StopStream( + from_session_type_2_0(session_type)); +} + +bool HidlToAidlMiddleware_2_0::SuspendStream( + const SessionType_2_0& session_type) { + return BluetoothAudioSessionControl::SuspendStream( + from_session_type_2_0(session_type)); +} + +bool HidlToAidlMiddleware_2_0::GetPresentationPosition( + const SessionType_2_0& session_type, uint64_t* remote_delay_report_ns, + uint64_t* total_bytes_readed, timespec* data_position) { + PresentationPosition presentation_position; + auto ret_val = BluetoothAudioSessionControl::GetPresentationPosition( + from_session_type_2_0(session_type), presentation_position); + if (remote_delay_report_ns) + *remote_delay_report_ns = presentation_position.remoteDeviceAudioDelayNanos; + if (total_bytes_readed) + *total_bytes_readed = presentation_position.transmittedOctets; + if (data_position) + *data_position = { + .tv_sec = static_cast<__kernel_old_time_t>( + presentation_position.transmittedOctetsTimestamp.tvSec), + .tv_nsec = static_cast<long>( + presentation_position.transmittedOctetsTimestamp.tvNSec)}; + return ret_val; +} + +void HidlToAidlMiddleware_2_0::UpdateTracksMetadata( + const SessionType_2_0& session_type, + const struct source_metadata* source_metadata) { + return BluetoothAudioSessionControl::UpdateSourceMetadata( + from_session_type_2_0(session_type), *source_metadata); +} + +size_t HidlToAidlMiddleware_2_0::OutWritePcmData( + const SessionType_2_0& session_type, const void* buffer, size_t bytes) { + return BluetoothAudioSessionControl::OutWritePcmData( + from_session_type_2_0(session_type), buffer, bytes); +} + +bool HidlToAidlMiddleware_2_0::IsAidlAvailable() { + return BluetoothAudioSession::IsAidlAvailable(); +} + +/*** + * + * 2.1 + * + ***/ + +const AudioConfig_2_1 HidlToAidlMiddleware_2_1::GetAudioConfig( + const SessionType_2_1& session_type) { + return to_hidl_audio_config_2_1(BluetoothAudioSessionControl::GetAudioConfig( + from_session_type_2_1(session_type))); +} + +/*** + * + * 2.2 + * + ***/ + +bool HidlToAidlMiddleware_2_2::IsSessionReady( + const SessionType_2_1& session_type) { + return BluetoothAudioSessionControl::IsSessionReady( + from_session_type_2_1(session_type)); +} + +uint16_t HidlToAidlMiddleware_2_2::RegisterControlResultCback( + const SessionType_2_1& session_type, + const PortStatusCallbacks_2_2& cbacks) { + LOG(INFO) << __func__ << ": " << toString(session_type); + auto aidl_session_type = from_session_type_2_1(session_type); + // Pass the exact reference to the lambda + auto& session_legacy_callback_table = + legacy_callback_table[aidl_session_type]; + PortStatusCallbacks aidl_callbacks{}; + if (cbacks.control_result_cb_) { + aidl_callbacks.control_result_cb_ = + [&session_legacy_callback_table](uint16_t cookie, bool start_resp, + const BluetoothAudioStatus& status) { + if (session_legacy_callback_table.find(cookie) == + session_legacy_callback_table.end()) { + LOG(ERROR) << __func__ << ": Unknown callback invoked!"; + return; + } + auto& cback = session_legacy_callback_table[cookie]; + cback->control_result_cb_(cookie, start_resp, to_hidl_status(status)); + }; + } + if (cbacks.session_changed_cb_) { + aidl_callbacks.session_changed_cb_ = + [&session_legacy_callback_table](uint16_t cookie) { + if (session_legacy_callback_table.find(cookie) == + session_legacy_callback_table.end()) { + LOG(ERROR) << __func__ << ": Unknown callback invoked!"; + return; + } + auto& cback = session_legacy_callback_table[cookie]; + cback->session_changed_cb_(cookie); + }; + }; + if (cbacks.audio_configuration_changed_cb_) { + aidl_callbacks.audio_configuration_changed_cb_ = + [&session_legacy_callback_table](uint16_t cookie) { + if (session_legacy_callback_table.find(cookie) == + session_legacy_callback_table.end()) { + LOG(ERROR) << __func__ << ": Unknown callback invoked!"; + return; + } + auto& cback = session_legacy_callback_table[cookie]; + cback->audio_configuration_changed_cb_(cookie); + }; + }; + auto cookie = BluetoothAudioSessionControl::RegisterControlResultCback( + aidl_session_type, aidl_callbacks); + { + std::lock_guard<std::mutex> guard(legacy_callback_lock); + session_legacy_callback_table[cookie] = + std::make_shared<PortStatusCallbacks_2_2>(cbacks); + } + return cookie; +} + +void HidlToAidlMiddleware_2_2::UnregisterControlResultCback( + const SessionType_2_1& session_type, uint16_t cookie) { + LOG(INFO) << __func__ << ": " << toString(session_type); + auto aidl_session_type = from_session_type_2_1(session_type); + BluetoothAudioSessionControl::UnregisterControlResultCback(aidl_session_type, + cookie); + auto& session_callback_table = legacy_callback_table[aidl_session_type]; + if (session_callback_table.find(cookie) != session_callback_table.end()) { + std::lock_guard<std::mutex> guard(legacy_callback_lock); + session_callback_table.erase(cookie); + } +} + +const AudioConfig_2_2 HidlToAidlMiddleware_2_2::GetAudioConfig( + const SessionType_2_1& session_type) { + return to_hidl_audio_config_2_2(BluetoothAudioSessionControl::GetAudioConfig( + from_session_type_2_1(session_type))); +} + +bool HidlToAidlMiddleware_2_2::StartStream( + const SessionType_2_1& session_type) { + return BluetoothAudioSessionControl::StartStream( + from_session_type_2_1(session_type)); +} + +bool HidlToAidlMiddleware_2_2::SuspendStream( + const SessionType_2_1& session_type) { + return BluetoothAudioSessionControl::SuspendStream( + from_session_type_2_1(session_type)); +} + +void HidlToAidlMiddleware_2_2::StopStream(const SessionType_2_1& session_type) { + return BluetoothAudioSessionControl::StopStream( + from_session_type_2_1(session_type)); +} + +void HidlToAidlMiddleware_2_2::UpdateSinkMetadata( + const SessionType_2_1& session_type, + const struct sink_metadata* sink_metadata) { + return BluetoothAudioSessionControl::UpdateSinkMetadata( + from_session_type_2_1(session_type), *sink_metadata); +} + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_0.h b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_0.h new file mode 100644 index 0000000000..d10ee3759a --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_0.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <android/hardware/bluetooth/audio/2.0/types.h> + +#include "../session/BluetoothAudioSession.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +using SessionType_2_0 = + ::android::hardware::bluetooth::audio::V2_0::SessionType; +using PortStatusCallbacks_2_0 = + ::android::bluetooth::audio::PortStatusCallbacks; +using AudioConfig_2_0 = + ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration; + +class HidlToAidlMiddleware_2_0 { + public: + static bool IsAidlAvailable(); + + static bool IsSessionReady(const SessionType_2_0& session_type); + + static uint16_t RegisterControlResultCback( + const SessionType_2_0& session_type, + const PortStatusCallbacks_2_0& cbacks); + + static void UnregisterControlResultCback(const SessionType_2_0& session_type, + uint16_t cookie); + + static const AudioConfig_2_0 GetAudioConfig( + const SessionType_2_0& session_type); + + static bool StartStream(const SessionType_2_0& session_type); + + static void StopStream(const SessionType_2_0& session_type); + + static bool SuspendStream(const SessionType_2_0& session_type); + + static bool GetPresentationPosition(const SessionType_2_0& session_type, + uint64_t* remote_delay_report_ns, + uint64_t* total_bytes_readed, + timespec* data_position); + + static void UpdateTracksMetadata( + const SessionType_2_0& session_type, + const struct source_metadata* source_metadata); + + static size_t OutWritePcmData(const SessionType_2_0& session_type, + const void* buffer, size_t bytes); +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_1.h b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_1.h new file mode 100644 index 0000000000..82dce96d3e --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_1.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <android/hardware/bluetooth/audio/2.1/types.h> + +#include "../session/BluetoothAudioSession.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +using SessionType_2_1 = + ::android::hardware::bluetooth::audio::V2_1::SessionType; +using AudioConfig_2_1 = + ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration; + +class HidlToAidlMiddleware_2_1 { + public: + static const AudioConfig_2_1 GetAudioConfig( + const SessionType_2_1& session_type); +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_2.h b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_2.h new file mode 100644 index 0000000000..149e4042d1 --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_2.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <android/hardware/bluetooth/audio/2.2/types.h> + +#include "../session/BluetoothAudioSession.h" +#include "../session/BluetoothAudioSession_2_2.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +using SessionType_2_1 = + ::android::hardware::bluetooth::audio::V2_1::SessionType; +using PortStatusCallbacks_2_0 = + ::android::bluetooth::audio::PortStatusCallbacks; +using PortStatusCallbacks_2_2 = + ::android::bluetooth::audio::PortStatusCallbacks_2_2; +using AudioConfig_2_2 = + ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration; + +class HidlToAidlMiddleware_2_2 { + public: + static bool IsSessionReady(const SessionType_2_1& session_type); + + static uint16_t RegisterControlResultCback( + const SessionType_2_1& session_type, + const PortStatusCallbacks_2_2& cbacks); + + static void UnregisterControlResultCback(const SessionType_2_1& session_type, + uint16_t cookie); + + static const AudioConfig_2_2 GetAudioConfig( + const SessionType_2_1& session_type); + + static bool StartStream(const SessionType_2_1& session_type); + + static bool SuspendStream(const SessionType_2_1& session_type); + + static void StopStream(const SessionType_2_1& session_type); + + static void UpdateSinkMetadata(const SessionType_2_1& session_type, + const struct sink_metadata* sink_metadata); +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession.cpp index 2f3ddaf213..6d5608b0a4 100644 --- a/bluetooth/audio/utils/session/BluetoothAudioSession.cpp +++ b/bluetooth/audio/utils/session/BluetoothAudioSession.cpp @@ -21,10 +21,13 @@ #include <android-base/logging.h> #include <android-base/stringprintf.h> +#include "../aidl_session/HidlToAidlMiddleware_2_0.h" + namespace android { namespace bluetooth { namespace audio { +using ::aidl::android::hardware::bluetooth::audio::HidlToAidlMiddleware_2_0; using ::android::hardware::audio::common::V5_0::AudioContentType; using ::android::hardware::audio::common::V5_0::AudioUsage; using ::android::hardware::audio::common::V5_0::PlaybackTrackMetadata; @@ -149,6 +152,8 @@ void BluetoothAudioSession::ReportControlStatus( // The function helps to check if this session is ready or not // @return: true if the Bluetooth stack has started the specified session bool BluetoothAudioSession::IsSessionReady() { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_0::IsSessionReady(session_type_); std::lock_guard<std::recursive_mutex> guard(mutex_); bool dataMQ_valid = (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH || @@ -200,6 +205,9 @@ bool BluetoothAudioSession::UpdateAudioConfig( // @return: cookie - the assigned number to this bluetooth_audio output uint16_t BluetoothAudioSession::RegisterStatusCback( const PortStatusCallbacks& cbacks) { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_0::RegisterControlResultCback(session_type_, + cbacks); std::lock_guard<std::recursive_mutex> guard(mutex_); uint16_t cookie = ObserversCookieGetInitValue(session_type_); uint16_t cookie_upper_bound = ObserversCookieGetUpperBound(session_type_); @@ -227,6 +235,9 @@ uint16_t BluetoothAudioSession::RegisterStatusCback( // PortStatusCallbacks // @param: cookie - indicates which bluetooth_audio output is void BluetoothAudioSession::UnregisterStatusCback(uint16_t cookie) { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_0::UnregisterControlResultCback(session_type_, + cookie); std::lock_guard<std::recursive_mutex> guard(mutex_); if (observers_.erase(cookie) != 1) { LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) @@ -238,6 +249,9 @@ void BluetoothAudioSession::UnregisterStatusCback(uint16_t cookie) { // The control function is for the bluetooth_audio module to get the current // AudioConfiguration const AudioConfiguration& BluetoothAudioSession::GetAudioConfig() { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return (audio_config_ = + HidlToAidlMiddleware_2_0::GetAudioConfig(session_type_)); std::lock_guard<std::recursive_mutex> guard(mutex_); if (IsSessionReady()) { return audio_config_; @@ -251,6 +265,8 @@ const AudioConfiguration& BluetoothAudioSession::GetAudioConfig() { // Those control functions are for the bluetooth_audio module to start, suspend, // stop stream, to check position, and to update metadata. bool BluetoothAudioSession::StartStream() { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_0::StartStream(session_type_); std::lock_guard<std::recursive_mutex> guard(mutex_); if (!IsSessionReady()) { LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) @@ -267,6 +283,8 @@ bool BluetoothAudioSession::StartStream() { } bool BluetoothAudioSession::SuspendStream() { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_0::SuspendStream(session_type_); std::lock_guard<std::recursive_mutex> guard(mutex_); if (!IsSessionReady()) { LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) @@ -283,6 +301,8 @@ bool BluetoothAudioSession::SuspendStream() { } void BluetoothAudioSession::StopStream() { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_0::StopStream(session_type_); std::lock_guard<std::recursive_mutex> guard(mutex_); if (!IsSessionReady()) { return; @@ -297,6 +317,10 @@ void BluetoothAudioSession::StopStream() { bool BluetoothAudioSession::GetPresentationPosition( uint64_t* remote_delay_report_ns, uint64_t* total_bytes_readed, timespec* data_position) { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_0::GetPresentationPosition( + session_type_, remote_delay_report_ns, total_bytes_readed, + data_position); std::lock_guard<std::recursive_mutex> guard(mutex_); if (!IsSessionReady()) { LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) @@ -330,6 +354,9 @@ bool BluetoothAudioSession::GetPresentationPosition( void BluetoothAudioSession::UpdateTracksMetadata( const struct source_metadata* source_metadata) { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_0::UpdateTracksMetadata(session_type_, + source_metadata); std::lock_guard<std::recursive_mutex> guard(mutex_); if (!IsSessionReady()) { LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) @@ -374,6 +401,9 @@ void BluetoothAudioSession::UpdateTracksMetadata( // The control function writes stream to FMQ size_t BluetoothAudioSession::OutWritePcmData(const void* buffer, size_t bytes) { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_0::OutWritePcmData(session_type_, buffer, + bytes); if (buffer == nullptr || !bytes) return 0; size_t totalWritten = 0; int ms_timeout = kFmqSendTimeoutMs; diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp index bf1f9b5b2a..276a291470 100644 --- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp +++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp @@ -21,9 +21,14 @@ #include <android-base/logging.h> #include <android-base/stringprintf.h> +#include "../aidl_session/HidlToAidlMiddleware_2_0.h" +#include "../aidl_session/HidlToAidlMiddleware_2_1.h" + namespace android { namespace bluetooth { namespace audio { +using ::aidl::android::hardware::bluetooth::audio::HidlToAidlMiddleware_2_0; +using ::aidl::android::hardware::bluetooth::audio::HidlToAidlMiddleware_2_1; using SessionType_2_1 = ::android::hardware::bluetooth::audio::V2_1::SessionType; using SessionType_2_0 = @@ -72,6 +77,7 @@ BluetoothAudioSession_2_1::BluetoothAudioSession_2_1( } else { session_type_2_1_ = (session_type); } + raw_session_type_ = session_type; } std::shared_ptr<BluetoothAudioSession> @@ -83,6 +89,8 @@ BluetoothAudioSession_2_1::GetAudioSession() { // AudioConfiguration const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration BluetoothAudioSession_2_1::GetAudioConfig() { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_1::GetAudioConfig(raw_session_type_); std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_); if (audio_session->IsSessionReady()) { // If session is unknown it means it should be 2.0 type diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h index 5a351531a3..e6340649d8 100644 --- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h +++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h @@ -31,6 +31,7 @@ class BluetoothAudioSession_2_1 { std::shared_ptr<BluetoothAudioSession> audio_session; ::android::hardware::bluetooth::audio::V2_1::SessionType session_type_2_1_; + ::android::hardware::bluetooth::audio::V2_1::SessionType raw_session_type_; // audio data configuration for both software and offloading ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp index 60ac4ece6f..4613ddc05a 100644 --- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp +++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp @@ -22,10 +22,15 @@ #include <android-base/stringprintf.h> #include <android/hardware/bluetooth/audio/2.2/IBluetoothAudioPort.h> +#include "../aidl_session/HidlToAidlMiddleware_2_0.h" +#include "../aidl_session/HidlToAidlMiddleware_2_2.h" + namespace android { namespace bluetooth { namespace audio { +using ::aidl::android::hardware::bluetooth::audio::HidlToAidlMiddleware_2_0; +using ::aidl::android::hardware::bluetooth::audio::HidlToAidlMiddleware_2_2; using ::android::hardware::audio::common::V5_0::AudioSource; using ::android::hardware::audio::common::V5_0::RecordTrackMetadata; using ::android::hardware::audio::common::V5_0::SinkMetadata; @@ -93,6 +98,7 @@ BluetoothAudioSession_2_2::BluetoothAudioSession_2_2( } else { session_type_2_1_ = (session_type); } + raw_session_type_ = session_type; invalidSoftwareAudioConfiguration.pcmConfig(kInvalidPcmParameters); invalidOffloadAudioConfiguration.codecConfig( audio_session->kInvalidCodecConfiguration); @@ -100,6 +106,8 @@ BluetoothAudioSession_2_2::BluetoothAudioSession_2_2( } bool BluetoothAudioSession_2_2::IsSessionReady() { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_2::IsSessionReady(raw_session_type_); if (session_type_2_1_ != SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH && session_type_2_1_ != @@ -122,6 +130,9 @@ BluetoothAudioSession_2_2::GetAudioSession_2_1() { void BluetoothAudioSession_2_2::UpdateSinkMetadata( const struct sink_metadata* sink_metadata) { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_2::UpdateSinkMetadata(raw_session_type_, + sink_metadata); std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_); if (!IsSessionReady()) { LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_2_1_) @@ -172,6 +183,8 @@ void BluetoothAudioSession_2_2::UpdateSinkMetadata( // AudioConfiguration const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration BluetoothAudioSession_2_2::GetAudioConfig() { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_2::GetAudioConfig(raw_session_type_); std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_); if (IsSessionReady()) { auto audio_config_discriminator = audio_config_2_2_.getDiscriminator(); @@ -226,6 +239,8 @@ BluetoothAudioSession_2_2::GetAudioConfig() { // Those control functions are for the bluetooth_audio module to start, suspend, // stop stream, to check position, and to update metadata. bool BluetoothAudioSession_2_2::StartStream() { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_2::StartStream(raw_session_type_); std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_); if (!IsSessionReady()) { LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_2_1_) @@ -242,6 +257,8 @@ bool BluetoothAudioSession_2_2::StartStream() { } bool BluetoothAudioSession_2_2::SuspendStream() { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_2::SuspendStream(raw_session_type_); std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_); if (!IsSessionReady()) { LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_2_1_) @@ -258,6 +275,8 @@ bool BluetoothAudioSession_2_2::SuspendStream() { } void BluetoothAudioSession_2_2::StopStream() { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_2::StopStream(raw_session_type_); std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_); if (!IsSessionReady()) { return; @@ -395,6 +414,9 @@ void BluetoothAudioSession_2_2::OnSessionEnded() { // @return: cookie - the assigned number to this bluetooth_audio output uint16_t BluetoothAudioSession_2_2::RegisterStatusCback( const PortStatusCallbacks_2_2& cbacks) { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_2::RegisterControlResultCback( + raw_session_type_, cbacks); if (session_type_2_1_ != SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH && session_type_2_1_ != @@ -432,6 +454,9 @@ uint16_t BluetoothAudioSession_2_2::RegisterStatusCback( // PortStatusCallbacks_2_2 // @param: cookie - indicates which bluetooth_audio output is void BluetoothAudioSession_2_2::UnregisterStatusCback(uint16_t cookie) { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_2::UnregisterControlResultCback( + raw_session_type_, cookie); std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_); if (session_type_2_1_ != SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH && diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h index 3673fd8ccf..b6f96ab25c 100644 --- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h +++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h @@ -68,6 +68,7 @@ class BluetoothAudioSession_2_2 { std::shared_ptr<BluetoothAudioSession_2_1> audio_session_2_1; ::android::hardware::bluetooth::audio::V2_1::SessionType session_type_2_1_; + ::android::hardware::bluetooth::audio::V2_1::SessionType raw_session_type_; // audio data configuration for both software and offloading ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration diff --git a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp index 34cfd7efb7..4c99b0f620 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::Lc3FrameDuration; 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 @@ bool IsOffloadLeAudioConfigurationValid( 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 89da6a383f..34bba5f671 100644 --- a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h +++ b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h @@ -31,7 +31,7 @@ bool IsOffloadLeAudioConfigurationValid( 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/camera/common/1.0/default/HandleImporter.cpp b/camera/common/1.0/default/HandleImporter.cpp index 7fcf52330c..fbe8686766 100644 --- a/camera/common/1.0/default/HandleImporter.cpp +++ b/camera/common/1.0/default/HandleImporter.cpp @@ -30,6 +30,7 @@ namespace helper { using aidl::android::hardware::graphics::common::PlaneLayout; using aidl::android::hardware::graphics::common::PlaneLayoutComponent; using aidl::android::hardware::graphics::common::PlaneLayoutComponentType; +using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType; using MapperErrorV2 = android::hardware::graphics::mapper::V2_0::Error; using MapperErrorV3 = android::hardware::graphics::mapper::V3_0::Error; using MapperErrorV4 = android::hardware::graphics::mapper::V4_0::Error; @@ -123,6 +124,21 @@ YCbCrLayout HandleImporter::lockYCbCrInternal(const sp<M> mapper, buffer_handle_ return layout; } +bool isMetadataPesent(const sp<IMapperV4> mapper, const buffer_handle_t& buf, + MetadataType metadataType) { + auto buffer = const_cast<native_handle_t*>(buf); + mapper->get(buffer, metadataType, [] (const auto& tmpError, + const auto& tmpMetadata) { + if (tmpError == MapperErrorV4::NONE) { + return tmpMetadata.size() > 0; + } else { + ALOGE("%s: failed to get metadata %d!", __FUNCTION__, tmpError); + return false; + }}); + + return false; +} + std::vector<PlaneLayout> getPlaneLayouts(const sp<IMapperV4> mapper, buffer_handle_t& buf) { auto buffer = const_cast<native_handle_t*>(buf); std::vector<PlaneLayout> planeLayouts; @@ -449,6 +465,55 @@ int HandleImporter::unlock(buffer_handle_t& buf) { return -1; } +bool HandleImporter::isSmpte2086Present(const buffer_handle_t& buf) { + Mutex::Autolock lock(mLock); + + if (!mInitialized) { + initializeLocked(); + } + + if (mMapperV4 != nullptr) { + return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2086); + } else { + ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__); + } + + return false; +} + +bool HandleImporter::isSmpte2094_10Present(const buffer_handle_t& buf) { + Mutex::Autolock lock(mLock); + + if (!mInitialized) { + initializeLocked(); + } + + if (mMapperV4 != nullptr) { + return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2094_10); + } else { + ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__); + } + + return false; +} + +bool HandleImporter::isSmpte2094_40Present(const buffer_handle_t& buf) { + Mutex::Autolock lock(mLock); + + if (!mInitialized) { + initializeLocked(); + } + + if (mMapperV4 != nullptr) { + return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2094_40); + } else { + ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__); + } + + return false; +} + + } // namespace helper } // namespace V1_0 } // namespace common diff --git a/camera/common/1.0/default/include/HandleImporter.h b/camera/common/1.0/default/include/HandleImporter.h index e404439cb6..83fa755c99 100644 --- a/camera/common/1.0/default/include/HandleImporter.h +++ b/camera/common/1.0/default/include/HandleImporter.h @@ -61,6 +61,11 @@ public: int unlock(buffer_handle_t& buf); // returns release fence + // Query Gralloc4 metadata + bool isSmpte2086Present(const buffer_handle_t& buf); + bool isSmpte2094_10Present(const buffer_handle_t& buf); + bool isSmpte2094_40Present(const buffer_handle_t& buf); + private: void initializeLocked(); void cleanup(); diff --git a/camera/device/3.8/Android.bp b/camera/device/3.8/Android.bp index 2a1f215023..c3c29416a9 100644 --- a/camera/device/3.8/Android.bp +++ b/camera/device/3.8/Android.bp @@ -9,7 +9,6 @@ package { default_applicable_licenses: ["hardware_interfaces_license"], } - hidl_interface { name: "android.hardware.camera.device@3.8", root: "android.hardware", @@ -17,6 +16,7 @@ hidl_interface { "types.hal", "ICameraDevice.hal", "ICameraDeviceCallback.hal", + "ICameraDeviceSession.hal", ], interfaces: [ "android.hardware.camera.common@1.0", @@ -31,6 +31,7 @@ hidl_interface { "android.hardware.camera.metadata@3.4", "android.hardware.camera.metadata@3.5", "android.hardware.camera.metadata@3.6", + "android.hardware.camera.metadata@3.8", "android.hardware.graphics.common@1.0", "android.hidl.base@1.0", ], diff --git a/camera/device/3.8/ICameraDevice.hal b/camera/device/3.8/ICameraDevice.hal index 1101819a4d..8832c68098 100644 --- a/camera/device/3.8/ICameraDevice.hal +++ b/camera/device/3.8/ICameraDevice.hal @@ -26,8 +26,8 @@ import @3.7::ICameraDevice; * API at LIMITED or better hardware level. * * ICameraDevice.open() must return @3.2::ICameraDeviceSession, - * @3.5::ICameraDeviceSession, @3.6::ICameraDeviceSession, or - * @3.7::ICameraDeviceSession. + * @3.5::ICameraDeviceSession, @3.6::ICameraDeviceSession, + * @3.7::ICameraDeviceSession, or @3.8::ICameraDeviceSession. */ interface ICameraDevice extends @3.7::ICameraDevice { /** @@ -107,4 +107,15 @@ interface ICameraDevice extends @3.7::ICameraDevice { * */ getTorchStrengthLevel() generates (Status status, int32_t torchStrength); + + /** + * isStreamCombinationSupported_3_8: + * + * Identical to @3.7::ICameraDevice.isStreamCombinationSupported, except + * that it takes a @3.8::StreamConfiguration parameter, which could contain + * additional information about a specific 10-bit dynamic range profile. + * + */ + isStreamCombinationSupported_3_8(StreamConfiguration streams) + generates (Status status, bool queryStatus); }; diff --git a/camera/device/3.8/ICameraDeviceSession.hal b/camera/device/3.8/ICameraDeviceSession.hal new file mode 100644 index 0000000000..88e4338209 --- /dev/null +++ b/camera/device/3.8/ICameraDeviceSession.hal @@ -0,0 +1,95 @@ +/* + * 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.camera.device@3.8; + +import android.hardware.camera.common@1.0::Status; +import @3.5::StreamConfiguration; +import @3.7::ICameraDeviceSession; +import @3.6::HalStreamConfiguration; + +/** + * Camera device active session interface. + * + * Obtained via ICameraDevice::open(), this interface contains the methods to + * configure and request captures from an active camera device. + */ +interface ICameraDeviceSession extends @3.7::ICameraDeviceSession { + /** + * configureStreams_3_8: + * + * Identical to @3.7::ICameraDeviceSession.configureStreams_3_7, except that: + * + * - The requestedConfiguration allows the camera framework to configure + * 10-bit dynamic range profile. + * + * @return status Status code for the operation, one of: + * OK: + * On successful stream configuration. + * INTERNAL_ERROR: + * If there has been a fatal error and the device is no longer + * operational. Only close() can be called successfully by the + * framework after this error is returned. + * ILLEGAL_ARGUMENT: + * If the requested stream configuration is invalid. Some examples + * of invalid stream configurations include: + * - Including more than 1 INPUT stream + * - Not including any OUTPUT streams + * - Including streams with unsupported formats, or an unsupported + * size for that format. + * - Including too many output streams of a certain format. + * - Unsupported rotation configuration + * - Stream sizes/formats don't satisfy the + * StreamConfigurationMode requirements + * for non-NORMAL mode, or the requested operation_mode is not + * supported by the HAL. + * - Unsupported usage flag + * - Unsupported stream groupIds, or unsupported multi-resolution + * input stream. + * - Invalid combination between a 10-bit dynamic range profile + * and none impl. defined 8-bit format for a particular stream. + * The camera service cannot filter out all possible illegal stream + * configurations, since some devices may support more simultaneous + * streams or larger stream resolutions than the minimum required + * for a given camera device hardware level. The HAL must return an + * ILLEGAL_ARGUMENT for any unsupported stream set, and then be + * ready to accept a future valid stream configuration in a later + * configureStreams call. + * @return halConfiguration The stream parameters desired by the HAL for + * each stream, including maximum buffers, the usage flags, and the + * override format and dataspace. + */ + configureStreams_3_8(StreamConfiguration requestedConfiguration) + generates (Status status, @3.6::HalStreamConfiguration halConfiguration); + + /** + * repeatingRequestEnd: + * + * Notification about the last frame number in a repeating request along with the + * ids of all streams included in the repeating request. + * + * This can be called at any point after 'processCaptureRequest' in response + * to camera clients disabling an active repeating request. + * + * Performance requirements: + * The call must not be blocked for extensive periods and should be extremely lightweight. There + * must be no frame rate degradation or frame jitter introduced. + * + * This method must always succeed, even if the device has encountered a + * serious error. + */ + repeatingRequestEnd(uint32_t frameNumber, vec<int32_t> streamIds); +}; diff --git a/camera/device/3.8/types.hal b/camera/device/3.8/types.hal index 843d050bb2..9d1ac22f5a 100644 --- a/camera/device/3.8/types.hal +++ b/camera/device/3.8/types.hal @@ -19,6 +19,11 @@ package android.hardware.camera.device@3.8; import @3.2::ErrorMsg; import @3.2::MsgType; import @3.2::ShutterMsg; +import @3.2::CameraMetadata; +import @3.2::StreamConfigurationMode; +import @3.7::Stream; + +import android.hardware.camera.metadata@3.8::CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap; /** * ShutterMsg: @@ -67,3 +72,75 @@ struct NotifyMsg { ShutterMsg shutter; } msg; }; + +/** + * Stream: + * + * A descriptor for a single camera input or output stream. A stream is defined + * by the framework by its buffer resolution and format, and additionally by the + * HAL with the gralloc usage flags and the maximum in-flight buffer count. + * + * This version extends the @3.7 Stream with the dynamic range profile field. + */ +struct Stream { + /** + * The definition of Stream from the prior version. + */ + @3.7::Stream v3_7; + + /** + * The dynamic range profile for this stream. + * + * This field is valid and must only be considered for streams with format + * android.hardware.graphics.common.PixelFormat.YCBCR_P010 or + * android.hardware.graphics.common.PixelFormat.IMPLEMENTATION_DEFINED on devices supporting the + * ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_10_BIT capability. + * + */ + CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap dynamicRangeProfile; +}; + +/** + * StreamConfiguration: + * + * Identical to @3.7::StreamConfiguration, except that the streams + * vector contains @3.8::Stream. + */ +struct StreamConfiguration { + /** + * An array of camera stream pointers, defining the input/output + * configuration for the camera HAL device. + */ + vec<Stream> streams; + + /** + * The definition of operation mode from prior version. + * + */ + @3.2::StreamConfigurationMode operationMode; + + /** + * The definition of session parameters from prior version. + */ + @3.2::CameraMetadata sessionParams; + + /** + * The definition of stream configuration counter from prior version. + */ + uint32_t streamConfigCounter; + + /** + * If an input stream is configured, whether the input stream is expected to + * receive variable resolution images. + * + * This flag can only be set to true if the camera device supports + * multi-resolution input streams by advertising input stream configurations in + * physicalCameraMultiResolutionStreamConfigurations in its physical cameras' + * characteristics. + * + * When this flag is set to true, the input stream's width and height can be + * any one of the supported multi-resolution input stream sizes. + */ + bool multiResolutionInputImage; +}; + diff --git a/camera/metadata/3.8/types.hal b/camera/metadata/3.8/types.hal index 11360da72b..4c70eb9528 100644 --- a/camera/metadata/3.8/types.hal +++ b/camera/metadata/3.8/types.hal @@ -53,6 +53,21 @@ enum CameraMetadataTag : @3.7::CameraMetadataTag { ANDROID_FLASH_INFO_END_3_8, + /** android.request.availableDynamicRangeProfilesMap [static, enum[], ndk_public] + * + * <p>A map of all available 10-bit dynamic range profiles along with their + * capture request constraints.</p> + */ + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP = android.hardware.camera.metadata@3.4::CameraMetadataTag:ANDROID_REQUEST_END_3_4, + + /** android.request.recommendedTenBitDynamicRangeProfile [static, int32, java_public] + * + * <p>Recommended 10-bit dynamic range profile.</p> + */ + ANDROID_REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE, + + ANDROID_REQUEST_END_3_8, + }; /* @@ -66,3 +81,51 @@ enum CameraMetadataEnumAndroidControlVideoStabilizationMode : @3.2::CameraMetadataEnumAndroidControlVideoStabilizationMode { ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION, }; + +/** android.request.availableCapabilities enumeration values added since v3.6 + * @see ANDROID_REQUEST_AVAILABLE_CAPABILITIES + */ +enum CameraMetadataEnumAndroidRequestAvailableCapabilities : + @3.6::CameraMetadataEnumAndroidRequestAvailableCapabilities { + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT, +}; + +/** android.request.availableDynamicRangeProfilesMap enumeration values + * @see ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP + */ +enum CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap : uint32_t { + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD + = 0x1, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10 = 0x2, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10 = 0x4, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS + = 0x8, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF + = 0x10, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO + = 0x20, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM + = 0x40, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO + = 0x80, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF + = 0x100, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO + = 0x200, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM + = 0x400, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO + = 0x800, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_MAX = 0x1000, +}; + +/** android.scaler.availableRecommendedStreamConfigurations enumeration values added since v3.4 + * @see ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS + */ +enum CameraMetadataEnumAndroidScalerAvailableRecommendedStreamConfigurations : + @3.4::CameraMetadataEnumAndroidScalerAvailableRecommendedStreamConfigurations { + ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_10BIT_OUTPUT + = 0x8, + ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END_3_8 + = 0x9, +}; diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp index 2c141ee1d6..0e622655df 100644 --- a/camera/provider/2.4/vts/functional/Android.bp +++ b/camera/provider/2.4/vts/functional/Android.bp @@ -51,11 +51,15 @@ cc_test { "android.hardware.camera.device@3.7", "android.hardware.camera.device@3.8", "android.hardware.camera.metadata@3.4", + "android.hardware.camera.metadata@3.8", "android.hardware.camera.provider@2.4", "android.hardware.camera.provider@2.5", "android.hardware.camera.provider@2.6", "android.hardware.camera.provider@2.7", "android.hardware.graphics.common@1.0", + "android.hardware.graphics.mapper@2.0", + "android.hardware.graphics.mapper@3.0", + "android.hardware.graphics.mapper@4.0", "android.hidl.allocator@1.0", "libgrallocusage", "libhidlmemory", diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp index d39850d06d..dd45b0dca8 100644 --- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp +++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp @@ -30,6 +30,7 @@ #include <CameraMetadata.h> #include <CameraParameters.h> +#include <HandleImporter.h> #include <android/hardware/camera/device/1.0/ICameraDevice.h> #include <android/hardware/camera/device/3.2/ICameraDevice.h> #include <android/hardware/camera/device/3.3/ICameraDeviceSession.h> @@ -45,7 +46,9 @@ #include <android/hardware/camera/device/3.7/ICameraDeviceSession.h> #include <android/hardware/camera/device/3.7/ICameraInjectionSession.h> #include <android/hardware/camera/device/3.8/ICameraDeviceCallback.h> +#include <android/hardware/camera/device/3.8/ICameraDeviceSession.h> #include <android/hardware/camera/metadata/3.4/types.h> +#include <android/hardware/camera/metadata/3.8/types.h> #include <android/hardware/camera/provider/2.4/ICameraProvider.h> #include <android/hardware/camera/provider/2.5/ICameraProvider.h> #include <android/hardware/camera/provider/2.6/ICameraProvider.h> @@ -97,6 +100,7 @@ using ::android::hardware::camera::common::V1_0::Status; using ::android::hardware::camera::common::V1_0::TorchMode; using ::android::hardware::camera::common::V1_0::TorchModeStatus; using ::android::hardware::camera::common::V1_0::helper::CameraParameters; +using ::android::hardware::camera::common::V1_0::helper::HandleImporter; using ::android::hardware::camera::common::V1_0::helper::Size; using ::android::hardware::camera::device::V1_0::CameraFacing; using ::android::hardware::camera::device::V1_0::CameraFrameMetadata; @@ -129,6 +133,8 @@ using ::android::hardware::camera::metadata::V3_4:: CameraMetadataEnumAndroidSensorInfoColorFilterArrangement; using ::android::hardware::camera::metadata::V3_4::CameraMetadataTag; using ::android::hardware::camera::metadata::V3_6::CameraMetadataEnumAndroidSensorPixelMode; +using ::android::hardware::camera::metadata::V3_8:: + CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap; using ::android::hardware::camera::provider::V2_4::ICameraProvider; using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback; using ::android::hardware::camera::provider::V2_6::CameraIdAndStreamCombination; @@ -136,7 +142,6 @@ using ::android::hardware::graphics::common::V1_0::BufferUsage; using ::android::hardware::graphics::common::V1_0::Dataspace; using ::android::hardware::graphics::common::V1_0::PixelFormat; using ::android::hidl::allocator::V1_0::IAllocator; -using ::android::hidl::memory::V1_0::IMapper; using ::android::hidl::memory::V1_0::IMemory; using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>; using ::android::hidl::manager::V1_0::IServiceManager; @@ -781,13 +786,15 @@ public: sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/, sp<device::V3_5::ICameraDeviceSession> *session3_5 /*out*/, sp<device::V3_6::ICameraDeviceSession> *session3_6 /*out*/, - sp<device::V3_7::ICameraDeviceSession> *session3_7 /*out*/); + sp<device::V3_7::ICameraDeviceSession> *session3_7 /*out*/, + sp<device::V3_8::ICameraDeviceSession> *session3_8 /*out*/); void castInjectionSession( const sp<ICameraDeviceSession>& session, sp<device::V3_7::ICameraInjectionSession>* injectionSession3_7 /*out*/); void castDevice(const sp<device::V3_2::ICameraDevice>& device, int32_t deviceVersion, sp<device::V3_5::ICameraDevice>* device3_5 /*out*/, - sp<device::V3_7::ICameraDevice>* device3_7 /*out*/); + sp<device::V3_7::ICameraDevice>* device3_7 /*out*/, + sp<device::V3_8::ICameraDevice>* device3_8 /*out*/); void createStreamConfiguration( const ::android::hardware::hidl_vec<V3_2::Stream>& streams3_2, StreamConfigurationMode configMode, @@ -817,6 +824,16 @@ public: uint32_t* partialResultCount /*out*/, bool* useHalBufManager /*out*/, sp<DeviceCb>* outCb /*out*/, uint32_t streamConfigCounter, bool maxResolution); + void configureStreams3_8(const std::string& name, int32_t deviceVersion, + sp<ICameraProvider> provider, PixelFormat format, + sp<device::V3_8::ICameraDeviceSession>* session3_8 /*out*/, + V3_2::Stream* previewStream /*out*/, + device::V3_6::HalStreamConfiguration* halStreamConfig /*out*/, + bool* supportsPartialResults /*out*/, + uint32_t* partialResultCount /*out*/, bool* useHalBufManager /*out*/, + sp<DeviceCb>* outCb /*out*/, uint32_t streamConfigCounter, + bool maxResolution, + CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap prof); void configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion, sp<ICameraProvider> provider, @@ -896,6 +913,9 @@ public: static bool isDepthOnly(const camera_metadata_t* staticMeta); static bool isUltraHighResolution(const camera_metadata_t* staticMeta); + static void get10BitDynamicRangeProfiles(const camera_metadata_t* staticMeta, + std::vector<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap> *profiles); + static bool is10BitDynamicRangeCapable(const camera_metadata_t* staticMeta); static Status getAvailableOutputStreams(const camera_metadata_t* staticMeta, std::vector<AvailableStream>& outputStreams, @@ -1077,6 +1097,10 @@ protected: expectedPhysicalResults(extraPhysicalResult) {} }; + static void verify10BitMetadata(HandleImporter& importer, + const InFlightRequest& request, + CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap profile); + // Map from frame number to the in-flight request state typedef ::android::KeyedVector<uint32_t, InFlightRequest*> InFlightMap; @@ -1105,6 +1129,8 @@ protected: // Camera provider type. std::string mProviderType; + + HandleImporter mHandleImporter; }; Return<void> CameraHidlTest::Camera1DeviceCb::notifyCallback( @@ -3342,10 +3368,13 @@ TEST_P(CameraHidlTest, openClose) { sp<device::V3_5::ICameraDeviceSession> sessionV3_5; sp<device::V3_6::ICameraDeviceSession> sessionV3_6; sp<device::V3_7::ICameraDeviceSession> sessionV3_7; + sp<device::V3_8::ICameraDeviceSession> sessionV3_8; castSession(session, deviceVersion, &sessionV3_3, &sessionV3_4, &sessionV3_5, &sessionV3_6, - &sessionV3_7); - if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_7) { + &sessionV3_7, &sessionV3_8); + if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_8) { + ASSERT_TRUE(sessionV3_8.get() != nullptr); + } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_7) { ASSERT_TRUE(sessionV3_7.get() != nullptr); } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_6) { ASSERT_TRUE(sessionV3_6.get() != nullptr); @@ -3513,14 +3542,17 @@ TEST_P(CameraHidlTest, configureStreamsAvailableOutputs) { sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; sp<device::V3_2::ICameraDevice> cameraDevice; sp<device::V3_5::ICameraDevice> cameraDevice3_5; sp<device::V3_7::ICameraDevice> cameraDevice3_7; + sp<device::V3_8::ICameraDevice> cameraDevice3_8; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); - castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + &session3_6, &session3_7, &session3_8); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, + &cameraDevice3_8); outputStreams.clear(); ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams)); @@ -3616,9 +3648,11 @@ TEST_P(CameraHidlTest, configureConcurrentStreamsAvailableOutputs) { sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; sp<device::V3_2::ICameraDevice> cameraDevice; sp<device::V3_5::ICameraDevice> cameraDevice3_5; sp<device::V3_7::ICameraDevice> cameraDevice3_7; + sp<device::V3_8::ICameraDevice> cameraDevice3_8; ::android::hardware::camera::device::V3_7::StreamConfiguration config3_7; ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5; ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4; @@ -3655,8 +3689,9 @@ TEST_P(CameraHidlTest, configureConcurrentStreamsAvailableOutputs) { openEmptyDeviceSession(name, mProvider2_6, &cti.session /*out*/, &cti.staticMeta /*out*/, &cti.cameraDevice /*out*/); castSession(cti.session, deviceVersion, &cti.session3_3, &cti.session3_4, - &cti.session3_5, &cti.session3_6, &cti.session3_7); - castDevice(cti.cameraDevice, deviceVersion, &cti.cameraDevice3_5, &cti.cameraDevice3_7); + &cti.session3_5, &cti.session3_6, &cti.session3_7, &cti.session3_8); + castDevice(cti.cameraDevice, deviceVersion, &cti.cameraDevice3_5, &cti.cameraDevice3_7, + &cti.cameraDevice3_8); outputStreams.clear(); ASSERT_EQ(Status::OK, getMandatoryConcurrentStreams(cti.staticMeta, &outputStreams)); @@ -3785,14 +3820,17 @@ TEST_P(CameraHidlTest, configureStreamsInvalidOutputs) { sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; sp<device::V3_2::ICameraDevice> cameraDevice; sp<device::V3_5::ICameraDevice> cameraDevice3_5; sp<device::V3_7::ICameraDevice> cameraDevice3_7; + sp<device::V3_8::ICameraDevice> cameraDevice3_8; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); - castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + &session3_6, &session3_7, &session3_8); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, + &cameraDevice3_8); outputStreams.clear(); ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams)); @@ -3998,14 +4036,17 @@ TEST_P(CameraHidlTest, configureStreamsZSLInputOutputs) { sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; sp<device::V3_2::ICameraDevice> cameraDevice; sp<device::V3_5::ICameraDevice> cameraDevice3_5; sp<device::V3_7::ICameraDevice> cameraDevice3_7; + sp<device::V3_8::ICameraDevice> cameraDevice3_8; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); - castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + &session3_6, &session3_7, &session3_8); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, + &cameraDevice3_8); Status rc = isZSLModeAvailable(staticMeta); if (Status::METHOD_NOT_SUPPORTED == rc) { @@ -4184,9 +4225,10 @@ TEST_P(CameraHidlTest, configureStreamsWithSessionParameters) { sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/); castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); + &session3_6, &session3_7, &session3_8); if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4) { ASSERT_NE(session3_4, nullptr); } else { @@ -4325,14 +4367,17 @@ TEST_P(CameraHidlTest, configureStreamsPreviewStillOutputs) { sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; sp<device::V3_2::ICameraDevice> cameraDevice; sp<device::V3_5::ICameraDevice> cameraDevice3_5; sp<device::V3_7::ICameraDevice> cameraDevice3_7; + sp<device::V3_8::ICameraDevice> cameraDevice3_8; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); - castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + &session3_6, &session3_7, &session3_8); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, + &cameraDevice3_8); // Check if camera support depth only if (isDepthOnly(staticMeta)) { @@ -4459,14 +4504,17 @@ TEST_P(CameraHidlTest, configureStreamsConstrainedOutputs) { sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; sp<device::V3_2::ICameraDevice> cameraDevice; sp<device::V3_5::ICameraDevice> cameraDevice3_5; sp<device::V3_7::ICameraDevice> cameraDevice3_7; + sp<device::V3_8::ICameraDevice> cameraDevice3_8; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); - castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + &session3_6, &session3_7, &session3_8); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, + &cameraDevice3_8); Status rc = isConstrainedModeAvailable(staticMeta); if (Status::METHOD_NOT_SUPPORTED == rc) { @@ -4706,14 +4754,17 @@ TEST_P(CameraHidlTest, configureStreamsVideoStillOutputs) { sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; sp<device::V3_2::ICameraDevice> cameraDevice; sp<device::V3_5::ICameraDevice> cameraDevice3_5; sp<device::V3_7::ICameraDevice> cameraDevice3_7; + sp<device::V3_8::ICameraDevice> cameraDevice3_8; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); - castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + &session3_6, &session3_7, &session3_8); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, + &cameraDevice3_8); // Check if camera support depth only if (isDepthOnly(staticMeta)) { @@ -4997,6 +5048,20 @@ void CameraHidlTest::processCaptureRequestInternal(uint64_t bufferUsage, ASSERT_EQ(Status::OK, status); ASSERT_EQ(numRequestProcessed, 1u); + if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_8) { + sp<device::V3_3::ICameraDeviceSession> session3_3; + sp<device::V3_4::ICameraDeviceSession> session3_4; + sp<device::V3_5::ICameraDeviceSession> session3_5; + sp<device::V3_6::ICameraDeviceSession> session3_6; + sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, + &session3_6, &session3_7, &session3_8); + ASSERT_TRUE(session3_8.get() != nullptr); + hidl_vec<int32_t> streamIds = { halStreamConfig.streams[0].id }; + session3_8->repeatingRequestEnd(request.frameNumber, streamIds); + } + { std::unique_lock<std::mutex> l(mLock); while (!inflightReq.errorCodeValid && @@ -5640,6 +5705,188 @@ TEST_P(CameraHidlTest, processUltraHighResolutionRequest) { } } +// Generate and verify 10-bit dynamic range request +TEST_P(CameraHidlTest, process10BitDynamicRangeRequest) { + hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); + uint64_t bufferId = 1; + uint32_t frameNumber = 1; + ::android::hardware::hidl_vec<uint8_t> settings; + + for (const auto& name : cameraDeviceNames) { + int deviceVersion = getCameraDeviceVersion(name, mProviderType); + if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_8) { + continue; + } + std::string version, deviceId; + ASSERT_TRUE(::matchDeviceName(name, mProviderType, &version, &deviceId)); + camera_metadata_t* staticMeta; + Return<void> ret; + sp<ICameraDeviceSession> session; + openEmptyDeviceSession(name, mProvider, &session, &staticMeta); + if (!is10BitDynamicRangeCapable(staticMeta)) { + free_camera_metadata(staticMeta); + ret = session->close(); + ASSERT_TRUE(ret.isOk()); + continue; + } + std::vector<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap> profileList; + get10BitDynamicRangeProfiles(staticMeta, &profileList); + ASSERT_FALSE(profileList.empty()); + + android::hardware::camera::common::V1_0::helper::CameraMetadata defaultSettings; + ret = session->constructDefaultRequestSettings( + RequestTemplate::STILL_CAPTURE, + [&defaultSettings](auto status, const auto& req) mutable { + ASSERT_EQ(Status::OK, status); + + const camera_metadata_t* metadata = + reinterpret_cast<const camera_metadata_t*>(req.data()); + size_t expectedSize = req.size(); + int result = validate_camera_metadata_structure(metadata, &expectedSize); + ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED)); + + size_t entryCount = get_camera_metadata_entry_count(metadata); + ASSERT_GT(entryCount, 0u); + defaultSettings = metadata; + }); + ASSERT_TRUE(ret.isOk()); + + const camera_metadata_t* settingsBuffer = defaultSettings.getAndLock(); + settings.setToExternal( + reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(settingsBuffer)), + get_camera_metadata_size(settingsBuffer)); + overrideRotateAndCrop(&settings); + + free_camera_metadata(staticMeta); + ret = session->close(); + ASSERT_TRUE(ret.isOk()); + V3_6::HalStreamConfiguration halStreamConfig; + bool supportsPartialResults = false; + bool useHalBufManager = false; + uint32_t partialResultCount = 0; + V3_2::Stream previewStream; + sp<device::V3_8::ICameraDeviceSession> session3_8; + sp<DeviceCb> cb; + for (const auto& profile : profileList) { + configureStreams3_8(name, deviceVersion, mProvider, PixelFormat::IMPLEMENTATION_DEFINED, + &session3_8, &previewStream, &halStreamConfig, + &supportsPartialResults, &partialResultCount, &useHalBufManager, + &cb, 0, /*maxResolution*/ false, profile); + ASSERT_NE(session3_8, nullptr); + + std::shared_ptr<ResultMetadataQueue> resultQueue; + auto resultQueueRet = session3_8->getCaptureResultMetadataQueue( + [&resultQueue](const auto& descriptor) { + resultQueue = std::make_shared<ResultMetadataQueue>(descriptor); + if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) { + ALOGE("%s: HAL returns empty result metadata fmq," + " not use it", + __func__); + resultQueue = nullptr; + // Don't use the queue onwards. + } + }); + ASSERT_TRUE(resultQueueRet.isOk()); + + std::vector<hidl_handle> graphicBuffers; + graphicBuffers.reserve(halStreamConfig.streams.size()); + ::android::hardware::hidl_vec<StreamBuffer> outputBuffers; + outputBuffers.resize(halStreamConfig.streams.size()); + InFlightRequest inflightReq = {static_cast<ssize_t>(halStreamConfig.streams.size()), + false, + supportsPartialResults, + partialResultCount, + std::unordered_set<std::string>(), + resultQueue}; + + size_t k = 0; + for (const auto& halStream : halStreamConfig.streams) { + hidl_handle buffer_handle; + if (useHalBufManager) { + outputBuffers[k] = {halStream.v3_4.v3_3.v3_2.id, + 0, + buffer_handle, + BufferStatus::OK, + nullptr, + nullptr}; + } else { + allocateGraphicBuffer( + previewStream.width, previewStream.height, + android_convertGralloc1To0Usage(halStream.v3_4.v3_3.v3_2.producerUsage, + halStream.v3_4.v3_3.v3_2.consumerUsage), + halStream.v3_4.v3_3.v3_2.overrideFormat, &buffer_handle); + + graphicBuffers.push_back(buffer_handle); + outputBuffers[k] = {halStream.v3_4.v3_3.v3_2.id, + bufferId, + buffer_handle, + BufferStatus::OK, + nullptr, + nullptr}; + bufferId++; + } + k++; + } + + StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr}; + V3_4::CaptureRequest request3_4; + request3_4.v3_2.frameNumber = frameNumber; + request3_4.v3_2.fmqSettingsSize = 0; + request3_4.v3_2.settings = settings; + request3_4.v3_2.inputBuffer = emptyInputBuffer; + request3_4.v3_2.outputBuffers = outputBuffers; + V3_7::CaptureRequest request3_7; + request3_7.v3_4 = request3_4; + request3_7.inputWidth = 0; + request3_7.inputHeight = 0; + + { + std::unique_lock<std::mutex> l(mLock); + mInflightMap.clear(); + mInflightMap.add(frameNumber, &inflightReq); + } + + Status stat = Status::INTERNAL_ERROR; + uint32_t numRequestProcessed = 0; + hidl_vec<BufferCache> cachesToRemove; + Return<void> returnStatus = session3_8->processCaptureRequest_3_7( + {request3_7}, cachesToRemove, + [&stat, &numRequestProcessed](auto s, uint32_t n) { + stat = s; + numRequestProcessed = n; + }); + ASSERT_TRUE(returnStatus.isOk()); + ASSERT_EQ(Status::OK, stat); + ASSERT_EQ(numRequestProcessed, 1u); + + { + std::unique_lock<std::mutex> l(mLock); + while (!inflightReq.errorCodeValid && + ((0 < inflightReq.numBuffersLeft) || (!inflightReq.haveResultMetadata))) { + auto timeout = std::chrono::system_clock::now() + + std::chrono::seconds(kStreamBufferTimeoutSec); + ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout)); + } + + ASSERT_FALSE(inflightReq.errorCodeValid); + ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); + verify10BitMetadata(mHandleImporter, inflightReq, profile); + } + if (useHalBufManager) { + hidl_vec<int32_t> streamIds(halStreamConfig.streams.size()); + for (size_t i = 0; i < streamIds.size(); i++) { + streamIds[i] = halStreamConfig.streams[i].v3_4.v3_3.v3_2.id; + } + session3_8->signalStreamFlush(streamIds, /*streamConfigCounter*/ 0); + cb->waitForBuffersReturned(); + } + + ret = session3_8->close(); + ASSERT_TRUE(ret.isOk()); + } + } +} + // Generate and verify a burst containing alternating sensor sensitivity values TEST_P(CameraHidlTest, processCaptureRequestBurstISO) { hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); @@ -7448,8 +7695,9 @@ void CameraHidlTest::configureStreams3_7( sp<device::V3_4::ICameraDeviceSession> session3_4; sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; + sp<device::V3_8::ICameraDeviceSession> session3_8; castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6, - session3_7); + session3_7, &session3_8); ASSERT_NE(nullptr, (*session3_7).get()); *useHalBufManager = false; @@ -7497,7 +7745,8 @@ void CameraHidlTest::configureStreams3_7( ASSERT_TRUE(deviceVersion >= CAMERA_DEVICE_API_VERSION_3_7); sp<device::V3_5::ICameraDevice> cameraDevice3_5 = nullptr; sp<device::V3_7::ICameraDevice> cameraDevice3_7 = nullptr; - castDevice(device3_x, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + sp<device::V3_8::ICameraDevice> cameraDevice3_8 = nullptr; + castDevice(device3_x, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, &cameraDevice3_8); ASSERT_NE(cameraDevice3_7, nullptr); bool supported = false; ret = cameraDevice3_7->isStreamCombinationSupported_3_7( @@ -7530,6 +7779,153 @@ void CameraHidlTest::configureStreams3_7( ASSERT_TRUE(ret.isOk()); } +// Configure streams +void CameraHidlTest::configureStreams3_8( + const std::string& name, int32_t deviceVersion, sp<ICameraProvider> provider, + PixelFormat format, sp<device::V3_8::ICameraDeviceSession>* session3_8 /*out*/, + V3_2::Stream* previewStream /*out*/, + device::V3_6::HalStreamConfiguration* halStreamConfig /*out*/, + bool* supportsPartialResults /*out*/, uint32_t* partialResultCount /*out*/, + bool* useHalBufManager /*out*/, sp<DeviceCb>* outCb /*out*/, uint32_t streamConfigCounter, + bool maxResolution, + CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap prof) { + ASSERT_NE(nullptr, session3_8); + ASSERT_NE(nullptr, halStreamConfig); + ASSERT_NE(nullptr, previewStream); + ASSERT_NE(nullptr, supportsPartialResults); + ASSERT_NE(nullptr, partialResultCount); + ASSERT_NE(nullptr, useHalBufManager); + ASSERT_NE(nullptr, outCb); + ASSERT_TRUE(deviceVersion >= CAMERA_DEVICE_API_VERSION_3_8); + + std::vector<AvailableStream> outputStreams; + ::android::sp<ICameraDevice> device3_x; + ALOGI("configureStreams: Testing camera device %s", name.c_str()); + Return<void> ret; + ret = provider->getCameraDeviceInterface_V3_x(name, [&](auto status, const auto& device) { + ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status); + ASSERT_EQ(Status::OK, status); + ASSERT_NE(device, nullptr); + device3_x = device; + }); + ASSERT_TRUE(ret.isOk()); + + camera_metadata_t* staticMeta; + ret = device3_x->getCameraCharacteristics([&](Status s, CameraMetadata metadata) { + ASSERT_EQ(Status::OK, s); + staticMeta = + clone_camera_metadata(reinterpret_cast<const camera_metadata_t*>(metadata.data())); + ASSERT_NE(nullptr, staticMeta); + }); + ASSERT_TRUE(ret.isOk()); + + camera_metadata_ro_entry entry; + auto status = + find_camera_metadata_ro_entry(staticMeta, ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &entry); + if ((0 == status) && (entry.count > 0)) { + *partialResultCount = entry.data.i32[0]; + *supportsPartialResults = (*partialResultCount > 1); + } + + sp<DeviceCb> cb = new DeviceCb(this, deviceVersion, staticMeta); + sp<ICameraDeviceSession> session; + ret = device3_x->open(cb, [&session](auto status, const auto& newSession) { + ALOGI("device::open returns status:%d", (int)status); + ASSERT_EQ(Status::OK, status); + ASSERT_NE(newSession, nullptr); + session = newSession; + }); + ASSERT_TRUE(ret.isOk()); + *outCb = cb; + + sp<device::V3_3::ICameraDeviceSession> session3_3; + sp<device::V3_4::ICameraDeviceSession> session3_4; + sp<device::V3_5::ICameraDeviceSession> session3_5; + sp<device::V3_6::ICameraDeviceSession> session3_6; + sp<device::V3_7::ICameraDeviceSession> session3_7; + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6, + &session3_7, session3_8); + ASSERT_NE(nullptr, (*session3_8).get()); + + *useHalBufManager = false; + status = find_camera_metadata_ro_entry( + staticMeta, ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &entry); + if ((0 == status) && (entry.count == 1)) { + *useHalBufManager = (entry.data.u8[0] == + ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5); + } + + outputStreams.clear(); + Size maxSize; + auto rc = getMaxOutputSizeForFormat(staticMeta, format, &maxSize, maxResolution); + ASSERT_EQ(Status::OK, rc); + free_camera_metadata(staticMeta); + + ::android::hardware::hidl_vec<V3_8::Stream> streams3_8(1); + streams3_8[0].v3_7.groupId = -1; + streams3_8[0].v3_7.sensorPixelModesUsed = { + CameraMetadataEnumAndroidSensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT}; + streams3_8[0].v3_7.v3_4.bufferSize = 0; + streams3_8[0].v3_7.v3_4.v3_2.id = 0; + streams3_8[0].v3_7.v3_4.v3_2.streamType = StreamType::OUTPUT; + streams3_8[0].v3_7.v3_4.v3_2.width = static_cast<uint32_t>(maxSize.width); + streams3_8[0].v3_7.v3_4.v3_2.height = static_cast<uint32_t>(maxSize.height); + streams3_8[0].v3_7.v3_4.v3_2.format = static_cast<PixelFormat>(format); + streams3_8[0].v3_7.v3_4.v3_2.usage = GRALLOC1_CONSUMER_USAGE_CPU_READ; + streams3_8[0].v3_7.v3_4.v3_2.dataSpace = 0; + streams3_8[0].v3_7.v3_4.v3_2.rotation = StreamRotation::ROTATION_0; + streams3_8[0].dynamicRangeProfile = prof; + + ::android::hardware::camera::device::V3_8::StreamConfiguration config3_8; + config3_8.streams = streams3_8; + config3_8.operationMode = StreamConfigurationMode::NORMAL_MODE; + config3_8.streamConfigCounter = streamConfigCounter; + config3_8.multiResolutionInputImage = false; + RequestTemplate reqTemplate = RequestTemplate::STILL_CAPTURE; + ret = (*session3_8) + ->constructDefaultRequestSettings(reqTemplate, + [&config3_8](auto status, const auto& req) { + ASSERT_EQ(Status::OK, status); + config3_8.sessionParams = req; + }); + ASSERT_TRUE(ret.isOk()); + + sp<device::V3_5::ICameraDevice> cameraDevice3_5 = nullptr; + sp<device::V3_7::ICameraDevice> cameraDevice3_7 = nullptr; + sp<device::V3_8::ICameraDevice> cameraDevice3_8 = nullptr; + castDevice(device3_x, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, &cameraDevice3_8); + ASSERT_NE(cameraDevice3_8, nullptr); + bool supported = false; + ret = cameraDevice3_8->isStreamCombinationSupported_3_8( + config3_8, [&supported](Status s, bool combStatus) { + ASSERT_TRUE((Status::OK == s) || (Status::METHOD_NOT_SUPPORTED == s)); + if (Status::OK == s) { + supported = combStatus; + } + }); + ASSERT_TRUE(ret.isOk()); + ASSERT_EQ(supported, true); + + if (*session3_8 != nullptr) { + ret = (*session3_8) + ->configureStreams_3_8( + config3_8, + [&](Status s, device::V3_6::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + *halStreamConfig = halConfig; + if (*useHalBufManager) { + hidl_vec<V3_4::Stream> streams(1); + hidl_vec<V3_2::HalStream> halStreams(1); + streams[0] = streams3_8[0].v3_7.v3_4; + halStreams[0] = halConfig.streams[0].v3_4.v3_3.v3_2; + cb->setCurrentStreamConfig(streams, halStreams); + } + }); + } + *previewStream = streams3_8[0].v3_7.v3_4.v3_2; + ASSERT_TRUE(ret.isOk()); +} + // Configure multiple preview streams using different physical ids. void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion, sp<ICameraProvider> provider, @@ -7604,8 +8000,9 @@ void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t sp<device::V3_3::ICameraDeviceSession> session3_3; sp<device::V3_6::ICameraDeviceSession> session3_6; sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; castSession(session, deviceVersion, &session3_3, session3_4, session3_5, - &session3_6, &session3_7); + &session3_6, &session3_7, &session3_8); ASSERT_NE(nullptr, (*session3_4).get()); *useHalBufManager = false; @@ -7650,7 +8047,8 @@ void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t if (allowUnsupport) { sp<device::V3_5::ICameraDevice> cameraDevice3_5; sp<device::V3_7::ICameraDevice> cameraDevice3_7; - castDevice(device3_x, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + sp<device::V3_8::ICameraDevice> cameraDevice3_8; + castDevice(device3_x, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, &cameraDevice3_8); bool supported = false; ret = cameraDevice3_5->isStreamCombinationSupported(config3_4, @@ -7843,6 +8241,95 @@ bool CameraHidlTest::isUltraHighResolution(const camera_metadata_t* staticMeta) return false; } +void CameraHidlTest::get10BitDynamicRangeProfiles(const camera_metadata_t* staticMeta, + std::vector<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap> *profiles) { + ASSERT_NE(nullptr, staticMeta); + ASSERT_NE(nullptr, profiles); + camera_metadata_ro_entry entry; + std::unordered_set<int32_t> entries; + int rc = find_camera_metadata_ro_entry(staticMeta, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP, &entry); + ASSERT_EQ(rc, 0); + ASSERT_TRUE(entry.count > 0); + ASSERT_EQ(entry.count % 2, 0); + + for (uint32_t i = 0; i < entry.count; i += 2) { + ASSERT_NE(entry.data.i32[i], + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD); + ASSERT_EQ(entries.find(entry.data.i32[i]), entries.end()); + entries.insert(static_cast<int32_t>(entry.data.i32[i])); + profiles->emplace_back( + static_cast<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap> + (entry.data.i32[i])); + } + + if (!entries.empty()) { + ASSERT_NE(entries.find(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10), + entries.end()); + } +} + +bool CameraHidlTest::is10BitDynamicRangeCapable(const camera_metadata_t* staticMeta) { + camera_metadata_ro_entry scalarEntry; + int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_REQUEST_AVAILABLE_CAPABILITIES, + &scalarEntry); + if (rc == 0) { + for (uint32_t i = 0; i < scalarEntry.count; i++) { + if (scalarEntry.data.u8[i] == + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT) { + return true; + } + } + } + return false; +} + +void CameraHidlTest::verify10BitMetadata(HandleImporter& importer, + const InFlightRequest& request, + CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap profile) { + for (const auto& b : request.resultOutputBuffers) { + bool smpte2086Present = importer.isSmpte2086Present(b.buffer.buffer.getNativeHandle()); + bool smpte2094_10Present = importer.isSmpte2094_10Present( + b.buffer.buffer.getNativeHandle()); + bool smpte2094_40Present = importer.isSmpte2094_40Present( + b.buffer.buffer.getNativeHandle()); + + switch (static_cast<uint32_t>(profile)) { + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10: + ASSERT_FALSE(smpte2086Present); + ASSERT_FALSE(smpte2094_10Present); + ASSERT_FALSE(smpte2094_40Present); + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10: + ASSERT_TRUE(smpte2086Present); + ASSERT_FALSE(smpte2094_10Present); + ASSERT_FALSE(smpte2094_40Present); + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS: + ASSERT_FALSE(smpte2086Present); + ASSERT_FALSE(smpte2094_10Present); + ASSERT_TRUE(smpte2094_40Present); + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF: + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO: + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM: + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO: + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF: + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO: + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM: + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO: + ASSERT_FALSE(smpte2086Present); + ASSERT_TRUE(smpte2094_10Present); + ASSERT_FALSE(smpte2094_40Present); + break; + default: + ALOGE("%s: Unexpected 10-bit dynamic range profile: %d", + __FUNCTION__, profile); + ADD_FAILURE(); + } + } +} + bool CameraHidlTest::isDepthOnly(const camera_metadata_t* staticMeta) { camera_metadata_ro_entry scalarEntry; camera_metadata_ro_entry depthEntry; @@ -8006,8 +8493,9 @@ void CameraHidlTest::configureSingleStream( sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; castSession(*session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); + &session3_6, &session3_7, &session3_8); *useHalBufManager = false; status = find_camera_metadata_ro_entry(staticMeta, @@ -8138,12 +8626,19 @@ void CameraHidlTest::configureSingleStream( void CameraHidlTest::castDevice(const sp<device::V3_2::ICameraDevice>& device, int32_t deviceVersion, sp<device::V3_5::ICameraDevice>* device3_5 /*out*/, - sp<device::V3_7::ICameraDevice>* device3_7 /*out*/) { + sp<device::V3_7::ICameraDevice>* device3_7 /*out*/, + sp<device::V3_8::ICameraDevice>* device3_8 /*out*/) { ASSERT_NE(nullptr, device3_5); ASSERT_NE(nullptr, device3_7); + ASSERT_NE(nullptr, device3_8); switch (deviceVersion) { - case CAMERA_DEVICE_API_VERSION_3_8: + case CAMERA_DEVICE_API_VERSION_3_8: { + auto castResult = device::V3_8::ICameraDevice::castFrom(device); + ASSERT_TRUE(castResult.isOk()); + *device3_8 = castResult; + } + [[fallthrough]]; case CAMERA_DEVICE_API_VERSION_3_7: { auto castResult = device::V3_7::ICameraDevice::castFrom(device); ASSERT_TRUE(castResult.isOk()); @@ -8192,15 +8687,22 @@ void CameraHidlTest::castSession(const sp<ICameraDeviceSession> &session, int32_ sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/, sp<device::V3_5::ICameraDeviceSession> *session3_5 /*out*/, sp<device::V3_6::ICameraDeviceSession> *session3_6 /*out*/, - sp<device::V3_7::ICameraDeviceSession> *session3_7 /*out*/) { + sp<device::V3_7::ICameraDeviceSession> *session3_7 /*out*/, + sp<device::V3_8::ICameraDeviceSession> *session3_8 /*out*/) { ASSERT_NE(nullptr, session3_3); ASSERT_NE(nullptr, session3_4); ASSERT_NE(nullptr, session3_5); ASSERT_NE(nullptr, session3_6); ASSERT_NE(nullptr, session3_7); + ASSERT_NE(nullptr, session3_8); switch (deviceVersion) { - case CAMERA_DEVICE_API_VERSION_3_8: + case CAMERA_DEVICE_API_VERSION_3_8: { + auto castResult = device::V3_8::ICameraDeviceSession::castFrom(session); + ASSERT_TRUE(castResult.isOk()); + *session3_8 = castResult; + } + [[fallthrough]]; case CAMERA_DEVICE_API_VERSION_3_7: { auto castResult = device::V3_7::ICameraDeviceSession::castFrom(session); ASSERT_TRUE(castResult.isOk()); @@ -9077,8 +9579,9 @@ void CameraHidlTest::verifyBuffersReturned( sp<device::V3_5::ICameraDeviceSession> session3_5; sp<device::V3_6::ICameraDeviceSession> session3_6; sp<device::V3_7::ICameraDeviceSession> session3_7; + sp<device::V3_8::ICameraDeviceSession> session3_8; castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); + &session3_6, &session3_7, &session3_8); ASSERT_NE(nullptr, session3_5.get()); hidl_vec<int32_t> streamIds(1); @@ -9320,7 +9823,7 @@ void CameraHidlTest::verifyRecommendedConfigs(const CameraMetadata& chars) { size_t CONFIG_ENTRY_TYPE_OFFSET = 3; size_t CONFIG_ENTRY_BITFIELD_OFFSET = 4; uint32_t maxPublicUsecase = - ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END; + ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END_3_8; uint32_t vendorUsecaseStart = ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VENDOR_START; uint32_t usecaseMask = (1 << vendorUsecaseStart) - 1; diff --git a/common/support/Android.bp b/common/support/Android.bp index b24893b16e..718901ef6a 100644 --- a/common/support/Android.bp +++ b/common/support/Android.bp @@ -11,7 +11,11 @@ cc_library_static { name: "libaidlcommonsupport", vendor_available: true, host_supported: true, - defaults: ["libbinder_ndk_host_user"], + target: { + darwin: { + enabled: false, + }, + }, srcs: ["NativeHandle.cpp"], export_include_dirs: ["include"], shared_libs: [ @@ -28,7 +32,11 @@ cc_library_static { cc_test { name: "libaidlcommonsupport_test", host_supported: true, - defaults: ["libbinder_ndk_host_user"], + target: { + darwin: { + enabled: false, + }, + }, srcs: ["test.cpp"], static_libs: [ "android.hardware.common-V2-ndk", diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index a31b52b8f8..7a70f10cf6 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -77,14 +77,6 @@ <instance>default</instance> </interface> </hal> - <hal format="hidl" optional="true"> - <name>android.hardware.automotive.sv</name> - <version>1.0</version> - <interface> - <name>ISurroundViewService</name> - <instance>default</instance> - </interface> - </hal> <hal format="aidl" optional="true"> <name>android.hardware.automotive.vehicle</name> <interface> @@ -110,6 +102,7 @@ </hal> <hal format="aidl" optional="true"> <name>android.hardware.biometrics.face</name> + <version>2</version> <interface> <name>IFace</name> <instance>default</instance> @@ -209,6 +202,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> @@ -260,6 +265,14 @@ <instance>default</instance> </interface> </hal> + <hal format="aidl" optional="true"> + <name>android.hardware.gnss.measurement_corrections</name> + <version>1</version> + <interface> + <name>IMeasurementCorrectionsInterface</name> + <instance>default</instance> + </interface> + </hal> <hal format="hidl" optional="false"> <name>android.hardware.graphics.allocator</name> <!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test --> @@ -316,7 +329,7 @@ </hal> <hal format="aidl" optional="true"> <name>android.hardware.identity</name> - <version>1-3</version> + <version>1-4</version> <interface> <name>IIdentityCredentialStore</name> <instance>default</instance> @@ -443,7 +456,7 @@ </hal> <hal format="aidl" optional="true"> <name>android.hardware.neuralnetworks</name> - <version>1-3</version> + <version>1-4</version> <interface> <name>IDevice</name> <regex-instance>.*</regex-instance> @@ -765,7 +778,7 @@ </hal> <hal format="hidl" optional="true"> <name>android.hardware.wifi</name> - <version>1.3-5</version> + <version>1.3-6</version> <interface> <name>IWifi</name> <instance>default</instance> diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp index 2aa4bb2a22..414c502fd7 100644 --- a/compatibility_matrices/exclude/fcm_exclude.cpp +++ b/compatibility_matrices/exclude/fcm_exclude.cpp @@ -56,6 +56,7 @@ bool ShouldCheckMissingHalsInFcm(const std::string& package) { "android.hardware.common", "android.hardware.common.fmq", "android.hardware.graphics.common", + "android.hardware.input.common", "android.hardware.keymaster", "android.hardware.radio", "android.hardware.uwb.fira_android", diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/HostEndpointInfo.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/HostEndpointInfo.aidl index e7dcbc706d..84e8531eb9 100644 --- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/HostEndpointInfo.aidl +++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/HostEndpointInfo.aidl @@ -40,7 +40,7 @@ parcelable HostEndpointInfo { @nullable String attributionTag; @Backing(type="int") @VintfStability enum Type { - TYPE_FRAMEWORK = 1, - TYPE_APP = 2, + FRAMEWORK = 1, + APP = 2, } } diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl index facce4b65e..f0676bec74 100644 --- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl +++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl @@ -35,14 +35,15 @@ package android.hardware.contexthub; @VintfStability interface IContextHub { List<android.hardware.contexthub.ContextHubInfo> getContextHubs(); - boolean loadNanoapp(in int contextHubId, in android.hardware.contexthub.NanoappBinary appBinary, in int transactionId); - boolean unloadNanoapp(in int contextHubId, in long appId, in int transactionId); - boolean disableNanoapp(in int contextHubId, in long appId, in int transactionId); - boolean enableNanoapp(in int contextHubId, in long appId, in int transactionId); + void loadNanoapp(in int contextHubId, in android.hardware.contexthub.NanoappBinary appBinary, in int transactionId); + void unloadNanoapp(in int contextHubId, in long appId, in int transactionId); + void disableNanoapp(in int contextHubId, in long appId, in int transactionId); + void enableNanoapp(in int contextHubId, in long appId, in int transactionId); void onSettingChanged(in android.hardware.contexthub.Setting setting, in boolean enabled); - boolean queryNanoapps(in int contextHubId); - boolean registerCallback(in int contextHubId, in android.hardware.contexthub.IContextHubCallback cb); - boolean sendMessageToHub(in int contextHubId, in android.hardware.contexthub.ContextHubMessage message); + void queryNanoapps(in int contextHubId); + void registerCallback(in int contextHubId, in android.hardware.contexthub.IContextHubCallback cb); + void sendMessageToHub(in int contextHubId, in android.hardware.contexthub.ContextHubMessage message); void onHostEndpointConnected(in android.hardware.contexthub.HostEndpointInfo hostEndpointInfo); void onHostEndpointDisconnected(char hostEndpointId); + const int EX_CONTEXT_HUB_UNSPECIFIED = -1; } diff --git a/contexthub/aidl/android/hardware/contexthub/ContextHubMessage.aidl b/contexthub/aidl/android/hardware/contexthub/ContextHubMessage.aidl index 867da2f9c0..95d478e6c2 100644 --- a/contexthub/aidl/android/hardware/contexthub/ContextHubMessage.aidl +++ b/contexthub/aidl/android/hardware/contexthub/ContextHubMessage.aidl @@ -32,10 +32,14 @@ parcelable ContextHubMessage { */ char hostEndPoint; - /** The type of this message */ + /** + * The type of this message payload, defined by the communication endpoints (i.e. + * either the nanoapp or the host endpoint). This value can be used to distinguish + * the handling of messageBody (e.g. for decoding). + */ int messageType; - /** The payload containing the message */ + /** The payload containing the message. */ byte[] messageBody; /** diff --git a/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl b/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl index 40a231d804..a9d6657097 100644 --- a/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl +++ b/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl @@ -37,12 +37,12 @@ parcelable HostEndpointInfo { @Backing(type="int") enum Type { /** - This endpoint is from the Android framework, where packageName and attributionTag may be - empty. + * This endpoint is from the Android framework, where packageName and attributionTag may be + * empty. */ - TYPE_FRAMEWORK = 1, + FRAMEWORK = 1, /** This endpoint is an Android app. */ - TYPE_APP = 2, + APP = 2, } } diff --git a/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl b/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl index 33d241a3c3..2135041ed7 100644 --- a/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl +++ b/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl @@ -52,9 +52,12 @@ interface IContextHub { * @param appBinary The nanoapp binary with header * @param transactionId The transaction ID associated with this request * - * @return The return code + * @throws EX_ILLEGAL_ARGUMENT if any of the arguments are invalid. + * EX_UNSUPPORTED_OPERATION if this functionality is unsupported. + * EX_SERVICE_SPECIFIC on error + * - EX_CONTEXT_HUB_UNSPECIFIED if the request failed for other reasons. */ - boolean loadNanoapp(in int contextHubId, in NanoappBinary appBinary, in int transactionId); + void loadNanoapp(in int contextHubId, in NanoappBinary appBinary, in int transactionId); /** * Invokes the nanoapp's deinitialization "end()" entrypoint, and unloads the nanoapp. @@ -69,9 +72,12 @@ interface IContextHub { * @param appId The unique ID of the nanoapp * @param transactionId The transaction ID associated with this request * - * @return The return code + * @throws EX_ILLEGAL_ARGUMENT if any of the arguments are invalid. + * EX_UNSUPPORTED_OPERATION if this functionality is unsupported. + * EX_SERVICE_SPECIFIC on error + * - EX_CONTEXT_HUB_UNSPECIFIED if the request failed for other reasons. */ - boolean unloadNanoapp(in int contextHubId, in long appId, in int transactionId); + void unloadNanoapp(in int contextHubId, in long appId, in int transactionId); /** * Disables a nanoapp by invoking the nanoapp's "end()" entrypoint, but does not unload the @@ -87,9 +93,12 @@ interface IContextHub { * @param appId The unique ID of the nanoapp * @param transactionId The transaction ID associated with this request * - * @return The return code + * @throws EX_ILLEGAL_ARGUMENT if any of the arguments are invalid. + * EX_UNSUPPORTED_OPERATION if this functionality is unsupported. + * EX_SERVICE_SPECIFIC on error + * - EX_CONTEXT_HUB_UNSPECIFIED if the request failed for other reasons. */ - boolean disableNanoapp(in int contextHubId, in long appId, in int transactionId); + void disableNanoapp(in int contextHubId, in long appId, in int transactionId); /** * Enables a nanoapp by invoking the nanoapp's initialization "start()" entrypoint. @@ -104,9 +113,12 @@ interface IContextHub { * @param appId appIdentifier returned by the HAL * @param message message to be sent * - * @return true on success + * @throws EX_ILLEGAL_ARGUMENT if any of the arguments are invalid. + * EX_UNSUPPORTED_OPERATION if this functionality is unsupported. + * EX_SERVICE_SPECIFIC on error + * - EX_CONTEXT_HUB_UNSPECIFIED if the request failed for other reasons. */ - boolean enableNanoapp(in int contextHubId, in long appId, in int transactionId); + void enableNanoapp(in int contextHubId, in long appId, in int transactionId); /** * Notification sent by the framework to indicate that the user has changed a setting. @@ -124,9 +136,12 @@ interface IContextHub { * * @param contextHubId The identifier of the Context Hub * - * @return true on success + * @throws EX_ILLEGAL_ARGUMENT if any of the arguments are invalid. + * EX_UNSUPPORTED_OPERATION if this functionality is unsupported. + * EX_SERVICE_SPECIFIC on error + * - EX_CONTEXT_HUB_UNSPECIFIED if the request failed for other reasons. */ - boolean queryNanoapps(in int contextHubId); + void queryNanoapps(in int contextHubId); /** * Register a callback for the HAL implementation to send asynchronous messages to the service @@ -138,10 +153,11 @@ interface IContextHub { * @param contextHubId The identifier of the Context Hub * @param callback an implementation of the IContextHubCallbacks * - * @return true on success - * + * @throws EX_ILLEGAL_ARGUMENT if any of the arguments are invalid. + * EX_SERVICE_SPECIFIC on error + * - EX_CONTEXT_HUB_UNSPECIFIED if the request failed for other reasons. */ - boolean registerCallback(in int contextHubId, in IContextHubCallback cb); + void registerCallback(in int contextHubId, in IContextHubCallback cb); /** * Sends a message targeted to a nanoapp to the Context Hub. @@ -149,9 +165,11 @@ interface IContextHub { * @param contextHubId The identifier of the Context Hub * @param message The message to be sent * - * @return true on success + * @throws EX_ILLEGAL_ARGUMENT if any of the arguments are invalid. + * EX_SERVICE_SPECIFIC on error + * - EX_CONTEXT_HUB_UNSPECIFIED if the request failed for other reasons. */ - boolean sendMessageToHub(in int contextHubId, in ContextHubMessage message); + void sendMessageToHub(in int contextHubId, in ContextHubMessage message); /** * Invoked when a host endpoint has connected with the ContextHubService. @@ -173,8 +191,13 @@ interface IContextHub { * * @param hostEndPointId The ID of the host that has disconnected. * - * @return Status::ok on success - * EX_ILLEGAL_ARGUMENT if hostEndpointId is not associated with a connected host. + * @throws EX_ILLEGAL_ARGUMENT if hostEndpointId is not associated with a connected host. */ void onHostEndpointDisconnected(char hostEndpointId); + + /** + * Error codes that are used as service specific errors with the AIDL return + * value EX_SERVICE_SPECIFIC. + */ + const int EX_CONTEXT_HUB_UNSPECIFIED = -1; } diff --git a/contexthub/aidl/default/ContextHub.cpp b/contexthub/aidl/default/ContextHub.cpp index 6da690da4f..4c23cbc8bf 100644 --- a/contexthub/aidl/default/ContextHub.cpp +++ b/contexthub/aidl/default/ContextHub.cpp @@ -21,7 +21,9 @@ namespace android { namespace hardware { namespace contexthub { -::ndk::ScopedAStatus ContextHub::getContextHubs(std::vector<ContextHubInfo>* out_contextHubInfos) { +using ::ndk::ScopedAStatus; + +ScopedAStatus ContextHub::getContextHubs(std::vector<ContextHubInfo>* out_contextHubInfos) { ContextHubInfo hub = {}; hub.name = "Mock Context Hub"; hub.vendor = "AOSP"; @@ -39,85 +41,70 @@ namespace contexthub { } // We don't expose any nanoapps for the default impl, therefore all nanoapp-related APIs fail. -::ndk::ScopedAStatus ContextHub::loadNanoapp(int32_t /* in_contextHubId */, - const NanoappBinary& /* in_appBinary */, - int32_t /* in_transactionId */, bool* _aidl_return) { - *_aidl_return = false; - return ndk::ScopedAStatus::ok(); +ScopedAStatus ContextHub::loadNanoapp(int32_t /* in_contextHubId */, + const NanoappBinary& /* in_appBinary */, + int32_t /* in_transactionId */) { + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } -::ndk::ScopedAStatus ContextHub::unloadNanoapp(int32_t /* in_contextHubId */, - int64_t /* in_appId */, - int32_t /* in_transactionId */, bool* _aidl_return) { - *_aidl_return = false; - return ndk::ScopedAStatus::ok(); +ScopedAStatus ContextHub::unloadNanoapp(int32_t /* in_contextHubId */, int64_t /* in_appId */, + int32_t /* in_transactionId */) { + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } -::ndk::ScopedAStatus ContextHub::disableNanoapp(int32_t /* in_contextHubId */, - int64_t /* in_appId */, - int32_t /* in_transactionId */, - bool* _aidl_return) { - *_aidl_return = false; - return ndk::ScopedAStatus::ok(); +ScopedAStatus ContextHub::disableNanoapp(int32_t /* in_contextHubId */, int64_t /* in_appId */, + int32_t /* in_transactionId */) { + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } -::ndk::ScopedAStatus ContextHub::enableNanoapp(int32_t /* in_contextHubId */, - int64_t /* in_appId */, - int32_t /* in_transactionId */, bool* _aidl_return) { - *_aidl_return = false; - return ndk::ScopedAStatus::ok(); +ScopedAStatus ContextHub::enableNanoapp(int32_t /* in_contextHubId */, int64_t /* in_appId */, + int32_t /* in_transactionId */) { + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } -::ndk::ScopedAStatus ContextHub::onSettingChanged(Setting /* in_setting */, bool /*in_enabled */) { +ScopedAStatus ContextHub::onSettingChanged(Setting /* in_setting */, bool /*in_enabled */) { return ndk::ScopedAStatus::ok(); } -::ndk::ScopedAStatus ContextHub::queryNanoapps(int32_t in_contextHubId, bool* _aidl_return) { +ScopedAStatus ContextHub::queryNanoapps(int32_t in_contextHubId) { if (in_contextHubId == kMockHubId && mCallback != nullptr) { std::vector<NanoappInfo> nanoapps; mCallback->handleNanoappInfo(nanoapps); - *_aidl_return = true; + return ndk::ScopedAStatus::ok(); } else { - *_aidl_return = false; + return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } - - return ndk::ScopedAStatus::ok(); } -::ndk::ScopedAStatus ContextHub::registerCallback(int32_t in_contextHubId, - const std::shared_ptr<IContextHubCallback>& in_cb, - bool* _aidl_return) { +ScopedAStatus ContextHub::registerCallback(int32_t in_contextHubId, + const std::shared_ptr<IContextHubCallback>& in_cb) { if (in_contextHubId == kMockHubId) { mCallback = in_cb; - *_aidl_return = true; + return ndk::ScopedAStatus::ok(); } else { - *_aidl_return = false; + return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } - return ndk::ScopedAStatus::ok(); } -::ndk::ScopedAStatus ContextHub::sendMessageToHub(int32_t in_contextHubId, - const ContextHubMessage& /* in_message */, - bool* _aidl_return) { +ScopedAStatus ContextHub::sendMessageToHub(int32_t in_contextHubId, + const ContextHubMessage& /* in_message */) { if (in_contextHubId == kMockHubId) { // Return true here to indicate that the HAL has accepted the message. // Successful delivery of the message to a nanoapp should be handled at // a higher level protocol. - *_aidl_return = true; + return ndk::ScopedAStatus::ok(); } else { - *_aidl_return = false; + return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } - - return ndk::ScopedAStatus::ok(); } -::ndk::ScopedAStatus ContextHub::onHostEndpointConnected(const HostEndpointInfo& in_info) { +ScopedAStatus ContextHub::onHostEndpointConnected(const HostEndpointInfo& in_info) { mConnectedHostEndpoints.insert(in_info.hostEndpointId); return ndk::ScopedAStatus::ok(); } -::ndk::ScopedAStatus ContextHub::onHostEndpointDisconnected(char16_t in_hostEndpointId) { +ScopedAStatus ContextHub::onHostEndpointDisconnected(char16_t in_hostEndpointId) { if (mConnectedHostEndpoints.count(in_hostEndpointId) > 0) { mConnectedHostEndpoints.erase(in_hostEndpointId); return ndk::ScopedAStatus::ok(); diff --git a/contexthub/aidl/default/include/contexthub-impl/ContextHub.h b/contexthub/aidl/default/include/contexthub-impl/ContextHub.h index dd739e63f8..03d8432134 100644 --- a/contexthub/aidl/default/include/contexthub-impl/ContextHub.h +++ b/contexthub/aidl/default/include/contexthub-impl/ContextHub.h @@ -28,21 +28,19 @@ namespace contexthub { class ContextHub : public BnContextHub { ::ndk::ScopedAStatus getContextHubs(std::vector<ContextHubInfo>* out_contextHubInfos) override; ::ndk::ScopedAStatus loadNanoapp(int32_t in_contextHubId, const NanoappBinary& in_appBinary, - int32_t in_transactionId, bool* _aidl_return) override; + int32_t in_transactionId) override; ::ndk::ScopedAStatus unloadNanoapp(int32_t in_contextHubId, int64_t in_appId, - int32_t in_transactionId, bool* _aidl_return) override; + int32_t in_transactionId) override; ::ndk::ScopedAStatus disableNanoapp(int32_t in_contextHubId, int64_t in_appId, - int32_t in_transactionId, bool* _aidl_return) override; + int32_t in_transactionId) override; ::ndk::ScopedAStatus enableNanoapp(int32_t in_contextHubId, int64_t in_appId, - int32_t in_transactionId, bool* _aidl_return) override; + int32_t in_transactionId) override; ::ndk::ScopedAStatus onSettingChanged(Setting in_setting, bool in_enabled) override; - ::ndk::ScopedAStatus queryNanoapps(int32_t in_contextHubId, bool* _aidl_return) override; - ::ndk::ScopedAStatus registerCallback(int32_t in_contextHubId, - const std::shared_ptr<IContextHubCallback>& in_cb, - bool* _aidl_return) override; + ::ndk::ScopedAStatus queryNanoapps(int32_t in_contextHubId) override; + ::ndk::ScopedAStatus registerCallback( + int32_t in_contextHubId, const std::shared_ptr<IContextHubCallback>& in_cb) override; ::ndk::ScopedAStatus sendMessageToHub(int32_t in_contextHubId, - const ContextHubMessage& in_message, - bool* _aidl_return) override; + const ContextHubMessage& in_message) override; ::ndk::ScopedAStatus onHostEndpointConnected(const HostEndpointInfo& in_info) override; ::ndk::ScopedAStatus onHostEndpointDisconnected(char16_t in_hostEndpointId) override; diff --git a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp index 392e23c9c1..a47f64e5be 100644 --- a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp +++ b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp @@ -103,15 +103,12 @@ class EmptyContextHubCallback : public android::hardware::contexthub::BnContextH }; TEST_P(ContextHubAidl, TestRegisterCallback) { - bool success; sp<EmptyContextHubCallback> cb = sp<EmptyContextHubCallback>::make(); - ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb, &success).isOk()); - ASSERT_TRUE(success); + ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb).isOk()); } TEST_P(ContextHubAidl, TestRegisterNullCallback) { - bool success; - ASSERT_TRUE(contextHub->registerCallback(getHubId(), nullptr, &success).isOk()); + ASSERT_TRUE(contextHub->registerCallback(getHubId(), nullptr).isOk()); } // Helper callback that puts the async appInfo callback data into a promise @@ -140,12 +137,8 @@ class QueryAppsCallback : public android::hardware::contexthub::BnContextHubCall // Calls queryApps() and checks the returned metadata TEST_P(ContextHubAidl, TestQueryApps) { sp<QueryAppsCallback> cb = sp<QueryAppsCallback>::make(); - bool success; - ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb, &success).isOk()); - ASSERT_TRUE(success); - - ASSERT_TRUE(contextHub->queryNanoapps(getHubId(), &success).isOk()); - ASSERT_TRUE(success); + ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb).isOk()); + ASSERT_TRUE(contextHub->queryNanoapps(getHubId()).isOk()); std::vector<NanoappInfo> appInfoList; ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &appInfoList)); @@ -197,9 +190,7 @@ class ContextHubTransactionTest : public ContextHubAidl { public: virtual void SetUp() override { ContextHubAidl::SetUp(); - bool success; - ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb, &success).isOk()); - ASSERT_TRUE(success); + ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb).isOk()); } sp<TransactionResultCallback> cb = sp<TransactionResultCallback>::make(); @@ -213,9 +204,7 @@ TEST_P(ContextHubTransactionTest, TestSendMessageToNonExistentNanoapp) { std::fill(message.messageBody.begin(), message.messageBody.end(), 0); ALOGD("Sending message to non-existent nanoapp"); - bool success; - ASSERT_TRUE(contextHub->sendMessageToHub(getHubId(), message, &success).isOk()); - ASSERT_TRUE(success); + ASSERT_TRUE(contextHub->sendMessageToHub(getHubId(), message).isOk()); } TEST_P(ContextHubTransactionTest, TestLoadEmptyNanoapp) { @@ -229,9 +218,7 @@ TEST_P(ContextHubTransactionTest, TestLoadEmptyNanoapp) { emptyApp.targetChreApiMinorVersion = 0; ALOGD("Loading empty nanoapp"); - bool success; - ASSERT_TRUE(contextHub->loadNanoapp(getHubId(), emptyApp, cb->expectedTransactionId, &success) - .isOk()); + bool success = contextHub->loadNanoapp(getHubId(), emptyApp, cb->expectedTransactionId).isOk(); if (success) { bool transactionSuccess; ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &transactionSuccess)); @@ -243,11 +230,9 @@ TEST_P(ContextHubTransactionTest, TestUnloadNonexistentNanoapp) { cb->expectedTransactionId = 1234; ALOGD("Unloading nonexistent nanoapp"); - bool success; - ASSERT_TRUE(contextHub - ->unloadNanoapp(getHubId(), kNonExistentAppId, cb->expectedTransactionId, - &success) - .isOk()); + bool success = + contextHub->unloadNanoapp(getHubId(), kNonExistentAppId, cb->expectedTransactionId) + .isOk(); if (success) { bool transactionSuccess; ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &transactionSuccess)); @@ -259,11 +244,9 @@ TEST_P(ContextHubTransactionTest, TestEnableNonexistentNanoapp) { cb->expectedTransactionId = 2345; ALOGD("Enabling nonexistent nanoapp"); - bool success; - ASSERT_TRUE(contextHub - ->enableNanoapp(getHubId(), kNonExistentAppId, cb->expectedTransactionId, - &success) - .isOk()); + bool success = + contextHub->enableNanoapp(getHubId(), kNonExistentAppId, cb->expectedTransactionId) + .isOk(); if (success) { bool transactionSuccess; ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &transactionSuccess)); @@ -275,11 +258,9 @@ TEST_P(ContextHubTransactionTest, TestDisableNonexistentNanoapp) { cb->expectedTransactionId = 3456; ALOGD("Disabling nonexistent nanoapp"); - bool success; - ASSERT_TRUE(contextHub - ->disableNanoapp(getHubId(), kNonExistentAppId, cb->expectedTransactionId, - &success) - .isOk()); + bool success = + contextHub->disableNanoapp(getHubId(), kNonExistentAppId, cb->expectedTransactionId) + .isOk(); if (success) { bool transactionSuccess; ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &transactionSuccess)); @@ -290,16 +271,13 @@ TEST_P(ContextHubTransactionTest, TestDisableNonexistentNanoapp) { void ContextHubAidl::testSettingChanged(Setting setting) { // In VTS, we only test that sending the values doesn't cause things to blow up - GTS tests // verify the expected E2E behavior in CHRE - bool success; sp<EmptyContextHubCallback> cb = sp<EmptyContextHubCallback>::make(); - ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb, &success).isOk()); - ASSERT_TRUE(success); + ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb).isOk()); ASSERT_TRUE(contextHub->onSettingChanged(setting, true /* enabled */).isOk()); ASSERT_TRUE(contextHub->onSettingChanged(setting, false /* enabled */).isOk()); - ASSERT_TRUE(contextHub->registerCallback(getHubId(), nullptr, &success).isOk()); - ASSERT_TRUE(success); + ASSERT_TRUE(contextHub->registerCallback(getHubId(), nullptr).isOk()); } TEST_P(ContextHubAidl, TestOnLocationSettingChanged) { diff --git a/current.txt b/current.txt index 1dbf5ab1be..1fedaa0d6e 100644 --- a/current.txt +++ b/current.txt @@ -907,6 +907,7 @@ c8a57364f6ad20842be14f4db284df5304f7521ca8eac6bcc1fa6c5b466fb8a6 android.hardwar # ABI preserving changes to HALs during Android T 62ace52d9c3ff1f60f94118557a2aaf0b953513e59dcd34d5f94ae28d4c7e780 android.hardware.fastboot@1.0::IFastboot f767a132ef28275294db15353f14f3876a4048770751931a77d038d4228f2cb7 android.hardware.graphics.composer@2.4::IComposerClient +d0fb32f3ddeb9af7115ab32905225ea69b930d2472be8e9610f0cf136c15aefb android.hardware.keymaster@4.0::IKeymasterDevice # b/210424594 ca62a2a95d173ed323309e5e00f653ad3cceec82a6e5e4976a249cb5aafe2515 android.hardware.neuralnetworks@1.2::types fa76bced6b1b71c40fc706c508a9011284c57f57831cd0cf5f45653ed4ea463e android.hardware.neuralnetworks@1.3::types diff --git a/drm/aidl/Android.bp b/drm/aidl/Android.bp new file mode 100644 index 0000000000..d8500ec3b2 --- /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 0000000000..b6ec34d897 --- /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 0000000000..d2b48d2b98 --- /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 0000000000..4f2d133cae --- /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 0000000000..c78dff0b16 --- /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 0000000000..4128eaa54d --- /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 0000000000..76ec35c0cf --- /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 0000000000..806491357c --- /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 0000000000..80ebb285ae --- /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 0000000000..5704fb0726 --- /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 0000000000..a6f86ace67 --- /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 0000000000..0d4296ec1f --- /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 0000000000..2224795198 --- /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 0000000000..af48737892 --- /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 0000000000..5f839d763c --- /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 0000000000..0a4b4b70bc --- /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 0000000000..267f532755 --- /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 0000000000..34b9615c55 --- /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 0000000000..58dfe1a412 --- /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 0000000000..53ab70f0fb --- /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 0000000000..e88d3886a2 --- /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 0000000000..7a9d633578 --- /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 0000000000..35d7b77bc9 --- /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 0000000000..93f76e1c41 --- /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 0000000000..83362c359f --- /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 0000000000..7379774093 --- /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 0000000000..a421125fc3 --- /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 0000000000..629564d706 --- /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 0000000000..3085889faf --- /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 0000000000..b01562e67e --- /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 0000000000..827de59093 --- /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 0000000000..84c56621f2 --- /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 0000000000..81d2dfe75c --- /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 0000000000..2b904c8629 --- /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 0000000000..65b2b9d2ae --- /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 0000000000..973ef0db3d --- /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 0000000000..c64068958f --- /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 0000000000..57d815eeb2 --- /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 0000000000..ec2eb164c9 --- /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 0000000000..089c950656 --- /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 0000000000..17e939bc95 --- /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 0000000000..0f1e3f5398 --- /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 0000000000..6199af6d4d --- /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 0000000000..3b1f3c9b0e --- /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 0000000000..5bb17a6036 --- /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 0000000000..0203f3f801 --- /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 0000000000..7a06eb0505 --- /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 0000000000..3497b78431 --- /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 0000000000..cd4642ba42 --- /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 0000000000..202bd3dbfe --- /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 0000000000..80a63dfdae --- /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 0000000000..b9622a427b --- /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 0000000000..e649f264ea --- /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 0000000000..d52da66742 --- /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 0000000000..0c732055f2 --- /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 0000000000..3a603ff6c8 --- /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 0000000000..be0ce0efa8 --- /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 0000000000..16e042a147 --- /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 0000000000..6902d8708c --- /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 0000000000..78b4d8369c --- /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 0000000000..e26781b58b --- /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 0000000000..8ac1ced585 --- /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 0000000000..4db3b40982 --- /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 0000000000..6fc00651a8 --- /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 0000000000..75b7c2ece8 --- /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 0000000000..0f447db2fa --- /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 0000000000..6b2a2e79c0 --- /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 0000000000..88d22cf221 --- /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 0000000000..e9f1e2b956 --- /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 0000000000..eb42d32c87 --- /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 0000000000..37cfbd39ab --- /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 0000000000..775e60b391 --- /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 0000000000..aac1b686f3 --- /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 0000000000..69772840ba --- /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 0000000000..ee57d64608 --- /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 0000000000..68a8fb1123 --- /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 0000000000..b36c409c66 --- /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/dumpstate/aidl/android/hardware/dumpstate/IDumpstateDevice.aidl b/dumpstate/aidl/android/hardware/dumpstate/IDumpstateDevice.aidl index 3b42546a46..b994d04e0c 100644 --- a/dumpstate/aidl/android/hardware/dumpstate/IDumpstateDevice.aidl +++ b/dumpstate/aidl/android/hardware/dumpstate/IDumpstateDevice.aidl @@ -103,8 +103,9 @@ interface IDumpstateDevice { * @param timeoutMillis An approximate "budget" for how much time this call has been allotted. * If execution runs longer than this, the IDumpstateDevice service may be killed and only * partial information will be included in the report. - * @return If error, return service specific error with code - * ERROR_UNSUPPORTED_MODE or ERROR_DEVICE_LOGGING_NOT_ENABLED + * @throws ServiceSpecificException with one of the following values: + * |ERROR_UNSUPPORTED_MODE|, + * |ERROR_DEVICE_LOGGING_NOT_ENABLED| */ void dumpstateBoard(in ParcelFileDescriptor[] fd, in DumpstateMode mode, in long timeoutMillis); diff --git a/gnss/1.1/vts/functional/Android.bp b/gnss/1.1/vts/functional/Android.bp index c59d5e7a64..f8fad94a34 100644 --- a/gnss/1.1/vts/functional/Android.bp +++ b/gnss/1.1/vts/functional/Android.bp @@ -36,6 +36,7 @@ cc_test { "android.hardware.gnss@1.1", "android.hardware.gnss@2.0", "android.hardware.gnss@common-vts-lib", + "android.hardware.gnss-V2-cpp", ], shared_libs: [ "android.hardware.gnss.measurement_corrections@1.0", diff --git a/gnss/2.0/vts/functional/Android.bp b/gnss/2.0/vts/functional/Android.bp index 3bbd572841..2042dd9f17 100644 --- a/gnss/2.0/vts/functional/Android.bp +++ b/gnss/2.0/vts/functional/Android.bp @@ -39,6 +39,10 @@ cc_test { "android.hardware.gnss@2.0", "android.hardware.gnss@2.1", "android.hardware.gnss@common-vts-lib", + "android.hardware.gnss-V2-cpp", + ], + test_suites: [ + "general-tests", + "vts", ], - test_suites: ["general-tests", "vts"], } diff --git a/gnss/2.1/vts/functional/Android.bp b/gnss/2.1/vts/functional/Android.bp index aaddd96f8c..d7b6eebbe9 100644 --- a/gnss/2.1/vts/functional/Android.bp +++ b/gnss/2.1/vts/functional/Android.bp @@ -40,6 +40,7 @@ cc_test { "android.hardware.gnss@2.0", "android.hardware.gnss@2.1", "android.hardware.gnss@common-vts-lib", + "android.hardware.gnss-V2-cpp", ], shared_libs: [ "libvintf", diff --git a/gnss/aidl/Android.bp b/gnss/aidl/Android.bp index 12dd0ac16e..4d9c5cc231 100644 --- a/gnss/aidl/Android.bp +++ b/gnss/aidl/Android.bp @@ -24,27 +24,13 @@ package { } aidl_interface { - name: "android.hardware.gnss.visibility_control", - vendor_available: true, - srcs: ["android/hardware/gnss/visibility_control/*.aidl"], - stability: "vintf", - backend: { - java: { - platform_apis: true, - }, - ndk: { - vndk: { - enabled: true, - }, - }, - }, -} - -aidl_interface { name: "android.hardware.gnss", vendor_available: true, - srcs: ["android/hardware/gnss/*.aidl"], - imports: ["android.hardware.gnss.visibility_control"], + srcs: [ + "android/hardware/gnss/*.aidl", + "android/hardware/gnss/measurement_corrections/*.aidl", + "android/hardware/gnss/visibility_control/*.aidl", + ], stability: "vintf", backend: { java: { diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl index ebb5d0bdff..aa514da38c 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl @@ -37,4 +37,11 @@ parcelable GnssData { android.hardware.gnss.GnssMeasurement[] measurements; android.hardware.gnss.GnssClock clock; android.hardware.gnss.ElapsedRealtime elapsedRealtime; + @nullable android.hardware.gnss.GnssData.GnssAgc[] gnssAgcs; + @VintfStability + parcelable GnssAgc { + double agcLevelDb; + android.hardware.gnss.GnssConstellationType constellation = android.hardware.gnss.GnssConstellationType.UNKNOWN; + long carrierFrequencyHz; + } } 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 1b4c5817ce..fb13e026bb 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 @@ -53,6 +53,8 @@ interface IGnss { 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); + android.hardware.gnss.IGnssAntennaInfo getExtensionGnssAntennaInfo(); + @nullable android.hardware.gnss.measurement_corrections.IMeasurementCorrectionsInterface getExtensionMeasurementCorrections(); const int ERROR_INVALID_ARGUMENT = 1; const int ERROR_ALREADY_INIT = 2; const int ERROR_GENERIC = 3; diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssAntennaInfo.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssAntennaInfo.aidl new file mode 100644 index 0000000000..2734ac1d69 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssAntennaInfo.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.gnss; +@VintfStability +interface IGnssAntennaInfo { + void setCallback(in android.hardware.gnss.IGnssAntennaInfoCallback callback); + void close(); +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssAntennaInfoCallback.aidl index 3c40ad63bf..ada97077e7 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssAntennaInfoCallback.aidl @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 The Android Open Source Project + * 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. @@ -31,23 +31,30 @@ // with such a backward incompatible change, it has a high risk of breaking // later when a module using the interface is updated, e.g., Mainline modules. -package android.hardware.biometrics.fingerprint; +package android.hardware.gnss; @VintfStability -interface ISessionCallback { - void onChallengeGenerated(in long challenge); - void onChallengeRevoked(in long challenge); - void onAcquired(in android.hardware.biometrics.fingerprint.AcquiredInfo info, in int vendorCode); - void onError(in android.hardware.biometrics.fingerprint.Error error, in int vendorCode); - void onEnrollmentProgress(in int enrollmentId, int remaining); - void onAuthenticationSucceeded(in int enrollmentId, in android.hardware.keymaster.HardwareAuthToken hat); - void onAuthenticationFailed(); - void onLockoutTimed(in long durationMillis); - void onLockoutPermanent(); - void onLockoutCleared(); - void onInteractionDetected(); - void onEnrollmentsEnumerated(in int[] enrollmentIds); - void onEnrollmentsRemoved(in int[] enrollmentIds); - void onAuthenticatorIdRetrieved(in long authenticatorId); - void onAuthenticatorIdInvalidated(in long newAuthenticatorId); - void onSessionClosed(); +interface IGnssAntennaInfoCallback { + void gnssAntennaInfoCb(in android.hardware.gnss.IGnssAntennaInfoCallback.GnssAntennaInfo[] gnssAntennaInfos); + @VintfStability + parcelable Row { + double[] row; + } + @VintfStability + parcelable Coord { + double x; + double xUncertainty; + double y; + double yUncertainty; + double z; + double zUncertainty; + } + @VintfStability + parcelable GnssAntennaInfo { + long carrierFrequencyHz; + android.hardware.gnss.IGnssAntennaInfoCallback.Coord phaseCenterOffsetCoordinateMillimeters; + android.hardware.gnss.IGnssAntennaInfoCallback.Row[] phaseCenterVariationCorrectionMillimeters; + android.hardware.gnss.IGnssAntennaInfoCallback.Row[] phaseCenterVariationCorrectionUncertaintyMillimeters; + android.hardware.gnss.IGnssAntennaInfoCallback.Row[] signalGainCorrectionDbi; + android.hardware.gnss.IGnssAntennaInfoCallback.Row[] signalGainCorrectionUncertaintyDbi; + } } diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsCallback.aidl new file mode 100644 index 0000000000..c4cf13f406 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsCallback.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.gnss.measurement_corrections; +@VintfStability +interface IMeasurementCorrectionsCallback { + void setCapabilitiesCb(in int capabilities); + const int CAPABILITY_LOS_SATS = 1; + const int CAPABILITY_EXCESS_PATH_LENGTH = 2; + const int CAPABILITY_REFLECTING_PLANE = 4; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.aidl new file mode 100644 index 0000000000..5dc55960c5 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.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.gnss.measurement_corrections; +@VintfStability +interface IMeasurementCorrectionsInterface { + void setCorrections(in android.hardware.gnss.measurement_corrections.MeasurementCorrections corrections); + void setCallback(in android.hardware.gnss.measurement_corrections.IMeasurementCorrectionsCallback callback); +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorProps.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/MeasurementCorrections.aidl index 782d2899d3..f32c8c27bf 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorProps.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/MeasurementCorrections.aidl @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 The Android Open Source Project + * 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. @@ -31,14 +31,17 @@ // with such a backward incompatible change, it has a high risk of breaking // later when a module using the interface is updated, e.g., Mainline modules. -package android.hardware.biometrics.fingerprint; +package android.hardware.gnss.measurement_corrections; @VintfStability -parcelable SensorProps { - android.hardware.biometrics.common.CommonProps commonProps; - android.hardware.biometrics.fingerprint.FingerprintSensorType sensorType = android.hardware.biometrics.fingerprint.FingerprintSensorType.UNKNOWN; - android.hardware.biometrics.fingerprint.SensorLocation[] sensorLocations; - boolean supportsNavigationGestures; - boolean supportsDetectInteraction; - boolean halHandlesDisplayTouches; - boolean halControlsIllumination; +parcelable MeasurementCorrections { + double latitudeDegrees; + double longitudeDegrees; + double altitudeMeters; + double horizontalPositionUncertaintyMeters; + double verticalPositionUncertaintyMeters; + long toaGpsNanosecondsOfWeek; + android.hardware.gnss.measurement_corrections.SingleSatCorrection[] satCorrections; + boolean hasEnvironmentBearing; + float environmentBearingDegrees; + float environmentBearingUncertaintyDegrees; } diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl new file mode 100644 index 0000000000..90c3818b1c --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/ReflectingPlane.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.gnss.measurement_corrections; +@VintfStability +parcelable ReflectingPlane { + double latitudeDegrees; + double longitudeDegrees; + double altitudeMeters; + double azimuthDegrees; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl new file mode 100644 index 0000000000..d18c1a7339 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl @@ -0,0 +1,49 @@ +/* + * 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.gnss.measurement_corrections; +@VintfStability +parcelable SingleSatCorrection { + int singleSatCorrectionFlags; + android.hardware.gnss.GnssConstellationType constellation; + int svid; + long carrierFrequencyHz; + float probSatIsLos; + float excessPathLengthMeters; + float excessPathLengthUncertaintyMeters; + android.hardware.gnss.measurement_corrections.ReflectingPlane reflectingPlane; + const int SINGLE_SAT_CORRECTION_HAS_SAT_IS_LOS_PROBABILITY = 1; + const int SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH = 2; + const int SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH_UNC = 4; + const int SINGLE_SAT_CORRECTION_HAS_REFLECTING_PLANE = 8; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss.visibility_control/current/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl index 7ef08d2f52..f6740992c4 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss.visibility_control/current/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl @@ -34,6 +34,6 @@ package android.hardware.gnss.visibility_control; @VintfStability interface IGnssVisibilityControl { - void enableNfwLocationAccess(in String[] proxyApps); + void enableNfwLocationAccess(in @utf8InCpp String[] proxyApps); void setCallback(in android.hardware.gnss.visibility_control.IGnssVisibilityControlCallback callback); } diff --git a/gnss/aidl/aidl_api/android.hardware.gnss.visibility_control/current/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.aidl index 37e1886576..37e1886576 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss.visibility_control/current/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.aidl diff --git a/gnss/aidl/android/hardware/gnss/GnssData.aidl b/gnss/aidl/android/hardware/gnss/GnssData.aidl index ed30c989f8..204eb65e6b 100644 --- a/gnss/aidl/android/hardware/gnss/GnssData.aidl +++ b/gnss/aidl/android/hardware/gnss/GnssData.aidl @@ -18,6 +18,7 @@ package android.hardware.gnss; import android.hardware.gnss.ElapsedRealtime; import android.hardware.gnss.GnssClock; +import android.hardware.gnss.GnssConstellationType; import android.hardware.gnss.GnssMeasurement; /** @@ -41,4 +42,55 @@ parcelable GnssData { * clock. */ ElapsedRealtime elapsedRealtime; -}
\ No newline at end of file + + /** + * Represents a reading of GNSS AGC value of a constellation type and a frequency band. + */ + @VintfStability + parcelable GnssAgc { + /** + * Automatic gain control (AGC) level. AGC acts as a variable gain amplifier adjusting the + * power of the incoming signal. The AGC level may be used to indicate potential + * interference. Higher gain (and/or lower input power) must be output as a positive number. + * Hence in cases of strong jamming, in the band of this signal, this value must go more + * negative. This value must be consistent given the same level of the incoming signal + * power. + * + * Note: Different hardware designs (e.g. antenna, pre-amplification, or other RF HW + * components) may also affect the typical output of this value on any given hardware design + * in an open sky test - the important aspect of this output is that changes in this value + * are indicative of changes on input signal power in the frequency band for this + * measurement. + */ + double agcLevelDb; + + /** + * Constellation type of the SV that transmits the signal. + */ + GnssConstellationType constellation = GnssConstellationType.UNKNOWN; + + /** + * 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 not set, 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 raw measurement structs must be reported for this same + * satellite, in one of the measurement structs, all the values related + * to L1 must be filled, and in the other all of the values related to + * L5 must be filled. + */ + long carrierFrequencyHz; + } + + /** + * The array of GNSS AGC values. + * + * This field must be reported when the GNSS measurement engine is running, even when the + * GnssMeasurement or GnssClock fields are not reported yet. E.g., when a GNSS signal is too + * weak to be acquired, the AGC value must still be reported. + */ + @nullable GnssAgc[] gnssAgcs; +} diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl index 4ddc6a6193..1e1c0fab96 100644 --- a/gnss/aidl/android/hardware/gnss/IGnss.aidl +++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl @@ -18,6 +18,7 @@ package android.hardware.gnss; import android.hardware.gnss.GnssLocation; import android.hardware.gnss.IAGnss; +import android.hardware.gnss.IGnssAntennaInfo; import android.hardware.gnss.IGnssBatching; import android.hardware.gnss.IGnssCallback; import android.hardware.gnss.IGnssConfiguration; @@ -27,6 +28,7 @@ import android.hardware.gnss.IGnssMeasurementInterface; import android.hardware.gnss.IGnssNavigationMessageInterface; import android.hardware.gnss.IGnssPowerIndication; import android.hardware.gnss.IGnssPsds; +import android.hardware.gnss.measurement_corrections.IMeasurementCorrectionsInterface; import android.hardware.gnss.visibility_control.IGnssVisibilityControl; /** @@ -277,4 +279,18 @@ interface IGnss { void setPositionMode(in GnssPositionMode mode, in GnssPositionRecurrence recurrence, in int minIntervalMs, in int preferredAccuracyMeters, in int preferredTimeMs, in boolean lowPowerMode); + + /* + * This method returns the IGnssAntennaInfo. + * + * @return Handle to the IGnssAntennaInfo. + */ + IGnssAntennaInfo getExtensionGnssAntennaInfo(); + + /** + * This method returns the IMeasurementCorrectionsInterface. + * + * @return Handle to the IMeasurementCorrectionsInterface. + */ + @nullable IMeasurementCorrectionsInterface getExtensionMeasurementCorrections(); } diff --git a/gnss/aidl/android/hardware/gnss/IGnssAntennaInfo.aidl b/gnss/aidl/android/hardware/gnss/IGnssAntennaInfo.aidl new file mode 100644 index 0000000000..de83b67bd6 --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/IGnssAntennaInfo.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. + */ + +package android.hardware.gnss; + +import android.hardware.gnss.IGnssAntennaInfoCallback; + +/** + * Extended interface for GNSS antenna information support. + */ +@VintfStability +interface IGnssAntennaInfo { + /** + * Registers the callback routines with the HAL. + * + * @param callback Handle to the GnssAntennaInfo callback interface. + */ + void setCallback(in IGnssAntennaInfoCallback callback); + + /** + * Stops updates from the HAL, and unregisters the callback routines. + * After a call to close(), the previously registered callbacks must be + * considered invalid by the HAL. + * If close() is invoked without a previous setCallback, this function must perform + * no work. + */ + void close(); +} diff --git a/gnss/aidl/android/hardware/gnss/IGnssAntennaInfoCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssAntennaInfoCallback.aidl new file mode 100644 index 0000000000..ef0a7fc6fd --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/IGnssAntennaInfoCallback.aidl @@ -0,0 +1,140 @@ +/* + * 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.gnss; + +/** + * The callback interface to report GNSS antenna information from the HAL. + */ +@VintfStability +interface IGnssAntennaInfoCallback { + /** + * A row of doubles. This is used to represent a row in a 2D array, which are used to + * characterize the phase center variation corrections and signal gain corrections. + */ + @VintfStability + parcelable Row { + double[] row; + } + + /** + * A point in 3D space, with associated uncertainty. + */ + @VintfStability + parcelable Coord { + double x; + + double xUncertainty; + + double y; + + double yUncertainty; + + double z; + + double zUncertainty; + } + + @VintfStability + parcelable GnssAntennaInfo { + /** + * The carrier frequency in Hz. + */ + long carrierFrequencyHz; + + /** + * Phase center offset (PCO) with associated 1-sigma uncertainty. PCO is defined with + * respect to the origin of the Android sensor coordinate system, e.g., center of primary + * screen for mobiles - see sensor or form factor documents for details. + */ + Coord phaseCenterOffsetCoordinateMillimeters; + + /** + * 2D vectors representing the phase center variation (PCV) corrections, in + * millimeters, at regularly spaced azimuthal angle (theta) and zenith angle + * (phi). The PCV correction is added to the phase measurement to obtain the + * corrected value. + * + * The azimuthal angle, theta, is defined with respect to the X axis of the + * Android sensor coordinate system, increasing toward the Y axis. The zenith + * angle, phi, is defined with respect to the Z axis of the Android Sensor + * coordinate system, increasing toward the X-Y plane. + * + * Each row vector (outer vectors) represents a fixed theta. The first row + * corresponds to a theta angle of 0 degrees. The last row corresponds to a + * theta angle of (360 - deltaTheta) degrees, where deltaTheta is the regular + * spacing between azimuthal angles, i.e., deltaTheta = 360 / (number of rows). + * + * The columns (inner vectors) represent fixed zenith angles, beginning at 0 + * degrees and ending at 180 degrees. They are separated by deltaPhi, the regular + * spacing between zenith angles, i.e., deltaPhi = 180 / (number of columns - 1). + * + * This field is optional, i.e., an empty vector. + */ + Row[] phaseCenterVariationCorrectionMillimeters; + + /** + * 2D vectors of 1-sigma uncertainty in millimeters associated with the PCV + * correction values. + * + * This field is optional, i.e., an empty vector. + */ + Row[] phaseCenterVariationCorrectionUncertaintyMillimeters; + + /** + * 2D vectors representing the signal gain corrections at regularly spaced + * azimuthal angle (theta) and zenith angle (phi). The values are calculated or + * measured at the antenna feed point without considering the radio and receiver + * noise figure and path loss contribution, in dBi, i.e., decibel over isotropic + * antenna with the same total power. The signal gain correction is added the + * signal gain measurement to obtain the corrected value. + * + * The azimuthal angle, theta, is defined with respect to the X axis of the + * Android sensor coordinate system, increasing toward the Y axis. The zenith + * angle, phi, is defined with respect to the Z axis of the Android Sensor + * coordinate system, increasing toward the X-Y plane. + * + * Each row vector (outer vectors) represents a fixed theta. The first row + * corresponds to a theta angle of 0 degrees. The last row corresponds to a + * theta angle of (360 - deltaTheta) degrees, where deltaTheta is the regular + * spacing between azimuthal angles, i.e., deltaTheta = 360 / (number of rows). + * + * The columns (inner vectors) represent fixed zenith angles, beginning at 0 + * degrees and ending at 180 degrees. They are separated by deltaPhi, the regular + * spacing between zenith angles, i.e., deltaPhi = 180 / (number of columns - 1). + * + * This field is optional, i.e., an empty vector. + */ + Row[] signalGainCorrectionDbi; + + /** + * 2D vectors of 1-sigma uncertainty in dBi associated with the signal + * gain correction values. + * + * This field is optional, i.e., an empty vector. + */ + Row[] signalGainCorrectionUncertaintyDbi; + } + + /** + * Called when on connection, and on known-change to these values, such as upon a known + * GNSS RF antenna tuning change, or a foldable device state change. + * + * This is optional. It can never be called if the GNSS antenna information is not + * available. + */ + void gnssAntennaInfoCb(in GnssAntennaInfo[] gnssAntennaInfos); +} diff --git a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl index 157c912054..a74d097ad6 100644 --- a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl +++ b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl @@ -67,7 +67,7 @@ interface IGnssCallback { /** 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 */ + /** Capability bit mask indicating that GNSS supports antenna info */ const int CAPABILITY_ANTENNA_INFO = 1 << 11; /** Capability bit mask indicating that GNSS supports correlation vector */ diff --git a/gnss/aidl/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsCallback.aidl b/gnss/aidl/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsCallback.aidl new file mode 100644 index 0000000000..d695e70451 --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsCallback.aidl @@ -0,0 +1,57 @@ +/* + * 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.gnss.measurement_corrections; + +/** + * GNSS measurement corrections callback interface. + */ +@VintfStability +interface IMeasurementCorrectionsCallback { + /** + * Flags to indicate supported measurement corrections capabilities + * + * Either the LOS_SATS or the EXCESS_PATH_LENGTH capability must be supported. + */ + /** + * Capability bit flag indicating that GNSS supports line-of-sight satellite identification + * measurement corrections + */ + const int CAPABILITY_LOS_SATS = 1 << 0; + /** + * Capability bit flag indicating that GNSS supports per satellite excess-path-length + * measurement corrections + */ + const int CAPABILITY_EXCESS_PATH_LENGTH = 1 << 1; + /** + * Capability bit flag indicating that GNSS supports reflecting planes measurement + * corrections + */ + const int CAPABILITY_REFLECTING_PLANE = 1 << 2; + + /** + * Callback to inform framework the measurement correction specific capabilities of the GNSS + * HAL implementation. + * + * The GNSS HAL must call this method immediately after the framework opens the measurement + * corrections interface. + * + * @param capabilities A bit field of flags indicating the capabilities of measurement + * corrections. + * It is mandatory to support either LOS_STATS or EXCESS_PATH_LENGTH capability. + */ + void setCapabilitiesCb(in int capabilities); +} diff --git a/gnss/aidl/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.aidl b/gnss/aidl/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.aidl new file mode 100644 index 0000000000..eeabc6d399 --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.aidl @@ -0,0 +1,48 @@ +/* + * 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.gnss.measurement_corrections; + +import android.hardware.gnss.measurement_corrections.IMeasurementCorrectionsCallback; +import android.hardware.gnss.measurement_corrections.MeasurementCorrections; + +/** + * Interface for measurement corrections support. + */ +@VintfStability +interface IMeasurementCorrectionsInterface { + /** + * Injects measurement corrections to be used by the HAL to improve the GNSS location output. + * + * These are NOT to be used to adjust the IGnssMeasurementCallback output values - + * those remain raw, uncorrected measurements. + * + * In general, these are injected when conditions defined by the platform are met, such as when + * GNSS Location is being requested at a sufficiently high accuracy, based on the capabilities + * of the GNSS chipset as reported in the IGnssCallback. + * + * @param corrections The computed corrections to be used by the HAL. + */ + void setCorrections(in MeasurementCorrections corrections); + + /** + * Opens the interface and provides the callback routines to the implementation of this + * interface. + * + * @param callback Callback interface for IMeasurementCorrections. + */ + void setCallback(in IMeasurementCorrectionsCallback callback); +} diff --git a/gnss/aidl/android/hardware/gnss/measurement_corrections/MeasurementCorrections.aidl b/gnss/aidl/android/hardware/gnss/measurement_corrections/MeasurementCorrections.aidl new file mode 100644 index 0000000000..285c7d4faa --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/measurement_corrections/MeasurementCorrections.aidl @@ -0,0 +1,102 @@ +/* + * 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.gnss.measurement_corrections; + +import android.hardware.gnss.measurement_corrections.SingleSatCorrection; + +/** + * A struct containing a set of measurement corrections for all used GNSS satellites at the location + * specified by latitudeDegrees, longitudeDegrees, altitudeMeters and at the time of week specified + * toaGpsNanosecondsOfWeek + */ +@VintfStability +parcelable MeasurementCorrections { + /** Represents latitude in degrees at which the corrections are computed.. */ + double latitudeDegrees; + + /** Represents longitude in degrees at which the corrections are computed.. */ + double longitudeDegrees; + + /** + * Represents altitude in meters above the WGS 84 reference ellipsoid at which the corrections + * are computed. + */ + double altitudeMeters; + + /** + * Represents the horizontal uncertainty (63% to 68% confidence) in meters on the device + * position at which the corrections are provided. + * + * This value is useful for example to judge how accurate the provided corrections are. + */ + double horizontalPositionUncertaintyMeters; + + /** + * Represents the vertical uncertainty (63% to 68% confidence) in meters on the device position + * at which the corrections are provided. + * + * This value is useful for example to judge how accurate the provided corrections are. + */ + double verticalPositionUncertaintyMeters; + + /** Time Of Applicability, GPS time of week in nanoseconds. */ + long toaGpsNanosecondsOfWeek; + + /** + * A set of SingleSatCorrection each containing measurement corrections for a satellite in view + */ + SingleSatCorrection[] satCorrections; + + /** + * Boolean indicating if environment bearing is available. + */ + boolean hasEnvironmentBearing; + + /** + * Environment bearing in degrees clockwise from true North (0.0 to 360.0], in direction of + * user motion. Environment bearing is provided when it is known with high probability that + * velocity is aligned with an environment feature, such as a building or road. + * + * If user speed is zero, environmentBearingDegrees represents bearing of most recent speed + * that was > 0. + * + * As position approaches another road, environmentBearingUncertaintyDegrees will grow, and at + * some stage hasEnvironmentBearing = false. + * + * As position moves towards an open area, environmentBearingUncertaintyDegrees will grow, and + * at some stage hasEnvironmentBearing = false. + * + * If the road is curved in the vicinity of the user location, then + * environmentBearingUncertaintyDegrees will include the amount by which the road direction + * changes in the area of position uncertainty. + * + * hasEnvironmentBearing should be checked to verify the environment bearing is available + * before calling this method. The value is undefined if hasEnvironmentBearing is false. + */ + float environmentBearingDegrees; + + /** + * Environment bearing uncertainty [0 to 180]. It represents the standard deviation of the + * physical structure in the circle of position uncertainty. hasEnvironmentBearing becomes false + * as the uncertainty value passes a predefined threshold depending on the physical structure + * around the user. + * + * hasEnvironmentBearing should be checked to verify the environment bearing is available + * before calling this method. The value is undefined if hasEnvironmentBearing is false. + */ + float environmentBearingUncertaintyDegrees; +} diff --git a/gnss/aidl/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl b/gnss/aidl/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl new file mode 100644 index 0000000000..9bf2b4417d --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/measurement_corrections/ReflectingPlane.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. + */ + +package android.hardware.gnss.measurement_corrections; + +/** + * A struct containing the characteristics of the reflecting plane that the satellite signal has + * bounced from. + * + * The value is only valid if HAS_REFLECTING_PLANE flag is set. An invalid reflecting plane + * means either reflection planes serving is not supported or the satellite signal has gone + * through multiple reflections. + */ +@VintfStability +parcelable ReflectingPlane { + /** Represents latitude of the reflecting plane in degrees. */ + double latitudeDegrees; + + /** Represents longitude of the reflecting plane in degrees. */ + double longitudeDegrees; + + /** + * Represents altitude of the reflecting point in the plane in meters above the WGS 84 reference + * ellipsoid. + */ + double altitudeMeters; + + /** Represents azimuth clockwise from north of the reflecting plane in degrees. */ + double azimuthDegrees; +} diff --git a/gnss/aidl/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl b/gnss/aidl/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl new file mode 100644 index 0000000000..d9f7105170 --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl @@ -0,0 +1,85 @@ +/* + * 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.gnss.measurement_corrections; + +import android.hardware.gnss.GnssConstellationType; +import android.hardware.gnss.measurement_corrections.ReflectingPlane; + +/** + * A struct with measurement corrections for a single visible satellites + * + * The bit mask singleSatCorrectionFlags indicates which correction values are valid in the struct + */ +@VintfStability +parcelable SingleSatCorrection { + /** Bit mask to indicate which values are valid in a SingleSatCorrection object. */ + /** GnssSingleSatCorrectionFlags has valid satellite-is-line-of-sight-probability field. */ + const int SINGLE_SAT_CORRECTION_HAS_SAT_IS_LOS_PROBABILITY = 0x0001; + /** GnssSingleSatCorrectionFlags has valid Excess Path Length field. */ + const int SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH = 0x0002; + /** GnssSingleSatCorrectionFlags has valid Excess Path Length Uncertainty field. */ + const int SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH_UNC = 0x0004; + /** GnssSingleSatCorrectionFlags has valid Reflecting Plane field. */ + const int SINGLE_SAT_CORRECTION_HAS_REFLECTING_PLANE = 0x0008; + + /** Contains GnssSingleSatCorrectionFlags bits. */ + int singleSatCorrectionFlags; + + /** + * Defines the constellation of the given satellite. + */ + GnssConstellationType constellation; + + /** + * Satellite vehicle ID number, as defined in GnssSvInfo::svid + */ + int svid; + + /** + * Carrier frequency of the signal to be corrected, for example it can be the + * GPS center frequency for L1 = 1,575,420,000 Hz, varying GLO channels, etc. + * + * For a receiver with capabilities to track multiple frequencies for the same satellite, + * multiple corrections for the same satellite may be provided. + */ + long carrierFrequencyHz; + + /** + * The probability that the satellite is estimated to be in Line-of-Sight condition at the given + * location. + */ + float probSatIsLos; + + /** + * Excess path length to be subtracted from pseudorange before using it in calculating location. + * + * Note this value is NOT to be used to adjust the GnsseasurementCallback outputs. + */ + float excessPathLengthMeters; + + /** Error estimate (1-sigma) for the Excess path length estimate */ + float excessPathLengthUncertaintyMeters; + + /** + * Defines the reflecting plane characteristics such as location and azimuth + * + * The value is only valid if HAS_REFLECTING_PLANE flag is set. An invalid reflecting plane + * means either reflection planes serving is not supported or the satellite signal has gone + * through multiple reflections. + */ + ReflectingPlane reflectingPlane; +} diff --git a/gnss/aidl/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl b/gnss/aidl/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl index 93c3f2c94f..c9c15491fb 100644 --- a/gnss/aidl/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl +++ b/gnss/aidl/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl @@ -71,7 +71,7 @@ interface IGnssVisibilityControl { * The package name of the proxy Android application follows the standard Java language * package naming format. For example, com.example.myapp. */ - void enableNfwLocationAccess(in String[] proxyApps); + void enableNfwLocationAccess(in @utf8InCpp String[] proxyApps); /** * Registers the callback for HAL implementation to use. diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp index 29c26d16ec..3be7fb929e 100644 --- a/gnss/aidl/default/Android.bp +++ b/gnss/aidl/default/Android.bp @@ -52,12 +52,12 @@ cc_binary { "android.hardware.gnss.measurement_corrections@1.1", "android.hardware.gnss.measurement_corrections@1.0", "android.hardware.gnss.visibility_control@1.0", - "android.hardware.gnss.visibility_control-V1-ndk", "android.hardware.gnss-V2-ndk", ], srcs: [ "AGnss.cpp", "Gnss.cpp", + "GnssAntennaInfo.cpp", "GnssBatching.cpp", "GnssDebug.cpp", "GnssGeofence.cpp", @@ -68,6 +68,7 @@ cc_binary { "GnssConfiguration.cpp", "GnssMeasurementInterface.cpp", "GnssVisibilityControl.cpp", + "MeasurementCorrectionsInterface.cpp", "service.cpp", ], static_libs: [ diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp index e296351d95..c11a99ae9b 100644 --- a/gnss/aidl/default/Gnss.cpp +++ b/gnss/aidl/default/Gnss.cpp @@ -20,6 +20,8 @@ #include <inttypes.h> #include <log/log.h> #include "AGnss.h" +#include "DeviceFileReader.h" +#include "GnssAntennaInfo.h" #include "GnssBatching.h" #include "GnssConfiguration.h" #include "GnssDebug.h" @@ -28,10 +30,14 @@ #include "GnssNavigationMessageInterface.h" #include "GnssPsds.h" #include "GnssVisibilityControl.h" +#include "MeasurementCorrectionsInterface.h" +#include "NmeaFixInfo.h" #include "Utils.h" namespace aidl::android::hardware::gnss { +using ::android::hardware::gnss::common::NmeaFixInfo; using ::android::hardware::gnss::common::Utils; + using ndk::ScopedAStatus; using GnssSvInfo = IGnssCallback::GnssSvInfo; @@ -62,6 +68,12 @@ ScopedAStatus Gnss::setCallback(const std::shared_ptr<IGnssCallback>& callback) return ScopedAStatus::ok(); } +std::unique_ptr<GnssLocation> Gnss::getLocationFromHW() { + std::string inputStr = + ::android::hardware::gnss::common::DeviceFileReader::Instance().getLocationData(); + return ::android::hardware::gnss::common::NmeaFixInfo::getAidlLocationFromInputStr(inputStr); +} + ScopedAStatus Gnss::start() { ALOGD("start()"); if (mIsActive) { @@ -82,9 +94,14 @@ ScopedAStatus Gnss::start() { auto svStatus = filterBlocklistedSatellites(Utils::getMockSvInfoList()); this->reportSvStatus(svStatus); + auto currentLocation = getLocationFromHW(); mGnssPowerIndication->notePowerConsumption(); - const auto location = Utils::getMockLocation(); - this->reportLocation(location); + if (currentLocation != nullptr) { + this->reportLocation(*currentLocation); + } else { + const auto location = Utils::getMockLocation(); + this->reportLocation(location); + } std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs)); } }); @@ -264,4 +281,22 @@ ndk::ScopedAStatus Gnss::getExtensionGnssVisibilityControl( return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus Gnss::getExtensionGnssAntennaInfo( + std::shared_ptr<IGnssAntennaInfo>* iGnssAntennaInfo) { + ALOGD("Gnss::getExtensionGnssAntennaInfo"); + + *iGnssAntennaInfo = SharedRefBase::make<GnssAntennaInfo>(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Gnss::getExtensionMeasurementCorrections( + std::shared_ptr<measurement_corrections::IMeasurementCorrectionsInterface>* + iMeasurementCorrections) { + ALOGD("Gnss::getExtensionMeasurementCorrections"); + + *iMeasurementCorrections = + SharedRefBase::make<measurement_corrections::MeasurementCorrectionsInterface>(); + return ndk::ScopedAStatus::ok(); +} + } // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h index 384c8629a2..478dc94e4d 100644 --- a/gnss/aidl/default/Gnss.h +++ b/gnss/aidl/default/Gnss.h @@ -18,12 +18,14 @@ #include <aidl/android/hardware/gnss/BnAGnss.h> #include <aidl/android/hardware/gnss/BnGnss.h> +#include <aidl/android/hardware/gnss/BnGnssAntennaInfo.h> #include <aidl/android/hardware/gnss/BnGnssBatching.h> #include <aidl/android/hardware/gnss/BnGnssConfiguration.h> #include <aidl/android/hardware/gnss/BnGnssDebug.h> #include <aidl/android/hardware/gnss/BnGnssMeasurementInterface.h> #include <aidl/android/hardware/gnss/BnGnssPowerIndication.h> #include <aidl/android/hardware/gnss/BnGnssPsds.h> +#include <aidl/android/hardware/gnss/measurement_corrections/BnMeasurementCorrectionsInterface.h> #include <aidl/android/hardware/gnss/visibility_control/BnGnssVisibilityControl.h> #include <atomic> #include <mutex> @@ -69,6 +71,12 @@ class Gnss : public BnGnss { ndk::ScopedAStatus getExtensionGnssVisibilityControl( std::shared_ptr<android::hardware::gnss::visibility_control::IGnssVisibilityControl>* iGnssVisibilityControl) override; + ndk::ScopedAStatus getExtensionGnssAntennaInfo( + std::shared_ptr<IGnssAntennaInfo>* iGnssAntennaInfo) override; + ndk::ScopedAStatus getExtensionMeasurementCorrections( + std::shared_ptr<android::hardware::gnss::measurement_corrections:: + IMeasurementCorrectionsInterface>* iMeasurementCorrections) + override; std::shared_ptr<GnssConfiguration> mGnssConfiguration; std::shared_ptr<GnssPowerIndication> mGnssPowerIndication; @@ -79,6 +87,7 @@ class Gnss : public BnGnss { std::vector<IGnssCallback::GnssSvInfo> filterBlocklistedSatellites( std::vector<IGnssCallback::GnssSvInfo> gnssSvInfoList); void reportGnssStatusValue(const IGnssCallback::GnssStatusValue gnssStatusValue) const; + std::unique_ptr<GnssLocation> getLocationFromHW(); static std::shared_ptr<IGnssCallback> sGnssCallback; diff --git a/gnss/aidl/default/GnssAntennaInfo.cpp b/gnss/aidl/default/GnssAntennaInfo.cpp new file mode 100644 index 0000000000..72def716de --- /dev/null +++ b/gnss/aidl/default/GnssAntennaInfo.cpp @@ -0,0 +1,149 @@ +/* + * 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. + */ + +#define LOG_TAG "GnssAntennaInfoAidl" + +#include "GnssAntennaInfo.h" +#include <aidl/android/hardware/gnss/BnGnss.h> +#include <log/log.h> +#include "Utils.h" + +namespace aidl::android::hardware::gnss { + +using namespace ::android::hardware::gnss; +using Row = IGnssAntennaInfoCallback::Row; +using Coord = IGnssAntennaInfoCallback::Coord; + +std::shared_ptr<IGnssAntennaInfoCallback> GnssAntennaInfo::sCallback = nullptr; + +GnssAntennaInfo::GnssAntennaInfo() : mMinIntervalMs(1000) {} + +GnssAntennaInfo::~GnssAntennaInfo() { + stop(); +} + +// Methods from ::android::hardware::gnss::V2_1::IGnssAntennaInfo follow. +ndk::ScopedAStatus GnssAntennaInfo::setCallback( + const std::shared_ptr<IGnssAntennaInfoCallback>& callback) { + ALOGD("setCallback"); + std::unique_lock<std::mutex> lock(mMutex); + sCallback = callback; + + if (mIsActive) { + ALOGW("GnssAntennaInfo callback already set. Resetting the callback..."); + stop(); + } + start(); + + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus GnssAntennaInfo::close() { + ALOGD("close"); + stop(); + std::unique_lock<std::mutex> lock(mMutex); + sCallback = nullptr; + return ndk::ScopedAStatus::ok(); +} + +void GnssAntennaInfo::start() { + ALOGD("start"); + mIsActive = true; + mThread = std::thread([this]() { + while (mIsActive == true) { + if (sCallback != nullptr) { + IGnssAntennaInfoCallback::GnssAntennaInfo mockAntennaInfo_1 = { + .carrierFrequencyHz = 1575420000, + .phaseCenterOffsetCoordinateMillimeters = Coord{.x = 1, + .xUncertainty = 0.1, + .y = 2, + .yUncertainty = 0.1, + .z = 3, + .zUncertainty = 0.1}, + .phaseCenterVariationCorrectionMillimeters = + { + Row{std::vector<double>{1, -1, 5, -2, 3, -1}}, + Row{std::vector<double>{-2, 3, 2, 0, 1, 2}}, + Row{std::vector<double>{1, 3, 2, -1, -3, 5}}, + }, + .phaseCenterVariationCorrectionUncertaintyMillimeters = + { + Row{std::vector<double>{0.1, 0.2, 0.4, 0.1, 0.2, 0.3}}, + Row{std::vector<double>{0.3, 0.2, 0.3, 0.6, 0.1, 0.1}}, + Row{std::vector<double>{0.1, 0.1, 0.4, 0.2, 0.5, 0.3}}, + }, + .signalGainCorrectionDbi = + { + Row{std::vector<double>{2, -3, 1, -3, 0, -4}}, + Row{std::vector<double>{1, 0, -4, 1, 3, -2}}, + Row{std::vector<double>{3, -2, 0, -2, 3, 0}}, + }, + .signalGainCorrectionUncertaintyDbi = + { + Row{std::vector<double>{0.3, 0.1, 0.2, 0.6, 0.1, 0.3}}, + Row{std::vector<double>{0.1, 0.1, 0.5, 0.2, 0.3, 0.1}}, + Row{std::vector<double>{0.2, 0.4, 0.2, 0.1, 0.1, 0.2}}, + }, + }; + + IGnssAntennaInfoCallback::GnssAntennaInfo mockAntennaInfo_2 = { + .carrierFrequencyHz = 1176450000, + .phaseCenterOffsetCoordinateMillimeters = Coord{.x = 5, + .xUncertainty = 0.1, + .y = 6, + .yUncertainty = 0.1, + .z = 7, + .zUncertainty = 0.1}, + }; + + std::vector<IGnssAntennaInfoCallback::GnssAntennaInfo> mockAntennaInfos = { + mockAntennaInfo_1, + mockAntennaInfo_2, + }; + this->reportAntennaInfo(mockAntennaInfos); + } + + /** For mock implementation this is good. On real device, we should only report + antennaInfo at start and when there is a configuration change. **/ + std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs)); + } + }); +} + +void GnssAntennaInfo::stop() { + ALOGD("stop"); + mIsActive = false; + if (mThread.joinable()) { + mThread.join(); + } +} + +void GnssAntennaInfo::reportAntennaInfo( + const std::vector<IGnssAntennaInfoCallback::GnssAntennaInfo>& antennaInfo) const { + std::unique_lock<std::mutex> lock(mMutex); + + if (sCallback == nullptr) { + ALOGE("%s: No non-null callback", __func__); + return; + } + + auto ret = sCallback->gnssAntennaInfoCb(antennaInfo); + if (!ret.isOk()) { + ALOGE("%s: Unable to invoke callback", __func__); + } +} + +} // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/GnssAntennaInfo.h b/gnss/aidl/default/GnssAntennaInfo.h new file mode 100644 index 0000000000..2cf7b1366b --- /dev/null +++ b/gnss/aidl/default/GnssAntennaInfo.h @@ -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. + */ + +#pragma once + +#include <aidl/android/hardware/gnss/BnGnssAntennaInfo.h> +#include <atomic> +#include <mutex> +#include <thread> + +namespace aidl::android::hardware::gnss { + +struct GnssAntennaInfo : public BnGnssAntennaInfo { + public: + GnssAntennaInfo(); + ~GnssAntennaInfo(); + ndk::ScopedAStatus setCallback( + const std::shared_ptr<IGnssAntennaInfoCallback>& callback) override; + ndk::ScopedAStatus close() override; + + private: + void start(); + void stop(); + void reportAntennaInfo( + const std::vector<IGnssAntennaInfoCallback::GnssAntennaInfo>& antennaInfo) const; + + // Guarded by mMutex + static std::shared_ptr<IGnssAntennaInfoCallback> sCallback; + + std::atomic<bool> mIsActive; + std::atomic<long> mMinIntervalMs; + std::thread mThread; + + // Synchronization lock for sCallback + mutable std::mutex mMutex; +}; + +} // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/MeasurementCorrectionsInterface.cpp b/gnss/aidl/default/MeasurementCorrectionsInterface.cpp new file mode 100644 index 0000000000..0f1851cafe --- /dev/null +++ b/gnss/aidl/default/MeasurementCorrectionsInterface.cpp @@ -0,0 +1,68 @@ +/* + * 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. + */ + +#define LOG_TAG "MeasurementCorrectionsInterface" + +#include "MeasurementCorrectionsInterface.h" +#include <inttypes.h> +#include <log/log.h> + +namespace aidl::android::hardware::gnss::measurement_corrections { + +std::shared_ptr<IMeasurementCorrectionsCallback> MeasurementCorrectionsInterface::sCallback = + nullptr; + +ndk::ScopedAStatus MeasurementCorrectionsInterface::setCorrections( + const MeasurementCorrections& corrections) { + ALOGD("setCorrections"); + ALOGD("corrections = lat: %f, lng: %f, alt: %f, hUnc: %f, vUnc: %f, toa: %llu, " + "satCorrections.size: %d", + corrections.latitudeDegrees, corrections.longitudeDegrees, corrections.altitudeMeters, + corrections.horizontalPositionUncertaintyMeters, + corrections.verticalPositionUncertaintyMeters, + static_cast<unsigned long long>(corrections.toaGpsNanosecondsOfWeek), + static_cast<int>(corrections.satCorrections.size())); + for (auto singleSatCorrection : corrections.satCorrections) { + ALOGD("singleSatCorrection = flags: %d, constellation: %d, svid: %d" + ", cfHz: %" PRId64 ", probLos: %f, epl: %f, eplUnc: %f", + singleSatCorrection.singleSatCorrectionFlags, singleSatCorrection.constellation, + singleSatCorrection.svid, singleSatCorrection.carrierFrequencyHz, + singleSatCorrection.probSatIsLos, singleSatCorrection.excessPathLengthMeters, + singleSatCorrection.excessPathLengthUncertaintyMeters); + ALOGD("reflecting plane = lat: %f, lng: %f, alt: %f, azm: %f", + singleSatCorrection.reflectingPlane.latitudeDegrees, + singleSatCorrection.reflectingPlane.longitudeDegrees, + singleSatCorrection.reflectingPlane.altitudeMeters, + singleSatCorrection.reflectingPlane.azimuthDegrees); + } + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus MeasurementCorrectionsInterface::setCallback( + const std::shared_ptr<IMeasurementCorrectionsCallback>& callback) { + ALOGD("MeasurementCorrections::setCallback"); + std::unique_lock<std::mutex> lock(mMutex); + sCallback = callback; + auto ret = sCallback->setCapabilitiesCb( + IMeasurementCorrectionsCallback::CAPABILITY_LOS_SATS | + IMeasurementCorrectionsCallback::CAPABILITY_EXCESS_PATH_LENGTH | + IMeasurementCorrectionsCallback::CAPABILITY_REFLECTING_PLANE); + if (!ret.isOk()) { + ALOGE("%s: Unable to invoke callback", __func__); + } + return ndk::ScopedAStatus::ok(); +} +} // namespace aidl::android::hardware::gnss::measurement_corrections diff --git a/gnss/aidl/default/MeasurementCorrectionsInterface.h b/gnss/aidl/default/MeasurementCorrectionsInterface.h new file mode 100644 index 0000000000..af58725050 --- /dev/null +++ b/gnss/aidl/default/MeasurementCorrectionsInterface.h @@ -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. + */ + +#pragma once + +#include <aidl/android/hardware/gnss/measurement_corrections/BnMeasurementCorrectionsInterface.h> + +namespace aidl::android::hardware::gnss::measurement_corrections { + +struct MeasurementCorrectionsInterface : public BnMeasurementCorrectionsInterface { + public: + ndk::ScopedAStatus setCorrections(const MeasurementCorrections& corrections) override; + ndk::ScopedAStatus setCallback( + const std::shared_ptr<IMeasurementCorrectionsCallback>& callback) override; + + private: + // Synchronization lock for sCallback + mutable std::mutex mMutex; + // Guarded by mMutex + static std::shared_ptr<IMeasurementCorrectionsCallback> sCallback; +}; + +} // namespace aidl::android::hardware::gnss::measurement_corrections diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp index d532fad357..4244ab354d 100644 --- a/gnss/aidl/vts/Android.bp +++ b/gnss/aidl/vts/Android.bp @@ -31,6 +31,7 @@ cc_test { "gnss_hal_test.cpp", "gnss_hal_test_cases.cpp", "AGnssCallbackAidl.cpp", + "GnssAntennaInfoCallbackAidl.cpp", "GnssBatchingCallback.cpp", "GnssCallbackAidl.cpp", "GnssGeofenceCallback.cpp", @@ -38,6 +39,7 @@ cc_test { "GnssNavigationMessageCallback.cpp", "GnssPowerIndicationCallback.cpp", "GnssVisibilityControlCallback.cpp", + "MeasurementCorrectionsCallback.cpp", "VtsHalGnssTargetTest.cpp", ], shared_libs: [ @@ -50,7 +52,6 @@ cc_test { static_libs: [ "android.hardware.gnss-V2-cpp", "android.hardware.gnss@common-vts-lib", - "android.hardware.gnss.visibility_control-V1-cpp", ], test_suites: [ "general-tests", diff --git a/gnss/aidl/vts/GnssAntennaInfoCallbackAidl.cpp b/gnss/aidl/vts/GnssAntennaInfoCallbackAidl.cpp new file mode 100644 index 0000000000..11001cde89 --- /dev/null +++ b/gnss/aidl/vts/GnssAntennaInfoCallbackAidl.cpp @@ -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. + */ + +#include "GnssAntennaInfoCallbackAidl.h" +#include <inttypes.h> +#include <log/log.h> + +android::binder::Status GnssAntennaInfoCallbackAidl::gnssAntennaInfoCb( + const std::vector<IGnssAntennaInfoCallback::GnssAntennaInfo>& gnssAntennaInfos) { + ALOGD("GnssAntennaInfo received. Size = %d", (int)gnssAntennaInfos.size()); + antenna_info_cbq_.store(gnssAntennaInfos); + return android::binder::Status::ok(); +} diff --git a/gnss/aidl/vts/GnssAntennaInfoCallbackAidl.h b/gnss/aidl/vts/GnssAntennaInfoCallbackAidl.h new file mode 100644 index 0000000000..77e105797a --- /dev/null +++ b/gnss/aidl/vts/GnssAntennaInfoCallbackAidl.h @@ -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. + */ + +#pragma once + +#include <android/hardware/gnss/BnGnssAntennaInfoCallback.h> +#include <vector> +#include "GnssCallbackEventQueue.h" + +/** Implementation for IGnssAntennaInfoCallback. */ +class GnssAntennaInfoCallbackAidl : public android::hardware::gnss::BnGnssAntennaInfoCallback { + public: + GnssAntennaInfoCallbackAidl() : antenna_info_cbq_("info"){}; + ~GnssAntennaInfoCallbackAidl(){}; + + android::binder::Status gnssAntennaInfoCb( + const std::vector<IGnssAntennaInfoCallback::GnssAntennaInfo>& gnssAntennaInfos) + override; + + android::hardware::gnss::common::GnssCallbackEventQueue< + std::vector<IGnssAntennaInfoCallback::GnssAntennaInfo>> + antenna_info_cbq_; +}; diff --git a/gnss/aidl/vts/MeasurementCorrectionsCallback.cpp b/gnss/aidl/vts/MeasurementCorrectionsCallback.cpp new file mode 100644 index 0000000000..db1f7a6893 --- /dev/null +++ b/gnss/aidl/vts/MeasurementCorrectionsCallback.cpp @@ -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. + */ + +#define LOG_TAG "MeasurementCorrectionsCallback" + +#include "MeasurementCorrectionsCallback.h" +#include <log/log.h> + +android::binder::Status MeasurementCorrectionsCallback::setCapabilitiesCb(const int capabilities) { + ALOGI("Capabilities received %d", capabilities); + capabilities_cbq_.store(capabilities); + return android::binder::Status::ok(); +} diff --git a/gnss/aidl/vts/MeasurementCorrectionsCallback.h b/gnss/aidl/vts/MeasurementCorrectionsCallback.h new file mode 100644 index 0000000000..27e5b3cde2 --- /dev/null +++ b/gnss/aidl/vts/MeasurementCorrectionsCallback.h @@ -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. + */ + +#pragma once + +#include <android/hardware/gnss/measurement_corrections/BnMeasurementCorrectionsCallback.h> +#include "GnssCallbackEventQueue.h" + +class MeasurementCorrectionsCallback + : public android::hardware::gnss::measurement_corrections::BnMeasurementCorrectionsCallback { + public: + MeasurementCorrectionsCallback() : capabilities_cbq_("capabilities"){}; + ~MeasurementCorrectionsCallback(){}; + android::binder::Status setCapabilitiesCb(const int capabilities) override; + + android::hardware::gnss::common::GnssCallbackEventQueue<int> capabilities_cbq_; + int last_capabilities_; +}; diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp index 9acef8bed0..6e363f9815 100644 --- a/gnss/aidl/vts/gnss_hal_test_cases.cpp +++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp @@ -18,21 +18,26 @@ #include <android/hardware/gnss/IAGnss.h> #include <android/hardware/gnss/IGnss.h> +#include <android/hardware/gnss/IGnssAntennaInfo.h> #include <android/hardware/gnss/IGnssBatching.h> #include <android/hardware/gnss/IGnssDebug.h> #include <android/hardware/gnss/IGnssMeasurementCallback.h> #include <android/hardware/gnss/IGnssMeasurementInterface.h> #include <android/hardware/gnss/IGnssPowerIndication.h> #include <android/hardware/gnss/IGnssPsds.h> +#include <android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.h> #include <android/hardware/gnss/visibility_control/IGnssVisibilityControl.h> #include <cutils/properties.h> #include "AGnssCallbackAidl.h" +#include "GnssAntennaInfoCallbackAidl.h" #include "GnssBatchingCallback.h" #include "GnssGeofenceCallback.h" #include "GnssMeasurementCallbackAidl.h" #include "GnssNavigationMessageCallback.h" #include "GnssPowerIndicationCallback.h" #include "GnssVisibilityControlCallback.h" +#include "MeasurementCorrectionsCallback.h" +#include "Utils.h" #include "gnss_hal_test.h" using android::sp; @@ -44,6 +49,8 @@ using android::hardware::gnss::GnssMeasurement; using android::hardware::gnss::GnssPowerStats; using android::hardware::gnss::IAGnss; using android::hardware::gnss::IGnss; +using android::hardware::gnss::IGnssAntennaInfo; +using android::hardware::gnss::IGnssAntennaInfoCallback; using android::hardware::gnss::IGnssBatching; using android::hardware::gnss::IGnssBatchingCallback; using android::hardware::gnss::IGnssCallback; @@ -58,6 +65,8 @@ using android::hardware::gnss::IGnssPowerIndication; using android::hardware::gnss::IGnssPsds; using android::hardware::gnss::PsdsType; using android::hardware::gnss::SatellitePvt; +using android::hardware::gnss::common::Utils; +using android::hardware::gnss::measurement_corrections::IMeasurementCorrectionsInterface; using android::hardware::gnss::visibility_control::IGnssVisibilityControl; using GnssConstellationTypeV2_0 = android::hardware::gnss::V2_0::GnssConstellationType; @@ -905,7 +914,6 @@ TEST_P(GnssHalTest, GnssDebugValuesSanityTest) { } /* - * TestAGnssExtension: * TestGnssVisibilityControlExtension: * 1. Gets the IGnssVisibilityControl extension. * 2. Sets GnssVisibilityControlCallback @@ -923,7 +931,8 @@ TEST_P(GnssHalTest, TestGnssVisibilityControlExtension) { status = iGnssVisibilityControl->setCallback(gnssVisibilityControlCallback); ASSERT_TRUE(status.isOk()); - std::vector<String16> proxyApps{String16("com.example.ims"), String16("com.example.mdt")}; + std::vector<std::string> proxyApps{std::string("com.example.ims"), + std::string("com.example.mdt")}; status = iGnssVisibilityControl->enableNfwLocationAccess(proxyApps); ASSERT_TRUE(status.isOk()); } @@ -966,3 +975,167 @@ TEST_P(GnssHalTest, TestGnssMeasurementSetCallbackWithOptions) { status = iGnssMeasurement->close(); ASSERT_TRUE(status.isOk()); } + +/* + * TestGnssAgcInGnssMeasurement: + * 1. Gets the GnssMeasurementExtension and verifies that it returns a non-null extension. + * 2. Sets a GnssMeasurementCallback, waits for a measurement. + */ +TEST_P(GnssHalTest, TestGnssAgcInGnssMeasurement) { + if (aidl_gnss_hal_->getInterfaceVersion() == 1) { + return; + } + const int kFirstGnssMeasurementTimeoutSeconds = 10; + const int kNumMeasurementEvents = 15; + + sp<IGnssMeasurementInterface> iGnssMeasurement; + auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement); + ASSERT_TRUE(status.isOk()); + ASSERT_TRUE(iGnssMeasurement != nullptr); + + auto callback = sp<GnssMeasurementCallbackAidl>::make(); + status = iGnssMeasurement->setCallback(callback, /* enableFullTracking= */ false, + /* enableCorrVecOutputs */ false); + ASSERT_TRUE(status.isOk()); + + for (int i = 0; i < kNumMeasurementEvents; i++) { + GnssData lastMeasurement; + ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastMeasurement, + kFirstGnssMeasurementTimeoutSeconds)); + EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), i + 1); + ASSERT_TRUE(lastMeasurement.measurements.size() > 0); + + // Validity check GnssData fields + CheckGnssMeasurementClockFields(lastMeasurement); + + ASSERT_TRUE(lastMeasurement.gnssAgcs.has_value()); + for (const auto& gnssAgc : lastMeasurement.gnssAgcs.value()) { + ASSERT_TRUE(gnssAgc.has_value()); + ASSERT_TRUE(gnssAgc.value().carrierFrequencyHz >= 0); + } + } + + status = iGnssMeasurement->close(); + ASSERT_TRUE(status.isOk()); +} + +/* + * TestGnssAntennaInfo: + * Sets a GnssAntennaInfoCallback, waits for report, and verifies + * 1. phaseCenterOffsetCoordinateMillimeters is valid + * 2. phaseCenterOffsetCoordinateUncertaintyMillimeters is valid. + * PhaseCenterVariationCorrections and SignalGainCorrections are optional. + */ +TEST_P(GnssHalTest, TestGnssAntennaInfo) { + const int kAntennaInfoTimeoutSeconds = 2; + + if (aidl_gnss_hal_->getInterfaceVersion() == 1) { + return; + } + + sp<IGnssAntennaInfo> iGnssAntennaInfo; + auto status = aidl_gnss_hal_->getExtensionGnssAntennaInfo(&iGnssAntennaInfo); + ASSERT_TRUE(status.isOk()); + + if (!(aidl_gnss_cb_->last_capabilities_ & (int)GnssCallbackAidl::CAPABILITY_ANTENNA_INFO) || + iGnssAntennaInfo == nullptr) { + ALOGD("GnssAntennaInfo AIDL is not supported."); + return; + } + + auto callback = sp<GnssAntennaInfoCallbackAidl>::make(); + status = iGnssAntennaInfo->setCallback(callback); + ASSERT_TRUE(status.isOk()); + + std::vector<IGnssAntennaInfoCallback::GnssAntennaInfo> antennaInfos; + ASSERT_TRUE(callback->antenna_info_cbq_.retrieve(antennaInfos, kAntennaInfoTimeoutSeconds)); + EXPECT_EQ(callback->antenna_info_cbq_.calledCount(), 1); + ASSERT_TRUE(antennaInfos.size() > 0); + + for (auto antennaInfo : antennaInfos) { + // Remaining fields are optional + if (!antennaInfo.phaseCenterVariationCorrectionMillimeters.empty()) { + int numRows = antennaInfo.phaseCenterVariationCorrectionMillimeters.size(); + int numColumns = antennaInfo.phaseCenterVariationCorrectionMillimeters[0].row.size(); + // Must have at least 1 row and 2 columns + ASSERT_TRUE(numRows >= 1 && numColumns >= 2); + + // Corrections and uncertainties must have same dimensions + ASSERT_TRUE(antennaInfo.phaseCenterVariationCorrectionMillimeters.size() == + antennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters.size()); + ASSERT_TRUE( + antennaInfo.phaseCenterVariationCorrectionMillimeters[0].row.size() == + antennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters[0].row.size()); + + // Must be rectangular + for (auto row : antennaInfo.phaseCenterVariationCorrectionMillimeters) { + ASSERT_TRUE(row.row.size() == numColumns); + } + for (auto row : antennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters) { + ASSERT_TRUE(row.row.size() == numColumns); + } + } + if (!antennaInfo.signalGainCorrectionDbi.empty()) { + int numRows = antennaInfo.signalGainCorrectionDbi.size(); + int numColumns = antennaInfo.signalGainCorrectionUncertaintyDbi[0].row.size(); + // Must have at least 1 row and 2 columns + ASSERT_TRUE(numRows >= 1 && numColumns >= 2); + + // Corrections and uncertainties must have same dimensions + ASSERT_TRUE(antennaInfo.signalGainCorrectionDbi.size() == + antennaInfo.signalGainCorrectionUncertaintyDbi.size()); + ASSERT_TRUE(antennaInfo.signalGainCorrectionDbi[0].row.size() == + antennaInfo.signalGainCorrectionUncertaintyDbi[0].row.size()); + + // Must be rectangular + for (auto row : antennaInfo.signalGainCorrectionDbi) { + ASSERT_TRUE(row.row.size() == numColumns); + } + for (auto row : antennaInfo.signalGainCorrectionUncertaintyDbi) { + ASSERT_TRUE(row.row.size() == numColumns); + } + } + } + + iGnssAntennaInfo->close(); +} + +/* + * TestGnssMeasurementCorrections: + * If measurement corrections capability is supported, verifies that the measurement corrections + * capabilities are reported and the mandatory LOS_SATS or the EXCESS_PATH_LENGTH + * capability flag is set. + */ +TEST_P(GnssHalTest, TestGnssMeasurementCorrections) { + if (aidl_gnss_hal_->getInterfaceVersion() == 1) { + return; + } + if (!(aidl_gnss_cb_->last_capabilities_ & + (int)GnssCallbackAidl::CAPABILITY_MEASUREMENT_CORRECTIONS)) { + return; + } + + sp<IMeasurementCorrectionsInterface> iMeasurementCorrectionsAidl; + auto status = aidl_gnss_hal_->getExtensionMeasurementCorrections(&iMeasurementCorrectionsAidl); + ASSERT_TRUE(status.isOk()); + ASSERT_TRUE(iMeasurementCorrectionsAidl != nullptr); + + // Setup measurement corrections callback. + auto gnssMeasurementCorrectionsCallback = sp<MeasurementCorrectionsCallback>::make(); + status = iMeasurementCorrectionsAidl->setCallback(gnssMeasurementCorrectionsCallback); + ASSERT_TRUE(status.isOk()); + + const int kTimeoutSec = 5; + EXPECT_TRUE(gnssMeasurementCorrectionsCallback->capabilities_cbq_.retrieve( + gnssMeasurementCorrectionsCallback->last_capabilities_, kTimeoutSec)); + ASSERT_TRUE(gnssMeasurementCorrectionsCallback->capabilities_cbq_.calledCount() > 0); + + ASSERT_TRUE((gnssMeasurementCorrectionsCallback->last_capabilities_ & + (MeasurementCorrectionsCallback::CAPABILITY_LOS_SATS | + MeasurementCorrectionsCallback::CAPABILITY_EXCESS_PATH_LENGTH)) != 0); + + // Set a mock MeasurementCorrections. + status = iMeasurementCorrectionsAidl->setCorrections( + Utils::getMockMeasurementCorrections_aidl()); + ASSERT_TRUE(status.isOk()); +} diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp index 05bec882de..b896f04ddf 100644 --- a/gnss/common/utils/default/Android.bp +++ b/gnss/common/utils/default/Android.bp @@ -39,6 +39,7 @@ cc_library_static { "v2_1/GnssMeasurement.cpp", "v2_1/GnssMeasurementCorrections.cpp", "DeviceFileReader.cpp", + "FixLocationParser.cpp", "GnssRawMeasurementParser.cpp", "GnssReplayUtils.cpp", "MockLocation.cpp", diff --git a/gnss/common/utils/default/FixLocationParser.cpp b/gnss/common/utils/default/FixLocationParser.cpp new file mode 100644 index 0000000000..f391d96616 --- /dev/null +++ b/gnss/common/utils/default/FixLocationParser.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2022 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 "FixLocationParser.h" + +namespace android { +namespace hardware { +namespace gnss { +namespace common { + +using aidl::android::hardware::gnss::ElapsedRealtime; +using aidl::android::hardware::gnss::GnssLocation; + +std::unique_ptr<GnssLocation> FixLocationParser::getLocationFromInputStr( + const std::string& locationStr) { + /* + * Fix,Provider,LatitudeDegrees,LongitudeDegrees,AltitudeMeters,SpeedMps, + * AccuracyMeters,BearingDegrees,UnixTimeMillis,SpeedAccuracyMps,BearingAccuracyDegrees, + * elapsedRealtimeNanos + */ + if (locationStr.empty()) { + return nullptr; + } + std::vector<std::string> locationStrRecords; + ParseUtils::splitStr(locationStr, LINE_SEPARATOR, locationStrRecords); + if (locationStrRecords.empty()) { + return nullptr; + } + + std::vector<std::string> locationValues; + ParseUtils::splitStr(locationStrRecords[0], COMMA_SEPARATOR, locationValues); + if (locationValues.size() < 12) { + return nullptr; + } + ElapsedRealtime elapsedRealtime = { + .flags = ElapsedRealtime::HAS_TIMESTAMP_NS | ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS, + .timestampNs = ::android::elapsedRealtimeNano(), + // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks. + // In an actual implementation provide an estimate of the synchronization uncertainty + // or don't set the field. + .timeUncertaintyNs = 1020400}; + + GnssLocation location = { + .gnssLocationFlags = 0xFF, + .latitudeDegrees = ParseUtils::tryParseDouble(locationValues[2], 0), + .longitudeDegrees = ParseUtils::tryParseDouble(locationValues[3], 0), + .altitudeMeters = ParseUtils::tryParseDouble(locationValues[4], 0), + .speedMetersPerSec = ParseUtils::tryParseDouble(locationValues[5], 0), + .bearingDegrees = ParseUtils::tryParseDouble(locationValues[7], 0), + .horizontalAccuracyMeters = ParseUtils::tryParseDouble(locationValues[6], 0), + .verticalAccuracyMeters = ParseUtils::tryParseDouble(locationValues[6], 0), + .speedAccuracyMetersPerSecond = ParseUtils::tryParseDouble(locationValues[9], 0), + .bearingAccuracyDegrees = ParseUtils::tryParseDouble(locationValues[10], 0), + .timestampMillis = ParseUtils::tryParseLongLong(locationValues[8], 0), + .elapsedRealtime = elapsedRealtime}; + return std::make_unique<GnssLocation>(location); +} + +} // namespace common +} // namespace gnss +} // namespace hardware +} // namespace android
\ No newline at end of file diff --git a/gnss/common/utils/default/GnssReplayUtils.cpp b/gnss/common/utils/default/GnssReplayUtils.cpp index e3f4ff82a0..535647716b 100644 --- a/gnss/common/utils/default/GnssReplayUtils.cpp +++ b/gnss/common/utils/default/GnssReplayUtils.cpp @@ -41,7 +41,7 @@ bool ReplayUtils::isGnssRawMeasurement(const std::string& inputStr) { bool ReplayUtils::isNMEA(const std::string& inputStr) { return !inputStr.empty() && (inputStr.find("$GPRMC,", 0) != std::string::npos || - inputStr.find("$GPRMA,", 0) != std::string::npos); + inputStr.find("$GPGGA,", 0) != std::string::npos); } } // namespace common diff --git a/gnss/common/utils/default/NmeaFixInfo.cpp b/gnss/common/utils/default/NmeaFixInfo.cpp index c7ee13488b..22aef90204 100644 --- a/gnss/common/utils/default/NmeaFixInfo.cpp +++ b/gnss/common/utils/default/NmeaFixInfo.cpp @@ -34,6 +34,9 @@ namespace hardware { namespace gnss { namespace common { +using aidl::android::hardware::gnss::ElapsedRealtime; +using aidl::android::hardware::gnss::GnssLocation; + NmeaFixInfo::NmeaFixInfo() : hasGMCRecord(false), hasGGARecord(false) {} float NmeaFixInfo::getAltitudeMeters() const { @@ -237,6 +240,40 @@ std::unique_ptr<V2_0::GnssLocation> NmeaFixInfo::getLocationFromInputStr( } /** + * Convert V2_0::GnssLocation to aidl::GnssLocation. + */ +std::unique_ptr<GnssLocation> NmeaFixInfo::getAidlLocationFromInputStr( + const std::string& inputStr) { + std::unique_ptr<V2_0::GnssLocation> locationV2 = getLocationFromInputStr(inputStr); + if (locationV2 == nullptr) { + return nullptr; + } + + ElapsedRealtime elapsedRealtime = { + .flags = ElapsedRealtime::HAS_TIMESTAMP_NS | ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS, + .timestampNs = ::android::elapsedRealtimeNano(), + // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks. + // In an actual implementation provide an estimate of the synchronization uncertainty + // or don't set the field. + .timeUncertaintyNs = 1020400}; + + GnssLocation location = { + .gnssLocationFlags = locationV2->v1_0.gnssLocationFlags, + .latitudeDegrees = locationV2->v1_0.latitudeDegrees, + .longitudeDegrees = locationV2->v1_0.longitudeDegrees, + .altitudeMeters = locationV2->v1_0.altitudeMeters, + .speedMetersPerSec = locationV2->v1_0.speedMetersPerSec, + .bearingDegrees = locationV2->v1_0.bearingDegrees, + .horizontalAccuracyMeters = locationV2->v1_0.horizontalAccuracyMeters, + .verticalAccuracyMeters = locationV2->v1_0.verticalAccuracyMeters, + .speedAccuracyMetersPerSecond = locationV2->v1_0.speedAccuracyMetersPerSecond, + .bearingAccuracyDegrees = locationV2->v1_0.bearingAccuracyDegrees, + .timestampMillis = locationV2->v1_0.timestamp, + .elapsedRealtime = elapsedRealtime}; + return std::make_unique<GnssLocation>(location); +} + +/** * Parses the input string in NMEA format and convert to GnssLocation. */ std::unique_ptr<V2_0::GnssLocation> NmeaFixInfo::toGnssLocation() const { diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp index 563c6d5d21..1ff84eb9a5 100644 --- a/gnss/common/utils/default/Utils.cpp +++ b/gnss/common/utils/default/Utils.cpp @@ -38,6 +38,7 @@ using GnssSvInfo = aidl::android::hardware::gnss::IGnssCallback::GnssSvInfo; using GnssSvFlags = aidl::android::hardware::gnss::IGnssCallback::GnssSvFlags; using GnssSvFlagsV1_0 = V1_0::IGnssCallback::GnssSvFlags; +using GnssAgc = aidl::android::hardware::gnss::GnssData::GnssAgc; using GnssMeasurementFlagsV1_0 = V1_0::IGnssMeasurementCallback::GnssMeasurementFlags; using GnssMeasurementFlagsV2_1 = V2_1::IGnssMeasurementCallback::GnssMeasurementFlags; using GnssMeasurementStateV2_0 = V2_0::IGnssMeasurementCallback::GnssMeasurementState; @@ -231,8 +232,23 @@ GnssData Utils::getMockMeasurement(const bool enableCorrVecOutputs) { measurement.flags |= GnssMeasurement::HAS_CORRELATION_VECTOR; } - GnssData gnssData = { - .measurements = {measurement}, .clock = clock, .elapsedRealtime = timestamp}; + GnssAgc gnssAgc1 = { + .agcLevelDb = 3.5, + .constellation = GnssConstellationType::GLONASS, + .carrierFrequencyHz = (int64_t)kGloG1FreqHz, + }; + + GnssAgc gnssAgc2 = { + .agcLevelDb = -5.1, + .constellation = GnssConstellationType::GPS, + .carrierFrequencyHz = (int64_t)kGpsL1FreqHz, + }; + + GnssData gnssData = {.measurements = {measurement}, + .clock = clock, + .elapsedRealtime = timestamp, + .gnssAgcs = std::make_optional(std::vector( + {std::make_optional(gnssAgc1), std::make_optional(gnssAgc2)}))}; return gnssData; } diff --git a/gnss/common/utils/default/include/FixLocationParser.h b/gnss/common/utils/default/include/FixLocationParser.h new file mode 100644 index 0000000000..a73891452a --- /dev/null +++ b/gnss/common/utils/default/include/FixLocationParser.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef android_hardware_gnss_common_default_FixLocationParser_H_ +#define android_hardware_gnss_common_default_FixLocationParser_H_ + +#include <aidl/android/hardware/gnss/BnGnss.h> + +#include <utils/SystemClock.h> +#include <string> +#include <vector> + +#include <Constants.h> +#include <Utils.h> +#include <log/log.h> +#include "Constants.h" +#include "ParseUtils.h" + +namespace android { +namespace hardware { +namespace gnss { +namespace common { + +struct FixLocationParser { + public: + static std::unique_ptr<aidl::android::hardware::gnss::GnssLocation> getLocationFromInputStr( + const std::string& inputStr); +}; + +} // namespace common +} // namespace gnss +} // namespace hardware +} // namespace android + +#endif // android_hardware_gnss_common_default_FixLocationParser_H_
\ No newline at end of file diff --git a/gnss/common/utils/default/include/NmeaFixInfo.h b/gnss/common/utils/default/include/NmeaFixInfo.h index 5c27045316..407336121d 100644 --- a/gnss/common/utils/default/include/NmeaFixInfo.h +++ b/gnss/common/utils/default/include/NmeaFixInfo.h @@ -22,6 +22,7 @@ #include <hidl/Status.h> #include <ctime> #include <string> +#include "aidl/android/hardware/gnss/IGnss.h" namespace android { namespace hardware { namespace gnss { @@ -45,6 +46,8 @@ class NmeaFixInfo { public: static std::unique_ptr<V2_0::GnssLocation> getLocationFromInputStr(const std::string& inputStr); + static std::unique_ptr<aidl::android::hardware::gnss::GnssLocation> getAidlLocationFromInputStr( + const std::string& inputStr); private: static void splitStr(const std::string& line, const char& delimiter, diff --git a/gnss/common/utils/vts/Utils.cpp b/gnss/common/utils/vts/Utils.cpp index 06bce9d3a7..da4c07fc05 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/BnGnss.h> #include <android/hardware/gnss/IGnss.h> #include "gtest/gtest.h" @@ -28,6 +29,12 @@ namespace common { using namespace measurement_corrections::V1_0; using V1_0::GnssLocationFlags; +using MeasurementCorrectionsAidl = + android::hardware::gnss::measurement_corrections::MeasurementCorrections; +using ReflectingPlaneAidl = android::hardware::gnss::measurement_corrections::ReflectingPlane; +using SingleSatCorrectionAidl = + android::hardware::gnss::measurement_corrections::SingleSatCorrection; + template <> int64_t Utils::getLocationTimestampMillis(const android::hardware::gnss::GnssLocation& location) { return location.timestampMillis; @@ -63,6 +70,7 @@ const MeasurementCorrections Utils::getMockMeasurementCorrections() { .singleSatCorrectionFlags = GnssSingleSatCorrectionFlags::HAS_SAT_IS_LOS_PROBABILITY | GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH | GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH_UNC, + .constellation = V1_0::GnssConstellationType::GPS, .svid = 9, .carrierFrequencyHz = 1.59975e+09, @@ -114,6 +122,56 @@ Utils::getMockMeasurementCorrections_1_1() { return mockCorrections_1_1; } +const MeasurementCorrectionsAidl Utils::getMockMeasurementCorrections_aidl() { + ReflectingPlaneAidl reflectingPlane; + reflectingPlane.latitudeDegrees = 37.4220039; + reflectingPlane.longitudeDegrees = -122.0840991; + reflectingPlane.altitudeMeters = 250.35; + reflectingPlane.azimuthDegrees = 203.0; + + SingleSatCorrectionAidl singleSatCorrection1; + singleSatCorrection1.singleSatCorrectionFlags = + SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_SAT_IS_LOS_PROBABILITY | + SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH | + SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH_UNC | + SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_REFLECTING_PLANE; + singleSatCorrection1.constellation = android::hardware::gnss::GnssConstellationType::GPS; + singleSatCorrection1.svid = 12; + singleSatCorrection1.carrierFrequencyHz = 1.59975e+09; + singleSatCorrection1.probSatIsLos = 0.50001; + singleSatCorrection1.excessPathLengthMeters = 137.4802; + singleSatCorrection1.excessPathLengthUncertaintyMeters = 25.5; + singleSatCorrection1.reflectingPlane = reflectingPlane; + + SingleSatCorrectionAidl singleSatCorrection2; + singleSatCorrection2.singleSatCorrectionFlags = + SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_SAT_IS_LOS_PROBABILITY | + SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH | + SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH_UNC; + singleSatCorrection2.constellation = GnssConstellationType::GPS; + singleSatCorrection2.svid = 9; + singleSatCorrection2.carrierFrequencyHz = 1.59975e+09; + singleSatCorrection2.probSatIsLos = 0.873; + singleSatCorrection2.excessPathLengthMeters = 26.294; + singleSatCorrection2.excessPathLengthUncertaintyMeters = 10.0; + + std::vector<SingleSatCorrectionAidl> singleSatCorrections = {singleSatCorrection1, + singleSatCorrection2}; + MeasurementCorrectionsAidl mockCorrections; + mockCorrections.latitudeDegrees = 37.4219999; + mockCorrections.longitudeDegrees = -122.0840575; + mockCorrections.altitudeMeters = 30.60062531; + mockCorrections.horizontalPositionUncertaintyMeters = 9.23542; + mockCorrections.verticalPositionUncertaintyMeters = 15.02341; + mockCorrections.toaGpsNanosecondsOfWeek = 2935633453L; + mockCorrections.hasEnvironmentBearing = true; + mockCorrections.environmentBearingDegrees = 45.0; + mockCorrections.environmentBearingUncertaintyDegrees = 4.0; + mockCorrections.satCorrections = singleSatCorrections; + + return mockCorrections; +} + /* * MapConstellationType: * Given a GnssConstellationType_2_0 type constellation, maps to its equivalent diff --git a/gnss/common/utils/vts/include/Utils.h b/gnss/common/utils/vts/include/Utils.h index 40f31d288e..4ea6cd617d 100644 --- a/gnss/common/utils/vts/include/Utils.h +++ b/gnss/common/utils/vts/include/Utils.h @@ -21,6 +21,8 @@ #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 <android/hardware/gnss/measurement_corrections/BnMeasurementCorrectionsInterface.h> + #include <gtest/gtest.h> namespace android { @@ -36,6 +38,8 @@ struct Utils { getMockMeasurementCorrections(); static const measurement_corrections::V1_1::MeasurementCorrections getMockMeasurementCorrections_1_1(); + static const android::hardware::gnss::measurement_corrections::MeasurementCorrections + getMockMeasurementCorrections_aidl(); static V1_0::GnssConstellationType mapConstellationType( V2_0::GnssConstellationType constellation); diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Transform.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Transform.aidl index 5c3d4cb16f..359c655e00 100644 --- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Transform.aidl +++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Transform.aidl @@ -34,6 +34,7 @@ package android.hardware.graphics.common; @Backing(type="int") @VintfStability enum Transform { + NONE = 0, FLIP_H = 1, FLIP_V = 2, ROT_90 = 4, diff --git a/graphics/common/aidl/android/hardware/graphics/common/Transform.aidl b/graphics/common/aidl/android/hardware/graphics/common/Transform.aidl index 325816c98a..4b3a1b11fe 100644 --- a/graphics/common/aidl/android/hardware/graphics/common/Transform.aidl +++ b/graphics/common/aidl/android/hardware/graphics/common/Transform.aidl @@ -23,6 +23,11 @@ package android.hardware.graphics.common; @Backing(type="int") enum Transform { /** + * Identity transform (i.e. no rotation or flip). + */ + NONE = 0, + + /** * Horizontal flip. FLIP_H/FLIP_V is applied before ROT_90. */ FLIP_H = 1 << 0, diff --git a/graphics/composer/2.1/default/OWNERS b/graphics/composer/2.1/default/OWNERS index 709c4d1c35..331c80d22a 100644 --- a/graphics/composer/2.1/default/OWNERS +++ b/graphics/composer/2.1/default/OWNERS @@ -1,3 +1,4 @@ # Graphics team adyabr@google.com +alecmouri@google.com lpy@google.com diff --git a/graphics/composer/2.1/utils/OWNERS b/graphics/composer/2.1/utils/OWNERS index 7af69b4203..83c4f5f613 100644 --- a/graphics/composer/2.1/utils/OWNERS +++ b/graphics/composer/2.1/utils/OWNERS @@ -1,2 +1,3 @@ adyabr@google.com +alecmouri@google.com lpy@google.com diff --git a/graphics/composer/2.1/vts/OWNERS b/graphics/composer/2.1/vts/OWNERS index ea06752da7..a643bbdf0e 100644 --- a/graphics/composer/2.1/vts/OWNERS +++ b/graphics/composer/2.1/vts/OWNERS @@ -1,5 +1,6 @@ # Graphics team adyabr@google.com +alecmouri@google.com lpy@google.com # VTS team diff --git a/graphics/composer/2.1/vts/functional/OWNERS b/graphics/composer/2.1/vts/functional/OWNERS index a2ed8c8500..3d970d16fc 100644 --- a/graphics/composer/2.1/vts/functional/OWNERS +++ b/graphics/composer/2.1/vts/functional/OWNERS @@ -1,2 +1,4 @@ # Bug component: 25423 +adyabr@google.com +alecmouri@google.com sumir@google.com diff --git a/graphics/composer/2.2/default/OWNERS b/graphics/composer/2.2/default/OWNERS index 709c4d1c35..e8f584dd15 100644 --- a/graphics/composer/2.2/default/OWNERS +++ b/graphics/composer/2.2/default/OWNERS @@ -1,3 +1,5 @@ # Graphics team adyabr@google.com +alecmouri@google.com lpy@google.com + diff --git a/graphics/composer/2.2/utils/OWNERS b/graphics/composer/2.2/utils/OWNERS index 709c4d1c35..331c80d22a 100644 --- a/graphics/composer/2.2/utils/OWNERS +++ b/graphics/composer/2.2/utils/OWNERS @@ -1,3 +1,4 @@ # Graphics team adyabr@google.com +alecmouri@google.com lpy@google.com diff --git a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp index 30596fc4c9..a1794afeed 100644 --- a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp +++ b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp @@ -17,6 +17,7 @@ #include <composer-vts/2.2/ReadbackVts.h> #include <composer-vts/2.2/RenderEngineVts.h> #include "renderengine/ExternalTexture.h" +#include "renderengine/impl/ExternalTexture.h" namespace android { namespace hardware { @@ -281,11 +282,11 @@ void TestBufferLayer::write(const std::shared_ptr<CommandWriterBase>& writer) { LayerSettings TestBufferLayer::toRenderEngineLayerSettings() { LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings(); - layerSettings.source.buffer.buffer = std::make_shared<renderengine::ExternalTexture>( + layerSettings.source.buffer.buffer = std::make_shared<renderengine::impl::ExternalTexture>( new GraphicBuffer(mBufferHandle->get(), GraphicBuffer::CLONE_HANDLE, mWidth, mHeight, static_cast<int32_t>(mFormat), 1, mUsage, mStride), mRenderEngine.getInternalRenderEngine(), - renderengine::ExternalTexture::Usage::READABLE); + renderengine::impl::ExternalTexture::Usage::READABLE); layerSettings.source.buffer.usePremultipliedAlpha = mBlendMode == IComposerClient::BlendMode::PREMULTIPLIED; diff --git a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp index 2d4cc7d80e..4a33fb5b42 100644 --- a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp +++ b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp @@ -15,6 +15,7 @@ */ #include <composer-vts/2.2/RenderEngineVts.h> +#include "renderengine/impl/ExternalTexture.h" namespace android { namespace hardware { @@ -68,8 +69,8 @@ void TestRenderEngine::drawLayers() { [](renderengine::LayerSettings& settings) -> renderengine::LayerSettings { return settings; }); - auto texture = std::make_shared<renderengine::ExternalTexture>( - mGraphicBuffer, *mRenderEngine, renderengine::ExternalTexture::Usage::WRITEABLE); + auto texture = std::make_shared<renderengine::impl::ExternalTexture>( + mGraphicBuffer, *mRenderEngine, renderengine::impl::ExternalTexture::Usage::WRITEABLE); auto [status, readyFence] = mRenderEngine ->drawLayers(mDisplaySettings, compositionLayers, texture, true, std::move(bufferFence)) diff --git a/graphics/composer/2.2/vts/functional/OWNERS b/graphics/composer/2.2/vts/functional/OWNERS index 31b0dc752b..a4eb0caf84 100644 --- a/graphics/composer/2.2/vts/functional/OWNERS +++ b/graphics/composer/2.2/vts/functional/OWNERS @@ -1,5 +1,6 @@ # Bug component: 25423 # Graphics team adyabr@google.com +alecmouri@google.com lpy@google.com sumir@google.com diff --git a/graphics/composer/2.3/default/OWNERS b/graphics/composer/2.3/default/OWNERS index 709c4d1c35..331c80d22a 100644 --- a/graphics/composer/2.3/default/OWNERS +++ b/graphics/composer/2.3/default/OWNERS @@ -1,3 +1,4 @@ # Graphics team adyabr@google.com +alecmouri@google.com lpy@google.com diff --git a/graphics/composer/2.3/utils/OWNERS b/graphics/composer/2.3/utils/OWNERS index 709c4d1c35..331c80d22a 100644 --- a/graphics/composer/2.3/utils/OWNERS +++ b/graphics/composer/2.3/utils/OWNERS @@ -1,3 +1,4 @@ # Graphics team adyabr@google.com +alecmouri@google.com lpy@google.com diff --git a/graphics/composer/2.3/vts/functional/OWNERS b/graphics/composer/2.3/vts/functional/OWNERS index 31b0dc752b..a4eb0caf84 100644 --- a/graphics/composer/2.3/vts/functional/OWNERS +++ b/graphics/composer/2.3/vts/functional/OWNERS @@ -1,5 +1,6 @@ # Bug component: 25423 # Graphics team adyabr@google.com +alecmouri@google.com lpy@google.com sumir@google.com diff --git a/graphics/composer/2.4/default/OWNERS b/graphics/composer/2.4/default/OWNERS index 709c4d1c35..331c80d22a 100644 --- a/graphics/composer/2.4/default/OWNERS +++ b/graphics/composer/2.4/default/OWNERS @@ -1,3 +1,4 @@ # Graphics team adyabr@google.com +alecmouri@google.com lpy@google.com diff --git a/graphics/composer/2.4/utils/OWNERS b/graphics/composer/2.4/utils/OWNERS index 709c4d1c35..331c80d22a 100644 --- a/graphics/composer/2.4/utils/OWNERS +++ b/graphics/composer/2.4/utils/OWNERS @@ -1,3 +1,4 @@ # Graphics team adyabr@google.com +alecmouri@google.com lpy@google.com diff --git a/graphics/composer/2.4/vts/functional/OWNERS b/graphics/composer/2.4/vts/functional/OWNERS index 31b0dc752b..a4eb0caf84 100644 --- a/graphics/composer/2.4/vts/functional/OWNERS +++ b/graphics/composer/2.4/vts/functional/OWNERS @@ -1,5 +1,6 @@ # Bug component: 25423 # Graphics team adyabr@google.com +alecmouri@google.com lpy@google.com sumir@google.com diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Color.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Color.aidl index 7733debc9e..822290908e 100644 --- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Color.aidl +++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Color.aidl @@ -34,8 +34,8 @@ package android.hardware.graphics.composer3; @VintfStability parcelable Color { - byte r; - byte g; - byte b; - byte a; + float r; + float g; + float b; + float a; } diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayBrightness.aidl index faadf575d1..be623df763 100644 --- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl +++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayBrightness.aidl @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021, The Android Open Source Project + * Copyright 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. @@ -33,9 +33,6 @@ package android.hardware.graphics.composer3; @VintfStability -parcelable FloatColor { - float r; - float g; - float b; - float a; +parcelable DisplayBrightness { + float brightness; } 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 9f5342ef4b..fdf110032d 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 @@ enum DisplayCapability { PROTECTED_CONTENTS = 4, AUTO_LOW_LATENCY_MODE = 5, SUSPEND = 6, + DISPLAY_DECORATION = 7, } diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl index 3382633554..662240e96b 100644 --- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl +++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl @@ -37,6 +37,7 @@ parcelable DisplayCommand { long display; android.hardware.graphics.composer3.LayerCommand[] layers; @nullable float[] colorTransformMatrix; + @nullable android.hardware.graphics.composer3.DisplayBrightness brightness; @nullable android.hardware.graphics.composer3.ClientTarget clientTarget; @nullable android.hardware.graphics.composer3.Buffer virtualDisplayOutputBuffer; @nullable android.hardware.graphics.composer3.ClockMonotonicTimestamp expectedPresentTime; diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl index 2d17e0fdea..5593c57069 100644 --- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl +++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl @@ -51,6 +51,7 @@ interface IComposerClient { int getDisplayVsyncPeriod(long display); android.hardware.graphics.composer3.DisplayContentSample getDisplayedContentSample(long display, long maxFrames, long timestamp); android.hardware.graphics.composer3.DisplayContentSamplingAttributes getDisplayedContentSamplingAttributes(long display); + android.hardware.graphics.common.Transform getDisplayPhysicalOrientation(long display); android.hardware.graphics.composer3.HdrCapabilities getHdrCapabilities(long display); int getMaxVirtualDisplayCount(); android.hardware.graphics.composer3.PerFrameMetadataKey[] getPerFrameMetadataKeys(long display); @@ -61,11 +62,13 @@ interface IComposerClient { void registerCallback(in android.hardware.graphics.composer3.IComposerCallback callback); void setActiveConfig(long display, int config); android.hardware.graphics.composer3.VsyncPeriodChangeTimeline setActiveConfigWithConstraints(long display, int config, in android.hardware.graphics.composer3.VsyncPeriodChangeConstraints vsyncPeriodChangeConstraints); + void setBootDisplayConfig(long display, int config); + void clearBootDisplayConfig(long display); + int getPreferredBootDisplayConfig(long display); void setAutoLowLatencyMode(long display, boolean on); void setClientTargetSlotCount(long display, int clientTargetSlotCount); void setColorMode(long display, android.hardware.graphics.composer3.ColorMode mode, android.hardware.graphics.composer3.RenderIntent intent); void setContentType(long display, android.hardware.graphics.composer3.ContentType type); - void setDisplayBrightness(long display, float brightness); void setDisplayedContentSamplingEnabled(long display, boolean enable, android.hardware.graphics.composer3.FormatColorComponent componentMask, long maxFrames); void setPowerMode(long display, android.hardware.graphics.composer3.PowerMode mode); void setReadbackBuffer(long display, in android.hardware.common.NativeHandle buffer, in @nullable ParcelFileDescriptor releaseFence); diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl index ab77880daf..c1c01172c1 100644 --- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl +++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl @@ -40,7 +40,6 @@ parcelable LayerCommand { @nullable android.hardware.graphics.common.Rect[] damage; @nullable android.hardware.graphics.composer3.ParcelableBlendMode blendMode; @nullable android.hardware.graphics.composer3.Color color; - @nullable android.hardware.graphics.composer3.FloatColor floatColor; @nullable android.hardware.graphics.composer3.ParcelableComposition composition; @nullable android.hardware.graphics.composer3.ParcelableDataspace dataspace; @nullable android.hardware.graphics.common.Rect displayFrame; @@ -51,7 +50,8 @@ parcelable LayerCommand { @nullable android.hardware.graphics.common.Rect[] visibleRegion; @nullable android.hardware.graphics.composer3.ZOrder z; @nullable float[] colorTransform; - @nullable android.hardware.graphics.composer3.WhitePointNits whitePointNits; + @nullable android.hardware.graphics.composer3.Luminance whitePointNits; @nullable android.hardware.graphics.composer3.PerFrameMetadata[] perFrameMetadata; @nullable android.hardware.graphics.composer3.PerFrameMetadataBlob[] perFrameMetadataBlob; + @nullable android.hardware.graphics.common.Rect[] blockingRegion; } diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Luminance.aidl index c3925d2153..adb49a81b4 100644 --- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl +++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Luminance.aidl @@ -33,6 +33,6 @@ package android.hardware.graphics.composer3; @VintfStability -parcelable WhitePointNits { +parcelable Luminance { float nits; } diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Color.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/Color.aidl index 979f677379..151a8540c9 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/Color.aidl +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/Color.aidl @@ -16,10 +16,13 @@ package android.hardware.graphics.composer3; +/** + * Color representation as a floating point number in the range [0.0 - 1.0] + */ @VintfStability parcelable Color { - byte r; - byte g; - byte b; - byte a; + float r; + float g; + float b; + float a; } diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/WhitePointNits.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayBrightness.aidl index 2a1d1c666c..f66b235098 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/WhitePointNits.aidl +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayBrightness.aidl @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021, The Android Open Source Project + * Copyright 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. @@ -17,13 +17,10 @@ package android.hardware.graphics.composer3; @VintfStability -parcelable WhitePointNits { +parcelable DisplayBrightness { /** - * The desired white point for the layer. This is intended to be used when presenting - * an SDR layer alongside HDR content. The HDR content will be presented at the display - * brightness in nits, and accordingly SDR content shall be dimmed to the desired white point - * provided. - * @see LayerCommand.whitePointNits. + * A number between 0.0f (minimum brightness) and 1.0f (maximum brightness), a negative value to + * turn the backlight off. */ - float nits; + float brightness; } diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl index eacf1068e1..249fed03a0 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 @@ enum DisplayCapability { * 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/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl index 18461aded7..f1ce1a7dad 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl @@ -19,6 +19,7 @@ package android.hardware.graphics.composer3; import android.hardware.graphics.composer3.Buffer; import android.hardware.graphics.composer3.ClientTarget; import android.hardware.graphics.composer3.ClockMonotonicTimestamp; +import android.hardware.graphics.composer3.DisplayBrightness; import android.hardware.graphics.composer3.LayerCommand; @VintfStability @@ -69,6 +70,29 @@ parcelable DisplayCommand { @nullable float[] colorTransformMatrix; /** + * Sets the desired brightness of the display. + * + * Ideally, the brightness of the display will take effect within this frame so that it can be + * aligned with color transforms. Some display architectures may take multiple frames to apply + * the display brightness, for example when internally switching the display between multiple + * power modes to achieve higher luminance. In those cases, the underlying display panel's real + * brightness may not be applied atomically; however, layer dimming when mixing HDR and SDR + * content must be synchronized. + * + * As an illustrative example: suppose two layers have white + * points of 200 nits and 1000 nits respectively, the old display luminance is 200 nits, and the + * new display luminance is 1000 nits. If the new display luminance takes two frames to apply, + * then: In the first frame, there must not be any relative dimming of layers (treat both layers + * as 200 nits as the maximum luminance of the display is 200 nits). In the second frame, there + * dimming should be applied to ensure that the first layer does not become perceptually + * brighter during the transition. + * + * The display luminance must be updated by this command even if there is not pending validate + * or present command. + */ + @nullable DisplayBrightness brightness; + + /** * Sets the buffer handle which will receive the output of client * composition. Layers marked as Composition.CLIENT must be composited * into this buffer prior to the call to PRESENT_DISPLAY, and layers not diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Hidl2AidlAsserts.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/Hidl2AidlAsserts.cpp index d34b4051fa..d2cabff346 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/Hidl2AidlAsserts.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/Hidl2AidlAsserts.cpp @@ -25,7 +25,6 @@ #include "aidl/android/hardware/graphics/composer3/DisplayAttribute.h" #include "aidl/android/hardware/graphics/composer3/DisplayCapability.h" #include "aidl/android/hardware/graphics/composer3/DisplayConnectionType.h" -#include "aidl/android/hardware/graphics/composer3/FloatColor.h" #include "aidl/android/hardware/graphics/composer3/FormatColorComponent.h" #include "aidl/android/hardware/graphics/composer3/IComposer.h" #include "aidl/android/hardware/graphics/composer3/PerFrameMetadata.h" diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl index ab7f39781e..c86b9bdaec 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl @@ -16,6 +16,7 @@ package android.hardware.graphics.composer3; +import android.hardware.graphics.common.Transform; import android.hardware.graphics.composer3.ClientTargetProperty; import android.hardware.graphics.composer3.ColorMode; import android.hardware.graphics.composer3.CommandResultPayload; @@ -354,6 +355,23 @@ interface IComposerClient { DisplayContentSamplingAttributes getDisplayedContentSamplingAttributes(long display); /** + * Queries the physical orientation of a display. Orientation 'Transform::NONE' + * represents a display that doesn't require any transformation on layers + * to be presented at their natural orientation. + * + * @param display is the display where the physical orientation is queried. + * + * @return is one of the below values: + * Transform::NONE + * Transform::ROT_90 + * Transform::ROT_180 + * Transform::ROT_270 + * + * @exception EX_BAD_DISPLAY when an invalid display was passed in. + */ + Transform getDisplayPhysicalOrientation(long display); + + /** * Returns the high dynamic range (HDR) capabilities of the given display, * which are invariant with regard to the active configuration. * @@ -549,6 +567,58 @@ interface IComposerClient { long display, int config, in VsyncPeriodChangeConstraints vsyncPeriodChangeConstraints); /** + * Sets the display config in which the device boots. + * + * If the device is unable to boot in this config for any reason (example HDMI display changed), + * the implementation should try to find a config which matches the resolution and refresh-rate + * of this config. If no such config exists, the implementation's preferred display config + * should be used. + * + * @param display is the display for which the boot config is set. + * @param config is the new boot config for the display. + * + * @exception EX_BAD_DISPLAY when an invalid display handle was passed in. + * @exception EX_BAD_CONFIG when an invalid config id was passed in. + * + * @see getDisplayConfigs + * @see clearBootDisplayConfig + * @see getPreferredBootDisplayConfig + */ + void setBootDisplayConfig(long display, int config); + + /** + * Clears the boot display config. + * + * The device should boot in the implementation's preferred display config. + * + * @param display is the display for which the cached boot config is cleared. + * + * @exception EX_BAD_DISPLAY when an invalid display handle was passed in. + * + * @see getDisplayConfigs + * @see setBootDisplayConfig + * @see getPreferredBootDisplayConfig + */ + void clearBootDisplayConfig(long display); + + /** + * Returns the implementation's preferred display config. + * + * This is the display config used by the implementation at boot time, if the boot display + * config has not been requested yet, or if it has been previously cleared. + * + * @param display is the display to which the preferred config is queried. + * @return the implementation's preferred display config. + * + * @exception EX_BAD_DISPLAY when an invalid display handle was passed in. + * + * @see getDisplayConfigs + * @see setBootDisplayConfig + * @see clearBootDisplayConfig + */ + int getPreferredBootDisplayConfig(long display); + + /** * Requests the display to enable/disable its low latency mode. * * If the display is connected via HDMI 2.1, then Auto Low Latency Mode should be triggered. If @@ -616,25 +686,6 @@ interface IComposerClient { void setContentType(long display, ContentType type); /** - * Sets the brightness of a display. - * - * Ideally, the brightness change should take effect in the next frame post (so that it can be - * aligned with color transforms). - * - * @param display - * The display whose brightness is set. - * @param brightness - * A number between 0.0f (minimum brightness) and 1.0f (maximum brightness), or -1.0 to - * turn the backlight off. - * - * @exception EX_BAD_DISPLAY when the display is invalid, or - * @exception EX_UNSUPPORTED when brightness operations are not supported, or - * @exception EX_BAD_PARAMETER when the brightness is invalid, or - * @exception EX_NO_RESOURCES when the brightness cannot be applied. - */ - void setDisplayBrightness(long display, float brightness); - - /** * Enables or disables the collection of color content statistics * on this display. * diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl index 44fd4dcb9a..0a2711b056 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl @@ -22,7 +22,7 @@ import android.hardware.graphics.common.Point; import android.hardware.graphics.common.Rect; import android.hardware.graphics.composer3.Buffer; import android.hardware.graphics.composer3.Color; -import android.hardware.graphics.composer3.FloatColor; +import android.hardware.graphics.composer3.Luminance; import android.hardware.graphics.composer3.ParcelableBlendMode; import android.hardware.graphics.composer3.ParcelableComposition; import android.hardware.graphics.composer3.ParcelableDataspace; @@ -30,7 +30,6 @@ import android.hardware.graphics.composer3.ParcelableTransform; import android.hardware.graphics.composer3.PerFrameMetadata; import android.hardware.graphics.composer3.PerFrameMetadataBlob; import android.hardware.graphics.composer3.PlaneAlpha; -import android.hardware.graphics.composer3.WhitePointNits; import android.hardware.graphics.composer3.ZOrder; @VintfStability @@ -114,13 +113,6 @@ parcelable LayerCommand { @nullable Color color; /** - * Sets the color of the given layer. If the composition type of the layer - * is not Composition.SOLID_COLOR, this call must succeed and have no - * other effect. - */ - @nullable FloatColor floatColor; - - /** * Sets the desired composition type of the given layer. During * validateDisplay, the device may request changes to the composition * types of any of the layers as described in the definition of @@ -243,7 +235,7 @@ parcelable LayerCommand { * brightness in nits, and accordingly SDR content shall be dimmed to the desired white point * provided. */ - @nullable WhitePointNits whitePointNits; + @nullable Luminance whitePointNits; /** * Sets the PerFrameMetadata for the display. This metadata must be used @@ -264,4 +256,15 @@ parcelable LayerCommand { * This command may be called every frame. */ @nullable PerFrameMetadataBlob[] perFrameMetadataBlob; + + /** + * Specifies a region of the layer that is transparent and may be skipped + * by the DPU, e.g. using a blocking region, in order to save power. This + * is only a hint, so the composition of the layer must look the same + * whether or not this region is skipped. + * + * The region is in screen space and must not exceed the dimensions of + * the screen. + */ + @nullable Rect[] blockingRegion; } diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/Luminance.aidl index a0a1d4b179..5b1c1b40fe 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/Luminance.aidl @@ -16,14 +16,11 @@ package android.hardware.graphics.composer3; -/** - * Color representation as a floating point number in the range [0.0 - 1.0] - */ - @VintfStability -parcelable FloatColor { - float r; - float g; - float b; - float a; +parcelable Luminance { + /** + * Photometric measure of luminous intensity per unit area of light. + * Units are nits, or cd/m^2. + */ + float nits; } diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp index 0ece1d55a4..e519221159 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp @@ -922,35 +922,30 @@ class GraphicsBlendModeCompositionTest auto layer = mLayers[1]; BlendMode blendMode = layer->getBlendMode(); - float alpha = mTopLayerColor.a / 255.0f * layer->getAlpha(); + float alpha = mTopLayerColor.a * layer->getAlpha(); if (blendMode == BlendMode::NONE) { for (auto& expectedColor : expectedColors) { - expectedColor.r = mTopLayerColor.r * static_cast<int8_t>(layer->getAlpha()); - expectedColor.g = mTopLayerColor.g * static_cast<int8_t>(layer->getAlpha()); - expectedColor.b = mTopLayerColor.b * static_cast<int8_t>(layer->getAlpha()); - expectedColor.a = static_cast<int8_t>(alpha * 255.0); + expectedColor.r = mTopLayerColor.r * layer->getAlpha(); + expectedColor.g = mTopLayerColor.g * layer->getAlpha(); + expectedColor.b = mTopLayerColor.b * layer->getAlpha(); + expectedColor.a = alpha; } } else if (blendMode == BlendMode::PREMULTIPLIED) { for (auto& expectedColor : expectedColors) { - expectedColor.r = static_cast<int8_t>( - mTopLayerColor.r * static_cast<int8_t>(layer->getAlpha()) + - mBackgroundColor.r * (1.0 - alpha)); - expectedColor.g = static_cast<int8_t>(mTopLayerColor.g * layer->getAlpha() + - mBackgroundColor.g * (1.0 - alpha)); - expectedColor.b = static_cast<int8_t>(mTopLayerColor.b * layer->getAlpha() + - mBackgroundColor.b * (1.0 - alpha)); - expectedColor.a = static_cast<int8_t>(alpha + mBackgroundColor.a * (1.0 - alpha)); + expectedColor.r = + mTopLayerColor.r * layer->getAlpha() + mBackgroundColor.r * (1.0f - alpha); + expectedColor.g = + mTopLayerColor.g * layer->getAlpha() + mBackgroundColor.g * (1.0f - alpha); + expectedColor.b = + mTopLayerColor.b * layer->getAlpha() + mBackgroundColor.b * (1.0f - alpha); + expectedColor.a = alpha + mBackgroundColor.a * (1.0f - alpha); } } else if (blendMode == BlendMode::COVERAGE) { for (auto& expectedColor : expectedColors) { - expectedColor.r = static_cast<int8_t>(mTopLayerColor.r * alpha + - mBackgroundColor.r * (1.0 - alpha)); - expectedColor.g = static_cast<int8_t>(mTopLayerColor.g * alpha + - mBackgroundColor.g * (1.0 - alpha)); - expectedColor.b = static_cast<int8_t>(mTopLayerColor.b * alpha + - mBackgroundColor.b * (1.0 - alpha)); - expectedColor.a = static_cast<int8_t>(mTopLayerColor.a * alpha + - mBackgroundColor.a * (1.0 - alpha)); + expectedColor.r = mTopLayerColor.r * alpha + mBackgroundColor.r * (1.0f - alpha); + expectedColor.g = mTopLayerColor.g * alpha + mBackgroundColor.g * (1.0f - alpha); + expectedColor.b = mTopLayerColor.b * alpha + mBackgroundColor.b * (1.0f - alpha); + expectedColor.a = mTopLayerColor.a * alpha + mBackgroundColor.a * (1.0f - alpha); } } } @@ -1083,7 +1078,7 @@ class GraphicsTransformCompositionTest : public GraphicsCompositionTest { GraphicsCompositionTest::SetUp(); auto backgroundLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay); - backgroundLayer->setColor({0, 0, 0, 0}); + backgroundLayer->setColor({0.0f, 0.0f, 0.0f, 0.0f}); backgroundLayer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); backgroundLayer->setZOrder(0); diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp index 4dbe191f0c..1cfd3f95bb 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp @@ -568,37 +568,6 @@ TEST_P(GraphicsComposerAidlTest, GetDisplayedContentSample) { } } -/* - * Test that if brightness operations are supported, setDisplayBrightness works as expected. - */ -TEST_P(GraphicsComposerAidlTest, setDisplayBrightness) { - std::vector<DisplayCapability> capabilities; - auto error = mComposerClient->getDisplayCapabilities(mPrimaryDisplay, &capabilities); - ASSERT_TRUE(error.isOk()); - bool brightnessSupport = std::find(capabilities.begin(), capabilities.end(), - DisplayCapability::BRIGHTNESS) != capabilities.end(); - if (!brightnessSupport) { - EXPECT_EQ(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 0.5f) - .getServiceSpecificError(), - IComposerClient::EX_UNSUPPORTED); - GTEST_SUCCEED() << "Brightness operations are not supported"; - return; - } - - EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 0.0f).isOk()); - EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 0.5f).isOk()); - EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 1.0f).isOk()); - EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, -1.0f).isOk()); - - error = mComposerClient->setDisplayBrightness(mPrimaryDisplay, +2.0f); - EXPECT_FALSE(error.isOk()); - EXPECT_EQ(error.getServiceSpecificError(), IComposerClient::EX_BAD_PARAMETER); - - error = mComposerClient->setDisplayBrightness(mPrimaryDisplay, -2.0f); - EXPECT_FALSE(error.isOk()); - EXPECT_EQ(error.getServiceSpecificError(), IComposerClient::EX_BAD_PARAMETER); -} - TEST_P(GraphicsComposerAidlTest, getDisplayConnectionType) { DisplayConnectionType type; EXPECT_FALSE(mComposerClient->getDisplayConnectionType(mInvalidDisplayId, &type).isOk()); @@ -747,6 +716,61 @@ TEST_P(GraphicsComposerAidlTest, setActiveConfigWithConstraints_BadConfig) { } } +TEST_P(GraphicsComposerAidlTest, setBootDisplayConfig_BadDisplay) { + int32_t config = 0; + auto const error = mComposerClient->setBootDisplayConfig(mInvalidDisplayId, config); + + EXPECT_FALSE(error.isOk()); + EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError()); +} + +TEST_P(GraphicsComposerAidlTest, setBootDisplayConfig_BadConfig) { + for (VtsDisplay& display : mDisplays) { + int32_t invalidConfigId = GetInvalidConfigId(); + const auto error = mComposerClient->setBootDisplayConfig(display.get(), invalidConfigId); + EXPECT_FALSE(error.isOk()); + EXPECT_EQ(IComposerClient::EX_BAD_CONFIG, error.getServiceSpecificError()); + } +} + +TEST_P(GraphicsComposerAidlTest, setBootDisplayConfig) { + std::vector<int32_t> configs; + EXPECT_TRUE(mComposerClient->getDisplayConfigs(mPrimaryDisplay, &configs).isOk()); + for (auto config : configs) { + EXPECT_TRUE(mComposerClient->setBootDisplayConfig(mPrimaryDisplay, config).isOk()); + } +} + +TEST_P(GraphicsComposerAidlTest, clearBootDisplayConfig_BadDisplay) { + auto const error = mComposerClient->clearBootDisplayConfig(mInvalidDisplayId); + + EXPECT_FALSE(error.isOk()); + EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError()); +} + +TEST_P(GraphicsComposerAidlTest, clearBootDisplayConfig) { + EXPECT_TRUE(mComposerClient->clearBootDisplayConfig(mPrimaryDisplay).isOk()); +} + +TEST_P(GraphicsComposerAidlTest, getPreferredBootDisplayConfig_BadDisplay) { + int32_t config; + auto const error = mComposerClient->getPreferredBootDisplayConfig(mInvalidDisplayId, &config); + + EXPECT_FALSE(error.isOk()); + EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError()); +} + +TEST_P(GraphicsComposerAidlTest, getPreferredBootDisplayConfig) { + int32_t preferredDisplayConfig = 0; + auto const error = mComposerClient->getPreferredBootDisplayConfig(mPrimaryDisplay, + &preferredDisplayConfig); + EXPECT_TRUE(error.isOk()); + + std::vector<int32_t> configs; + EXPECT_TRUE(mComposerClient->getDisplayConfigs(mPrimaryDisplay, &configs).isOk()); + EXPECT_NE(configs.end(), std::find(configs.begin(), configs.end(), preferredDisplayConfig)); +} + TEST_P(GraphicsComposerAidlTest, setAutoLowLatencyModeBadDisplay) { EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, mComposerClient->setAutoLowLatencyMode(mInvalidDisplayId, true) @@ -935,6 +959,33 @@ TEST_P(GraphicsComposerAidlTest, GetDisplayName) { EXPECT_TRUE(mComposerClient->getDisplayName(mPrimaryDisplay, &displayName).isOk()); } +TEST_P(GraphicsComposerAidlTest, GetDisplayPhysicalOrientationBadDisplay) { + Transform displayOrientation; + const auto error = + mComposerClient->getDisplayPhysicalOrientation(mInvalidDisplayId, &displayOrientation); + + EXPECT_FALSE(error.isOk()); + ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError()); +} + +TEST_P(GraphicsComposerAidlTest, GetDisplayPhysicalOrientation) { + const auto allowedDisplayOrientations = std::array<Transform, 4>{ + Transform::NONE, + Transform::ROT_90, + Transform::ROT_180, + Transform::ROT_270, + }; + + Transform displayOrientation; + const auto error = + mComposerClient->getDisplayPhysicalOrientation(mPrimaryDisplay, &displayOrientation); + + EXPECT_TRUE(error.isOk()); + EXPECT_NE(std::find(allowedDisplayOrientations.begin(), allowedDisplayOrientations.end(), + displayOrientation), + allowedDisplayOrientations.end()); +} + TEST_P(GraphicsComposerAidlTest, SetClientTargetSlotCount) { EXPECT_TRUE( mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kBufferSlotCount).isOk()); @@ -1457,8 +1508,7 @@ class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest { presentFence2->waitForever(LOG_TAG); const auto actualPresentTime = presentFence2->getSignalTime(); - const auto presentError = std::abs(expectedPresentTime - actualPresentTime); - EXPECT_LE(presentError, vsyncPeriod / 2); + EXPECT_GE(actualPresentTime, expectedPresentTime - vsyncPeriod / 2); ASSERT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::OFF).isOk()); } @@ -1494,6 +1544,55 @@ TEST_P(GraphicsComposerAidlCommandTest, SetLayerColorTransform) { } } +TEST_P(GraphicsComposerAidlCommandTest, SetDisplayBrightness) { + std::vector<DisplayCapability> capabilities; + auto error = mComposerClient->getDisplayCapabilities(mPrimaryDisplay, &capabilities); + ASSERT_TRUE(error.isOk()); + bool brightnessSupport = std::find(capabilities.begin(), capabilities.end(), + DisplayCapability::BRIGHTNESS) != capabilities.end(); + if (!brightnessSupport) { + mWriter.setDisplayBrightness(mPrimaryDisplay, 0.5f); + execute(); + const auto errors = mReader.takeErrors(); + EXPECT_EQ(1, errors.size()); + EXPECT_EQ(EX_UNSUPPORTED_OPERATION, errors[0].errorCode); + GTEST_SUCCEED() << "SetDisplayBrightness is not supported"; + return; + } + + mWriter.setDisplayBrightness(mPrimaryDisplay, 0.0f); + execute(); + EXPECT_TRUE(mReader.takeErrors().empty()); + + mWriter.setDisplayBrightness(mPrimaryDisplay, 0.5f); + execute(); + EXPECT_TRUE(mReader.takeErrors().empty()); + + mWriter.setDisplayBrightness(mPrimaryDisplay, 1.0f); + execute(); + EXPECT_TRUE(mReader.takeErrors().empty()); + + mWriter.setDisplayBrightness(mPrimaryDisplay, -1.0f); + execute(); + EXPECT_TRUE(mReader.takeErrors().empty()); + + mWriter.setDisplayBrightness(mPrimaryDisplay, 2.0f); + execute(); + { + const auto errors = mReader.takeErrors(); + ASSERT_EQ(1, errors.size()); + EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode); + } + + mWriter.setDisplayBrightness(mPrimaryDisplay, -2.0f); + execute(); + { + const auto errors = mReader.takeErrors(); + ASSERT_EQ(1, errors.size()); + EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode); + } +} + TEST_P(GraphicsComposerAidlCommandTest, SET_CLIENT_TARGET) { EXPECT_TRUE( mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kBufferSlotCount).isOk()); @@ -1681,6 +1780,26 @@ TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_SURFACE_DAMAGE) { ASSERT_TRUE(mReader.takeErrors().empty()); } +TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_BLOCKING_REGION) { + int64_t layer; + EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk()); + + Rect empty{0, 0, 0, 0}; + Rect unit{0, 0, 1, 1}; + + mWriter.setLayerBlockingRegion(mPrimaryDisplay, layer, std::vector<Rect>(1, empty)); + execute(); + ASSERT_TRUE(mReader.takeErrors().empty()); + + mWriter.setLayerBlockingRegion(mPrimaryDisplay, layer, std::vector<Rect>(1, unit)); + execute(); + ASSERT_TRUE(mReader.takeErrors().empty()); + + mWriter.setLayerBlockingRegion(mPrimaryDisplay, layer, std::vector<Rect>()); + execute(); + ASSERT_TRUE(mReader.takeErrors().empty()); +} + TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_BLEND_MODE) { int64_t layer; EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk()); @@ -1702,13 +1821,11 @@ TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_COLOR) { int64_t layer; EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk()); - mWriter.setLayerColor(mPrimaryDisplay, layer, - Color{static_cast<int8_t>(0xff), static_cast<int8_t>(0xff), - static_cast<int8_t>(0xff), static_cast<int8_t>(0xff)}); + mWriter.setLayerColor(mPrimaryDisplay, layer, Color{1.0f, 1.0f, 1.0f, 1.0f}); execute(); ASSERT_TRUE(mReader.takeErrors().empty()); - mWriter.setLayerColor(mPrimaryDisplay, layer, Color{0, 0, 0, 0}); + mWriter.setLayerColor(mPrimaryDisplay, layer, Color{0.0f, 0.0f, 0.0f, 0.0f}); execute(); ASSERT_TRUE(mReader.takeErrors().empty()); } diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp index 5eb912bb3f..ee597a1b1c 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp @@ -22,6 +22,7 @@ #include <aidl/android/hardware/graphics/common/BufferUsage.h> #include "include/RenderEngineVts.h" #include "renderengine/ExternalTexture.h" +#include "renderengine/impl/ExternalTexture.h" // TODO(b/129481165): remove the #pragma below and fix conversion issues #pragma clang diagnostic pop // ignored "-Wconversion @@ -131,12 +132,12 @@ void ReadbackHelper::fillBuffer(uint32_t width, uint32_t height, uint32_t stride int offset = (row * static_cast<int32_t>(stride) + col) * bytesPerPixel; uint8_t* pixelColor = (uint8_t*)bufferData + offset; - pixelColor[0] = static_cast<uint8_t>(srcColor.r); - pixelColor[1] = static_cast<uint8_t>(srcColor.g); - pixelColor[2] = static_cast<uint8_t>(srcColor.b); + pixelColor[0] = static_cast<uint8_t>(std::round(255.0f * srcColor.r)); + pixelColor[1] = static_cast<uint8_t>(std::round(255.0f * srcColor.g)); + pixelColor[2] = static_cast<uint8_t>(std::round(255.0f * srcColor.b)); if (bytesPerPixel == 4) { - pixelColor[3] = static_cast<uint8_t>(srcColor.a); + pixelColor[3] = static_cast<uint8_t>(std::round(255.0f * srcColor.a)); } } } @@ -184,13 +185,11 @@ void ReadbackHelper::compareColorBuffers(std::vector<Color>& expectedColors, voi auto pixel = row * static_cast<int32_t>(width) + col; int offset = (row * stride + col) * bytesPerPixel; uint8_t* pixelColor = (uint8_t*)bufferData + offset; + const Color expectedColor = expectedColors[static_cast<size_t>(pixel)]; - ASSERT_EQ(static_cast<int8_t>(expectedColors[static_cast<size_t>(pixel)].r), - pixelColor[0]); - ASSERT_EQ(static_cast<int8_t>(expectedColors[static_cast<size_t>(pixel)].g), - pixelColor[1]); - ASSERT_EQ(static_cast<int8_t>(expectedColors[static_cast<size_t>(pixel)].b), - pixelColor[2]); + ASSERT_EQ(std::round(255.0f * expectedColor.r), pixelColor[0]); + ASSERT_EQ(std::round(255.0f * expectedColor.g), pixelColor[1]); + ASSERT_EQ(std::round(255.0f * expectedColor.b), pixelColor[2]); } } } @@ -262,12 +261,8 @@ void TestColorLayer::write(ComposerClientWriter& writer) { LayerSettings TestColorLayer::toRenderEngineLayerSettings() { LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings(); - layerSettings.source.solidColor = - ::android::half3(static_cast<::android::half>(mColor.r) / 255.0, - static_cast<::android::half>(mColor.g) / 255.0, - static_cast<::android::half>(mColor.b) / 255.0); - layerSettings.alpha = - mAlpha * static_cast<float>((static_cast<::android::half>(mColor.a) / 255.0)); + layerSettings.source.solidColor = ::android::half3(mColor.r, mColor.g, mColor.b); + layerSettings.alpha = mAlpha * mColor.a; return layerSettings; } @@ -306,12 +301,13 @@ void TestBufferLayer::write(ComposerClientWriter& writer) { LayerSettings TestBufferLayer::toRenderEngineLayerSettings() { LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings(); - layerSettings.source.buffer.buffer = std::make_shared<::android::renderengine::ExternalTexture>( - ::android::sp<::android::GraphicBuffer>::make( - mGraphicBuffer->handle, ::android::GraphicBuffer::CLONE_HANDLE, mWidth, mHeight, - static_cast<int32_t>(mPixelFormat), 1, mUsage, mStride), - mRenderEngine.getInternalRenderEngine(), - ::android::renderengine::ExternalTexture::Usage::READABLE); + layerSettings.source.buffer.buffer = + std::make_shared<::android::renderengine::impl::ExternalTexture>( + ::android::sp<::android::GraphicBuffer>::make( + mGraphicBuffer->handle, ::android::GraphicBuffer::CLONE_HANDLE, mWidth, + mHeight, static_cast<int32_t>(mPixelFormat), 1, mUsage, mStride), + mRenderEngine.getInternalRenderEngine(), + ::android::renderengine::impl::ExternalTexture::Usage::READABLE); layerSettings.source.buffer.usePremultipliedAlpha = mBlendMode == BlendMode::PREMULTIPLIED; diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp index 50ce462459..6ff064f93c 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp @@ -15,6 +15,7 @@ */ #include "include/RenderEngineVts.h" +#include "renderengine/impl/ExternalTexture.h" namespace aidl::android::hardware::graphics::composer3::vts { @@ -62,9 +63,9 @@ void TestRenderEngine::drawLayers() { std::back_insert_iterator(compositionLayers), [](::android::renderengine::LayerSettings& settings) -> ::android::renderengine::LayerSettings { return settings; }); - auto texture = std::make_shared<::android::renderengine::ExternalTexture>( + auto texture = std::make_shared<::android::renderengine::impl::ExternalTexture>( mGraphicBuffer, *mRenderEngine, - ::android::renderengine::ExternalTexture::Usage::WRITEABLE); + ::android::renderengine::impl::ExternalTexture::Usage::WRITEABLE); auto [status, readyFence] = mRenderEngine ->drawLayers(mDisplaySettings, compositionLayers, texture, true, std::move(bufferFence)) diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h index 60a036e3fd..0fac2b3bfe 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h @@ -41,13 +41,12 @@ using common::Dataspace; using common::PixelFormat; using IMapper2_1 = ::android::hardware::graphics::mapper::V2_1::IMapper; -static const Color BLACK = {0, 0, 0, static_cast<int8_t>(0xff)}; -static const Color RED = {static_cast<int8_t>(0xff), 0, 0, static_cast<int8_t>(0xff)}; -static const Color TRANSLUCENT_RED = {static_cast<int8_t>(0xff), 0, 0, 0x33}; -static const Color GREEN = {0, static_cast<int8_t>(0xff), 0, static_cast<int8_t>(0xff)}; -static const Color BLUE = {0, 0, static_cast<int8_t>(0xff), static_cast<int8_t>(0xff)}; -static const Color WHITE = {static_cast<int8_t>(0xff), static_cast<int8_t>(0xff), - static_cast<int8_t>(0xff), static_cast<int8_t>(0xff)}; +static const Color BLACK = {0.0f, 0.0f, 0.0f, 1.0f}; +static const Color RED = {1.0f, 0.0f, 0.0f, 1.0f}; +static const Color TRANSLUCENT_RED = {1.0f, 0.0f, 0.0f, 0.3f}; +static const Color GREEN = {0.0f, 1.0f, 0.0f, 1.0f}; +static const Color BLUE = {0.0f, 0.0f, 1.0f, 1.0f}; +static const Color WHITE = {1.0f, 1.0f, 1.0f, 1.0f}; class TestRenderEngine; diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h index 16d63e57ca..d3266e7623 100644 --- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h +++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h @@ -29,7 +29,8 @@ #include <aidl/android/hardware/graphics/common/BlendMode.h> #include <aidl/android/hardware/graphics/composer3/Color.h> #include <aidl/android/hardware/graphics/composer3/Composition.h> -#include <aidl/android/hardware/graphics/composer3/FloatColor.h> +#include <aidl/android/hardware/graphics/composer3/DisplayBrightness.h> +#include <aidl/android/hardware/graphics/composer3/Luminance.h> #include <aidl/android/hardware/graphics/composer3/PerFrameMetadata.h> #include <aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h> @@ -79,6 +80,10 @@ class ComposerClientWriter { getDisplayCommand(display).colorTransformMatrix.emplace(std::move(matVec)); } + void setDisplayBrightness(int64_t display, float brightness) { + getDisplayCommand(display).brightness.emplace(DisplayBrightness{.brightness = brightness}); + } + void setClientTarget(int64_t display, uint32_t slot, const native_handle_t* target, int acquireFence, Dataspace dataspace, const std::vector<Rect>& damage) { ClientTarget clientTargetCommand; @@ -204,13 +209,12 @@ class ComposerClientWriter { .perFrameMetadataBlob.emplace(metadata.begin(), metadata.end()); } - void setLayerFloatColor(int64_t display, int64_t layer, FloatColor color) { - getLayerCommand(display, layer).floatColor.emplace(color); + void setLayerWhitePointNits(int64_t display, int64_t layer, float whitePointNits) { + getLayerCommand(display, layer).whitePointNits.emplace(Luminance{.nits = whitePointNits}); } - void setLayerWhitePointNits(int64_t display, int64_t layer, float whitePointNits) { - getLayerCommand(display, layer) - .whitePointNits.emplace(WhitePointNits{.nits = whitePointNits}); + void setLayerBlockingRegion(int64_t display, int64_t layer, const std::vector<Rect>& blocking) { + getLayerCommand(display, layer).blockingRegion.emplace(blocking.begin(), blocking.end()); } const std::vector<DisplayCommand>& getPendingCommands() { diff --git a/health/2.1/vts/OWNERS b/health/2.1/vts/OWNERS index 20450ba407..a6803cd82a 100644 --- a/health/2.1/vts/OWNERS +++ b/health/2.1/vts/OWNERS @@ -1,3 +1,2 @@ elsk@google.com -hridya@google.com sspatil@google.com diff --git a/health/aidl/Android.bp b/health/aidl/Android.bp index 22bb4fadc3..86bca69e07 100644 --- a/health/aidl/Android.bp +++ b/health/aidl/Android.bp @@ -62,9 +62,11 @@ cc_library { "android.hardware.health@2.0", "android.hardware.health@2.1", ], - defaults: [ - "libbinder_ndk_host_user", - ], + target: { + darwin: { + enabled: false, + }, + }, } java_library { diff --git a/health/utils/libhealthshim/Android.bp b/health/utils/libhealthshim/Android.bp index 311e951b7f..42e4ea7cc0 100644 --- a/health/utils/libhealthshim/Android.bp +++ b/health/utils/libhealthshim/Android.bp @@ -24,9 +24,11 @@ package { cc_defaults { name: "libhealthshim_defaults", host_supported: true, // for testing - defaults: [ - "libbinder_ndk_host_user", - ], + target: { + darwin: { + enabled: false, + }, + }, cflags: [ "-Wall", "-Werror", diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/Certificate.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/Certificate.aidl index d8a8128c8e..83e1797386 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/Certificate.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/Certificate.aidl @@ -12,7 +12,8 @@ * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/CipherSuite.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/CipherSuite.aidl index 2685525044..e6ec04e805 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/CipherSuite.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/CipherSuite.aidl @@ -12,7 +12,8 @@ * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl index f8d5a9e7e6..cd8d56b5bd 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl @@ -12,7 +12,8 @@ * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl index 3224e4bf06..5065641109 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl @@ -12,7 +12,8 @@ * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl index c6fb3c889e..c912c526ab 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl @@ -12,7 +12,8 @@ * 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. // /////////////////////////////////////////////////////////////////////////////// @@ -36,6 +37,7 @@ interface IIdentityCredentialStore { android.hardware.identity.HardwareInformation getHardwareInformation(); android.hardware.identity.IWritableIdentityCredential createCredential(in @utf8InCpp String docType, in boolean testCredential); android.hardware.identity.IIdentityCredential getCredential(in android.hardware.identity.CipherSuite cipherSuite, in byte[] credentialData); + android.hardware.identity.IPresentationSession createPresentationSession(in android.hardware.identity.CipherSuite cipherSuite); const int STATUS_OK = 0; const int STATUS_FAILED = 1; const int STATUS_CIPHER_SUITE_NOT_SUPPORTED = 2; diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IPresentationSession.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IPresentationSession.aidl new file mode 100644 index 0000000000..705dc292c5 --- /dev/null +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IPresentationSession.aidl @@ -0,0 +1,42 @@ +/* + * Copyright 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.identity; +@VintfStability +interface IPresentationSession { + byte[] getEphemeralKeyPair(); + long getAuthChallenge(); + void setReaderEphemeralPublicKey(in byte[] publicKey); + void setSessionTranscript(in byte[] sessionTranscript); + android.hardware.identity.IIdentityCredential getCredential(in byte[] credentialData); +} diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl index 19a29ec719..9a0fa9e9e5 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl @@ -12,7 +12,8 @@ * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestDataItem.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestDataItem.aidl index c9c2b9fec6..cec8e0c94d 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestDataItem.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestDataItem.aidl @@ -12,7 +12,8 @@ * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestNamespace.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestNamespace.aidl index aaf1e20f1d..05b9ec295f 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestNamespace.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestNamespace.aidl @@ -12,7 +12,8 @@ * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/SecureAccessControlProfile.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/SecureAccessControlProfile.aidl index 695fb3fb26..2003594eb4 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/SecureAccessControlProfile.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/SecureAccessControlProfile.aidl @@ -12,7 +12,8 @@ * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl index 8ae293b2d3..84d6ed0e8a 100644 --- a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl +++ b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl @@ -17,9 +17,9 @@ package android.hardware.identity; import android.hardware.identity.Certificate; +import android.hardware.identity.IWritableIdentityCredential; import android.hardware.identity.RequestNamespace; import android.hardware.identity.SecureAccessControlProfile; -import android.hardware.identity.IWritableIdentityCredential; import android.hardware.keymaster.HardwareAuthToken; import android.hardware.keymaster.VerificationToken; @@ -44,6 +44,9 @@ interface IIdentityCredential { * This method was deprecated in API version 3 because there's no challenge so freshness * can't be checked. Use deleteCredentalWithChallenge() instead. * + * If the method is called on an instance obtained via IPresentationSession.getCredential(), + * STATUS_FAILED must be returned. + * * @return a COSE_Sign1 signature described above * @deprecated use deleteCredentalWithChallenge() instead. */ @@ -60,6 +63,9 @@ interface IIdentityCredential { * This method may only be called once per instance. If called more than once, STATUS_FAILED * will be returned. * + * If the method is called on an instance obtained via IPresentationSession.getCredential(), + * STATUS_FAILED must be returned. + * * @return the private key, in DER format as specified in RFC 5915. */ byte[] createEphemeralKeyPair(); @@ -70,6 +76,9 @@ interface IIdentityCredential { * This method may only be called once per instance. If called more than once, STATUS_FAILED * will be returned. * + * If the method is called on an instance obtained via IPresentationSession.getCredential(), + * STATUS_FAILED must be returned. + * * @param publicKey contains the reader's ephemeral public key, in uncompressed * form (e.g. 0x04 || X || Y). */ @@ -83,6 +92,9 @@ interface IIdentityCredential { * This method may only be called once per instance. If called more than once, STATUS_FAILED * will be returned. If user authentication is not needed, this method may not be called. * + * If the method is called on an instance obtained via IPresentationSession.getCredential(), + * STATUS_FAILED must be returned. + * * @return challenge, a non-zero number. */ long createAuthChallenge(); @@ -371,6 +383,9 @@ interface IIdentityCredential { * This CBOR enables an issuer to determine the exact state of the credential it * returns issuer-signed data for. * + * If the method is called on an instance obtained via IPresentationSession.getCredential(), + * STATUS_FAILED must be returned. + * * @param out signingKeyBlob contains an AES-GCM-ENC(storageKey, R, signingKey, docType) * where signingKey is an EC private key in uncompressed form. That is, the returned * blob is an encrypted copy of the newly-generated private signing key. @@ -420,6 +435,9 @@ interface IIdentityCredential { * * This method was introduced in API version 3. * + * If the method is called on an instance obtained via IPresentationSession.getCredential(), + * STATUS_FAILED must be returned. + * * @param challenge a challenge set by the issuer to ensure freshness. Maximum size is 32 bytes * and it may be empty. Fails with STATUS_INVALID_DATA if bigger than 32 bytes. * @return a COSE_Sign1 signature described above. @@ -442,6 +460,9 @@ interface IIdentityCredential { * * This method was introduced in API version 3. * + * If the method is called on an instance obtained via IPresentationSession.getCredential(), + * STATUS_FAILED must be returned. + * * @param challenge a challenge set by the issuer to ensure freshness. Maximum size is 32 bytes * and it may be empty. Fails with STATUS_INVALID_DATA if bigger than 32 bytes. * @return a COSE_Sign1 signature described above. @@ -456,6 +477,9 @@ interface IIdentityCredential { * * This method was introduced in API version 3. * + * If the method is called on an instance obtained via IPresentationSession.getCredential(), + * STATUS_FAILED must be returned. + * * @return an IWritableIdentityCredential */ IWritableIdentityCredential updateCredential(); diff --git a/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl b/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl index 638be796c4..86be7f5879 100644 --- a/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl +++ b/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl @@ -16,10 +16,11 @@ package android.hardware.identity; +import android.hardware.identity.CipherSuite; +import android.hardware.identity.HardwareInformation; import android.hardware.identity.IIdentityCredential; +import android.hardware.identity.IPresentationSession; import android.hardware.identity.IWritableIdentityCredential; -import android.hardware.identity.HardwareInformation; -import android.hardware.identity.CipherSuite; /** * IIdentityCredentialStore provides an interface to a secure store for user identity documents. @@ -105,7 +106,7 @@ import android.hardware.identity.CipherSuite; * STATUS_* integers defined in this interface. Each method states which status can be returned * and under which circumstances. * - * The API described here is API version 3 which corresponds to feature version 202101 + * The API described here is API version 4 which corresponds to feature version 202201 * of the android.security.identity Framework API. An XML file declaring the feature * android.hardware.identity_credential (or android.hardware.identity_credential.direct_access * if implementing the Direct Access HAL) should be included declaring this feature version. @@ -241,4 +242,25 @@ interface IIdentityCredentialStore { * @return an IIdentityCredential interface that provides operations on the Credential. */ IIdentityCredential getCredential(in CipherSuite cipherSuite, in byte[] credentialData); + + /** + * createPresentationSession creates IPresentationSession interface which can be used to + * present one or more credentials to a remote verifier device. + * + * The cipher suite used to communicate with the remote verifier must be specified. Currently + * only a single cipher-suite is supported. Support for other cipher suites may be added in a + * future version of this HAL. If the requested cipher suite is not support the call fails + * with STATUS_CIPHER_SUITE_NOT_SUPPORTED. + * + * In this version of the HAL, implementations are only required to support a single session + * being active. In a future version, implementations may be required to support multiple + * presentation sessions being active at the same time. + * + * This method was introduced in API version 4. + * + * @param cipherSuite The cipher suite to use. + * + * @return an IPresentationSession interface. + */ + IPresentationSession createPresentationSession(in CipherSuite cipherSuite); } diff --git a/identity/aidl/android/hardware/identity/IPresentationSession.aidl b/identity/aidl/android/hardware/identity/IPresentationSession.aidl new file mode 100644 index 0000000000..b0449f0bba --- /dev/null +++ b/identity/aidl/android/hardware/identity/IPresentationSession.aidl @@ -0,0 +1,101 @@ +/* + * Copyright 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.identity; + +import android.hardware.identity.CipherSuite; +import android.hardware.identity.IIdentityCredential; + +/** + * An interface to present multiple credentials in the same session. + * + * This interface was introduced in API version 4. + * + */ +@VintfStability +interface IPresentationSession { + /** + * Gets the ephemeral EC key pair to be used in establishing a secure session with a reader. + * This method returns the private key so the caller can perform an ECDH key agreement operation + * with the reader. The reason for generating the key pair in the secure environment is so that + * the secure environment knows what public key to expect to find in the session transcript + * when presenting credentials. + * + * The generated key matches the selected cipher suite of the presentation session (e.g. EC + * key using the P-256 curve). + * + * @return the private key, in DER format as specified in RFC 5915. + */ + byte[] getEphemeralKeyPair(); + + /** + * Gets the challenge value to be used for proving successful user authentication. This + * is to be included in the authToken passed to the IIdentityCredential.startRetrieval() + * method and the verificationToken passed to the IIdentityCredential.setVerificationToken() + * method. + * + * @return challenge, a non-zero number. + */ + long getAuthChallenge(); + + /** + * Sets the public part of the reader's ephemeral key pair to be used to complete + * an ECDH key agreement for the session. + * + * The curve of the key must match the curve for the key returned by getEphemeralKeyPair(). + * + * This method may only be called once per instance. If called more than once, STATUS_FAILED + * must be returned. + * + * @param publicKey contains the reader's ephemeral public key, in uncompressed + * form (e.g. 0x04 || X || Y). + */ + void setReaderEphemeralPublicKey(in byte[] publicKey); + + /** + * Sets the session transcript for the session. + * + * This can be empty but if it's non-empty it must be valid CBOR. + * + * This method may only be called once per instance. If called more than once, STATUS_FAILED + * must be returned. + * + * @param sessionTrancsript the session transcript. + */ + void setSessionTranscript(in byte[] sessionTranscript); + + /** + * getCredential() retrieves an IIdentityCredential interface for presentation in the + * current presentation session. + * + * On the returned instance only the methods startRetrieval(), startRetrieveEntryValue(), + * retrieveEntryValue(), finishRetrieval(), setRequestedNamespaces(), setVerificationToken() + * may be called. Other methods will fail with STATUS_FAILED. + * + * The implementation is expected to get the session transcript, ephemeral key, reader + * ephemeral key, and auth challenge from this instance. + * + * @param credentialData is a CBOR-encoded structure containing metadata about the credential + * and an encrypted byte array that contains data used to secure the credential. See the + * return argument of the same name in IWritableIdentityCredential.finishAddingEntries(). + * + * Note that the format of credentialData may depend on the feature version. + * Implementations must support credentialData created by an earlier feature version. + * + * @return an IIdentityCredential interface that provides operations on the Credential. + */ + IIdentityCredential getCredential(in byte[] credentialData); +} diff --git a/identity/aidl/default/Android.bp b/identity/aidl/default/Android.bp index 3de8d30148..ca24afa6cc 100644 --- a/identity/aidl/default/Android.bp +++ b/identity/aidl/default/Android.bp @@ -13,6 +13,7 @@ cc_library_static { srcs: [ "common/IdentityCredential.cpp", "common/IdentityCredentialStore.cpp", + "common/PresentationSession.cpp", "common/WritableIdentityCredential.cpp", ], export_include_dirs: [ @@ -39,8 +40,8 @@ cc_library_static { "libsoft_attestation_cert", "libpuresoftkeymasterdevice", "android.hardware.identity-support-lib", - "android.hardware.identity-V3-ndk", - "android.hardware.keymaster-V3-ndk", + "android.hardware.identity-V4-ndk", + "android.hardware.keymaster-V4-ndk", ], } @@ -49,6 +50,7 @@ cc_library_static { vendor_available: true, srcs: [ "libeic/EicCbor.c", + "libeic/EicSession.c", "libeic/EicPresentation.c", "libeic/EicProvisioning.c", "EicOpsImpl.cc", @@ -100,8 +102,8 @@ cc_binary { "libsoft_attestation_cert", "libpuresoftkeymasterdevice", "android.hardware.identity-support-lib", - "android.hardware.identity-V3-ndk", - "android.hardware.keymaster-V3-ndk", + "android.hardware.identity-V4-ndk", + "android.hardware.keymaster-V4-ndk", "android.hardware.identity-libeic-hal-common", "android.hardware.identity-libeic-library", ], diff --git a/identity/aidl/default/EicOpsImpl.cc b/identity/aidl/default/EicOpsImpl.cc index 8ec4cc9b58..c98a91ebc3 100644 --- a/identity/aidl/default/EicOpsImpl.cc +++ b/identity/aidl/default/EicOpsImpl.cc @@ -20,9 +20,13 @@ #include <tuple> #include <vector> +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include <string.h> + #include <android-base/logging.h> #include <android-base/stringprintf.h> -#include <string.h> #include <android/hardware/identity/support/IdentityCredentialSupport.h> @@ -63,6 +67,11 @@ size_t eicStrLen(const char* s) { return strlen(s); } +void* eicMemMem(const uint8_t* haystack, size_t haystackLen, const uint8_t* needle, + size_t needleLen) { + return memmem(haystack, haystackLen, needle, needleLen); +} + int eicCryptoMemCmp(const void* s1, const void* s2, size_t n) { return CRYPTO_memcmp(s1, s2, n); } @@ -117,6 +126,25 @@ bool eicOpsRandom(uint8_t* buf, size_t numBytes) { return true; } +bool eicNextId(uint32_t* id) { + uint32_t oldId = *id; + uint32_t newId = 0; + + do { + union { + uint8_t value8; + uint32_t value32; + } value; + if (!eicOpsRandom(&value.value8, sizeof(value))) { + return false; + } + newId = value.value32; + } while (newId == oldId && newId == 0); + + *id = newId; + return true; +} + bool eicOpsEncryptAes128Gcm( const uint8_t* key, // Must be 16 bytes const uint8_t* nonce, // Must be 12 bytes diff --git a/identity/aidl/default/EicTests.cpp b/identity/aidl/default/EicTests.cpp index a28080d009..7b69b75acd 100644 --- a/identity/aidl/default/EicTests.cpp +++ b/identity/aidl/default/EicTests.cpp @@ -66,7 +66,8 @@ TEST(EicTest, AccessControlIsEnforced) { // Then present data from it... // FakeSecureHardwarePresentationProxy presentationProxy; - ASSERT_TRUE(presentationProxy.initialize(isTestCredential, docType, credData.value())); + ASSERT_TRUE(presentationProxy.initialize(0 /* sessionId */, isTestCredential, docType, + credData.value())); AccessCheckResult res = presentationProxy.startRetrieveEntryValue(nameSpace, name, 1, content.size(), acpIds); ASSERT_EQ(res, AccessCheckResult::kNoAccessControlProfiles); diff --git a/identity/aidl/default/FakeSecureHardwareProxy.cpp b/identity/aidl/default/FakeSecureHardwareProxy.cpp index f0307dc324..91e634c0c3 100644 --- a/identity/aidl/default/FakeSecureHardwareProxy.cpp +++ b/identity/aidl/default/FakeSecureHardwareProxy.cpp @@ -23,6 +23,7 @@ #include <android-base/logging.h> #include <android-base/stringprintf.h> #include <string.h> +#include <map> #include <openssl/sha.h> @@ -52,38 +53,110 @@ namespace android::hardware::identity { // ---------------------------------------------------------------------- -FakeSecureHardwareProvisioningProxy::FakeSecureHardwareProvisioningProxy() {} +// The singleton EicProvisioning object used everywhere. +// +EicProvisioning FakeSecureHardwareProvisioningProxy::ctx_; -FakeSecureHardwareProvisioningProxy::~FakeSecureHardwareProvisioningProxy() {} - -bool FakeSecureHardwareProvisioningProxy::shutdown() { - LOG(INFO) << "FakeSecureHardwarePresentationProxy shutdown"; - return true; +FakeSecureHardwareProvisioningProxy::~FakeSecureHardwareProvisioningProxy() { + if (id_ != 0) { + shutdown(); + } } bool FakeSecureHardwareProvisioningProxy::initialize(bool testCredential) { - LOG(INFO) << "FakeSecureHardwareProvisioningProxy created, sizeof(EicProvisioning): " - << sizeof(EicProvisioning); - return eicProvisioningInit(&ctx_, testCredential); + if (id_ != 0) { + LOG(WARNING) << "Proxy is already initialized"; + return false; + } + bool initialized = eicProvisioningInit(&ctx_, testCredential); + if (!initialized) { + return false; + } + optional<uint32_t> id = getId(); + if (!id) { + LOG(WARNING) << "Error getting id"; + return false; + } + id_ = id.value(); + return true; } bool FakeSecureHardwareProvisioningProxy::initializeForUpdate( - bool testCredential, string docType, vector<uint8_t> encryptedCredentialKeys) { - return eicProvisioningInitForUpdate(&ctx_, testCredential, docType.c_str(), - docType.size(), - encryptedCredentialKeys.data(), - encryptedCredentialKeys.size()); + bool testCredential, const string& docType, + const vector<uint8_t>& encryptedCredentialKeys) { + if (id_ != 0) { + LOG(WARNING) << "Proxy is already initialized"; + return false; + } + bool initialized = eicProvisioningInitForUpdate(&ctx_, testCredential, docType.c_str(), + docType.size(), encryptedCredentialKeys.data(), + encryptedCredentialKeys.size()); + if (!initialized) { + return false; + } + optional<uint32_t> id = getId(); + if (!id) { + LOG(WARNING) << "Error getting id"; + return false; + } + id_ = id.value(); + return true; +} + +optional<uint32_t> FakeSecureHardwareProvisioningProxy::getId() { + uint32_t id; + if (!eicProvisioningGetId(&ctx_, &id)) { + return std::nullopt; + } + return id; +} + +bool FakeSecureHardwareProvisioningProxy::validateId(const string& callerName) { + if (id_ == 0) { + LOG(WARNING) << "FakeSecureHardwareProvisioningProxy::" << callerName + << ": While validating expected id is 0"; + return false; + } + optional<uint32_t> id = getId(); + if (!id) { + LOG(WARNING) << "FakeSecureHardwareProvisioningProxy::" << callerName + << ": Error getting id for validating"; + return false; + } + if (id.value() != id_) { + LOG(WARNING) << "FakeSecureHardwareProvisioningProxy::" << callerName + << ": While validating expected id " << id_ << " but got " << id.value(); + return false; + } + return true; +} + +bool FakeSecureHardwareProvisioningProxy::shutdown() { + bool validated = validateId(__func__); + id_ = 0; + if (!validated) { + return false; + } + if (!eicProvisioningShutdown(&ctx_)) { + LOG(INFO) << "Error shutting down provisioning"; + return false; + } + return true; } // Returns public key certificate. optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::createCredentialKey( const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId) { + if (!validateId(__func__)) { + return std::nullopt; + } + uint8_t publicKeyCert[4096]; size_t publicKeyCertSize = sizeof publicKeyCert; if (!eicProvisioningCreateCredentialKey(&ctx_, challenge.data(), challenge.size(), applicationId.data(), applicationId.size(), publicKeyCert, &publicKeyCertSize)) { - return {}; + return std::nullopt; } vector<uint8_t> pubKeyCert(publicKeyCertSize); memcpy(pubKeyCert.data(), publicKeyCert, publicKeyCertSize); @@ -91,8 +164,11 @@ optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::createCredentialK } bool FakeSecureHardwareProvisioningProxy::startPersonalization( - int accessControlProfileCount, vector<int> entryCounts, const string& docType, + int accessControlProfileCount, const vector<int>& entryCounts, const string& docType, size_t expectedProofOfProvisioningSize) { + if (!validateId(__func__)) { + return false; + } if (!eicProvisioningStartPersonalization(&ctx_, accessControlProfileCount, entryCounts.data(), @@ -108,13 +184,17 @@ bool FakeSecureHardwareProvisioningProxy::startPersonalization( optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::addAccessControlProfile( int id, const vector<uint8_t>& readerCertificate, bool userAuthenticationRequired, uint64_t timeoutMillis, uint64_t secureUserId) { + if (!validateId(__func__)) { + return std::nullopt; + } + vector<uint8_t> mac(28); uint8_t scratchSpace[512]; if (!eicProvisioningAddAccessControlProfile( &ctx_, id, readerCertificate.data(), readerCertificate.size(), userAuthenticationRequired, timeoutMillis, secureUserId, mac.data(), scratchSpace, sizeof(scratchSpace))) { - return {}; + return std::nullopt; } return mac; } @@ -122,6 +202,10 @@ optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::addAccessControlP bool FakeSecureHardwareProvisioningProxy::beginAddEntry(const vector<int>& accessControlProfileIds, const string& nameSpace, const string& name, uint64_t entrySize) { + if (!validateId(__func__)) { + return false; + } + uint8_t scratchSpace[512]; vector<uint8_t> uint8AccessControlProfileIds; for (size_t i = 0; i < accessControlProfileIds.size(); i++) { @@ -138,6 +222,10 @@ bool FakeSecureHardwareProvisioningProxy::beginAddEntry(const vector<int>& acces optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::addEntryValue( const vector<int>& accessControlProfileIds, const string& nameSpace, const string& name, const vector<uint8_t>& content) { + if (!validateId(__func__)) { + return std::nullopt; + } + vector<uint8_t> eicEncryptedContent; uint8_t scratchSpace[512]; vector<uint8_t> uint8AccessControlProfileIds; @@ -150,16 +238,20 @@ optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::addEntryValue( &ctx_, uint8AccessControlProfileIds.data(), uint8AccessControlProfileIds.size(), nameSpace.c_str(), nameSpace.size(), name.c_str(), name.size(), content.data(), content.size(), eicEncryptedContent.data(), scratchSpace, sizeof(scratchSpace))) { - return {}; + return std::nullopt; } return eicEncryptedContent; } // Returns signatureOfToBeSigned (EIC_ECDSA_P256_SIGNATURE_SIZE bytes). optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::finishAddingEntries() { + if (!validateId(__func__)) { + return std::nullopt; + } + vector<uint8_t> signatureOfToBeSigned(EIC_ECDSA_P256_SIGNATURE_SIZE); if (!eicProvisioningFinishAddingEntries(&ctx_, signatureOfToBeSigned.data())) { - return {}; + return std::nullopt; } return signatureOfToBeSigned; } @@ -167,11 +259,15 @@ optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::finishAddingEntri // Returns encryptedCredentialKeys. optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::finishGetCredentialData( const string& docType) { + if (!validateId(__func__)) { + return std::nullopt; + } + vector<uint8_t> encryptedCredentialKeys(116); size_t size = encryptedCredentialKeys.size(); if (!eicProvisioningFinishGetCredentialData(&ctx_, docType.c_str(), docType.size(), encryptedCredentialKeys.data(), &size)) { - return {}; + return std::nullopt; } encryptedCredentialKeys.resize(size); return encryptedCredentialKeys; @@ -179,21 +275,200 @@ optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::finishGetCredenti // ---------------------------------------------------------------------- -FakeSecureHardwarePresentationProxy::FakeSecureHardwarePresentationProxy() {} +// The singleton EicSession object used everywhere. +// +EicSession FakeSecureHardwareSessionProxy::ctx_; + +FakeSecureHardwareSessionProxy::~FakeSecureHardwareSessionProxy() { + if (id_ != 0) { + shutdown(); + } +} + +bool FakeSecureHardwareSessionProxy::initialize() { + if (id_ != 0) { + LOG(WARNING) << "Proxy is already initialized"; + return false; + } + bool initialized = eicSessionInit(&ctx_); + if (!initialized) { + return false; + } + optional<uint32_t> id = getId(); + if (!id) { + LOG(WARNING) << "Error getting id"; + return false; + } + id_ = id.value(); + return true; +} + +optional<uint32_t> FakeSecureHardwareSessionProxy::getId() { + uint32_t id; + if (!eicSessionGetId(&ctx_, &id)) { + return std::nullopt; + } + return id; +} + +bool FakeSecureHardwareSessionProxy::shutdown() { + bool validated = validateId(__func__); + id_ = 0; + if (!validated) { + return false; + } + if (!eicSessionShutdown(&ctx_)) { + LOG(INFO) << "Error shutting down session"; + return false; + } + return true; +} + +bool FakeSecureHardwareSessionProxy::validateId(const string& callerName) { + if (id_ == 0) { + LOG(WARNING) << "FakeSecureHardwareSessionProxy::" << callerName + << ": While validating expected id is 0"; + return false; + } + optional<uint32_t> id = getId(); + if (!id) { + LOG(WARNING) << "FakeSecureHardwareSessionProxy::" << callerName + << ": Error getting id for validating"; + return false; + } + if (id.value() != id_) { + LOG(WARNING) << "FakeSecureHardwareSessionProxy::" << callerName + << ": While validating expected id " << id_ << " but got " << id.value(); + return false; + } + return true; +} -FakeSecureHardwarePresentationProxy::~FakeSecureHardwarePresentationProxy() {} +optional<uint64_t> FakeSecureHardwareSessionProxy::getAuthChallenge() { + if (!validateId(__func__)) { + return std::nullopt; + } -bool FakeSecureHardwarePresentationProxy::initialize(bool testCredential, string docType, - vector<uint8_t> encryptedCredentialKeys) { - LOG(INFO) << "FakeSecureHardwarePresentationProxy created, sizeof(EicPresentation): " - << sizeof(EicPresentation); - return eicPresentationInit(&ctx_, testCredential, docType.c_str(), docType.size(), - encryptedCredentialKeys.data(), encryptedCredentialKeys.size()); + uint64_t authChallenge; + if (!eicSessionGetAuthChallenge(&ctx_, &authChallenge)) { + return std::nullopt; + } + return authChallenge; +} + +optional<vector<uint8_t>> FakeSecureHardwareSessionProxy::getEphemeralKeyPair() { + if (!validateId(__func__)) { + return std::nullopt; + } + + vector<uint8_t> priv(EIC_P256_PRIV_KEY_SIZE); + if (!eicSessionGetEphemeralKeyPair(&ctx_, priv.data())) { + return std::nullopt; + } + return priv; +} + +bool FakeSecureHardwareSessionProxy::setReaderEphemeralPublicKey( + const vector<uint8_t>& readerEphemeralPublicKey) { + if (!validateId(__func__)) { + return false; + } + + return eicSessionSetReaderEphemeralPublicKey(&ctx_, readerEphemeralPublicKey.data()); +} + +bool FakeSecureHardwareSessionProxy::setSessionTranscript( + const vector<uint8_t>& sessionTranscript) { + if (!validateId(__func__)) { + return false; + } + + return eicSessionSetSessionTranscript(&ctx_, sessionTranscript.data(), + sessionTranscript.size()); +} + +// ---------------------------------------------------------------------- + +// The singleton EicPresentation object used everywhere. +// +EicPresentation FakeSecureHardwarePresentationProxy::ctx_; + +FakeSecureHardwarePresentationProxy::~FakeSecureHardwarePresentationProxy() { + if (id_ != 0) { + shutdown(); + } +} + +bool FakeSecureHardwarePresentationProxy::initialize( + uint32_t sessionId, bool testCredential, const string& docType, + const vector<uint8_t>& encryptedCredentialKeys) { + if (id_ != 0) { + LOG(WARNING) << "Proxy is already initialized"; + return false; + } + bool initialized = + eicPresentationInit(&ctx_, sessionId, testCredential, docType.c_str(), docType.size(), + encryptedCredentialKeys.data(), encryptedCredentialKeys.size()); + if (!initialized) { + return false; + } + optional<uint32_t> id = getId(); + if (!id) { + LOG(WARNING) << "Error getting id"; + return false; + } + id_ = id.value(); + return true; +} + +optional<uint32_t> FakeSecureHardwarePresentationProxy::getId() { + uint32_t id; + if (!eicPresentationGetId(&ctx_, &id)) { + return std::nullopt; + } + return id; +} + +bool FakeSecureHardwarePresentationProxy::validateId(const string& callerName) { + if (id_ == 0) { + LOG(WARNING) << "FakeSecureHardwarePresentationProxy::" << callerName + << ": While validating expected id is 0"; + return false; + } + optional<uint32_t> id = getId(); + if (!id) { + LOG(WARNING) << "FakeSecureHardwarePresentationProxy::" << callerName + << ": Error getting id for validating"; + return false; + } + if (id.value() != id_) { + LOG(WARNING) << "FakeSecureHardwarePresentationProxy::" << callerName + << ": While validating expected id " << id_ << " but got " << id.value(); + return false; + } + return true; +} + +bool FakeSecureHardwarePresentationProxy::shutdown() { + bool validated = validateId(__func__); + id_ = 0; + if (!validated) { + return false; + } + if (!eicPresentationShutdown(&ctx_)) { + LOG(INFO) << "Error shutting down presentation"; + return false; + } + return true; } // Returns publicKeyCert (1st component) and signingKeyBlob (2nd component) optional<pair<vector<uint8_t>, vector<uint8_t>>> -FakeSecureHardwarePresentationProxy::generateSigningKeyPair(string docType, time_t now) { +FakeSecureHardwarePresentationProxy::generateSigningKeyPair(const string& docType, time_t now) { + if (!validateId(__func__)) { + return std::nullopt; + } + uint8_t publicKeyCert[512]; size_t publicKeyCertSize = sizeof(publicKeyCert); vector<uint8_t> signingKeyBlob(60); @@ -201,7 +476,7 @@ FakeSecureHardwarePresentationProxy::generateSigningKeyPair(string docType, time if (!eicPresentationGenerateSigningKeyPair(&ctx_, docType.c_str(), docType.size(), now, publicKeyCert, &publicKeyCertSize, signingKeyBlob.data())) { - return {}; + return std::nullopt; } vector<uint8_t> cert; @@ -213,33 +488,44 @@ FakeSecureHardwarePresentationProxy::generateSigningKeyPair(string docType, time // Returns private key optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::createEphemeralKeyPair() { + if (!validateId(__func__)) { + return std::nullopt; + } + vector<uint8_t> priv(EIC_P256_PRIV_KEY_SIZE); if (!eicPresentationCreateEphemeralKeyPair(&ctx_, priv.data())) { - return {}; + return std::nullopt; } return priv; } optional<uint64_t> FakeSecureHardwarePresentationProxy::createAuthChallenge() { + if (!validateId(__func__)) { + return std::nullopt; + } + uint64_t challenge; if (!eicPresentationCreateAuthChallenge(&ctx_, &challenge)) { - return {}; + return std::nullopt; } return challenge; } -bool FakeSecureHardwarePresentationProxy::shutdown() { - LOG(INFO) << "FakeSecureHardwarePresentationProxy shutdown"; - return true; -} - bool FakeSecureHardwarePresentationProxy::pushReaderCert(const vector<uint8_t>& certX509) { + if (!validateId(__func__)) { + return false; + } + return eicPresentationPushReaderCert(&ctx_, certX509.data(), certX509.size()); } bool FakeSecureHardwarePresentationProxy::validateRequestMessage( const vector<uint8_t>& sessionTranscript, const vector<uint8_t>& requestMessage, int coseSignAlg, const vector<uint8_t>& readerSignatureOfToBeSigned) { + if (!validateId(__func__)) { + return false; + } + return eicPresentationValidateRequestMessage( &ctx_, sessionTranscript.data(), sessionTranscript.size(), requestMessage.data(), requestMessage.size(), coseSignAlg, readerSignatureOfToBeSigned.data(), @@ -251,6 +537,10 @@ bool FakeSecureHardwarePresentationProxy::setAuthToken( int hardwareAuthenticatorType, uint64_t timeStamp, const vector<uint8_t>& mac, uint64_t verificationTokenChallenge, uint64_t verificationTokenTimestamp, int verificationTokenSecurityLevel, const vector<uint8_t>& verificationTokenMac) { + if (!validateId(__func__)) { + return false; + } + return eicPresentationSetAuthToken(&ctx_, challenge, secureUserId, authenticatorId, hardwareAuthenticatorType, timeStamp, mac.data(), mac.size(), verificationTokenChallenge, verificationTokenTimestamp, @@ -261,6 +551,10 @@ bool FakeSecureHardwarePresentationProxy::setAuthToken( optional<bool> FakeSecureHardwarePresentationProxy::validateAccessControlProfile( int id, const vector<uint8_t>& readerCertificate, bool userAuthenticationRequired, int timeoutMillis, uint64_t secureUserId, const vector<uint8_t>& mac) { + if (!validateId(__func__)) { + return std::nullopt; + } + bool accessGranted = false; uint8_t scratchSpace[512]; if (!eicPresentationValidateAccessControlProfile(&ctx_, id, readerCertificate.data(), @@ -268,12 +562,16 @@ optional<bool> FakeSecureHardwarePresentationProxy::validateAccessControlProfile userAuthenticationRequired, timeoutMillis, secureUserId, mac.data(), &accessGranted, scratchSpace, sizeof(scratchSpace))) { - return {}; + return std::nullopt; } return accessGranted; } bool FakeSecureHardwarePresentationProxy::startRetrieveEntries() { + if (!validateId(__func__)) { + return false; + } + return eicPresentationStartRetrieveEntries(&ctx_); } @@ -281,6 +579,10 @@ bool FakeSecureHardwarePresentationProxy::calcMacKey( const vector<uint8_t>& sessionTranscript, const vector<uint8_t>& readerEphemeralPublicKey, const vector<uint8_t>& signingKeyBlob, const string& docType, unsigned int numNamespacesWithValues, size_t expectedProofOfProvisioningSize) { + if (!validateId(__func__)) { + return false; + } + if (signingKeyBlob.size() != 60) { eicDebug("Unexpected size %zd of signingKeyBlob, expected 60", signingKeyBlob.size()); return false; @@ -294,6 +596,10 @@ bool FakeSecureHardwarePresentationProxy::calcMacKey( AccessCheckResult FakeSecureHardwarePresentationProxy::startRetrieveEntryValue( const string& nameSpace, const string& name, unsigned int newNamespaceNumEntries, int32_t entrySize, const vector<int32_t>& accessControlProfileIds) { + if (!validateId(__func__)) { + return AccessCheckResult::kFailed; + } + uint8_t scratchSpace[512]; vector<uint8_t> uint8AccessControlProfileIds; for (size_t i = 0; i < accessControlProfileIds.size(); i++) { @@ -324,6 +630,10 @@ AccessCheckResult FakeSecureHardwarePresentationProxy::startRetrieveEntryValue( optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::retrieveEntryValue( const vector<uint8_t>& encryptedContent, const string& nameSpace, const string& name, const vector<int32_t>& accessControlProfileIds) { + if (!validateId(__func__)) { + return std::nullopt; + } + uint8_t scratchSpace[512]; vector<uint8_t> uint8AccessControlProfileIds; for (size_t i = 0; i < accessControlProfileIds.size(); i++) { @@ -337,16 +647,20 @@ optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::retrieveEntryValu nameSpace.c_str(), nameSpace.size(), name.c_str(), name.size(), uint8AccessControlProfileIds.data(), uint8AccessControlProfileIds.size(), scratchSpace, sizeof(scratchSpace))) { - return {}; + return std::nullopt; } return content; } optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::finishRetrieval() { + if (!validateId(__func__)) { + return std::nullopt; + } + vector<uint8_t> mac(32); size_t macSize = 32; if (!eicPresentationFinishRetrieval(&ctx_, mac.data(), &macSize)) { - return {}; + return std::nullopt; } mac.resize(macSize); return mac; @@ -355,11 +669,15 @@ optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::finishRetrieval() optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::deleteCredential( const string& docType, const vector<uint8_t>& challenge, bool includeChallenge, size_t proofOfDeletionCborSize) { + if (!validateId(__func__)) { + return std::nullopt; + } + vector<uint8_t> signatureOfToBeSigned(EIC_ECDSA_P256_SIGNATURE_SIZE); if (!eicPresentationDeleteCredential(&ctx_, docType.c_str(), docType.size(), challenge.data(), challenge.size(), includeChallenge, proofOfDeletionCborSize, signatureOfToBeSigned.data())) { - return {}; + return std::nullopt; } return signatureOfToBeSigned; } @@ -367,11 +685,15 @@ optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::deleteCredential( optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::proveOwnership( const string& docType, bool testCredential, const vector<uint8_t>& challenge, size_t proofOfOwnershipCborSize) { + if (!validateId(__func__)) { + return std::nullopt; + } + vector<uint8_t> signatureOfToBeSigned(EIC_ECDSA_P256_SIGNATURE_SIZE); if (!eicPresentationProveOwnership(&ctx_, docType.c_str(), docType.size(), testCredential, challenge.data(), challenge.size(), proofOfOwnershipCborSize, signatureOfToBeSigned.data())) { - return {}; + return std::nullopt; } return signatureOfToBeSigned; } diff --git a/identity/aidl/default/FakeSecureHardwareProxy.h b/identity/aidl/default/FakeSecureHardwareProxy.h index 6852c1a979..df98c7a121 100644 --- a/identity/aidl/default/FakeSecureHardwareProxy.h +++ b/identity/aidl/default/FakeSecureHardwareProxy.h @@ -27,21 +27,23 @@ namespace android::hardware::identity { // class FakeSecureHardwareProvisioningProxy : public SecureHardwareProvisioningProxy { public: - FakeSecureHardwareProvisioningProxy(); + FakeSecureHardwareProvisioningProxy() = default; virtual ~FakeSecureHardwareProvisioningProxy(); bool initialize(bool testCredential) override; - bool initializeForUpdate(bool testCredential, string docType, - vector<uint8_t> encryptedCredentialKeys) override; + bool initializeForUpdate(bool testCredential, const string& docType, + const vector<uint8_t>& encryptedCredentialKeys) override; bool shutdown() override; + optional<uint32_t> getId() override; + // Returns public key certificate. optional<vector<uint8_t>> createCredentialKey(const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId) override; - bool startPersonalization(int accessControlProfileCount, vector<int> entryCounts, + bool startPersonalization(int accessControlProfileCount, const vector<int>& entryCounts, const string& docType, size_t expectedProofOfProvisioningSize) override; @@ -67,21 +69,81 @@ class FakeSecureHardwareProvisioningProxy : public SecureHardwareProvisioningPro optional<vector<uint8_t>> finishGetCredentialData(const string& docType) override; protected: - EicProvisioning ctx_; + // See docs for id_. + // + bool validateId(const string& callerName); + + // We use a singleton libeic object, shared by all proxy instances. This is to + // properly simulate a situation where libeic is used on constrained hardware + // with only enough RAM for a single instance of the libeic object. + // + static EicProvisioning ctx_; + + // On the HAL side we keep track of the ID that was assigned to the libeic object + // created in secure hardware. For every call into libeic we validate that this + // identifier matches what is on the secure side. This is what the validateId() + // method does. + // + uint32_t id_ = 0; +}; + +// This implementation uses libEmbeddedIC in-process. +// +class FakeSecureHardwareSessionProxy : public SecureHardwareSessionProxy { + public: + FakeSecureHardwareSessionProxy() = default; + virtual ~FakeSecureHardwareSessionProxy(); + + bool initialize() override; + + bool shutdown() override; + + optional<uint32_t> getId() override; + + optional<uint64_t> getAuthChallenge() override; + + // Returns private key + optional<vector<uint8_t>> getEphemeralKeyPair() override; + + bool setReaderEphemeralPublicKey(const vector<uint8_t>& readerEphemeralPublicKey) override; + + bool setSessionTranscript(const vector<uint8_t>& sessionTranscript) override; + + protected: + // See docs for id_. + // + bool validateId(const string& callerName); + + // We use a singleton libeic object, shared by all proxy instances. This is to + // properly simulate a situation where libeic is used on constrained hardware + // with only enough RAM for a single instance of the libeic object. + // + static EicSession ctx_; + + // On the HAL side we keep track of the ID that was assigned to the libeic object + // created in secure hardware. For every call into libeic we validate that this + // identifier matches what is on the secure side. This is what the validateId() + // method does. + // + uint32_t id_ = 0; }; // This implementation uses libEmbeddedIC in-process. // class FakeSecureHardwarePresentationProxy : public SecureHardwarePresentationProxy { public: - FakeSecureHardwarePresentationProxy(); + FakeSecureHardwarePresentationProxy() = default; virtual ~FakeSecureHardwarePresentationProxy(); - bool initialize(bool testCredential, string docType, - vector<uint8_t> encryptedCredentialKeys) override; + bool initialize(uint32_t sessionId, bool testCredential, const string& docType, + const vector<uint8_t>& encryptedCredentialKeys) override; + + bool shutdown() override; + + optional<uint32_t> getId() override; // Returns publicKeyCert (1st component) and signingKeyBlob (2nd component) - optional<pair<vector<uint8_t>, vector<uint8_t>>> generateSigningKeyPair(string docType, + optional<pair<vector<uint8_t>, vector<uint8_t>>> generateSigningKeyPair(const string& docType, time_t now) override; // Returns private key @@ -133,10 +195,23 @@ class FakeSecureHardwarePresentationProxy : public SecureHardwarePresentationPro const vector<uint8_t>& challenge, size_t proofOfOwnershipCborSize) override; - bool shutdown() override; - protected: - EicPresentation ctx_; + // See docs for id_. + // + bool validateId(const string& callerName); + + // We use a singleton libeic object, shared by all proxy instances. This is to + // properly simulate a situation where libeic is used on constrained hardware + // with only enough RAM for a single instance of the libeic object. + // + static EicPresentation ctx_; + + // On the HAL side we keep track of the ID that was assigned to the libeic object + // created in secure hardware. For every call into libeic we validate that this + // identifier matches what is on the secure side. This is what the validateId() + // method does. + // + uint32_t id_ = 0; }; // Factory implementation. @@ -150,6 +225,10 @@ class FakeSecureHardwareProxyFactory : public SecureHardwareProxyFactory { return new FakeSecureHardwareProvisioningProxy(); } + sp<SecureHardwareSessionProxy> createSessionProxy() override { + return new FakeSecureHardwareSessionProxy(); + } + sp<SecureHardwarePresentationProxy> createPresentationProxy() override { return new FakeSecureHardwarePresentationProxy(); } diff --git a/identity/aidl/default/android.hardware.identity_credential.xml b/identity/aidl/default/android.hardware.identity_credential.xml index 5149792b7f..20b2710e1e 100644 --- a/identity/aidl/default/android.hardware.identity_credential.xml +++ b/identity/aidl/default/android.hardware.identity_credential.xml @@ -14,5 +14,5 @@ limitations under the License. --> <permissions> - <feature name="android.hardware.identity_credential" version="202101" /> + <feature name="android.hardware.identity_credential" version="202201" /> </permissions> diff --git a/identity/aidl/default/common/IdentityCredential.cpp b/identity/aidl/default/common/IdentityCredential.cpp index 95557b5c9d..7678ecb918 100644 --- a/identity/aidl/default/common/IdentityCredential.cpp +++ b/identity/aidl/default/common/IdentityCredential.cpp @@ -72,14 +72,38 @@ int IdentityCredential::initialize() { testCredential_ = testCredentialItem->value(); encryptedCredentialKeys_ = encryptedCredentialKeysItem->value(); - if (!hwProxy_->initialize(testCredential_, docType_, encryptedCredentialKeys_)) { - LOG(ERROR) << "hwProxy->initialize failed"; - return false; + + // If in a session, delay the initialization of the proxy. + // + if (!session_) { + ndk::ScopedAStatus status = ensureHwProxy(); + if (!status.isOk()) { + LOG(ERROR) << "Error initializing hw proxy"; + return IIdentityCredentialStore::STATUS_FAILED; + } } return IIdentityCredentialStore::STATUS_OK; } +ndk::ScopedAStatus IdentityCredential::ensureHwProxy() { + if (hwProxy_) { + return ndk::ScopedAStatus::ok(); + } + hwProxy_ = hwProxyFactory_->createPresentationProxy(); + if (!hwProxy_) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, "Error creating hw proxy")); + } + uint64_t sessionId = session_ ? session_->getSessionId() : EIC_PRESENTATION_ID_UNSET; + if (!hwProxy_->initialize(sessionId, testCredential_, docType_, encryptedCredentialKeys_)) { + hwProxy_.clear(); + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, "Error initializing hw proxy")); + } + return ndk::ScopedAStatus::ok(); +} + ndk::ScopedAStatus IdentityCredential::deleteCredential( vector<uint8_t>* outProofOfDeletionSignature) { return deleteCredentialCommon({}, false, outProofOfDeletionSignature); @@ -93,6 +117,14 @@ ndk::ScopedAStatus IdentityCredential::deleteCredentialWithChallenge( ndk::ScopedAStatus IdentityCredential::deleteCredentialCommon( const vector<uint8_t>& challenge, bool includeChallenge, vector<uint8_t>* outProofOfDeletionSignature) { + if (session_) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, "Cannot be called in a session")); + } + ndk::ScopedAStatus status = ensureHwProxy(); + if (!status.isOk()) { + return status; + } if (challenge.size() > 32) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( IIdentityCredentialStore::STATUS_INVALID_DATA, "Challenge too big")); @@ -128,6 +160,14 @@ ndk::ScopedAStatus IdentityCredential::deleteCredentialCommon( ndk::ScopedAStatus IdentityCredential::proveOwnership( const vector<uint8_t>& challenge, vector<uint8_t>* outProofOfOwnershipSignature) { + if (session_) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, "Cannot be called in a session")); + } + ndk::ScopedAStatus status = ensureHwProxy(); + if (!status.isOk()) { + return status; + } if (challenge.size() > 32) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( IIdentityCredentialStore::STATUS_INVALID_DATA, "Challenge too big")); @@ -159,6 +199,14 @@ ndk::ScopedAStatus IdentityCredential::proveOwnership( } ndk::ScopedAStatus IdentityCredential::createEphemeralKeyPair(vector<uint8_t>* outKeyPair) { + if (session_) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, "Cannot be called in a session")); + } + ndk::ScopedAStatus status = ensureHwProxy(); + if (!status.isOk()) { + return status; + } optional<vector<uint8_t>> ephemeralPriv = hwProxy_->createEphemeralKeyPair(); if (!ephemeralPriv) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( @@ -186,11 +234,23 @@ ndk::ScopedAStatus IdentityCredential::createEphemeralKeyPair(vector<uint8_t>* o ndk::ScopedAStatus IdentityCredential::setReaderEphemeralPublicKey( const vector<uint8_t>& publicKey) { + if (session_) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, "Cannot be called in a session")); + } readerPublicKey_ = publicKey; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus IdentityCredential::createAuthChallenge(int64_t* outChallenge) { + if (session_) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, "Cannot be called in a session")); + } + ndk::ScopedAStatus status = ensureHwProxy(); + if (!status.isOk()) { + return status; + } optional<uint64_t> challenge = hwProxy_->createAuthChallenge(); if (!challenge) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( @@ -217,16 +277,22 @@ ndk::ScopedAStatus IdentityCredential::startRetrieval( const HardwareAuthToken& authToken, const vector<uint8_t>& itemsRequest, const vector<uint8_t>& signingKeyBlob, const vector<uint8_t>& sessionTranscript, const vector<uint8_t>& readerSignature, const vector<int32_t>& requestCounts) { - std::unique_ptr<cppbor::Item> sessionTranscriptItem; - if (sessionTranscript.size() > 0) { - auto [item, _, message] = cppbor::parse(sessionTranscript); - if (item == nullptr) { + ndk::ScopedAStatus status = ensureHwProxy(); + if (!status.isOk()) { + return status; + } + + // If in a session, ensure the passed-in session transcript matches the + // session transcript from the session. + if (session_) { + if (sessionTranscript != session_->getSessionTranscript()) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( - IIdentityCredentialStore::STATUS_INVALID_DATA, - "SessionTranscript contains invalid CBOR")); + IIdentityCredentialStore::STATUS_SESSION_TRANSCRIPT_MISMATCH, + "In a session and passed-in SessionTranscript doesn't match the one " + "from the session")); } - sessionTranscriptItem = std::move(item); } + if (numStartRetrievalCalls_ > 0) { if (sessionTranscript_ != sessionTranscript) { LOG(ERROR) << "Session Transcript changed"; @@ -390,32 +456,36 @@ ndk::ScopedAStatus IdentityCredential::startRetrieval( } } - // TODO: move this check to the TA -#if 1 - // To prevent replay-attacks, we check that the public part of the ephemeral - // key we previously created, is present in the DeviceEngagement part of - // SessionTranscript as a COSE_Key, in uncompressed form. - // - // We do this by just searching for the X and Y coordinates. - if (sessionTranscript.size() > 0) { - auto [getXYSuccess, ePubX, ePubY] = support::ecPublicKeyGetXandY(ephemeralPublicKey_); - if (!getXYSuccess) { - return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( - IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND, - "Error extracting X and Y from ePub")); - } - if (sessionTranscript.size() > 0 && - !(memmem(sessionTranscript.data(), sessionTranscript.size(), ePubX.data(), - ePubX.size()) != nullptr && - memmem(sessionTranscript.data(), sessionTranscript.size(), ePubY.data(), - ePubY.size()) != nullptr)) { - return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( - IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND, - "Did not find ephemeral public key's X and Y coordinates in " - "SessionTranscript (make sure leading zeroes are not used)")); + if (session_) { + // If presenting in a session, the TA has already done this check. + + } else { + // To prevent replay-attacks, we check that the public part of the ephemeral + // key we previously created, is present in the DeviceEngagement part of + // SessionTranscript as a COSE_Key, in uncompressed form. + // + // We do this by just searching for the X and Y coordinates. + // + // Would be nice to move this check to the TA. + if (sessionTranscript.size() > 0) { + auto [getXYSuccess, ePubX, ePubY] = support::ecPublicKeyGetXandY(ephemeralPublicKey_); + if (!getXYSuccess) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND, + "Error extracting X and Y from ePub")); + } + if (sessionTranscript.size() > 0 && + !(memmem(sessionTranscript.data(), sessionTranscript.size(), ePubX.data(), + ePubX.size()) != nullptr && + memmem(sessionTranscript.data(), sessionTranscript.size(), ePubY.data(), + ePubY.size()) != nullptr)) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND, + "Did not find ephemeral public key's X and Y coordinates in " + "SessionTranscript (make sure leading zeroes are not used)")); + } } } -#endif // itemsRequest: If non-empty, contains request data that may be signed by the // reader. The content can be defined in the way appropriate for the @@ -537,21 +607,38 @@ ndk::ScopedAStatus IdentityCredential::startRetrieval( // Finally, pass info so the HMAC key can be derived and the TA can start // creating the DeviceNameSpaces CBOR... - if (sessionTranscript_.size() > 0 && readerPublicKey_.size() > 0 && signingKeyBlob.size() > 0) { - // We expect the reader ephemeral public key to be same size and curve - // as the ephemeral key we generated (e.g. P-256 key), otherwise ECDH - // won't work. So its length should be 65 bytes and it should be - // starting with 0x04. - if (readerPublicKey_.size() != 65 || readerPublicKey_[0] != 0x04) { - return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( - IIdentityCredentialStore::STATUS_FAILED, - "Reader public key is not in expected format")); + if (!session_) { + if (sessionTranscript_.size() > 0 && readerPublicKey_.size() > 0 && + signingKeyBlob.size() > 0) { + // We expect the reader ephemeral public key to be same size and curve + // as the ephemeral key we generated (e.g. P-256 key), otherwise ECDH + // won't work. So its length should be 65 bytes and it should be + // starting with 0x04. + if (readerPublicKey_.size() != 65 || readerPublicKey_[0] != 0x04) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, + "Reader public key is not in expected format")); + } + vector<uint8_t> pubKeyP256(readerPublicKey_.begin() + 1, readerPublicKey_.end()); + if (!hwProxy_->calcMacKey(sessionTranscript_, pubKeyP256, signingKeyBlob, docType_, + numNamespacesWithValues, expectedDeviceNameSpacesSize_)) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, + "Error starting retrieving entries")); + } } - vector<uint8_t> pubKeyP256(readerPublicKey_.begin() + 1, readerPublicKey_.end()); - if (!hwProxy_->calcMacKey(sessionTranscript_, pubKeyP256, signingKeyBlob, docType_, - numNamespacesWithValues, expectedDeviceNameSpacesSize_)) { - return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( - IIdentityCredentialStore::STATUS_FAILED, "Error starting retrieving entries")); + } else { + if (session_->getSessionTranscript().size() > 0 && + session_->getReaderEphemeralPublicKey().size() > 0 && signingKeyBlob.size() > 0) { + // Don't actually pass the reader ephemeral public key in, the TA will get + // it from the session object. + // + if (!hwProxy_->calcMacKey(sessionTranscript_, {}, signingKeyBlob, docType_, + numNamespacesWithValues, expectedDeviceNameSpacesSize_)) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, + "Error starting retrieving entries")); + } } } @@ -665,6 +752,11 @@ void IdentityCredential::calcDeviceNameSpacesSize(uint32_t accessControlProfileM ndk::ScopedAStatus IdentityCredential::startRetrieveEntryValue( const string& nameSpace, const string& name, int32_t entrySize, const vector<int32_t>& accessControlProfileIds) { + ndk::ScopedAStatus status = ensureHwProxy(); + if (!status.isOk()) { + return status; + } + if (name.empty()) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( IIdentityCredentialStore::STATUS_INVALID_DATA, "Name cannot be empty")); @@ -785,6 +877,11 @@ ndk::ScopedAStatus IdentityCredential::startRetrieveEntryValue( ndk::ScopedAStatus IdentityCredential::retrieveEntryValue(const vector<uint8_t>& encryptedContent, vector<uint8_t>* outContent) { + ndk::ScopedAStatus status = ensureHwProxy(); + if (!status.isOk()) { + return status; + } + optional<vector<uint8_t>> content = hwProxy_->retrieveEntryValue( encryptedContent, currentNameSpace_, currentName_, currentAccessControlProfileIds_); if (!content) { @@ -829,6 +926,11 @@ ndk::ScopedAStatus IdentityCredential::retrieveEntryValue(const vector<uint8_t>& ndk::ScopedAStatus IdentityCredential::finishRetrieval(vector<uint8_t>* outMac, vector<uint8_t>* outDeviceNameSpaces) { + ndk::ScopedAStatus status = ensureHwProxy(); + if (!status.isOk()) { + return status; + } + if (currentNameSpaceDeviceNameSpacesMap_.size() > 0) { deviceNameSpacesMap_.add(currentNameSpace_, std::move(currentNameSpaceDeviceNameSpacesMap_)); @@ -846,18 +948,23 @@ ndk::ScopedAStatus IdentityCredential::finishRetrieval(vector<uint8_t>* outMac, .c_str())); } - // If there's no signing key or no sessionTranscript or no reader ephemeral - // public key, we return the empty MAC. + // If the TA calculated a MAC (it might not have), format it as a COSE_Mac0 + // optional<vector<uint8_t>> mac; - if (signingKeyBlob_.size() > 0 && sessionTranscript_.size() > 0 && - readerPublicKey_.size() > 0) { - optional<vector<uint8_t>> digestToBeMaced = hwProxy_->finishRetrieval(); - if (!digestToBeMaced || digestToBeMaced.value().size() != 32) { + optional<vector<uint8_t>> digestToBeMaced = hwProxy_->finishRetrieval(); + + // The MAC not being set means an error occurred. + if (!digestToBeMaced) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_INVALID_DATA, "Error generating digestToBeMaced")); + } + // Size 0 means that the MAC isn't set. If it's set, it has to be 32 bytes. + if (digestToBeMaced.value().size() != 0) { + if (digestToBeMaced.value().size() != 32) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( IIdentityCredentialStore::STATUS_INVALID_DATA, - "Error generating digestToBeMaced")); + "Unexpected size for digestToBeMaced")); } - // Now construct COSE_Mac0 from the returned MAC... mac = support::coseMacWithDigest(digestToBeMaced.value(), {} /* data */); } @@ -868,6 +975,15 @@ ndk::ScopedAStatus IdentityCredential::finishRetrieval(vector<uint8_t>* outMac, ndk::ScopedAStatus IdentityCredential::generateSigningKeyPair( vector<uint8_t>* outSigningKeyBlob, Certificate* outSigningKeyCertificate) { + if (session_) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, "Cannot be called in a session")); + } + ndk::ScopedAStatus status = ensureHwProxy(); + if (!status.isOk()) { + return status; + } + time_t now = time(NULL); optional<pair<vector<uint8_t>, vector<uint8_t>>> pair = hwProxy_->generateSigningKeyPair(docType_, now); @@ -885,9 +1001,18 @@ ndk::ScopedAStatus IdentityCredential::generateSigningKeyPair( ndk::ScopedAStatus IdentityCredential::updateCredential( shared_ptr<IWritableIdentityCredential>* outWritableCredential) { - sp<SecureHardwareProvisioningProxy> hwProxy = hwProxyFactory_->createProvisioningProxy(); + if (session_) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, "Cannot be called in a session")); + } + sp<SecureHardwareProvisioningProxy> provisioningHwProxy = + hwProxyFactory_->createProvisioningProxy(); + if (!provisioningHwProxy) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, "Error creating provisioning proxy")); + } shared_ptr<WritableIdentityCredential> wc = - ndk::SharedRefBase::make<WritableIdentityCredential>(hwProxy, docType_, + ndk::SharedRefBase::make<WritableIdentityCredential>(provisioningHwProxy, docType_, testCredential_); if (!wc->initializeForUpdate(encryptedCredentialKeys_)) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( diff --git a/identity/aidl/default/common/IdentityCredential.h b/identity/aidl/default/common/IdentityCredential.h index ef9d13351c..2935fb80a7 100644 --- a/identity/aidl/default/common/IdentityCredential.h +++ b/identity/aidl/default/common/IdentityCredential.h @@ -30,6 +30,7 @@ #include <cppbor.h> #include "IdentityCredentialStore.h" +#include "PresentationSession.h" #include "SecureHardwareProxy.h" namespace aidl::android::hardware::identity { @@ -46,11 +47,11 @@ using ::std::vector; class IdentityCredential : public BnIdentityCredential { public: IdentityCredential(sp<SecureHardwareProxyFactory> hwProxyFactory, - sp<SecureHardwarePresentationProxy> hwProxy, - const vector<uint8_t>& credentialData) + const vector<uint8_t>& credentialData, + std::shared_ptr<PresentationSession> session) : hwProxyFactory_(hwProxyFactory), - hwProxy_(hwProxy), credentialData_(credentialData), + session_(std::move(session)), numStartRetrievalCalls_(0), expectedDeviceNameSpacesSize_(0) {} @@ -94,10 +95,13 @@ class IdentityCredential : public BnIdentityCredential { bool includeChallenge, vector<uint8_t>* outProofOfDeletionSignature); + // Creates and initializes hwProxy_. + ndk::ScopedAStatus ensureHwProxy(); + // Set by constructor sp<SecureHardwareProxyFactory> hwProxyFactory_; - sp<SecureHardwarePresentationProxy> hwProxy_; vector<uint8_t> credentialData_; + shared_ptr<PresentationSession> session_; int numStartRetrievalCalls_; // Set by initialize() @@ -105,6 +109,9 @@ class IdentityCredential : public BnIdentityCredential { bool testCredential_; vector<uint8_t> encryptedCredentialKeys_; + // Set by ensureHwProxy() + sp<SecureHardwarePresentationProxy> hwProxy_; + // Set by createEphemeralKeyPair() vector<uint8_t> ephemeralPublicKey_; diff --git a/identity/aidl/default/common/IdentityCredentialStore.cpp b/identity/aidl/default/common/IdentityCredentialStore.cpp index e6b5466096..4703ffe646 100644 --- a/identity/aidl/default/common/IdentityCredentialStore.cpp +++ b/identity/aidl/default/common/IdentityCredentialStore.cpp @@ -20,6 +20,7 @@ #include "IdentityCredential.h" #include "IdentityCredentialStore.h" +#include "PresentationSession.h" #include "WritableIdentityCredential.h" namespace aidl::android::hardware::identity { @@ -61,9 +62,8 @@ ndk::ScopedAStatus IdentityCredentialStore::getCredential( "Unsupported cipher suite")); } - sp<SecureHardwarePresentationProxy> hwProxy = hwProxyFactory_->createPresentationProxy(); - shared_ptr<IdentityCredential> credential = - ndk::SharedRefBase::make<IdentityCredential>(hwProxyFactory_, hwProxy, credentialData); + shared_ptr<IdentityCredential> credential = ndk::SharedRefBase::make<IdentityCredential>( + hwProxyFactory_, credentialData, nullptr /* session */); auto ret = credential->initialize(); if (ret != IIdentityCredentialStore::STATUS_OK) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( @@ -73,4 +73,25 @@ ndk::ScopedAStatus IdentityCredentialStore::getCredential( return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus IdentityCredentialStore::createPresentationSession( + CipherSuite cipherSuite, shared_ptr<IPresentationSession>* outSession) { + // We only support CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256 right now. + if (cipherSuite != CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_CIPHER_SUITE_NOT_SUPPORTED, + "Unsupported cipher suite")); + } + + sp<SecureHardwareSessionProxy> hwProxy = hwProxyFactory_->createSessionProxy(); + shared_ptr<PresentationSession> session = + ndk::SharedRefBase::make<PresentationSession>(hwProxyFactory_, hwProxy); + auto ret = session->initialize(); + if (ret != IIdentityCredentialStore::STATUS_OK) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + int(ret), "Error initializing PresentationSession")); + } + *outSession = session; + return ndk::ScopedAStatus::ok(); +} + } // namespace aidl::android::hardware::identity diff --git a/identity/aidl/default/common/IdentityCredentialStore.h b/identity/aidl/default/common/IdentityCredentialStore.h index d35e632984..77b894dbd6 100644 --- a/identity/aidl/default/common/IdentityCredentialStore.h +++ b/identity/aidl/default/common/IdentityCredentialStore.h @@ -47,6 +47,9 @@ class IdentityCredentialStore : public BnIdentityCredentialStore { ndk::ScopedAStatus getCredential(CipherSuite cipherSuite, const vector<uint8_t>& credentialData, shared_ptr<IIdentityCredential>* outCredential) override; + ndk::ScopedAStatus createPresentationSession( + CipherSuite cipherSuite, shared_ptr<IPresentationSession>* outSession) override; + private: sp<SecureHardwareProxyFactory> hwProxyFactory_; }; diff --git a/identity/aidl/default/common/PresentationSession.cpp b/identity/aidl/default/common/PresentationSession.cpp new file mode 100644 index 0000000000..fbd897281a --- /dev/null +++ b/identity/aidl/default/common/PresentationSession.cpp @@ -0,0 +1,149 @@ +/* + * Copyright 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. + */ + +#define LOG_TAG "PresentationSession" + +#include "PresentationSession.h" +#include "IdentityCredentialStore.h" + +#include <android/hardware/identity/support/IdentityCredentialSupport.h> + +#include <string.h> + +#include <android-base/logging.h> +#include <android-base/stringprintf.h> + +#include <cppbor.h> +#include <cppbor_parse.h> + +#include "FakeSecureHardwareProxy.h" +#include "IdentityCredential.h" +#include "PresentationSession.h" + +namespace aidl::android::hardware::identity { + +using ::std::optional; + +using namespace ::android::hardware::identity; + +PresentationSession::~PresentationSession() {} + +int PresentationSession::initialize() { + if (!hwProxy_->initialize()) { + LOG(ERROR) << "hwProxy->initialize failed"; + return IIdentityCredentialStore::STATUS_FAILED; + } + + optional<uint64_t> id = hwProxy_->getId(); + if (!id) { + LOG(ERROR) << "Error getting id for session"; + return IIdentityCredentialStore::STATUS_FAILED; + } + id_ = id.value(); + + optional<vector<uint8_t>> ephemeralKeyPriv = hwProxy_->getEphemeralKeyPair(); + if (!ephemeralKeyPriv) { + LOG(ERROR) << "Error getting ephemeral private key for session"; + return IIdentityCredentialStore::STATUS_FAILED; + } + optional<vector<uint8_t>> ephemeralKeyPair = + support::ecPrivateKeyToKeyPair(ephemeralKeyPriv.value()); + if (!ephemeralKeyPair) { + LOG(ERROR) << "Error creating ephemeral key-pair"; + return IIdentityCredentialStore::STATUS_FAILED; + } + ephemeralKeyPair_ = ephemeralKeyPair.value(); + + optional<uint64_t> authChallenge = hwProxy_->getAuthChallenge(); + if (!authChallenge) { + LOG(ERROR) << "Error getting authChallenge for session"; + return IIdentityCredentialStore::STATUS_FAILED; + } + authChallenge_ = authChallenge.value(); + + return IIdentityCredentialStore::STATUS_OK; +} + +ndk::ScopedAStatus PresentationSession::getEphemeralKeyPair(vector<uint8_t>* outKeyPair) { + *outKeyPair = ephemeralKeyPair_; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus PresentationSession::getAuthChallenge(int64_t* outChallenge) { + *outChallenge = authChallenge_; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus PresentationSession::setReaderEphemeralPublicKey( + const vector<uint8_t>& publicKey) { + // We expect the reader ephemeral public key to be same size and curve + // as the ephemeral key we generated (e.g. P-256 key), otherwise ECDH + // won't work. So its length should be 65 bytes and it should be + // starting with 0x04. + if (publicKey.size() != 65 || publicKey[0] != 0x04) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, + "Reader public key is not in expected format")); + } + readerPublicKey_ = publicKey; + vector<uint8_t> pubKeyP256(publicKey.begin() + 1, publicKey.end()); + if (!hwProxy_->setReaderEphemeralPublicKey(pubKeyP256)) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, + "Error setting readerEphemeralPublicKey for session")); + } + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus PresentationSession::setSessionTranscript( + const vector<uint8_t>& sessionTranscript) { + sessionTranscript_ = sessionTranscript; + if (!hwProxy_->setSessionTranscript(sessionTranscript)) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, + "Error setting SessionTranscript for session")); + } + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus PresentationSession::getCredential( + const vector<uint8_t>& credentialData, shared_ptr<IIdentityCredential>* outCredential) { + shared_ptr<PresentationSession> p = ref<PresentationSession>(); + shared_ptr<IdentityCredential> credential = + ndk::SharedRefBase::make<IdentityCredential>(hwProxyFactory_, credentialData, p); + int ret = credential->initialize(); + if (ret != IIdentityCredentialStore::STATUS_OK) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + ret, "Error initializing IdentityCredential")); + } + *outCredential = std::move(credential); + + return ndk::ScopedAStatus::ok(); +} + +uint64_t PresentationSession::getSessionId() { + return id_; +} + +vector<uint8_t> PresentationSession::getSessionTranscript() { + return sessionTranscript_; +} + +vector<uint8_t> PresentationSession::getReaderEphemeralPublicKey() { + return readerPublicKey_; +} + +} // namespace aidl::android::hardware::identity diff --git a/identity/aidl/default/common/PresentationSession.h b/identity/aidl/default/common/PresentationSession.h new file mode 100644 index 0000000000..76ca67b675 --- /dev/null +++ b/identity/aidl/default/common/PresentationSession.h @@ -0,0 +1,83 @@ +/* + * Copyright 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. + */ + +#ifndef ANDROID_HARDWARE_IDENTITY_PRESENTATIONSESSION_H +#define ANDROID_HARDWARE_IDENTITY_PRESENTATIONSESSION_H + +#include <aidl/android/hardware/identity/BnPresentationSession.h> +#include <android/hardware/identity/support/IdentityCredentialSupport.h> + +#include <vector> + +#include <cppbor.h> + +#include "IdentityCredentialStore.h" +#include "SecureHardwareProxy.h" + +namespace aidl::android::hardware::identity { + +using ::aidl::android::hardware::keymaster::HardwareAuthToken; +using ::aidl::android::hardware::keymaster::VerificationToken; +using ::android::sp; +using ::android::hardware::identity::SecureHardwareSessionProxy; +using ::std::vector; + +class PresentationSession : public BnPresentationSession { + public: + PresentationSession(sp<SecureHardwareProxyFactory> hwProxyFactory, + sp<SecureHardwareSessionProxy> hwProxy) + : hwProxyFactory_(std::move(hwProxyFactory)), hwProxy_(std::move(hwProxy)) {} + + virtual ~PresentationSession(); + + // Creates ephemeral key and auth-challenge in TA. Returns a status code from + // IIdentityCredentialStore. Must be called right after construction. + int initialize(); + + uint64_t getSessionId(); + + vector<uint8_t> getSessionTranscript(); + vector<uint8_t> getReaderEphemeralPublicKey(); + + // Methods from IPresentationSession follow. + ndk::ScopedAStatus getEphemeralKeyPair(vector<uint8_t>* outKeyPair) override; + ndk::ScopedAStatus getAuthChallenge(int64_t* outChallenge) override; + ndk::ScopedAStatus setReaderEphemeralPublicKey(const vector<uint8_t>& publicKey) override; + ndk::ScopedAStatus setSessionTranscript(const vector<uint8_t>& sessionTranscript) override; + + ndk::ScopedAStatus getCredential(const vector<uint8_t>& credentialData, + shared_ptr<IIdentityCredential>* outCredential) override; + + private: + // Set by constructor + sp<SecureHardwareProxyFactory> hwProxyFactory_; + sp<SecureHardwareSessionProxy> hwProxy_; + + // Set by initialize() + uint64_t id_; + vector<uint8_t> ephemeralKeyPair_; + uint64_t authChallenge_; + + // Set by setReaderEphemeralPublicKey() + vector<uint8_t> readerPublicKey_; + + // Set by setSessionTranscript() + vector<uint8_t> sessionTranscript_; +}; + +} // namespace aidl::android::hardware::identity + +#endif // ANDROID_HARDWARE_IDENTITY_PRESENTATIONSESSION_H diff --git a/identity/aidl/default/common/SecureHardwareProxy.h b/identity/aidl/default/common/SecureHardwareProxy.h index a1ed1ef03b..a580444230 100644 --- a/identity/aidl/default/common/SecureHardwareProxy.h +++ b/identity/aidl/default/common/SecureHardwareProxy.h @@ -42,6 +42,7 @@ using ::std::vector; // Forward declare. // class SecureHardwareProvisioningProxy; +class SecureHardwareSessionProxy; class SecureHardwarePresentationProxy; // This is a class used to create proxies. @@ -52,6 +53,7 @@ class SecureHardwareProxyFactory : public RefBase { virtual ~SecureHardwareProxyFactory() {} virtual sp<SecureHardwareProvisioningProxy> createProvisioningProxy() = 0; + virtual sp<SecureHardwareSessionProxy> createSessionProxy() = 0; virtual sp<SecureHardwarePresentationProxy> createPresentationProxy() = 0; }; @@ -64,8 +66,12 @@ class SecureHardwareProvisioningProxy : public RefBase { virtual bool initialize(bool testCredential) = 0; - virtual bool initializeForUpdate(bool testCredential, string docType, - vector<uint8_t> encryptedCredentialKeys) = 0; + virtual bool initializeForUpdate(bool testCredential, const string& docType, + const vector<uint8_t>& encryptedCredentialKeys) = 0; + + virtual optional<uint32_t> getId() = 0; + + virtual bool shutdown() = 0; // Returns public key certificate chain with attestation. // @@ -76,7 +82,7 @@ class SecureHardwareProvisioningProxy : public RefBase { virtual optional<vector<uint8_t>> createCredentialKey(const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId) = 0; - virtual bool startPersonalization(int accessControlProfileCount, vector<int> entryCounts, + virtual bool startPersonalization(int accessControlProfileCount, const vector<int>& entryCounts, const string& docType, size_t expectedProofOfProvisioningSize) = 0; @@ -98,8 +104,6 @@ class SecureHardwareProvisioningProxy : public RefBase { // Returns encryptedCredentialKeys (80 bytes). virtual optional<vector<uint8_t>> finishGetCredentialData(const string& docType) = 0; - - virtual bool shutdown() = 0; }; enum AccessCheckResult { @@ -110,6 +114,30 @@ enum AccessCheckResult { kReaderAuthenticationFailed, }; +// The proxy used for sessions. +// +class SecureHardwareSessionProxy : public RefBase { + public: + SecureHardwareSessionProxy() {} + + virtual ~SecureHardwareSessionProxy() {} + + virtual bool initialize() = 0; + + virtual optional<uint32_t> getId() = 0; + + virtual bool shutdown() = 0; + + virtual optional<uint64_t> getAuthChallenge() = 0; + + // Returns private key + virtual optional<vector<uint8_t>> getEphemeralKeyPair() = 0; + + virtual bool setReaderEphemeralPublicKey(const vector<uint8_t>& readerEphemeralPublicKey) = 0; + + virtual bool setSessionTranscript(const vector<uint8_t>& sessionTranscript) = 0; +}; + // The proxy used for presentation. // class SecureHardwarePresentationProxy : public RefBase { @@ -117,12 +145,16 @@ class SecureHardwarePresentationProxy : public RefBase { SecureHardwarePresentationProxy() {} virtual ~SecureHardwarePresentationProxy() {} - virtual bool initialize(bool testCredential, string docType, - vector<uint8_t> encryptedCredentialKeys) = 0; + virtual bool initialize(uint32_t sessionId, bool testCredential, const string& docType, + const vector<uint8_t>& encryptedCredentialKeys) = 0; + + virtual optional<uint32_t> getId() = 0; + + virtual bool shutdown() = 0; // Returns publicKeyCert (1st component) and signingKeyBlob (2nd component) - virtual optional<pair<vector<uint8_t>, vector<uint8_t>>> generateSigningKeyPair(string docType, - time_t now) = 0; + virtual optional<pair<vector<uint8_t>, vector<uint8_t>>> generateSigningKeyPair( + const string& docType, time_t now) = 0; // Returns private key virtual optional<vector<uint8_t>> createEphemeralKeyPair() = 0; @@ -174,8 +206,6 @@ class SecureHardwarePresentationProxy : public RefBase { virtual optional<vector<uint8_t>> proveOwnership(const string& docType, bool testCredential, const vector<uint8_t>& challenge, size_t proofOfOwnershipCborSize) = 0; - - virtual bool shutdown() = 0; }; } // namespace android::hardware::identity diff --git a/identity/aidl/default/identity-default.xml b/identity/aidl/default/identity-default.xml index a074250901..cc0ddc7d51 100644 --- a/identity/aidl/default/identity-default.xml +++ b/identity/aidl/default/identity-default.xml @@ -1,7 +1,7 @@ <manifest version="1.0" type="device"> <hal format="aidl"> <name>android.hardware.identity</name> - <version>3</version> + <version>4</version> <interface> <name>IIdentityCredentialStore</name> <instance>default</instance> diff --git a/identity/aidl/default/libeic/EicCommon.h b/identity/aidl/default/libeic/EicCommon.h index 476276ebcf..2a08a35f65 100644 --- a/identity/aidl/default/libeic/EicCommon.h +++ b/identity/aidl/default/libeic/EicCommon.h @@ -21,6 +21,9 @@ #ifndef ANDROID_HARDWARE_IDENTITY_EIC_COMMON_H #define ANDROID_HARDWARE_IDENTITY_EIC_COMMON_H +// KeyMint auth-challenges are 64-bit numbers and 0 typically means unset. +#define EIC_KM_AUTH_CHALLENGE_UNSET 0 + // Feature version 202009: // // CredentialKeys = [ diff --git a/identity/aidl/default/libeic/EicOps.h b/identity/aidl/default/libeic/EicOps.h index d4fcf0e1bb..aa26e6202a 100644 --- a/identity/aidl/default/libeic/EicOps.h +++ b/identity/aidl/default/libeic/EicOps.h @@ -141,6 +141,10 @@ void* eicMemCpy(void* dest, const void* src, size_t n); // String length, see strlen(3). size_t eicStrLen(const char* s); +// Locate a substring, see memmem(3) +void* eicMemMem(const uint8_t* haystack, size_t haystackLen, const uint8_t* needle, + size_t needleLen); + // Memory compare, see CRYPTO_memcmp(3SSL) // // It takes an amount of time dependent on len, but independent of the contents of the @@ -151,6 +155,12 @@ int eicCryptoMemCmp(const void* s1, const void* s2, size_t n); // Random number generation. bool eicOpsRandom(uint8_t* buf, size_t numBytes); +// Creates a new non-zero identifier in |id|. +// +// Is guaranteed to be non-zero and different than what is already in |id|. +// +bool eicNextId(uint32_t* id); + // If |testCredential| is true, returns the 128-bit AES Hardware-Bound Key (16 bytes). // // Otherwise returns all zeroes (16 bytes). @@ -295,6 +305,8 @@ bool eicOpsValidateAuthToken(uint64_t challenge, uint64_t secureUserId, uint64_t int verificationTokenSecurityLevel, const uint8_t* verificationTokenMac, size_t verificationTokenMacSize); +// Also see eicOpsLookupActiveSessionFromId() defined in EicSession.h + #ifdef __cplusplus } #endif diff --git a/identity/aidl/default/libeic/EicPresentation.c b/identity/aidl/default/libeic/EicPresentation.c index 0d03ae9620..104a559697 100644 --- a/identity/aidl/default/libeic/EicPresentation.c +++ b/identity/aidl/default/libeic/EicPresentation.c @@ -16,11 +16,17 @@ #include "EicPresentation.h" #include "EicCommon.h" +#include "EicSession.h" #include <inttypes.h> -bool eicPresentationInit(EicPresentation* ctx, bool testCredential, const char* docType, - size_t docTypeLength, const uint8_t* encryptedCredentialKeys, +// Global used for assigning ids for presentation objects. +// +static uint32_t gPresentationLastIdAssigned = 0; + +bool eicPresentationInit(EicPresentation* ctx, uint32_t sessionId, bool testCredential, + const char* docType, size_t docTypeLength, + const uint8_t* encryptedCredentialKeys, size_t encryptedCredentialKeysSize) { uint8_t credentialKeys[EIC_CREDENTIAL_KEYS_CBOR_SIZE_FEATURE_VERSION_202101]; bool expectPopSha256 = false; @@ -39,6 +45,13 @@ bool eicPresentationInit(EicPresentation* ctx, bool testCredential, const char* } eicMemSet(ctx, '\0', sizeof(EicPresentation)); + ctx->sessionId = sessionId; + + if (!eicNextId(&gPresentationLastIdAssigned)) { + eicDebug("Error getting id for object"); + return false; + } + ctx->id = gPresentationLastIdAssigned; if (!eicOpsDecryptAes128Gcm(eicOpsGetHardwareBoundKey(testCredential), encryptedCredentialKeys, encryptedCredentialKeysSize, @@ -86,6 +99,23 @@ bool eicPresentationInit(EicPresentation* ctx, bool testCredential, const char* if (expectPopSha256) { eicMemCpy(ctx->proofOfProvisioningSha256, credentialKeys + 54, EIC_SHA256_DIGEST_SIZE); } + + eicDebug("Initialized presentation with id %" PRIu32, ctx->id); + return true; +} + +bool eicPresentationShutdown(EicPresentation* ctx) { + if (ctx->id == 0) { + eicDebug("Trying to shut down presentation with id 0"); + return false; + } + eicDebug("Shut down presentation with id %" PRIu32, ctx->id); + eicMemSet(ctx, '\0', sizeof(EicPresentation)); + return true; +} + +bool eicPresentationGetId(EicPresentation* ctx, uint32_t* outId) { + *outId = ctx->id; return true; } @@ -174,7 +204,7 @@ bool eicPresentationCreateAuthChallenge(EicPresentation* ctx, uint64_t* authChal eicDebug("Failed generating random challenge"); return false; } - } while (ctx->authChallenge == 0); + } while (ctx->authChallenge == EIC_KM_AUTH_CHALLENGE_UNSET); eicDebug("Created auth challenge %" PRIu64, ctx->authChallenge); *authChallenge = ctx->authChallenge; return true; @@ -190,6 +220,24 @@ bool eicPresentationValidateRequestMessage(EicPresentation* ctx, const uint8_t* int coseSignAlg, const uint8_t* readerSignatureOfToBeSigned, size_t readerSignatureOfToBeSignedSize) { + if (ctx->sessionId != 0) { + EicSession* session = eicSessionGetForId(ctx->sessionId); + if (session == NULL) { + eicDebug("Error looking up session for sessionId %" PRIu32, ctx->sessionId); + return false; + } + EicSha256Ctx sha256; + uint8_t sessionTranscriptSha256[EIC_SHA256_DIGEST_SIZE]; + eicOpsSha256Init(&sha256); + eicOpsSha256Update(&sha256, sessionTranscript, sessionTranscriptSize); + eicOpsSha256Final(&sha256, sessionTranscriptSha256); + if (eicCryptoMemCmp(sessionTranscriptSha256, session->sessionTranscriptSha256, + EIC_SHA256_DIGEST_SIZE) != 0) { + eicDebug("SessionTranscript mismatch"); + return false; + } + } + if (ctx->readerPublicKeySize == 0) { eicDebug("No public key for reader"); return false; @@ -330,6 +378,20 @@ bool eicPresentationPushReaderCert(EicPresentation* ctx, const uint8_t* certX509 return true; } +static bool getChallenge(EicPresentation* ctx, uint64_t* outAuthChallenge) { + // Use authChallenge from session if applicable. + *outAuthChallenge = ctx->authChallenge; + if (ctx->sessionId != 0) { + EicSession* session = eicSessionGetForId(ctx->sessionId); + if (session == NULL) { + eicDebug("Error looking up session for sessionId %" PRIu32, ctx->sessionId); + return false; + } + *outAuthChallenge = session->authChallenge; + } + return true; +} + bool eicPresentationSetAuthToken(EicPresentation* ctx, uint64_t challenge, uint64_t secureUserId, uint64_t authenticatorId, int hardwareAuthenticatorType, uint64_t timeStamp, const uint8_t* mac, size_t macSize, @@ -338,14 +400,19 @@ bool eicPresentationSetAuthToken(EicPresentation* ctx, uint64_t challenge, uint6 int verificationTokenSecurityLevel, const uint8_t* verificationTokenMac, size_t verificationTokenMacSize) { + uint64_t authChallenge; + if (!getChallenge(ctx, &authChallenge)) { + return false; + } + // It doesn't make sense to accept any tokens if eicPresentationCreateAuthChallenge() // was never called. - if (ctx->authChallenge == 0) { - eicDebug("Trying validate tokens when no auth-challenge was previously generated"); + if (authChallenge == EIC_KM_AUTH_CHALLENGE_UNSET) { + eicDebug("Trying to validate tokens when no auth-challenge was previously generated"); return false; } // At least the verification-token must have the same challenge as what was generated. - if (verificationTokenChallenge != ctx->authChallenge) { + if (verificationTokenChallenge != authChallenge) { eicDebug("Challenge in verification token does not match the challenge " "previously generated"); return false; @@ -354,6 +421,7 @@ bool eicPresentationSetAuthToken(EicPresentation* ctx, uint64_t challenge, uint6 challenge, secureUserId, authenticatorId, hardwareAuthenticatorType, timeStamp, mac, macSize, verificationTokenChallenge, verificationTokenTimestamp, verificationTokenSecurityLevel, verificationTokenMac, verificationTokenMacSize)) { + eicDebug("Error validating authToken"); return false; } ctx->authTokenChallenge = challenge; @@ -377,11 +445,16 @@ static bool checkUserAuth(EicPresentation* ctx, bool userAuthenticationRequired, // Only ACP with auth-on-every-presentation - those with timeout == 0 - need the // challenge to match... if (timeoutMillis == 0) { - if (ctx->authTokenChallenge != ctx->authChallenge) { + uint64_t authChallenge; + if (!getChallenge(ctx, &authChallenge)) { + return false; + } + + if (ctx->authTokenChallenge != authChallenge) { eicDebug("Challenge in authToken (%" PRIu64 ") doesn't match the challenge " "that was created (%" PRIu64 ") for this session", - ctx->authTokenChallenge, ctx->authChallenge); + ctx->authTokenChallenge, authChallenge); return false; } } @@ -490,6 +563,25 @@ bool eicPresentationCalcMacKey(EicPresentation* ctx, const uint8_t* sessionTrans const uint8_t signingKeyBlob[60], const char* docType, size_t docTypeLength, unsigned int numNamespacesWithValues, size_t expectedDeviceNamespacesSize) { + if (ctx->sessionId != 0) { + EicSession* session = eicSessionGetForId(ctx->sessionId); + if (session == NULL) { + eicDebug("Error looking up session for sessionId %" PRIu32, ctx->sessionId); + return false; + } + EicSha256Ctx sha256; + uint8_t sessionTranscriptSha256[EIC_SHA256_DIGEST_SIZE]; + eicOpsSha256Init(&sha256); + eicOpsSha256Update(&sha256, sessionTranscript, sessionTranscriptSize); + eicOpsSha256Final(&sha256, sessionTranscriptSha256); + if (eicCryptoMemCmp(sessionTranscriptSha256, session->sessionTranscriptSha256, + EIC_SHA256_DIGEST_SIZE) != 0) { + eicDebug("SessionTranscript mismatch"); + return false; + } + readerEphemeralPublicKey = session->readerEphemeralPublicKey; + } + uint8_t signingKeyPriv[EIC_P256_PRIV_KEY_SIZE]; if (!eicOpsDecryptAes128Gcm(ctx->storageKey, signingKeyBlob, 60, (const uint8_t*)docType, docTypeLength, signingKeyPriv)) { diff --git a/identity/aidl/default/libeic/EicPresentation.h b/identity/aidl/default/libeic/EicPresentation.h index 6f7f432960..a031890e58 100644 --- a/identity/aidl/default/libeic/EicPresentation.h +++ b/identity/aidl/default/libeic/EicPresentation.h @@ -30,7 +30,13 @@ extern "C" { // The maximum size we support for public keys in reader certificates. #define EIC_PRESENTATION_MAX_READER_PUBLIC_KEY_SIZE 65 +// Constant used to convey that no session is associated with a presentation. +#define EIC_PRESENTATION_ID_UNSET 0 + typedef struct { + // A non-zero number unique for this EicPresentation instance + uint32_t id; + int featureLevel; uint8_t storageKey[EIC_AES_128_KEY_SIZE]; @@ -38,6 +44,10 @@ typedef struct { uint8_t ephemeralPrivateKey[EIC_P256_PRIV_KEY_SIZE]; + // If non-zero (not EIC_PRESENTATION_ID_UNSET), the id of the EicSession object this + // presentation object is associated with. + uint32_t sessionId; + // The challenge generated with eicPresentationCreateAuthChallenge() uint64_t authChallenge; @@ -93,10 +103,18 @@ typedef struct { EicCbor cbor; } EicPresentation; -bool eicPresentationInit(EicPresentation* ctx, bool testCredential, const char* docType, - size_t docTypeLength, const uint8_t* encryptedCredentialKeys, +// If sessionId is zero (EIC_PRESENTATION_ID_UNSET), the presentation object is not associated +// with a session object. Otherwise it's the id of the session object. +// +bool eicPresentationInit(EicPresentation* ctx, uint32_t sessionId, bool testCredential, + const char* docType, size_t docTypeLength, + const uint8_t* encryptedCredentialKeys, size_t encryptedCredentialKeysSize); +bool eicPresentationShutdown(EicPresentation* ctx); + +bool eicPresentationGetId(EicPresentation* ctx, uint32_t* outId); + bool eicPresentationGenerateSigningKeyPair(EicPresentation* ctx, const char* docType, size_t docTypeLength, time_t now, uint8_t* publicKeyCert, size_t* publicKeyCertSize, diff --git a/identity/aidl/default/libeic/EicProvisioning.c b/identity/aidl/default/libeic/EicProvisioning.c index c9df4fd74f..a241b71b50 100644 --- a/identity/aidl/default/libeic/EicProvisioning.c +++ b/identity/aidl/default/libeic/EicProvisioning.c @@ -17,8 +17,21 @@ #include "EicProvisioning.h" #include "EicCommon.h" +#include <inttypes.h> + +// Global used for assigning ids for provisioning objects. +// +static uint32_t gProvisioningLastIdAssigned = 0; + bool eicProvisioningInit(EicProvisioning* ctx, bool testCredential) { eicMemSet(ctx, '\0', sizeof(EicProvisioning)); + + if (!eicNextId(&gProvisioningLastIdAssigned)) { + eicDebug("Error getting id for object"); + return false; + } + ctx->id = gProvisioningLastIdAssigned; + ctx->testCredential = testCredential; if (!eicOpsRandom(ctx->storageKey, EIC_AES_128_KEY_SIZE)) { return false; @@ -47,6 +60,13 @@ bool eicProvisioningInitForUpdate(EicProvisioning* ctx, bool testCredential, con } eicMemSet(ctx, '\0', sizeof(EicProvisioning)); + + if (!eicNextId(&gProvisioningLastIdAssigned)) { + eicDebug("Error getting id for object"); + return false; + } + ctx->id = gProvisioningLastIdAssigned; + ctx->testCredential = testCredential; if (!eicOpsDecryptAes128Gcm(eicOpsGetHardwareBoundKey(testCredential), encryptedCredentialKeys, @@ -96,6 +116,21 @@ bool eicProvisioningInitForUpdate(EicProvisioning* ctx, bool testCredential, con return true; } +bool eicProvisioningShutdown(EicProvisioning* ctx) { + if (ctx->id == 0) { + eicDebug("Trying to shut down provsioning with id 0"); + return false; + } + eicDebug("Shut down provsioning with id %" PRIu32, ctx->id); + eicMemSet(ctx, '\0', sizeof(EicProvisioning)); + return true; +} + +bool eicProvisioningGetId(EicProvisioning* ctx, uint32_t* outId) { + *outId = ctx->id; + return true; +} + bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge, size_t challengeSize, const uint8_t* applicationId, size_t applicationIdSize, uint8_t* publicKeyCert, diff --git a/identity/aidl/default/libeic/EicProvisioning.h b/identity/aidl/default/libeic/EicProvisioning.h index 92f1e4a2a0..d94f8f18c2 100644 --- a/identity/aidl/default/libeic/EicProvisioning.h +++ b/identity/aidl/default/libeic/EicProvisioning.h @@ -31,6 +31,9 @@ extern "C" { #define EIC_MAX_NUM_ACCESS_CONTROL_PROFILE_IDS 32 typedef struct { + // A non-zero number unique for this EicProvisioning instance + uint32_t id; + // Set by eicCreateCredentialKey() OR eicProvisioningInitForUpdate() uint8_t credentialPrivateKey[EIC_P256_PRIV_KEY_SIZE]; @@ -68,6 +71,10 @@ bool eicProvisioningInitForUpdate(EicProvisioning* ctx, bool testCredential, con size_t docTypeLength, const uint8_t* encryptedCredentialKeys, size_t encryptedCredentialKeysSize); +bool eicProvisioningShutdown(EicProvisioning* ctx); + +bool eicProvisioningGetId(EicProvisioning* ctx, uint32_t* outId); + bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge, size_t challengeSize, const uint8_t* applicationId, size_t applicationIdSize, uint8_t* publicKeyCert, diff --git a/identity/aidl/default/libeic/EicSession.c b/identity/aidl/default/libeic/EicSession.c new file mode 100644 index 0000000000..d0c7a0d77e --- /dev/null +++ b/identity/aidl/default/libeic/EicSession.c @@ -0,0 +1,120 @@ +/* + * Copyright 2020, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <inttypes.h> + +#include "EicCommon.h" +#include "EicSession.h" + +// Global used for assigning ids for session objects. +// +static uint32_t gSessionLastIdAssigned = 0; + +// The current session object or NULL if never initialized or if it has been shut down. +// +static EicSession* gSessionCurrent = NULL; + +EicSession* eicSessionGetForId(uint32_t sessionId) { + if (gSessionCurrent != NULL && gSessionCurrent->id == sessionId) { + return gSessionCurrent; + } + return NULL; +} + +bool eicSessionInit(EicSession* ctx) { + eicMemSet(ctx, '\0', sizeof(EicSession)); + + if (!eicNextId(&gSessionLastIdAssigned)) { + eicDebug("Error getting id for object"); + return false; + } + ctx->id = gSessionLastIdAssigned; + + do { + if (!eicOpsRandom((uint8_t*)&(ctx->authChallenge), sizeof(ctx->authChallenge))) { + eicDebug("Failed generating random challenge"); + return false; + } + } while (ctx->authChallenge == EIC_KM_AUTH_CHALLENGE_UNSET); + + if (!eicOpsCreateEcKey(ctx->ephemeralPrivateKey, ctx->ephemeralPublicKey)) { + eicDebug("Error creating ephemeral key-pair"); + return false; + } + + gSessionCurrent = ctx; + eicDebug("Initialized session with id %" PRIu32, ctx->id); + return true; +} + +bool eicSessionShutdown(EicSession* ctx) { + if (ctx->id == 0) { + eicDebug("Trying to shut down session with id 0"); + return false; + } + eicDebug("Shut down session with id %" PRIu32, ctx->id); + eicMemSet(ctx, '\0', sizeof(EicSession)); + gSessionCurrent = NULL; + return true; +} + +bool eicSessionGetId(EicSession* ctx, uint32_t* outId) { + *outId = ctx->id; + return true; +} + +bool eicSessionGetAuthChallenge(EicSession* ctx, uint64_t* outAuthChallenge) { + *outAuthChallenge = ctx->authChallenge; + return true; +} + +bool eicSessionGetEphemeralKeyPair(EicSession* ctx, + uint8_t ephemeralPrivateKey[EIC_P256_PRIV_KEY_SIZE]) { + eicMemCpy(ephemeralPrivateKey, ctx->ephemeralPrivateKey, EIC_P256_PRIV_KEY_SIZE); + return true; +} + +bool eicSessionSetReaderEphemeralPublicKey( + EicSession* ctx, const uint8_t readerEphemeralPublicKey[EIC_P256_PUB_KEY_SIZE]) { + eicMemCpy(ctx->readerEphemeralPublicKey, readerEphemeralPublicKey, EIC_P256_PUB_KEY_SIZE); + return true; +} + +bool eicSessionSetSessionTranscript(EicSession* ctx, const uint8_t* sessionTranscript, + size_t sessionTranscriptSize) { + // Only accept the SessionTranscript if X and Y from the ephemeral key + // we created is somewhere in SessionTranscript... + // + if (eicMemMem(sessionTranscript, sessionTranscriptSize, ctx->ephemeralPublicKey, + EIC_P256_PUB_KEY_SIZE / 2) == NULL) { + eicDebug("Error finding X from ephemeralPublicKey in sessionTranscript"); + return false; + } + if (eicMemMem(sessionTranscript, sessionTranscriptSize, + ctx->ephemeralPublicKey + EIC_P256_PUB_KEY_SIZE / 2, + EIC_P256_PUB_KEY_SIZE / 2) == NULL) { + eicDebug("Error finding Y from ephemeralPublicKey in sessionTranscript"); + return false; + } + + // To save space we only store the SHA-256 of SessionTranscript + // + EicSha256Ctx shaCtx; + eicOpsSha256Init(&shaCtx); + eicOpsSha256Update(&shaCtx, sessionTranscript, sessionTranscriptSize); + eicOpsSha256Final(&shaCtx, ctx->sessionTranscriptSha256); + return true; +} diff --git a/identity/aidl/default/libeic/EicSession.h b/identity/aidl/default/libeic/EicSession.h new file mode 100644 index 0000000000..0303dae1c3 --- /dev/null +++ b/identity/aidl/default/libeic/EicSession.h @@ -0,0 +1,73 @@ +/* + * Copyright 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. + */ + +#if !defined(EIC_INSIDE_LIBEIC_H) && !defined(EIC_COMPILATION) +#error "Never include this file directly, include libeic.h instead." +#endif + +#ifndef ANDROID_HARDWARE_IDENTITY_EIC_SESSION_H +#define ANDROID_HARDWARE_IDENTITY_EIC_SESSION_H + +#include "EicOps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + // A non-zero number unique for this EicSession instance + uint32_t id; + + // The challenge generated at construction time by eicSessionInit(). + uint64_t authChallenge; + + uint8_t ephemeralPrivateKey[EIC_P256_PRIV_KEY_SIZE]; + uint8_t ephemeralPublicKey[EIC_P256_PUB_KEY_SIZE]; + + uint8_t readerEphemeralPublicKey[EIC_P256_PUB_KEY_SIZE]; + + uint8_t sessionTranscriptSha256[EIC_SHA256_DIGEST_SIZE]; + +} EicSession; + +bool eicSessionInit(EicSession* ctx); + +bool eicSessionShutdown(EicSession* ctx); + +bool eicSessionGetId(EicSession* ctx, uint32_t* outId); + +bool eicSessionGetAuthChallenge(EicSession* ctx, uint64_t* outAuthChallenge); + +bool eicSessionGetEphemeralKeyPair(EicSession* ctx, + uint8_t ephemeralPrivateKey[EIC_P256_PRIV_KEY_SIZE]); + +bool eicSessionSetReaderEphemeralPublicKey( + EicSession* ctx, const uint8_t readerEphemeralPublicKey[EIC_P256_PUB_KEY_SIZE]); + +bool eicSessionSetSessionTranscript(EicSession* ctx, const uint8_t* sessionTranscript, + size_t sessionTranscriptSize); + +// Looks up an active session with the given id. +// +// Returns NULL if no active session with the given id is found. +// +EicSession* eicSessionGetForId(uint32_t sessionId); + +#ifdef __cplusplus +} +#endif + +#endif // ANDROID_HARDWARE_IDENTITY_EIC_PRESENTATION_H diff --git a/identity/aidl/default/libeic/libeic.h b/identity/aidl/default/libeic/libeic.h index 20c889660f..d89fc9a0e3 100644 --- a/identity/aidl/default/libeic/libeic.h +++ b/identity/aidl/default/libeic/libeic.h @@ -27,10 +27,11 @@ extern "C" { */ #define EIC_INSIDE_LIBEIC_H #include "EicCbor.h" +#include "EicCommon.h" #include "EicOps.h" #include "EicPresentation.h" #include "EicProvisioning.h" -#include "EicCommon.h" +#include "EicSession.h" #undef EIC_INSIDE_LIBEIC_H #ifdef __cplusplus diff --git a/identity/aidl/vts/Android.bp b/identity/aidl/vts/Android.bp index e5de91e22e..7b6f2c81ee 100644 --- a/identity/aidl/vts/Android.bp +++ b/identity/aidl/vts/Android.bp @@ -28,6 +28,7 @@ cc_test { "EndToEndTests.cpp", "TestCredentialTests.cpp", "AuthenticationKeyTests.cpp", + "PresentationSessionTests.cpp", ], shared_libs: [ "libbinder", @@ -40,9 +41,9 @@ cc_test { "libpuresoftkeymasterdevice", "android.hardware.keymaster@4.0", "android.hardware.identity-support-lib", - "android.hardware.identity-V3-cpp", - "android.hardware.keymaster-V3-cpp", - "android.hardware.keymaster-V3-ndk", + "android.hardware.identity-V4-cpp", + "android.hardware.keymaster-V4-cpp", + "android.hardware.keymaster-V4-ndk", "libkeymaster4support", "libkeymaster4_1support", ], diff --git a/identity/aidl/vts/PresentationSessionTests.cpp b/identity/aidl/vts/PresentationSessionTests.cpp new file mode 100644 index 0000000000..88acb269e2 --- /dev/null +++ b/identity/aidl/vts/PresentationSessionTests.cpp @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "PresentationSessionTests" + +#include <aidl/Gtest.h> +#include <aidl/Vintf.h> +#include <aidl/android/hardware/keymaster/HardwareAuthToken.h> +#include <aidl/android/hardware/keymaster/VerificationToken.h> +#include <android-base/logging.h> +#include <android/hardware/identity/IIdentityCredentialStore.h> +#include <android/hardware/identity/support/IdentityCredentialSupport.h> +#include <binder/IServiceManager.h> +#include <binder/ProcessState.h> +#include <cppbor.h> +#include <cppbor_parse.h> +#include <gtest/gtest.h> +#include <future> +#include <map> +#include <utility> + +#include "Util.h" + +namespace android::hardware::identity { + +using std::endl; +using std::make_pair; +using std::map; +using std::optional; +using std::pair; +using std::string; +using std::tie; +using std::vector; + +using ::android::sp; +using ::android::String16; +using ::android::binder::Status; + +using ::android::hardware::keymaster::HardwareAuthToken; +using ::android::hardware::keymaster::VerificationToken; + +class PresentationSessionTests : public testing::TestWithParam<string> { + public: + virtual void SetUp() override { + credentialStore_ = android::waitForDeclaredService<IIdentityCredentialStore>( + String16(GetParam().c_str())); + ASSERT_NE(credentialStore_, nullptr); + halApiVersion_ = credentialStore_->getInterfaceVersion(); + } + + void provisionData(); + + void provisionSingleDocument(const string& docType, vector<uint8_t>* outCredentialData, + vector<uint8_t>* outCredentialPubKey); + + // Set by provisionData + vector<uint8_t> credential1Data_; + vector<uint8_t> credential1PubKey_; + vector<uint8_t> credential2Data_; + vector<uint8_t> credential2PubKey_; + + sp<IIdentityCredentialStore> credentialStore_; + int halApiVersion_; +}; + +void PresentationSessionTests::provisionData() { + provisionSingleDocument("org.iso.18013-5.2019.mdl", &credential1Data_, &credential1PubKey_); + provisionSingleDocument("org.blah.OtherhDocTypeXX", &credential2Data_, &credential2PubKey_); +} + +void PresentationSessionTests::provisionSingleDocument(const string& docType, + vector<uint8_t>* outCredentialData, + vector<uint8_t>* outCredentialPubKey) { + bool testCredential = true; + sp<IWritableIdentityCredential> wc; + ASSERT_TRUE(credentialStore_->createCredential(docType, testCredential, &wc).isOk()); + + vector<uint8_t> attestationApplicationId; + vector<uint8_t> attestationChallenge = {1}; + vector<Certificate> certChain; + ASSERT_TRUE(wc->getAttestationCertificate(attestationApplicationId, attestationChallenge, + &certChain) + .isOk()); + + optional<vector<uint8_t>> optCredentialPubKey = + support::certificateChainGetTopMostKey(certChain[0].encodedCertificate); + ASSERT_TRUE(optCredentialPubKey); + *outCredentialPubKey = optCredentialPubKey.value(); + + size_t proofOfProvisioningSize = 106; + // Not in v1 HAL, may fail + wc->setExpectedProofOfProvisioningSize(proofOfProvisioningSize); + + ASSERT_TRUE(wc->startPersonalization(1 /* numAccessControlProfiles */, + {1} /* numDataElementsPerNamespace */) + .isOk()); + + // Access control profile 0: open access - don't care about the returned SACP + SecureAccessControlProfile sacp; + ASSERT_TRUE(wc->addAccessControlProfile(1, {}, false, 0, 0, &sacp).isOk()); + + // Single entry - don't care about the returned encrypted data + ASSERT_TRUE(wc->beginAddEntry({1}, "ns", "Some Data", 1).isOk()); + vector<uint8_t> encryptedData; + ASSERT_TRUE(wc->addEntryValue({9}, &encryptedData).isOk()); + + vector<uint8_t> proofOfProvisioningSignature; + Status status = wc->finishAddingEntries(outCredentialData, &proofOfProvisioningSignature); + EXPECT_TRUE(status.isOk()) << status.exceptionCode() << ": " << status.exceptionMessage(); +} + +// This checks that any methods called on an IIdentityCredential obtained via a session +// returns STATUS_FAILED except for startRetrieval(), startRetrieveEntryValue(), +// retrieveEntryValue(), finishRetrieval(), setRequestedNamespaces(), setVerificationToken() +// +TEST_P(PresentationSessionTests, returnsFailureOnUnsupportedMethods) { + if (halApiVersion_ < 4) { + GTEST_SKIP() << "Need HAL API version 4, have " << halApiVersion_; + } + + provisionData(); + + sp<IPresentationSession> session; + ASSERT_TRUE(credentialStore_ + ->createPresentationSession( + CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256, + &session) + .isOk()); + + sp<IIdentityCredential> credential; + ASSERT_TRUE(session->getCredential(credential1Data_, &credential).isOk()); + + Status result; + + vector<uint8_t> signatureProofOfDeletion; + result = credential->deleteCredential(&signatureProofOfDeletion); + EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode()); + EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode()); + + vector<uint8_t> ephemeralKeyPair; + result = credential->createEphemeralKeyPair(&ephemeralKeyPair); + EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode()); + EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode()); + + result = credential->setReaderEphemeralPublicKey({}); + EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode()); + EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode()); + + int64_t authChallenge; + result = credential->createAuthChallenge(&authChallenge); + EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode()); + EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode()); + + Certificate certificate; + vector<uint8_t> signingKeyBlob; + result = credential->generateSigningKeyPair(&signingKeyBlob, &certificate); + EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode()); + EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode()); + + result = credential->deleteCredentialWithChallenge({}, &signatureProofOfDeletion); + EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode()); + EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode()); + + vector<uint8_t> signatureProofOfOwnership; + result = credential->proveOwnership({}, &signatureProofOfOwnership); + EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode()); + EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode()); + + sp<IWritableIdentityCredential> writableCredential; + result = credential->updateCredential(&writableCredential); + EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode()); + EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode()); +} + +// TODO: need to add tests to check that the returned IIdentityCredential works +// as intended. + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PresentationSessionTests); +INSTANTIATE_TEST_SUITE_P( + Identity, PresentationSessionTests, + testing::ValuesIn(android::getAidlHalInstanceNames(IIdentityCredentialStore::descriptor)), + android::PrintInstanceNameToString); + +} // namespace android::hardware::identity diff --git a/input/common/aidl/Android.bp b/input/common/aidl/Android.bp new file mode 100644 index 0000000000..6cf64a6fdd --- /dev/null +++ b/input/common/aidl/Android.bp @@ -0,0 +1,22 @@ +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.input.common", + srcs: ["android/hardware/input/common/*.aidl"], + stability: "vintf", + backend: { + cpp: { + enabled: false, + }, + java: { + enabled: false, + }, + }, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Action.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Action.aidl new file mode 100644 index 0000000000..a2e0381188 --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Action.aidl @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2022 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.input.common; +@Backing(type="int") @VintfStability +enum Action { + DOWN = 0, + UP = 1, + MOVE = 2, + CANCEL = 3, + OUTSIDE = 4, + POINTER_DOWN = 5, + POINTER_UP = 6, + HOVER_MOVE = 7, + SCROLL = 8, + HOVER_ENTER = 9, + HOVER_EXIT = 10, + BUTTON_PRESS = 11, + BUTTON_RELEASE = 12, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Axis.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Axis.aidl new file mode 100644 index 0000000000..2114c7deb1 --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Axis.aidl @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2022 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.input.common; +@Backing(type="int") @VintfStability +enum Axis { + X = 0, + Y = 1, + PRESSURE = 2, + SIZE = 3, + TOUCH_MAJOR = 4, + TOUCH_MINOR = 5, + TOOL_MAJOR = 6, + TOOL_MINOR = 7, + ORIENTATION = 8, + VSCROLL = 9, + HSCROLL = 10, + Z = 11, + RX = 12, + RY = 13, + RZ = 14, + HAT_X = 15, + HAT_Y = 16, + LTRIGGER = 17, + RTRIGGER = 18, + THROTTLE = 19, + RUDDER = 20, + WHEEL = 21, + GAS = 22, + BRAKE = 23, + DISTANCE = 24, + TILT = 25, + SCROLL = 26, + RELATIVE_X = 27, + RELATIVE_Y = 28, + GENERIC_1 = 32, + GENERIC_2 = 33, + GENERIC_3 = 34, + GENERIC_4 = 35, + GENERIC_5 = 36, + GENERIC_6 = 37, + GENERIC_7 = 38, + GENERIC_8 = 39, + GENERIC_9 = 40, + GENERIC_10 = 41, + GENERIC_11 = 42, + GENERIC_12 = 43, + GENERIC_13 = 44, + GENERIC_14 = 45, + GENERIC_15 = 46, + GENERIC_16 = 47, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Button.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Button.aidl new file mode 100644 index 0000000000..10ad65a19a --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Button.aidl @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2022 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.input.common; +@Backing(type="int") @VintfStability +enum Button { + NONE = 0, + PRIMARY = 1, + SECONDARY = 2, + TERTIARY = 4, + BACK = 8, + FORWARD = 16, + STYLUS_PRIMARY = 32, + STYLUS_SECONDARY = 64, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Classification.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Classification.aidl new file mode 100644 index 0000000000..ddd524685f --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Classification.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2022 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.input.common; +@Backing(type="byte") @VintfStability +enum Classification { + NONE = 0, + AMBIGUOUS_GESTURE = 1, + DEEP_PRESS = 2, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/EdgeFlag.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/EdgeFlag.aidl new file mode 100644 index 0000000000..1040049b81 --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/EdgeFlag.aidl @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2022 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.input.common; +@Backing(type="int") @VintfStability +enum EdgeFlag { + NONE = 0, + TOP = 1, + BOTTOM = 2, + LEFT = 4, + RIGHT = 8, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Flag.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Flag.aidl new file mode 100644 index 0000000000..d3fcd9ff16 --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Flag.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2022 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.input.common; +@Backing(type="int") @VintfStability +enum Flag { + WINDOW_IS_OBSCURED = 1, + IS_GENERATED_GESTURE = 8, + TAINTED = -2147483648, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Meta.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Meta.aidl new file mode 100644 index 0000000000..2c229f9f36 --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Meta.aidl @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2022 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.input.common; +@Backing(type="int") @VintfStability +enum Meta { + NONE = 0, + ALT_ON = 2, + ALT_LEFT_ON = 16, + ALT_RIGHT_ON = 32, + SHIFT_ON = 1, + SHIFT_LEFT_ON = 64, + SHIFT_RIGHT_ON = 128, + SYM_ON = 4, + FUNCTION_ON = 8, + CTRL_ON = 4096, + CTRL_LEFT_ON = 8192, + CTRL_RIGHT_ON = 16384, + META_ON = 65536, + META_LEFT_ON = 131072, + META_RIGHT_ON = 262144, + CAPS_LOCK_ON = 1048576, + NUM_LOCK_ON = 2097152, + SCROLL_LOCK_ON = 4194304, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/MotionEvent.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/MotionEvent.aidl new file mode 100644 index 0000000000..84af4bf4ca --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/MotionEvent.aidl @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2022 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.input.common; +@VintfStability +parcelable MotionEvent { + int deviceId; + android.hardware.input.common.Source source; + int displayId; + long downTime; + long eventTime; + android.hardware.input.common.Action action; + byte actionIndex; + android.hardware.input.common.Button actionButton; + android.hardware.input.common.Flag flags; + android.hardware.input.common.PolicyFlag policyFlags; + android.hardware.input.common.EdgeFlag edgeFlags; + android.hardware.input.common.Meta metaState; + android.hardware.input.common.Button buttonState; + float xPrecision; + float yPrecision; + android.hardware.input.common.PointerProperties[] pointerProperties; + android.hardware.input.common.PointerCoords[] pointerCoords; + int deviceTimestamp; + android.hardware.input.common.VideoFrame[] frames; +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PointerCoords.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PointerCoords.aidl new file mode 100644 index 0000000000..353a106868 --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PointerCoords.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2022 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.input.common; +@VintfStability +parcelable PointerCoords { + long bits; + float[] values; +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PointerProperties.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PointerProperties.aidl new file mode 100644 index 0000000000..a49581b438 --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PointerProperties.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2022 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.input.common; +@VintfStability +parcelable PointerProperties { + int id; + android.hardware.input.common.ToolType toolType; +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PolicyFlag.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PolicyFlag.aidl new file mode 100644 index 0000000000..247e868fcb --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PolicyFlag.aidl @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2022 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.input.common; +@Backing(type="int") @VintfStability +enum PolicyFlag { + WAKE = 1, + VIRTUAL = 2, + FUNCTION = 4, + GESTURE = 8, + INJECTED = 16777216, + TRUSTED = 33554432, + FILTERED = 67108864, + DISABLE_KEY_REPEAT = 134217728, + INTERACTIVE = 536870912, + PASS_TO_USER = 1073741824, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Source.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Source.aidl new file mode 100644 index 0000000000..24d02cdbdc --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Source.aidl @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2022 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.input.common; +@Backing(type="int") @VintfStability +enum Source { + UNKNOWN = 0, + KEYBOARD = 257, + DPAD = 513, + GAMEPAD = 1025, + TOUCHSCREEN = 4098, + MOUSE = 8194, + STYLUS = 16386, + BLUETOOTH_STYLUS = 49154, + TRACKBALL = 65540, + MOUSE_RELATIVE = 131076, + TOUCHPAD = 1048584, + TOUCH_NAVIGATION = 2097152, + ROTARY_ENCODER = 4194304, + JOYSTICK = 16777232, + SENSOR = 67108864, + ANY = -256, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/SourceClass.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/SourceClass.aidl new file mode 100644 index 0000000000..96eede24b0 --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/SourceClass.aidl @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2022 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.input.common; +@Backing(type="byte") @VintfStability +enum SourceClass { + NONE = 0, + BUTTON = 1, + POINTER = 2, + NAVIGATION = 4, + POSITION = 8, + JOYSTICK = 16, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/ToolType.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/ToolType.aidl new file mode 100644 index 0000000000..ac1b69d74e --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/ToolType.aidl @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2022 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.input.common; +@Backing(type="byte") @VintfStability +enum ToolType { + UNKNOWN = 0, + FINGER = 1, + STYLUS = 2, + MOUSE = 3, + ERASER = 4, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/VideoFrame.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/VideoFrame.aidl new file mode 100644 index 0000000000..14985c51d5 --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/VideoFrame.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2022 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.input.common; +@VintfStability +parcelable VideoFrame { + char[] data; + int height; + int width; + long timestamp; +} diff --git a/input/common/aidl/android/hardware/input/common/Action.aidl b/input/common/aidl/android/hardware/input/common/Action.aidl new file mode 100644 index 0000000000..ebe5e676dc --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/Action.aidl @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2022 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.input.common; + +/** + * Motion event actions + */ +@VintfStability +@Backing(type="int") +enum Action { + /** + * A pressed gesture has started, the motion contains the initial starting location. + */ + DOWN = 0, + /** + * A pressed gesture has finished, the motion contains the final release location + * as well as any intermediate points since the last down or move event. + */ + UP = 1, + /** + * A change has happened during a press gesture (between AMOTION_EVENT_ACTION_DOWN and + * AMOTION_EVENT_ACTION_UP). The motion contains the most recent point. + */ + MOVE = 2, + /** + * The current gesture has been aborted. + * You will not receive any more points in it. You must treat this as + * an up event, but not perform any action that you normally would. + */ + CANCEL = 3, + /** + * A movement has happened outside of the normal bounds of the UI element. + * This does not provide a full gesture, but only the initial location of the movement/touch. + */ + OUTSIDE = 4, + /** + * A non-primary pointer has gone down. + */ + POINTER_DOWN = 5, + /** + * A non-primary pointer has gone up. + */ + POINTER_UP = 6, + /** + * A change happened but the pointer is not down (unlike AMOTION_EVENT_ACTION_MOVE). + * The motion contains the most recent point, as well as any intermediate points since + * the last hover move event. + */ + HOVER_MOVE = 7, + /** + * The motion event contains relative vertical and/or horizontal scroll offsets. + * Use getAxisValue to retrieve the information from AMOTION_EVENT_AXIS_VSCROLL + * and AMOTION_EVENT_AXIS_HSCROLL. + * The pointer may or may not be down when this event is dispatched. + * The framework will always deliver this action to the window under the pointer, which + * may not be the window currently touched. + */ + SCROLL = 8, + /** + * The pointer is not down but has entered the boundaries of a window or view. + */ + HOVER_ENTER = 9, + /** + * The pointer is not down but has exited the boundaries of a window or view. + */ + HOVER_EXIT = 10, + /** + * One or more buttons have been pressed. + */ + BUTTON_PRESS = 11, + /** + * One or more buttons have been released. + */ + BUTTON_RELEASE = 12, +} diff --git a/input/common/aidl/android/hardware/input/common/Axis.aidl b/input/common/aidl/android/hardware/input/common/Axis.aidl new file mode 100644 index 0000000000..11509494fa --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/Axis.aidl @@ -0,0 +1,387 @@ +/* + * Copyright (C) 2022 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.input.common; + +/** + * Constants that identify each individual axis of a motion event. + * Each value represents a bit position. The user is expected to manually shift + * to the desired position (e.g., 1 << Axis.X) when reading or writing these + * from a bitfield manually. + */ +@VintfStability +@Backing(type="int") +enum Axis { + /** + * Axis constant: X axis of a motion event. + * + * - For a touch screen, reports the absolute X screen position of the center of + * the touch contact area. The units are display pixels. + * - For a touch pad, reports the absolute X surface position of the center of the touch + * contact area. The units are device-dependent. + * - For a mouse, reports the absolute X screen position of the mouse pointer. + * The units are display pixels. + * - For a trackball, reports the relative horizontal displacement of the trackball. + * The value is normalized to a range from -1.0 (left) to 1.0 (right). + * - For a joystick, reports the absolute X position of the joystick. + * The value is normalized to a range from -1.0 (left) to 1.0 (right). + */ + X = 0, + /** + * Axis constant: Y axis of a motion event. + * + * - For a touch screen, reports the absolute Y screen position of the center of + * the touch contact area. The units are display pixels. + * - For a touch pad, reports the absolute Y surface position of the center of the touch + * contact area. The units are device-dependent. + * - For a mouse, reports the absolute Y screen position of the mouse pointer. + * The units are display pixels. + * - For a trackball, reports the relative vertical displacement of the trackball. + * The value is normalized to a range from -1.0 (up) to 1.0 (down). + * - For a joystick, reports the absolute Y position of the joystick. + * The value is normalized to a range from -1.0 (up or far) to 1.0 (down or near). + */ + Y = 1, + /** + * Axis constant: Pressure axis of a motion event. + * + * - For a touch screen or touch pad, reports the approximate pressure applied to the surface + * by a finger or other tool. The value is normalized to a range from + * 0 (no pressure at all) to 1 (normal pressure), although values higher than 1 + * may be generated depending on the calibration of the input device. + * - For a trackball, the value is set to 1 if the trackball button is pressed + * or 0 otherwise. + * - For a mouse, the value is set to 1 if the primary mouse button is pressed + * or 0 otherwise. + */ + PRESSURE = 2, + /** + * Axis constant: Size axis of a motion event. + * + * - For a touch screen or touch pad, reports the approximate size of the contact area in + * relation to the maximum detectable size for the device. The value is normalized + * to a range from 0 (smallest detectable size) to 1 (largest detectable size), + * although it is not a linear scale. This value is of limited use. + * To obtain calibrated size information, see + * {@link TOUCH_MAJOR} or {@link TOOL_MAJOR}. + */ + SIZE = 3, + /** + * Axis constant: TouchMajor axis of a motion event. + * + * - For a touch screen, reports the length of the major axis of an ellipse that + * represents the touch area at the point of contact. + * The units are display pixels. + * - For a touch pad, reports the length of the major axis of an ellipse that + * represents the touch area at the point of contact. + * The units are device-dependent. + */ + TOUCH_MAJOR = 4, + /** + * Axis constant: TouchMinor axis of a motion event. + * + * - For a touch screen, reports the length of the minor axis of an ellipse that + * represents the touch area at the point of contact. + * The units are display pixels. + * - For a touch pad, reports the length of the minor axis of an ellipse that + * represents the touch area at the point of contact. + * The units are device-dependent. + * + * When the touch is circular, the major and minor axis lengths will be equal to one another. + */ + TOUCH_MINOR = 5, + /** + * Axis constant: ToolMajor axis of a motion event. + * + * - For a touch screen, reports the length of the major axis of an ellipse that + * represents the size of the approaching finger or tool used to make contact. + * - For a touch pad, reports the length of the major axis of an ellipse that + * represents the size of the approaching finger or tool used to make contact. + * The units are device-dependent. + * + * When the touch is circular, the major and minor axis lengths will be equal to one another. + * + * The tool size may be larger than the touch size since the tool may not be fully + * in contact with the touch sensor. + */ + TOOL_MAJOR = 6, + /** + * Axis constant: ToolMinor axis of a motion event. + * + * - For a touch screen, reports the length of the minor axis of an ellipse that + * represents the size of the approaching finger or tool used to make contact. + * - For a touch pad, reports the length of the minor axis of an ellipse that + * represents the size of the approaching finger or tool used to make contact. + * The units are device-dependent. + * + * When the touch is circular, the major and minor axis lengths will be equal to one another. + * + * The tool size may be larger than the touch size since the tool may not be fully + * in contact with the touch sensor. + */ + TOOL_MINOR = 7, + /** + * Axis constant: Orientation axis of a motion event. + * + * - For a touch screen or touch pad, reports the orientation of the finger + * or tool in radians relative to the vertical plane of the device. + * An angle of 0 radians indicates that the major axis of contact is oriented + * upwards, is perfectly circular or is of unknown orientation. A positive angle + * indicates that the major axis of contact is oriented to the right. A negative angle + * indicates that the major axis of contact is oriented to the left. + * The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians + * (finger pointing fully right). + * - For a stylus, the orientation indicates the direction in which the stylus + * is pointing in relation to the vertical axis of the current orientation of the screen. + * The range is from -PI radians to PI radians, where 0 is pointing up, + * -PI/2 radians is pointing left, -PI or PI radians is pointing down, and PI/2 radians + * is pointing right. See also {@link TILT}. + */ + ORIENTATION = 8, + /** + * Axis constant: Vertical Scroll axis of a motion event. + * + * - For a mouse, reports the relative movement of the vertical scroll wheel. + * The value is normalized to a range from -1.0 (down) to 1.0 (up). + * + * The framework may use this axis to scroll views vertically. + */ + VSCROLL = 9, + /** + * Axis constant: Horizontal Scroll axis of a motion event. + * + * - For a mouse, reports the relative movement of the horizontal scroll wheel. + * The value is normalized to a range from -1.0 (left) to 1.0 (right). + * + * The framework may use this axis to scroll views horizontally. + */ + HSCROLL = 10, + /** + * Axis constant: Z axis of a motion event. + * + * - For a joystick, reports the absolute Z position of the joystick. + * The value is normalized to a range from -1.0 (high) to 1.0 (low). + * <em>On game pads with two analog joysticks, this axis is often reinterpreted + * to report the absolute X position of the second joystick instead.</em> + */ + Z = 11, + /** + * Axis constant: X Rotation axis of a motion event. + * + * - For a joystick, reports the absolute rotation angle about the X axis. + * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise). + */ + RX = 12, + /** + * Axis constant: Y Rotation axis of a motion event. + * + * - For a joystick, reports the absolute rotation angle about the Y axis. + * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise). + */ + RY = 13, + /** + * Axis constant: Z Rotation axis of a motion event. + * + * - For a joystick, reports the absolute rotation angle about the Z axis. + * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise). + * On game pads with two analog joysticks, this axis is often reinterpreted + * to report the absolute Y position of the second joystick instead. + */ + RZ = 14, + /** + * Axis constant: Hat X axis of a motion event. + * + * - For a joystick, reports the absolute X position of the directional hat control. + * The value is normalized to a range from -1.0 (left) to 1.0 (right). + */ + HAT_X = 15, + /** + * Axis constant: Hat Y axis of a motion event. + * + * - For a joystick, reports the absolute Y position of the directional hat control. + * The value is normalized to a range from -1.0 (up) to 1.0 (down). + */ + HAT_Y = 16, + /** + * Axis constant: Left Trigger axis of a motion event. + * + * - For a joystick, reports the absolute position of the left trigger control. + * The value is normalized to a range from 0.0 (released) to 1.0 (fully pressed). + */ + LTRIGGER = 17, + /** + * Axis constant: Right Trigger axis of a motion event. + * + * - For a joystick, reports the absolute position of the right trigger control. + * The value is normalized to a range from 0.0 (released) to 1.0 (fully pressed). + */ + RTRIGGER = 18, + /** + * Axis constant: Throttle axis of a motion event. + * + * - For a joystick, reports the absolute position of the throttle control. + * The value is normalized to a range from 0.0 (fully open) to 1.0 (fully closed). + */ + THROTTLE = 19, + /** + * Axis constant: Rudder axis of a motion event. + * + * - For a joystick, reports the absolute position of the rudder control. + * The value is normalized to a range from -1.0 (turn left) to 1.0 (turn right). + */ + RUDDER = 20, + /** + * Axis constant: Wheel axis of a motion event. + * + * - For a joystick, reports the absolute position of the steering wheel control. + * The value is normalized to a range from -1.0 (turn left) to 1.0 (turn right). + */ + WHEEL = 21, + /** + * Axis constant: Gas axis of a motion event. + * + * - For a joystick, reports the absolute position of the gas (accelerator) control. + * The value is normalized to a range from 0.0 (no acceleration) + * to 1.0 (maximum acceleration). + */ + GAS = 22, + /** + * Axis constant: Brake axis of a motion event. + * + * - For a joystick, reports the absolute position of the brake control. + * The value is normalized to a range from 0.0 (no braking) to 1.0 (maximum braking). + */ + BRAKE = 23, + /** + * Axis constant: Distance axis of a motion event. + * + * - For a stylus, reports the distance of the stylus from the screen. + * A value of 0.0 indicates direct contact and larger values indicate increasing + * distance from the surface. + */ + DISTANCE = 24, + /** + * Axis constant: Tilt axis of a motion event. + * + * - For a stylus, reports the tilt angle of the stylus in radians where + * 0 radians indicates that the stylus is being held perpendicular to the + * surface, and PI/2 radians indicates that the stylus is being held flat + * against the surface. + */ + TILT = 25, + /** + * Axis constant: Generic scroll axis of a motion event. + * + * - This is used for scroll axis motion events that can't be classified as strictly + * vertical or horizontal. The movement of a rotating scroller is an example of this. + */ + SCROLL = 26, + /** + * Axis constant: The movement of x position of a motion event. + * + * - For a mouse, reports a difference of x position between the previous position. + * This is useful when pointer is captured, in that case the mouse pointer doesn't + * change the location but this axis reports the difference which allows the app + * to see how the mouse is moved. + */ + RELATIVE_X = 27, + /** + * Axis constant: The movement of y position of a motion event. + * + * Same as {@link RELATIVE_X}, but for y position. + */ + RELATIVE_Y = 28, + /** + * Axis constant: Generic 1 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + GENERIC_1 = 32, + /** + * Axis constant: Generic 2 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + GENERIC_2 = 33, + /** + * Axis constant: Generic 3 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + GENERIC_3 = 34, + /** + * Axis constant: Generic 4 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + GENERIC_4 = 35, + /** + * Axis constant: Generic 5 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + GENERIC_5 = 36, + /** + * Axis constant: Generic 6 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + GENERIC_6 = 37, + /** + * Axis constant: Generic 7 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + GENERIC_7 = 38, + /** + * Axis constant: Generic 8 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + GENERIC_8 = 39, + /** + * Axis constant: Generic 9 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + GENERIC_9 = 40, + /** + * Axis constant: Generic 10 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + GENERIC_10 = 41, + /** + * Axis constant: Generic 11 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + GENERIC_11 = 42, + /** + * Axis constant: Generic 12 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + GENERIC_12 = 43, + /** + * Axis constant: Generic 13 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + GENERIC_13 = 44, + /** + * Axis constant: Generic 14 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + GENERIC_14 = 45, + /** + * Axis constant: Generic 15 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + GENERIC_15 = 46, + /** + * Axis constant: Generic 16 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + GENERIC_16 = 47, +} diff --git a/input/common/aidl/android/hardware/input/common/Button.aidl b/input/common/aidl/android/hardware/input/common/Button.aidl new file mode 100644 index 0000000000..4bbd5f5a17 --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/Button.aidl @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2022 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.input.common; + +/** + * Buttons that are associated with motion events. + */ +@VintfStability +@Backing(type="int") +enum Button { + NONE = 0, + PRIMARY = 1 << 0, + SECONDARY = 1 << 1, + TERTIARY = 1 << 2, + BACK = 1 << 3, + FORWARD = 1 << 4, + STYLUS_PRIMARY = 1 << 5, + STYLUS_SECONDARY = 1 << 6, +} diff --git a/input/common/aidl/android/hardware/input/common/Classification.aidl b/input/common/aidl/android/hardware/input/common/Classification.aidl new file mode 100644 index 0000000000..f573174e90 --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/Classification.aidl @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2022 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.input.common; + +/** + * Classification of the current gesture, if available. + */ +@VintfStability +@Backing(type="byte") +enum Classification { + NONE = 0, + /** + * Too early to classify the gesture, need more events. + */ + AMBIGUOUS_GESTURE = 1, + /** + * User is force-pressing the screen. + */ + DEEP_PRESS = 2, +} diff --git a/input/common/aidl/android/hardware/input/common/EdgeFlag.aidl b/input/common/aidl/android/hardware/input/common/EdgeFlag.aidl new file mode 100644 index 0000000000..8d2263586e --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/EdgeFlag.aidl @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2022 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.input.common; + +/** + * Edge flags + */ +@VintfStability +@Backing(type="int") +enum EdgeFlag { + /** + * No edges are intersected + */ + NONE = 0, + /** + * Motion intersected top edge of the screen + */ + TOP = 1 << 0, + /** + * Motion intersected bottom edge of the screen + */ + BOTTOM = 1 << 1, + /** + * Motion intersected left edge of the screen + */ + LEFT = 1 << 2, + /** + * Motion intersected right edge of the screen + */ + RIGHT = 1 << 3, +} diff --git a/input/common/aidl/android/hardware/input/common/Flag.aidl b/input/common/aidl/android/hardware/input/common/Flag.aidl new file mode 100644 index 0000000000..600bdd3993 --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/Flag.aidl @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2022 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.input.common; + +/** + * Motion event flags + */ +@VintfStability +@Backing(type="int") +enum Flag { + /** + * Indicates that the window that received this motion event is partly + * or wholly obscured by another visible window above it. This flag is set to true + * even if the event did not directly pass through the obscured area. + * A security sensitive application can check this flag to identify situations in which + * a malicious application may have covered up part of its content for the purpose + * of misleading the user or hijacking touches. An appropriate response might be + * to drop the suspect touches or to take additional precautions to confirm the user's + * actual intent. + */ + WINDOW_IS_OBSCURED = 1 << 0, + /** + * This flag indicates that the event has been generated by a gesture generator. It + * could be used, for example, to determine whether touch slop should be applied. + */ + IS_GENERATED_GESTURE = 1 << 3, + /** + * Motion event is inconsistent with previously sent motion events. + */ + TAINTED = 1 << 31, +} diff --git a/input/common/aidl/android/hardware/input/common/Meta.aidl b/input/common/aidl/android/hardware/input/common/Meta.aidl new file mode 100644 index 0000000000..9ccf11b69d --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/Meta.aidl @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2022 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.input.common; + +/** + * Meta key / modifier state + */ +@VintfStability +@Backing(type="int") +enum Meta { + NONE = 0, + /** + * One of the ALT meta keys is pressed. + */ + ALT_ON = 1 << 1, + /** + * The left ALT meta key is pressed. + */ + ALT_LEFT_ON = 1 << 4, + /** + * The right ALT meta key is pressed. + */ + ALT_RIGHT_ON = 1 << 5, + /** + * One of the SHIFT meta keys is pressed. + */ + SHIFT_ON = 1 << 0, + /** + * The left SHIFT meta key is pressed. + */ + SHIFT_LEFT_ON = 1 << 6, + /** + * The right SHIFT meta key is pressed. + */ + SHIFT_RIGHT_ON = 1 << 7, + /** + * The SYM meta key is pressed. + */ + SYM_ON = 1 << 2, + /** + * The FUNCTION meta key is pressed. + */ + FUNCTION_ON = 1 << 3, + /** + * One of the CTRL meta keys is pressed. + */ + CTRL_ON = 1 << 12, + /** + * The left CTRL meta key is pressed. + */ + CTRL_LEFT_ON = 1 << 13, + /** + * The right CTRL meta key is pressed. + */ + CTRL_RIGHT_ON = 1 << 14, + /** + * One of the META meta keys is pressed. + */ + META_ON = 1 << 16, + /** + * The left META meta key is pressed. + */ + META_LEFT_ON = 1 << 17, + /** + * The right META meta key is pressed. + */ + META_RIGHT_ON = 1 << 18, + /** + * The CAPS LOCK meta key is on. + */ + CAPS_LOCK_ON = 1 << 20, + /** + * The NUM LOCK meta key is on. + */ + NUM_LOCK_ON = 1 << 21, + /** + * The SCROLL LOCK meta key is on. + */ + SCROLL_LOCK_ON = 1 << 22, +} diff --git a/input/common/aidl/android/hardware/input/common/MotionEvent.aidl b/input/common/aidl/android/hardware/input/common/MotionEvent.aidl new file mode 100644 index 0000000000..dfea7033f2 --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/MotionEvent.aidl @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2022 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.input.common; + +import android.hardware.input.common.Action; +import android.hardware.input.common.Button; +import android.hardware.input.common.EdgeFlag; +import android.hardware.input.common.Flag; +import android.hardware.input.common.Meta; +import android.hardware.input.common.PointerCoords; +import android.hardware.input.common.PointerProperties; +import android.hardware.input.common.PolicyFlag; +import android.hardware.input.common.Source; +import android.hardware.input.common.VideoFrame; + +/** + * Analogous to Android's native MotionEvent / NotifyMotionArgs. + * Stores the basic information about pointer movements. + */ +@VintfStability +parcelable MotionEvent { + /** + * The id of the device which produced this event. + */ + int deviceId; + /** + * The source type of this event. + */ + Source source; + /** + * The display id associated with this event. + */ + int displayId; + /** + * Time when the initial touch down occurred, in nanoseconds. + */ + long downTime; + /** + * Time when this event occurred, in nanoseconds. + */ + long eventTime; + /** + * The kind of action being performed. + */ + Action action; + /** + * For ACTION_POINTER_DOWN or ACTION_POINTER_UP, this contains the associated pointer index. + * The index may be used to get information about the pointer that has gone down or up. + */ + byte actionIndex; + /** + * The button that has been modified during a press or release action. + */ + Button actionButton; + /** + * The motion event flags. + */ + Flag flags; + /** + * The motion event policy flags. + */ + PolicyFlag policyFlags; + /** + * The edges, if any, that were touched by this motion event. + */ + EdgeFlag edgeFlags; + /** + * The state of any meta / modifier keys that were in effect when the event was generated. + */ + Meta metaState; + /** + * The state of buttons that are pressed. + */ + Button buttonState; + /** + * The precision of the X coordinate being reported. + */ + float xPrecision; + /** + * The precision of the Y coordinate being reported. + */ + float yPrecision; + /** + * The properties of each pointer present in this motion event. + */ + PointerProperties[] pointerProperties; + /** + * The coordinates of each pointer. + */ + PointerCoords[] pointerCoords; + /** + * Device time at which the event occurred, in microseconds. + * Will wrap after a little over an hour. + */ + int deviceTimestamp; + /** + * The video frames, if any, associated with the current or previous motion events. + */ + VideoFrame[] frames; +} diff --git a/input/common/aidl/android/hardware/input/common/PointerCoords.aidl b/input/common/aidl/android/hardware/input/common/PointerCoords.aidl new file mode 100644 index 0000000000..56d9a74a4f --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/PointerCoords.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2022 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.input.common; + +import android.hardware.input.common.Axis; + +/** + * Pointer coordinate data. Analogous to Android's PointerCoords. + */ +@VintfStability +parcelable PointerCoords { + /** + * Bitfield of axes that are present in this structure. + * Each bit position matches an axis defined in Axis.aidl. + */ + long bits; + /** + * The values corresponding to each non-zero axis. This vector only + * contains non-zero entries. If an axis that is not currently specified + * in "bits" is requested, a zero value is returned. + * There are only as many values stored here + * as there are non-zero bits in the "bits" field. + * The values are position-packed. So the first non-zero axis will be + * at position 0, the next non-zero axis will be at position 1, and so on. + */ + float[] values; +} diff --git a/input/common/aidl/android/hardware/input/common/PointerProperties.aidl b/input/common/aidl/android/hardware/input/common/PointerProperties.aidl new file mode 100644 index 0000000000..38d815e022 --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/PointerProperties.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2022 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.input.common; + +import android.hardware.input.common.ToolType; + +/** + * Properties of a particular pointer. Analogous to Android's PointerProperties. + */ +@VintfStability +parcelable PointerProperties { + /** + * A number identifying a specific pointer. When a pointer is lifted, + * this value may be reused by another new pointer, even during the + * same gesture. For example, if there are two pointers touching the screen + * at the same time, they might have pointer ID's of 0 and 1. If the + * pointer with id = 0 is lifted, while the pointer with id = 1 remains, and + * a new pointer is placed on the screen, then the new pointer may receive + * an id of 0. While a pointer is active, it is guaranteed to keep the same + * id. + */ + int id; + /** + * Type of tool used to make contact, such as a finger or stylus, if known. + */ + ToolType toolType; +} diff --git a/input/common/aidl/android/hardware/input/common/PolicyFlag.aidl b/input/common/aidl/android/hardware/input/common/PolicyFlag.aidl new file mode 100644 index 0000000000..c5edd0d433 --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/PolicyFlag.aidl @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2022 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.input.common; + +/** + * Policy flags. + * The values 1 << 4 through 1 << 23 are not currently used. + * When a new value is added, make sure it matches a value defined in Input.h + * and other relevant files in frameworks/base and frameworks/native. + */ +@VintfStability +@Backing(type="int") +enum PolicyFlag { + /** + * Event should wake the device + */ + WAKE = 1 << 0, + /** + * Key is virtual, and should generate haptic feedback + */ + VIRTUAL = 1 << 1, + /** + * Key is the special function modifier + */ + FUNCTION = 1 << 2, + /** + * Key represents a special gesture that has been detected + * by the touch firmware or driver. + */ + GESTURE = 1 << 3, + /** + * Event was injected + */ + INJECTED = 1 << 24, + /** + * Event comes from a trusted source, such as a directly attached input + * device or an application with system-wide event injection permission. + */ + TRUSTED = 1 << 25, + /** + * Event has passed through an input filter. + */ + FILTERED = 1 << 26, + /** + * Disable automatic key repeating behaviour. + */ + DISABLE_KEY_REPEAT = 1 << 27, + /** + * Device was in an interactive state when the event was intercepted + */ + INTERACTIVE = 1 << 29, + /** + * Event should be dispatched to applications + */ + PASS_TO_USER = 1 << 30, +} diff --git a/input/common/aidl/android/hardware/input/common/Source.aidl b/input/common/aidl/android/hardware/input/common/Source.aidl new file mode 100644 index 0000000000..7eb6d66d64 --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/Source.aidl @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2022 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.input.common; + +import android.hardware.input.common.SourceClass; + +/** + * Input sources + */ +@VintfStability +@Backing(type="int") +enum Source { + UNKNOWN = 0, + KEYBOARD = (1 << 8) | SourceClass.BUTTON, + DPAD = (1 << 9) | SourceClass.BUTTON, + GAMEPAD = (1 << 10) | SourceClass.BUTTON, + TOUCHSCREEN = (1 << 12) | SourceClass.POINTER, + MOUSE = (1 << 13) | SourceClass.POINTER, + STYLUS = (1 << 14) | SourceClass.POINTER, + BLUETOOTH_STYLUS = (1 << 15) | STYLUS, + TRACKBALL = (1 << 16) | SourceClass.NAVIGATION, + MOUSE_RELATIVE = (1 << 17) | SourceClass.NAVIGATION, + TOUCHPAD = (1 << 20) | SourceClass.POSITION, + TOUCH_NAVIGATION = (1 << 21) | SourceClass.NONE, + ROTARY_ENCODER = (1 << 22) | SourceClass.NONE, + JOYSTICK = (1 << 24) | SourceClass.JOYSTICK, + SENSOR = (1 << 26) | SourceClass.NONE, + ANY = 0xFFFFFF00, +} diff --git a/input/common/aidl/android/hardware/input/common/SourceClass.aidl b/input/common/aidl/android/hardware/input/common/SourceClass.aidl new file mode 100644 index 0000000000..43157981e3 --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/SourceClass.aidl @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2022 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.input.common; + +@VintfStability +@Backing(type="byte") +enum SourceClass { + NONE = 0 << 0, + BUTTON = 1 << 0, + POINTER = 1 << 1, + NAVIGATION = 1 << 2, + POSITION = 1 << 3, + JOYSTICK = 1 << 4, +} diff --git a/input/common/aidl/android/hardware/input/common/ToolType.aidl b/input/common/aidl/android/hardware/input/common/ToolType.aidl new file mode 100644 index 0000000000..cfa057dc15 --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/ToolType.aidl @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2022 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.input.common; + +/** + * Tool type of a pointer + */ +@VintfStability +@Backing(type="byte") +enum ToolType { + UNKNOWN = 0, + FINGER = 1, + STYLUS = 2, + MOUSE = 3, + ERASER = 4, +} diff --git a/input/common/aidl/android/hardware/input/common/VideoFrame.aidl b/input/common/aidl/android/hardware/input/common/VideoFrame.aidl new file mode 100644 index 0000000000..409cee50fc --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/VideoFrame.aidl @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2022 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.input.common; + +/** + * Touch heatmap. + * + * The array is a 2-D row-major matrix with dimensions (height, width). + * The heatmap data is rotated when device orientation changes. + * + * Example: + * + * If the data in the array is: + * data[i] = i for i in 0 .. 59, + * then it can be represented as a 10 x 6 matrix: + * + * <-- width --> + * 0 1 2 3 4 5 ^ + * 6 7 8 9 10 11 | + * 12 13 14 15 16 17 | + * 18 ... 23 | + * 24 ... 29 | height + * 30 ... 35 | + * 36 ... 41 | + * 42 ... 47 | + * 48 ... 53 | + * 54 ... 59 v + * + * Looking at the device in standard portrait orientation, + * the element "0" is the top left of the screen, + * "5" is at the top right, and "59" is the bottom right. + * Here height=10 and width=6. + * + * If the screen orientation changes to landscape (a 90 degree orientation + * change), the frame's dimensions will become 6 x 10 + * and the data will look as follows: + * 54 48 42 36 30 24 18 12 6 0 ^ + * ... 13 7 1 | + * ... 14 8 2 | height + * ... 15 9 3 | + * ... 16 10 4 | + * 59 53 47 41 35 29 23 17 11 5 v + * <-- width --> + * + * Here the element "0" is at the physical top left of the unrotated screen. + * + * Since the coordinates of a MotionEvent are also adjusted based on the + * orientation, the rotation of the video frame data ensures that + * the axes for MotionEvent and VideoFrame data are consistent. + */ +@VintfStability +parcelable VideoFrame { + /** + * Video frame data. + * Size of the data is height * width. + */ + char[] data; + int height; + int width; + /** + * Time at which the frame was collected, in nanoseconds. + * Measured with the same clock that is used to populate MotionEvent times. + */ + long timestamp; +} diff --git a/ir/aidl/Android.bp b/ir/aidl/Android.bp index 6dacb858d2..5dbf68fdbe 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, @@ -26,8 +35,7 @@ aidl_interface { }, ndk: { vndk: { - // TODO(b/206116595) enable this - enabled: false, + enabled: true, }, }, }, diff --git a/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl b/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl index 056a8b1235..07bf4b4af2 100644 --- a/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl +++ b/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl @@ -35,5 +35,5 @@ package android.hardware.ir; @VintfStability interface IConsumerIr { android.hardware.ir.ConsumerIrFreqRange[] getCarrierFreqs(); - void transmit(in int carrierFreq, in int[] pattern); + void transmit(in int carrierFreqHz, in int[] pattern); } diff --git a/ir/aidl/android/hardware/ir/IConsumerIr.aidl b/ir/aidl/android/hardware/ir/IConsumerIr.aidl index d14fa566bc..f6f9742fdb 100644 --- a/ir/aidl/android/hardware/ir/IConsumerIr.aidl +++ b/ir/aidl/android/hardware/ir/IConsumerIr.aidl @@ -23,23 +23,21 @@ interface IConsumerIr { /** * Enumerates which frequencies the IR transmitter supports. * - * Status OK (EX_NONE) on success. - * * @return - an array of all supported frequency ranges. */ ConsumerIrFreqRange[] getCarrierFreqs(); /** * Sends an IR pattern at a given frequency in HZ. + * This call must return when the transmit is complete or encounters an error. * - * The pattern is alternating series of carrier on and off periods measured in - * microseconds. The carrier should be turned off at the end of a transmit - * even if there are and odd number of entries in the pattern array. + * @param carrierFreq - Frequency of the transmission in HZ. * - * This call must return when the transmit is complete or encounters an error. + * @param pattern - Alternating series of on and off periods measured in + * microseconds. The carrier should be turned off at the end of a transmit + * even if there are an odd number of entries in the pattern array. * - * Status OK (EX_NONE) on success. - * EX_UNSUPPORTED_OPERATION when the frequency is not supported. + * @throws EX_UNSUPPORTED_OPERATION when the frequency is not supported. */ - void transmit(in int carrierFreq, in int[] pattern); + void transmit(in int carrierFreqHz, in int[] pattern); } diff --git a/ir/aidl/default/Android.bp b/ir/aidl/default/Android.bp index 6519664dec..a4fb439566 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/ir/aidl/default/main.cpp b/ir/aidl/default/main.cpp index 764aeaf641..7c4a8169c8 100644 --- a/ir/aidl/default/main.cpp +++ b/ir/aidl/default/main.cpp @@ -30,7 +30,7 @@ const std::vector<ConsumerIrFreqRange> kSupportedFreqs = { class ConsumerIr : public BnConsumerIr { ::ndk::ScopedAStatus getCarrierFreqs(std::vector<ConsumerIrFreqRange>* _aidl_return) override; - ::ndk::ScopedAStatus transmit(int32_t in_carrierFreq, + ::ndk::ScopedAStatus transmit(int32_t in_carrierFreqHz, const std::vector<int32_t>& in_pattern) override; }; @@ -46,9 +46,9 @@ bool isSupportedFreq(int32_t freq) { return false; } -::ndk::ScopedAStatus ConsumerIr::transmit(int32_t in_carrierFreq, +::ndk::ScopedAStatus ConsumerIr::transmit(int32_t in_carrierFreqHz, const std::vector<int32_t>& in_pattern) { - if (isSupportedFreq(in_carrierFreq)) { + if (isSupportedFreq(in_carrierFreqHz)) { // trasmit the pattern, each integer is number of microseconds in an // alternating on/off state. usleep(std::accumulate(in_pattern.begin(), in_pattern.end(), 0)); diff --git a/keymaster/4.0/IKeymasterDevice.hal b/keymaster/4.0/IKeymasterDevice.hal index dfde060e3f..1c6ae478f4 100644 --- a/keymaster/4.0/IKeymasterDevice.hal +++ b/keymaster/4.0/IKeymasterDevice.hal @@ -1254,7 +1254,8 @@ interface IKeymasterDevice { * o PaddingMode::RSA_PSS. For PSS-padded signature operations, the PSS salt length must match * the size of the PSS digest selected. The digest specified with Tag::DIGEST in inputParams * on begin() must be used as the PSS digest algorithm, MGF1 must be used as the mask - * generation function and SHA1 must be used as the MGF1 digest algorithm. + * generation function and the digest specified with Tag:DIGEST in inputParams must also be + * used as the MGF1 digest algorithm. * * o PaddingMode::RSA_OAEP. The digest specified with Tag::DIGEST in inputParams on begin is * used as the OAEP digest algorithm, MGF1 must be used as the mask generation function and diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp index 767614754b..6412f3a06b 100644 --- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp +++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp @@ -1712,6 +1712,7 @@ TEST_P(VerificationOperationsTest, RsaAllPaddingsAndDigests) { case PaddingMode::RSA_PSS: EXPECT_GT(EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING), 0); EXPECT_GT(EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, EVP_MD_size(md)), 0); + EXPECT_GT(EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, md), 0); break; case PaddingMode::RSA_PKCS1_1_5_SIGN: // PKCS1 is the default; don't need to set anything. diff --git a/neuralnetworks/aidl/Android.bp b/neuralnetworks/aidl/Android.bp index cbb6ce5163..47f3b30280 100644 --- a/neuralnetworks/aidl/Android.bp +++ b/neuralnetworks/aidl/Android.bp @@ -38,5 +38,6 @@ aidl_interface { versions: [ "1", "2", + "3", ], } diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/.hash b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/.hash new file mode 100644 index 0000000000..3b9f018381 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/.hash @@ -0,0 +1 @@ +8c2c4ca2327e6f779dad6119c03d832ea4e1def1 diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferDesc.aidl index 9c208c4e7c..05cec76c88 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferDesc.aidl @@ -31,13 +31,8 @@ // with such a backward incompatible change, it has a high risk of breaking // later when a module using the interface is updated, e.g., Mainline modules. -package android.hardware.biometrics.fingerprint; -@Backing(type="byte") @VintfStability -enum FingerprintSensorType { - UNKNOWN = 0, - REAR = 1, - UNDER_DISPLAY_ULTRASONIC = 2, - UNDER_DISPLAY_OPTICAL = 3, - POWER_BUTTON = 4, - HOME_BUTTON = 5, +package android.hardware.neuralnetworks; +@VintfStability +parcelable BufferDesc { + int[] dimensions; } diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferRole.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferRole.aidl new file mode 100644 index 0000000000..10a6b75ac7 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferRole.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +parcelable BufferRole { + int modelIndex; + int ioIndex; + float probability; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Capabilities.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Capabilities.aidl new file mode 100644 index 0000000000..30877c0294 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Capabilities.aidl @@ -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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +parcelable Capabilities { + android.hardware.neuralnetworks.PerformanceInfo relaxedFloat32toFloat16PerformanceScalar; + android.hardware.neuralnetworks.PerformanceInfo relaxedFloat32toFloat16PerformanceTensor; + android.hardware.neuralnetworks.OperandPerformance[] operandPerformance; + android.hardware.neuralnetworks.PerformanceInfo ifPerformance; + android.hardware.neuralnetworks.PerformanceInfo whilePerformance; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DataLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DataLocation.aidl new file mode 100644 index 0000000000..db49a38979 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DataLocation.aidl @@ -0,0 +1,41 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +parcelable DataLocation { + int poolIndex; + long offset; + long length; + long padding; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceBuffer.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceBuffer.aidl new file mode 100644 index 0000000000..7cdd6db742 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceBuffer.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +parcelable DeviceBuffer { + android.hardware.neuralnetworks.IBuffer buffer; + int token; +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/Error.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceType.aidl index af7bc3c56b..82fe8ae3e7 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/Error.aidl +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceType.aidl @@ -31,16 +31,11 @@ // with such a backward incompatible change, it has a high risk of breaking // later when a module using the interface is updated, e.g., Mainline modules. -package android.hardware.biometrics.fingerprint; -@Backing(type="byte") @VintfStability -enum Error { - UNKNOWN = 0, - HW_UNAVAILABLE = 1, - UNABLE_TO_PROCESS = 2, - TIMEOUT = 3, - NO_SPACE = 4, - CANCELED = 5, - UNABLE_TO_REMOVE = 6, - VENDOR = 7, - BAD_CALIBRATION = 8, +package android.hardware.neuralnetworks; +@Backing(type="int") @VintfStability +enum DeviceType { + OTHER = 1, + CPU = 2, + GPU = 3, + ACCELERATOR = 4, } diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ErrorStatus.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ErrorStatus.aidl new file mode 100644 index 0000000000..57d5d6e4cd --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ErrorStatus.aidl @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@Backing(type="int") @VintfStability +enum ErrorStatus { + NONE = 0, + DEVICE_UNAVAILABLE = 1, + GENERAL_FAILURE = 2, + OUTPUT_INSUFFICIENT_SIZE = 3, + INVALID_ARGUMENT = 4, + MISSED_DEADLINE_TRANSIENT = 5, + MISSED_DEADLINE_PERSISTENT = 6, + RESOURCE_EXHAUSTED_TRANSIENT = 7, + RESOURCE_EXHAUSTED_PERSISTENT = 8, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionPreference.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionPreference.aidl new file mode 100644 index 0000000000..4352d8f334 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionPreference.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@Backing(type="int") @VintfStability +enum ExecutionPreference { + LOW_POWER = 0, + FAST_SINGLE_ANSWER = 1, + SUSTAINED_SPEED = 2, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionResult.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionResult.aidl new file mode 100644 index 0000000000..44e9922f52 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionResult.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.neuralnetworks; +@VintfStability +parcelable ExecutionResult { + boolean outputSufficientSize; + android.hardware.neuralnetworks.OutputShape[] outputShapes; + android.hardware.neuralnetworks.Timing timing; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Extension.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Extension.aidl new file mode 100644 index 0000000000..c47028d99f --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Extension.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +parcelable Extension { + String name; + android.hardware.neuralnetworks.ExtensionOperandTypeInformation[] operandTypes; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl new file mode 100644 index 0000000000..6c287fd460 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +parcelable ExtensionNameAndPrefix { + String name; + char prefix; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl new file mode 100644 index 0000000000..a3680aa9dd --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +parcelable ExtensionOperandTypeInformation { + char type; + boolean isTensor; + int byteSize; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FencedExecutionResult.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FencedExecutionResult.aidl new file mode 100644 index 0000000000..7952b34632 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FencedExecutionResult.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.neuralnetworks; +@VintfStability +parcelable FencedExecutionResult { + android.hardware.neuralnetworks.IFencedExecutionCallback callback; + @nullable ParcelFileDescriptor syncFence; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FusedActivationFunc.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FusedActivationFunc.aidl new file mode 100644 index 0000000000..7e61bbbdb1 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FusedActivationFunc.aidl @@ -0,0 +1,41 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@Backing(type="int") @VintfStability +enum FusedActivationFunc { + NONE = 0, + RELU = 1, + RELU1 = 2, + RELU6 = 3, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBuffer.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBuffer.aidl new file mode 100644 index 0000000000..f10e7e24ca --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBuffer.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +interface IBuffer { + void copyFrom(in android.hardware.neuralnetworks.Memory src, in int[] dimensions); + void copyTo(in android.hardware.neuralnetworks.Memory dst); +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBurst.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBurst.aidl new file mode 100644 index 0000000000..eb3d0b004a --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBurst.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.neuralnetworks; +@VintfStability +interface IBurst { + android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in long[] memoryIdentifierTokens, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs); + void releaseMemoryResource(in long memoryIdentifierToken); +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/ISession.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IDevice.aidl index 9934a763e7..c9c67f2fcd 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IDevice.aidl @@ -31,21 +31,22 @@ // with such a backward incompatible change, it has a high risk of breaking // later when a module using the interface is updated, e.g., Mainline modules. -package android.hardware.biometrics.fingerprint; +package android.hardware.neuralnetworks; @VintfStability -interface ISession { - void generateChallenge(); - void revokeChallenge(in long challenge); - android.hardware.biometrics.common.ICancellationSignal enroll(in android.hardware.keymaster.HardwareAuthToken hat); - android.hardware.biometrics.common.ICancellationSignal authenticate(in long operationId); - android.hardware.biometrics.common.ICancellationSignal detectInteraction(); - void enumerateEnrollments(); - void removeEnrollments(in int[] enrollmentIds); - void getAuthenticatorId(); - void invalidateAuthenticatorId(); - void resetLockout(in android.hardware.keymaster.HardwareAuthToken hat); - void close(); - void onPointerDown(in int pointerId, in int x, in int y, in float minor, in float major); - void onPointerUp(in int pointerId); - void onUiReady(); +interface IDevice { + android.hardware.neuralnetworks.DeviceBuffer allocate(in android.hardware.neuralnetworks.BufferDesc desc, in android.hardware.neuralnetworks.IPreparedModelParcel[] preparedModels, in android.hardware.neuralnetworks.BufferRole[] inputRoles, in android.hardware.neuralnetworks.BufferRole[] outputRoles); + android.hardware.neuralnetworks.Capabilities getCapabilities(); + android.hardware.neuralnetworks.NumberOfCacheFiles getNumberOfCacheFilesNeeded(); + android.hardware.neuralnetworks.Extension[] getSupportedExtensions(); + boolean[] getSupportedOperations(in android.hardware.neuralnetworks.Model model); + android.hardware.neuralnetworks.DeviceType getType(); + String getVersionString(); + void prepareModel(in android.hardware.neuralnetworks.Model model, in android.hardware.neuralnetworks.ExecutionPreference preference, in android.hardware.neuralnetworks.Priority priority, in long deadlineNs, in ParcelFileDescriptor[] modelCache, in ParcelFileDescriptor[] dataCache, in byte[] token, in android.hardware.neuralnetworks.IPreparedModelCallback callback); + void prepareModelFromCache(in long deadlineNs, in ParcelFileDescriptor[] modelCache, in ParcelFileDescriptor[] dataCache, in byte[] token, in android.hardware.neuralnetworks.IPreparedModelCallback callback); + const int BYTE_SIZE_OF_CACHE_TOKEN = 32; + const int MAX_NUMBER_OF_CACHE_FILES = 32; + const int EXTENSION_TYPE_HIGH_BITS_PREFIX = 15; + const int EXTENSION_TYPE_LOW_BITS_TYPE = 16; + const int OPERAND_TYPE_BASE_MAX = 65535; + const int OPERATION_TYPE_BASE_MAX = 65535; } diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl index 5d3df6fbaa..0bfb80ac78 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/IFingerprint.aidl +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl @@ -31,9 +31,8 @@ // with such a backward incompatible change, it has a high risk of breaking // later when a module using the interface is updated, e.g., Mainline modules. -package android.hardware.biometrics.fingerprint; +package android.hardware.neuralnetworks; @VintfStability -interface IFingerprint { - android.hardware.biometrics.fingerprint.SensorProps[] getSensorProps(); - android.hardware.biometrics.fingerprint.ISession createSession(in int sensorId, in int userId, in android.hardware.biometrics.fingerprint.ISessionCallback cb); +interface IFencedExecutionCallback { + android.hardware.neuralnetworks.ErrorStatus getExecutionInfo(out android.hardware.neuralnetworks.Timing timingLaunched, out android.hardware.neuralnetworks.Timing timingFenced); } diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModel.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModel.aidl new file mode 100644 index 0000000000..fccb5dc98e --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModel.aidl @@ -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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +interface IPreparedModel { + android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs); + android.hardware.neuralnetworks.FencedExecutionResult executeFenced(in android.hardware.neuralnetworks.Request request, in ParcelFileDescriptor[] waitFor, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs, in long durationNs); + android.hardware.neuralnetworks.IBurst configureExecutionBurst(); + const long DEFAULT_LOOP_TIMEOUT_DURATION_NS = 2000000000; + const long MAXIMUM_LOOP_TIMEOUT_DURATION_NS = 15000000000; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelCallback.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelCallback.aidl new file mode 100644 index 0000000000..e0c763bc2a --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelCallback.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +interface IPreparedModelCallback { + void notify(in android.hardware.neuralnetworks.ErrorStatus status, in android.hardware.neuralnetworks.IPreparedModel preparedModel); +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelParcel.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelParcel.aidl new file mode 100644 index 0000000000..dbedf12772 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelParcel.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +parcelable IPreparedModelParcel { + android.hardware.neuralnetworks.IPreparedModel preparedModel; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Memory.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Memory.aidl new file mode 100644 index 0000000000..37fa102cf4 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Memory.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +union Memory { + android.hardware.common.Ashmem ashmem; + android.hardware.common.MappableFile mappableFile; + android.hardware.graphics.common.HardwareBuffer hardwareBuffer; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Model.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Model.aidl new file mode 100644 index 0000000000..30d8dda55d --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Model.aidl @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +parcelable Model { + android.hardware.neuralnetworks.Subgraph main; + android.hardware.neuralnetworks.Subgraph[] referenced; + byte[] operandValues; + android.hardware.neuralnetworks.Memory[] pools; + boolean relaxComputationFloat32toFloat16; + android.hardware.neuralnetworks.ExtensionNameAndPrefix[] extensionNameToPrefix; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl new file mode 100644 index 0000000000..9314760a43 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +parcelable NumberOfCacheFiles { + int numModelCache; + int numDataCache; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operand.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operand.aidl new file mode 100644 index 0000000000..1d9bdd8446 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operand.aidl @@ -0,0 +1,44 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +parcelable Operand { + android.hardware.neuralnetworks.OperandType type = android.hardware.neuralnetworks.OperandType.FLOAT32; + int[] dimensions; + float scale; + int zeroPoint; + android.hardware.neuralnetworks.OperandLifeTime lifetime = android.hardware.neuralnetworks.OperandLifeTime.TEMPORARY_VARIABLE; + android.hardware.neuralnetworks.DataLocation location; + @nullable android.hardware.neuralnetworks.OperandExtraParams extraParams; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandExtraParams.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandExtraParams.aidl new file mode 100644 index 0000000000..14792cff08 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandExtraParams.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +union OperandExtraParams { + android.hardware.neuralnetworks.SymmPerChannelQuantParams channelQuant; + byte[] extension; +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandLifeTime.aidl index c51aa033d4..40adfb1dd8 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandLifeTime.aidl @@ -31,20 +31,14 @@ // with such a backward incompatible change, it has a high risk of breaking // later when a module using the interface is updated, e.g., Mainline modules. -package android.hardware.biometrics.fingerprint; -@Backing(type="byte") @VintfStability -enum AcquiredInfo { - UNKNOWN = 0, - GOOD = 1, - PARTIAL = 2, - INSUFFICIENT = 3, - SENSOR_DIRTY = 4, - TOO_SLOW = 5, - TOO_FAST = 6, - VENDOR = 7, - START = 8, - TOO_DARK = 9, - TOO_BRIGHT = 10, - IMMOBILE = 11, - RETRYING_CAPTURE = 12, +package android.hardware.neuralnetworks; +@Backing(type="int") @VintfStability +enum OperandLifeTime { + TEMPORARY_VARIABLE = 0, + SUBGRAPH_INPUT = 1, + SUBGRAPH_OUTPUT = 2, + CONSTANT_COPY = 3, + CONSTANT_POOL = 4, + NO_VALUE = 5, + SUBGRAPH = 6, } diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandPerformance.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandPerformance.aidl new file mode 100644 index 0000000000..ebb361b762 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandPerformance.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +parcelable OperandPerformance { + android.hardware.neuralnetworks.OperandType type = android.hardware.neuralnetworks.OperandType.FLOAT32; + android.hardware.neuralnetworks.PerformanceInfo info; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandType.aidl new file mode 100644 index 0000000000..9f2c759d38 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandType.aidl @@ -0,0 +1,53 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@Backing(type="int") @VintfStability +enum OperandType { + FLOAT32 = 0, + INT32 = 1, + UINT32 = 2, + TENSOR_FLOAT32 = 3, + TENSOR_INT32 = 4, + TENSOR_QUANT8_ASYMM = 5, + BOOL = 6, + TENSOR_QUANT16_SYMM = 7, + TENSOR_FLOAT16 = 8, + TENSOR_BOOL8 = 9, + FLOAT16 = 10, + TENSOR_QUANT8_SYMM_PER_CHANNEL = 11, + TENSOR_QUANT16_ASYMM = 12, + TENSOR_QUANT8_SYMM = 13, + TENSOR_QUANT8_ASYMM_SIGNED = 14, + SUBGRAPH = 15, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operation.aidl new file mode 100644 index 0000000000..a4a3fbee60 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operation.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +parcelable Operation { + android.hardware.neuralnetworks.OperationType type = android.hardware.neuralnetworks.OperationType.ADD; + int[] inputs; + int[] outputs; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperationType.aidl new file mode 100644 index 0000000000..34506c8860 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperationType.aidl @@ -0,0 +1,143 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@Backing(type="int") @VintfStability +enum OperationType { + ADD = 0, + AVERAGE_POOL_2D = 1, + CONCATENATION = 2, + CONV_2D = 3, + DEPTHWISE_CONV_2D = 4, + DEPTH_TO_SPACE = 5, + DEQUANTIZE = 6, + EMBEDDING_LOOKUP = 7, + FLOOR = 8, + FULLY_CONNECTED = 9, + HASHTABLE_LOOKUP = 10, + L2_NORMALIZATION = 11, + L2_POOL_2D = 12, + LOCAL_RESPONSE_NORMALIZATION = 13, + LOGISTIC = 14, + LSH_PROJECTION = 15, + LSTM = 16, + MAX_POOL_2D = 17, + MUL = 18, + RELU = 19, + RELU1 = 20, + RELU6 = 21, + RESHAPE = 22, + RESIZE_BILINEAR = 23, + RNN = 24, + SOFTMAX = 25, + SPACE_TO_DEPTH = 26, + SVDF = 27, + TANH = 28, + BATCH_TO_SPACE_ND = 29, + DIV = 30, + MEAN = 31, + PAD = 32, + SPACE_TO_BATCH_ND = 33, + SQUEEZE = 34, + STRIDED_SLICE = 35, + SUB = 36, + TRANSPOSE = 37, + ABS = 38, + ARGMAX = 39, + ARGMIN = 40, + AXIS_ALIGNED_BBOX_TRANSFORM = 41, + BIDIRECTIONAL_SEQUENCE_LSTM = 42, + BIDIRECTIONAL_SEQUENCE_RNN = 43, + BOX_WITH_NMS_LIMIT = 44, + CAST = 45, + CHANNEL_SHUFFLE = 46, + DETECTION_POSTPROCESSING = 47, + EQUAL = 48, + EXP = 49, + EXPAND_DIMS = 50, + GATHER = 51, + GENERATE_PROPOSALS = 52, + GREATER = 53, + GREATER_EQUAL = 54, + GROUPED_CONV_2D = 55, + HEATMAP_MAX_KEYPOINT = 56, + INSTANCE_NORMALIZATION = 57, + LESS = 58, + LESS_EQUAL = 59, + LOG = 60, + LOGICAL_AND = 61, + LOGICAL_NOT = 62, + LOGICAL_OR = 63, + LOG_SOFTMAX = 64, + MAXIMUM = 65, + MINIMUM = 66, + NEG = 67, + NOT_EQUAL = 68, + PAD_V2 = 69, + POW = 70, + PRELU = 71, + QUANTIZE = 72, + QUANTIZED_16BIT_LSTM = 73, + RANDOM_MULTINOMIAL = 74, + REDUCE_ALL = 75, + REDUCE_ANY = 76, + REDUCE_MAX = 77, + REDUCE_MIN = 78, + REDUCE_PROD = 79, + REDUCE_SUM = 80, + ROI_ALIGN = 81, + ROI_POOLING = 82, + RSQRT = 83, + SELECT = 84, + SIN = 85, + SLICE = 86, + SPLIT = 87, + SQRT = 88, + TILE = 89, + TOPK_V2 = 90, + TRANSPOSE_CONV_2D = 91, + UNIDIRECTIONAL_SEQUENCE_LSTM = 92, + UNIDIRECTIONAL_SEQUENCE_RNN = 93, + RESIZE_NEAREST_NEIGHBOR = 94, + QUANTIZED_LSTM = 95, + IF = 96, + WHILE = 97, + ELU = 98, + HARD_SWISH = 99, + FILL = 100, + RANK = 101, + BATCH_MATMUL = 102, + PACK = 103, + MIRROR_PAD = 104, + REVERSE = 105, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OutputShape.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OutputShape.aidl new file mode 100644 index 0000000000..f7335054cf --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OutputShape.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +parcelable OutputShape { + int[] dimensions; + boolean isSufficient; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/PerformanceInfo.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/PerformanceInfo.aidl new file mode 100644 index 0000000000..04910f5410 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/PerformanceInfo.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +parcelable PerformanceInfo { + float execTime; + float powerUsage; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Priority.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Priority.aidl new file mode 100644 index 0000000000..8f357097ab --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Priority.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@Backing(type="int") @VintfStability +enum Priority { + LOW = 0, + MEDIUM = 1, + HIGH = 2, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Request.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Request.aidl new file mode 100644 index 0000000000..39ec7a9acd --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Request.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +parcelable Request { + android.hardware.neuralnetworks.RequestArgument[] inputs; + android.hardware.neuralnetworks.RequestArgument[] outputs; + android.hardware.neuralnetworks.RequestMemoryPool[] pools; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestArgument.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestArgument.aidl new file mode 100644 index 0000000000..e3541c0ece --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestArgument.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +parcelable RequestArgument { + boolean hasNoValue; + android.hardware.neuralnetworks.DataLocation location; + int[] dimensions; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestMemoryPool.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestMemoryPool.aidl new file mode 100644 index 0000000000..312f5813bc --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestMemoryPool.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +union RequestMemoryPool { + android.hardware.neuralnetworks.Memory pool; + int token; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Subgraph.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Subgraph.aidl new file mode 100644 index 0000000000..b7d44515f4 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Subgraph.aidl @@ -0,0 +1,41 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +parcelable Subgraph { + android.hardware.neuralnetworks.Operand[] operands; + android.hardware.neuralnetworks.Operation[] operations; + int[] inputIndexes; + int[] outputIndexes; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl new file mode 100644 index 0000000000..02d68f9ed1 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +parcelable SymmPerChannelQuantParams { + float[] scales; + int channelDim; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Timing.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Timing.aidl new file mode 100644 index 0000000000..bcc83cfbee --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Timing.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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.neuralnetworks; +@VintfStability +parcelable Timing { + long timeOnDeviceNs; + long timeInDriverNs; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IExecution.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IExecution.aidl new file mode 100644 index 0000000000..ab5275e582 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IExecution.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.neuralnetworks; +@VintfStability +interface IExecution { + android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in long deadlineNs); + android.hardware.neuralnetworks.FencedExecutionResult executeFenced(in ParcelFileDescriptor[] waitFor, in long deadlineNs, in long durationNs); +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl index fccb5dc98e..f89956719e 100644 --- a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl @@ -37,6 +37,7 @@ interface IPreparedModel { android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs); android.hardware.neuralnetworks.FencedExecutionResult executeFenced(in android.hardware.neuralnetworks.Request request, in ParcelFileDescriptor[] waitFor, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs, in long durationNs); android.hardware.neuralnetworks.IBurst configureExecutionBurst(); + android.hardware.neuralnetworks.IExecution createReusableExecution(in android.hardware.neuralnetworks.Request request, in boolean measureTiming, in long loopTimeoutDurationNs); const long DEFAULT_LOOP_TIMEOUT_DURATION_NS = 2000000000; const long MAXIMUM_LOOP_TIMEOUT_DURATION_NS = 15000000000; } diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl index decdc481f1..b089c499c6 100644 --- a/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl @@ -78,10 +78,10 @@ interface IBurst { * runs from the time the driver sees the call to the executeSynchronously * function to the time the driver returns from the function. * @param deadlineNs The time by which the execution is expected to complete. The time is - * measured in nanoseconds since epoch of the steady clock (as from - * std::chrono::steady_clock). If the execution cannot be finished by the - * deadline, the execution may be aborted. Passing -1 means the deadline is - * omitted. Other negative values are invalid. + * measured in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME, + * &ts) or ::android::base::boot_clock). If the execution cannot be finished + * by the deadline, the execution may be aborted. Passing -1 means the + * deadline is omitted. Other negative values are invalid. * @param loopTimeoutDurationNs The maximum amount of time in nanoseconds that should be spent * executing a {@link OperationType::WHILE} operation. If a loop * condition model does not output false within this duration, the diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/IExecution.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/IExecution.aidl new file mode 100644 index 0000000000..3cb9c1a592 --- /dev/null +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/IExecution.aidl @@ -0,0 +1,153 @@ +/* + * 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.neuralnetworks; + +import android.hardware.neuralnetworks.ExecutionResult; +import android.hardware.neuralnetworks.FencedExecutionResult; + +/** + * IExecution represents a reusable execution object with request and most other execution + * properties fixed. It is used to launch executions. + * + * At most one execution may occur on a reusable execution object at any given time, either by + * means of executeSynchronously or executeFenced. + * + * An IExecution object is used to control a set of executions on the same prepared model with + * the same request and properties. IExecution objects enable some optimizations: + * (1) An IExecution object can preserve resources between executions. For example, a driver can + * map a memory object when the IExecution object is created and cache the mapping for reuse in + * subsequent executions. Any cached resource can be released when the IExecution object is + * destroyed. + * (2) Because an IExecution object may be used for at most one execution at a time, any transient + * execution resources such as intermediate tensors can be allocated once when the IExecution + * object is created and freed when the IExecution object is destroyed. + * (3) An IExecution object is created for a fixed request. This enables the implementation to apply + * request-specific optimizations. For example, an implementation can avoid request validation + * and conversions when the IExecution object is reused. An implementation may also choose to + * specialize the dynamic tensor shapes in the IExecution object according to the request. + */ +@VintfStability +interface IExecution { + /** + * Performs a synchronous execution on the reusable execution object. + * + * The execution is performed synchronously with respect to the caller. executeSynchronously + * must verify the inputs to the function are correct, and the usages of memory pools allocated + * by IDevice::allocate are valid. If there is an error, executeSynchronously must immediately + * return a service specific exception with the appropriate ErrorStatus value. If the inputs to + * the function are valid and there is no error, executeSynchronously must perform the + * execution, and must not return until the execution is complete. + * + * The caller must not change the content of any data object referenced by the 'request' + * provided in {@link IPreparedModel::createReusableExecution} (described by the + * {@link DataLocation} of a {@link RequestArgument}) until executeSynchronously returns. + * executeSynchronously must not change the content of any of the data objects corresponding to + * 'request' inputs. + * + * If the execution object was configured from a prepared model wherein all tensor operands have + * fully specified dimensions, and the inputs to the function are valid, and at execution time + * every operation's input operands have legal values, then the execution should complete + * successfully: there must be no failure unless the device itself is in a bad state. + * + * If the execution object was created with measureTiming being true and the execution is + * successful, the driver may report the timing information in the returning + * {@link ExecutionResult}. The duration runs from the time the driver sees the call to the time + * the driver returns from the function. + * + * executeSynchronously may be called with an optional deadline. If the execution is not able to + * be completed before the provided deadline, the execution may be aborted, and either + * {@link ErrorStatus::MISSED_DEADLINE_TRANSIENT} or {@link + * ErrorStatus::MISSED_DEADLINE_PERSISTENT} may be returned. The error due to an abort must be + * sent the same way as other errors, described above. + * + * @param deadlineNs The time by which the execution is expected to complete. The time is + * measured in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME, + * &ts) or ::android::base::boot_clock). If the execution cannot be finished + * by the deadline, the execution may be aborted. Passing -1 means the + * deadline is omitted. Other negative values are invalid. + * @return ExecutionResult parcelable, containing the status of the execution, output shapes + * and timing information. + * @throws ServiceSpecificException with one of the following ErrorStatus values: + * - DEVICE_UNAVAILABLE if driver is offline or busy + * - GENERAL_FAILURE if there is an unspecified error + * - INVALID_ARGUMENT if one of the input arguments is invalid + * - MISSED_DEADLINE_* if the execution is aborted because it cannot be completed by the + * deadline + * - RESOURCE_EXHAUSTED_* if the task was aborted by the driver + */ + ExecutionResult executeSynchronously(in long deadlineNs); + + /** + * Launch a fenced asynchronous execution on the reusable execution object. + * + * The execution is performed asynchronously with respect to the caller. executeFenced must + * verify the inputs to the function are correct, and the usages of memory pools allocated by + * IDevice::allocate are valid. If there is an error, executeFenced must immediately return a + * service specific exception with the corresponding ErrorStatus. If the inputs to the function + * are valid and there is no error, executeFenced must dispatch an asynchronous task to perform + * the execution in the background, and immediately return a {@link FencedExecutionResult} + * containing two fields: a callback (which can be used by the client to query the duration and + * runtime error status) and a sync fence (which will be signaled once the execution is + * completed). If the task has finished before the call returns, syncFence file descriptor may + * be set to -1. The execution must wait for all the sync fences (if any) in waitFor to be + * signaled before starting the actual execution. + * + * When the asynchronous task has finished its execution, it must immediately signal the + * syncFence returned from the executeFenced call. After the syncFence is signaled, the task + * must not modify the content of any data object referenced by the 'request' provided in + * IPreparedModel::createReusableExecution (described by the {@link DataLocation} of a + * {@link RequestArgument}). + * + * executeFenced may be called with an optional deadline and an optional duration. If the + * execution is not able to be completed before the provided deadline or within the timeout + * duration (measured from when all sync fences in waitFor are signaled), whichever comes + * earlier, the execution may be aborted, and either + * {@link ErrorStatus::MISSED_DEADLINE_TRANSIENT} or {@link + * ErrorStatus::MISSED_DEADLINE_PERSISTENT} may be returned. The error due to an abort must be + * sent the same way as other errors, described above. + * + * If any of the sync fences in waitFor changes to error status after the executeFenced call + * succeeds, or the execution is aborted because it cannot finish before the deadline has been + * reached or the duration has elapsed, the driver must immediately set the returned syncFence + * to error status. + * + * @param waitFor A vector of sync fence file descriptors. Execution must not start until all + * sync fences have been signaled. + * @param deadlineNs The time by which the execution is expected to complete. The time is + * measured in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME, + * &ts) or ::android::base::boot_clock). If the execution cannot be finished + * by the deadline, the execution may be aborted. Passing -1 means the + * deadline is omitted. Other negative values are invalid. + * @param durationNs The length of time in nanoseconds within which the execution is expected + * to complete after all sync fences in waitFor are signaled. If the + * execution cannot be finished within the duration, the execution may be + * aborted. Passing -1 means the duration is omitted. Other negative values + * are invalid. + * @return The FencedExecutionResult parcelable, containing IFencedExecutionCallback and the + * sync fence. + * @throws ServiceSpecificException with one of the following ErrorStatus values: + * - DEVICE_UNAVAILABLE if driver is offline or busy + * - GENERAL_FAILURE if there is an unspecified error + * - INVALID_ARGUMENT if one of the input arguments is invalid, including fences in error + * states. + * - MISSED_DEADLINE_* if the execution is aborted because it cannot be completed by the + * deadline + * - RESOURCE_EXHAUSTED_* if the task was aborted by the driver + */ + FencedExecutionResult executeFenced( + in ParcelFileDescriptor[] waitFor, in long deadlineNs, in long durationNs); +} diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl index 956b626dd9..79053e527f 100644 --- a/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl @@ -21,6 +21,7 @@ import android.hardware.neuralnetworks.ErrorStatus; import android.hardware.neuralnetworks.ExecutionResult; import android.hardware.neuralnetworks.FencedExecutionResult; import android.hardware.neuralnetworks.IBurst; +import android.hardware.neuralnetworks.IExecution; import android.hardware.neuralnetworks.Request; /** @@ -105,11 +106,12 @@ interface IPreparedModel { * IDevice::allocate are valid. If there is an error, executeFenced must immediately return a * service specific exception with the corresponding ErrorStatus. If the inputs to the function * are valid and there is no error, executeFenced must dispatch an asynchronous task to perform - * the execution in the background, assign a sync fence that will be signaled once the execution - * is completed and immediately return a callback that can be used by the client to query the - * duration and runtime error status. If the task has finished before the call returns, - * syncFence file descriptor may be set to -1. The execution must wait for all the sync fences - * (if any) in waitFor to be signaled before starting the actual execution. + * the execution in the background, and immediately return a {@link FencedExecutionResult} + * containing two fields: a callback (which can be used by the client to query the duration and + * runtime error status) and a sync fence (which will be signaled once the execution is + * completed). If the task has finished before the call returns, syncFence file descriptor may + * be set to -1. The execution must wait for all the sync fences (if any) in waitFor to be + * signaled before starting the actual execution. * * When the asynchronous task has finished its execution, it must immediately signal the * syncFence returned from the executeFenced call. After the syncFence is signaled, the task @@ -186,4 +188,36 @@ interface IPreparedModel { * - RESOURCE_EXHAUSTED_* if the task was aborted by the driver */ IBurst configureExecutionBurst(); + + /** + * Create a reusable execution object to launch multiple executions with the same request and + * properties. + * + * createReusableExecution must verify the inputs to the function are correct, and the usages of + * memory pools allocated by IDevice::allocate are valid. If there is an error, + * createReusableExecution must immediately return a service specific exception with the + * appropriate ErrorStatus value. If the inputs to the function are valid and there is no error, + * createReusableExecution must construct a reusable execution. + * + * @param request The input and output information on which the prepared model is to be + * executed. + * @param measure Specifies whether or not to measure duration of the execution. + * @param loopTimeoutDurationNs The maximum amount of time in nanoseconds that should be spent + * executing a {@link OperationType::WHILE} operation. If a loop + * condition model does not output false within this duration, the + * computation performed on the returned reusable execution object + * must be aborted. If -1 is provided, the maximum amount + * of time is {@link DEFAULT_LOOP_TIMEOUT_DURATION_NS}. Other + * negative values are invalid. When provided, the duration must + * not exceed {@link MAXIMUM_LOOP_TIMEOUT_DURATION_NS}. + * @return execution An IExecution object representing a reusable execution that has been + * specialized for a fixed request. + * @throws ServiceSpecificException with one of the following ErrorStatus values: + * - DEVICE_UNAVAILABLE if driver is offline or busy + * - GENERAL_FAILURE if there is an unspecified error + * - INVALID_ARGUMENT if one of the input arguments is invalid + * - RESOURCE_EXHAUSTED_* if the task was aborted by the driver + */ + IExecution createReusableExecution( + in Request request, in boolean measureTiming, in long loopTimeoutDurationNs); } diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl index 0ad254dc4e..5f7810b778 100644 --- a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl @@ -5331,6 +5331,18 @@ enum OperationType { /** * Pads a tensor with mirrored values. * + * This operator specifies one of two padding modes: REFLECT or SYMMETRIC. + * In the case of REFLECT mode, the mirroring excludes the border element + * on the padding side. + * In the case of SYMMETRIC mode, the mirroring includes the border element + * on the padding side. + * + * For example, if the input is the 1-D tensor `[1, 2, 3]` and the padding + * is `[0, 2]` (i.e., pad no elements before the first (and only) dimension, + * and two elements after the first (and only) dimension), then: + * - REFLECT mode produces the output `[1, 2, 3, 2, 1]` + * - SYMMETRIC mode produces the output `[1, 2, 3, 3, 2]` + * * Supported tensor {@link OperandType}: * * {@link OperandType::TENSOR_FLOAT16} * * {@link OperandType::TENSOR_FLOAT32} @@ -5349,6 +5361,11 @@ enum OperationType { * front of dimension i. * padding[i, 1] specifies the number of elements to be padded after the * end of dimension i. + * Each padding value must be nonnegative. + * In the case of REFLECT mode, each padding value must be less than the + * corresponding dimension. + * In the case of SYMMETRIC mode, each padding value must be less than or + * equal to the corresponding dimension. * * 2: An {@link OperandType::INT32} scalar, specifying the mode. * Options are 0:REFLECT and 1:SYMMETRIC. * diff --git a/neuralnetworks/aidl/utils/Android.bp b/neuralnetworks/aidl/utils/Android.bp index e3561042be..3faa613514 100644 --- a/neuralnetworks/aidl/utils/Android.bp +++ b/neuralnetworks/aidl/utils/Android.bp @@ -26,7 +26,14 @@ package { cc_defaults { name: "neuralnetworks_utils_hal_aidl_defaults", defaults: ["neuralnetworks_utils_defaults"], - srcs: ["src/*"], + srcs: [ + // AIDL utils that a driver may depend on. + "src/BufferTracker.cpp", + "src/Conversions.cpp", + "src/HalUtils.cpp", + "src/Utils.cpp", + "src/ValidateHal.cpp", + ], local_include_dirs: ["include/nnapi/hal/aidl/"], export_include_dirs: ["include"], cflags: ["-Wthread-safety"], @@ -47,6 +54,7 @@ cc_defaults { }, } +// Deprecated. Remove once all modules depending on this are migrated away. cc_library_static { name: "neuralnetworks_utils_hal_aidl_v1", defaults: ["neuralnetworks_utils_hal_aidl_defaults"], @@ -56,19 +64,25 @@ cc_library_static { } cc_library_static { - name: "neuralnetworks_utils_hal_aidl_v2", - defaults: ["neuralnetworks_utils_hal_aidl_defaults"], - shared_libs: [ - "android.hardware.neuralnetworks-V2-ndk", - ], -} - -cc_library_static { name: "neuralnetworks_utils_hal_aidl", defaults: ["neuralnetworks_utils_hal_aidl_defaults"], + srcs: [ + // Additional AIDL utils for the runtime. + "src/Assertions.cpp", + "src/Buffer.cpp", + "src/Burst.cpp", + "src/Callbacks.cpp", + "src/Device.cpp", + "src/Execution.cpp", + "src/InvalidDevice.cpp", + "src/PreparedModel.cpp", + "src/ProtectCallback.cpp", + "src/Service.cpp", + ], shared_libs: [ - "android.hardware.neuralnetworks-V3-ndk", + "android.hardware.neuralnetworks-V4-ndk", ], + cflags: ["-DNN_AIDL_V4_OR_ABOVE"], } // A cc_defaults that includes the latest non-experimental AIDL utilities and other AIDL libraries @@ -79,9 +93,10 @@ cc_defaults { static_libs: [ "android.hardware.common-V2-ndk", "android.hardware.graphics.common-V3-ndk", - "android.hardware.neuralnetworks-V3-ndk", + "android.hardware.neuralnetworks-V4-ndk", "neuralnetworks_utils_hal_aidl", ], + cflags: ["-DNN_AIDL_V4_OR_ABOVE"], } cc_test { diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Callbacks.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Callbacks.h index 168264babf..960be2bb54 100644 --- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Callbacks.h +++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Callbacks.h @@ -36,6 +36,8 @@ class PreparedModelCallback final : public BnPreparedModelCallback, public IProt public: using Data = nn::GeneralResult<nn::SharedPreparedModel>; + PreparedModelCallback(nn::Version featureLevel) : kFeatureLevel(featureLevel) {} + ndk::ScopedAStatus notify(ErrorStatus status, const std::shared_ptr<IPreparedModel>& preparedModel) override; @@ -44,6 +46,7 @@ class PreparedModelCallback final : public BnPreparedModelCallback, public IProt Data get(); private: + const nn::Version kFeatureLevel; hal::utils::TransferValue<Data> mData; }; diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Conversions.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Conversions.h index 78433a74e9..477b311598 100644 --- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Conversions.h +++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Conversions.h @@ -112,11 +112,15 @@ GeneralResult<Priority> convert(const aidl_hal::Priority& priority); GeneralResult<Request> convert(const aidl_hal::Request& request); GeneralResult<Timing> convert(const aidl_hal::Timing& timing); GeneralResult<SharedHandle> convert(const ndk::ScopedFileDescriptor& handle); +GeneralResult<BufferDesc> convert(const aidl_hal::BufferDesc& bufferDesc); GeneralResult<std::vector<Extension>> convert(const std::vector<aidl_hal::Extension>& extension); GeneralResult<std::vector<SharedMemory>> convert(const std::vector<aidl_hal::Memory>& memories); GeneralResult<std::vector<OutputShape>> convert( const std::vector<aidl_hal::OutputShape>& outputShapes); +GeneralResult<std::vector<SharedHandle>> convert( + const std::vector<ndk::ScopedFileDescriptor>& handles); +GeneralResult<std::vector<BufferRole>> convert(const std::vector<aidl_hal::BufferRole>& roles); GeneralResult<std::vector<uint32_t>> toUnsigned(const std::vector<int32_t>& vec); @@ -129,6 +133,7 @@ namespace nn = ::android::nn; nn::GeneralResult<std::vector<uint8_t>> unvalidatedConvert(const nn::CacheToken& cacheToken); nn::GeneralResult<BufferDesc> unvalidatedConvert(const nn::BufferDesc& bufferDesc); nn::GeneralResult<BufferRole> unvalidatedConvert(const nn::BufferRole& bufferRole); +nn::GeneralResult<DeviceType> unvalidatedConvert(const nn::DeviceType& deviceType); nn::GeneralResult<bool> unvalidatedConvert(const nn::MeasureTiming& measureTiming); nn::GeneralResult<Memory> unvalidatedConvert(const nn::SharedMemory& memory); nn::GeneralResult<OutputShape> unvalidatedConvert(const nn::OutputShape& outputShape); @@ -154,14 +159,16 @@ nn::GeneralResult<Request> unvalidatedConvert(const nn::Request& request); nn::GeneralResult<RequestArgument> unvalidatedConvert(const nn::Request::Argument& requestArgument); nn::GeneralResult<RequestMemoryPool> unvalidatedConvert(const nn::Request::MemoryPool& memoryPool); nn::GeneralResult<Timing> unvalidatedConvert(const nn::Timing& timing); -nn::GeneralResult<int64_t> unvalidatedConvert(const nn::Duration& duration); nn::GeneralResult<int64_t> unvalidatedConvert(const nn::OptionalDuration& optionalDuration); nn::GeneralResult<int64_t> unvalidatedConvert(const nn::OptionalTimePoint& optionalTimePoint); nn::GeneralResult<ndk::ScopedFileDescriptor> unvalidatedConvert(const nn::SyncFence& syncFence); nn::GeneralResult<ndk::ScopedFileDescriptor> unvalidatedConvert(const nn::SharedHandle& handle); +nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities); +nn::GeneralResult<Extension> unvalidatedConvert(const nn::Extension& extension); nn::GeneralResult<std::vector<uint8_t>> convert(const nn::CacheToken& cacheToken); nn::GeneralResult<BufferDesc> convert(const nn::BufferDesc& bufferDesc); +nn::GeneralResult<DeviceType> convert(const nn::DeviceType& deviceType); nn::GeneralResult<bool> convert(const nn::MeasureTiming& measureTiming); nn::GeneralResult<Memory> convert(const nn::SharedMemory& memory); nn::GeneralResult<ErrorStatus> convert(const nn::ErrorStatus& errorStatus); @@ -172,6 +179,8 @@ nn::GeneralResult<Request> convert(const nn::Request& request); nn::GeneralResult<Timing> convert(const nn::Timing& timing); nn::GeneralResult<int64_t> convert(const nn::OptionalDuration& optionalDuration); nn::GeneralResult<int64_t> convert(const nn::OptionalTimePoint& optionalTimePoint); +nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities); +nn::GeneralResult<Extension> convert(const nn::Extension& extension); nn::GeneralResult<std::vector<BufferRole>> convert(const std::vector<nn::BufferRole>& bufferRoles); nn::GeneralResult<std::vector<OutputShape>> convert( @@ -180,6 +189,7 @@ nn::GeneralResult<std::vector<ndk::ScopedFileDescriptor>> convert( const std::vector<nn::SharedHandle>& handles); nn::GeneralResult<std::vector<ndk::ScopedFileDescriptor>> convert( const std::vector<nn::SyncFence>& syncFences); +nn::GeneralResult<std::vector<Extension>> convert(const std::vector<nn::Extension>& extensions); nn::GeneralResult<std::vector<int32_t>> toSigned(const std::vector<uint32_t>& vec); diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Execution.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Execution.h index a77ea984b2..14802b98cc 100644 --- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Execution.h +++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Execution.h @@ -17,6 +17,8 @@ #ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_EXECUTION_H #define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_EXECUTION_H +#include <aidl/android/hardware/neuralnetworks/IExecution.h> + #include <nnapi/IExecution.h> #include <nnapi/Result.h> #include <nnapi/Types.h> @@ -33,17 +35,22 @@ namespace aidl::android::hardware::neuralnetworks::utils { -class Execution final : public nn::IExecution, public std::enable_shared_from_this<Execution> { +// A reusable execution implementation with a cached Request, internally it is still passing the +// request to the driver in every computation. +class ExecutionWithCachedRequest final + : public nn::IExecution, + public std::enable_shared_from_this<ExecutionWithCachedRequest> { struct PrivateConstructorTag {}; public: - static nn::GeneralResult<std::shared_ptr<const Execution>> create( + static nn::GeneralResult<std::shared_ptr<const ExecutionWithCachedRequest>> create( std::shared_ptr<const PreparedModel> preparedModel, Request request, hal::utils::RequestRelocation relocation, bool measure, int64_t loopTimeoutDuration); - Execution(PrivateConstructorTag tag, std::shared_ptr<const PreparedModel> preparedModel, - Request request, hal::utils::RequestRelocation relocation, bool measure, - int64_t loopTimeoutDuration); + ExecutionWithCachedRequest(PrivateConstructorTag tag, + std::shared_ptr<const PreparedModel> preparedModel, Request request, + hal::utils::RequestRelocation relocation, bool measure, + int64_t loopTimeoutDuration); nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> compute( const nn::OptionalTimePoint& deadline) const override; @@ -60,6 +67,30 @@ class Execution final : public nn::IExecution, public std::enable_shared_from_th const int64_t kLoopTimeoutDuration; }; +// A reusable execution implementation that is backed by an actual AIDL IExecution object. +class Execution final : public nn::IExecution, public std::enable_shared_from_this<Execution> { + struct PrivateConstructorTag {}; + + public: + static nn::GeneralResult<std::shared_ptr<const Execution>> create( + std::shared_ptr<aidl_hal::IExecution> execution, + hal::utils::RequestRelocation relocation); + + Execution(PrivateConstructorTag tag, std::shared_ptr<aidl_hal::IExecution> execution, + hal::utils::RequestRelocation relocation); + + nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> compute( + const nn::OptionalTimePoint& deadline) const override; + + nn::GeneralResult<std::pair<nn::SyncFence, nn::ExecuteFencedInfoCallback>> computeFenced( + const std::vector<nn::SyncFence>& waitFor, const nn::OptionalTimePoint& deadline, + const nn::OptionalDuration& timeoutDurationAfterFence) const override; + + private: + const std::shared_ptr<aidl_hal::IExecution> kExecution; + const hal::utils::RequestRelocation kRelocation; +}; + } // namespace aidl::android::hardware::neuralnetworks::utils #endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_EXECUTION_H diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/HalInterfaces.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/HalInterfaces.h index 3fb443c388..205d428cf4 100644 --- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/HalInterfaces.h +++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/HalInterfaces.h @@ -61,6 +61,11 @@ #include <aidl/android/hardware/neuralnetworks/SymmPerChannelQuantParams.h> #include <aidl/android/hardware/neuralnetworks/Timing.h> +#ifdef NN_AIDL_V4_OR_ABOVE +#include <aidl/android/hardware/neuralnetworks/BnExecution.h> +#include <aidl/android/hardware/neuralnetworks/IExecution.h> +#endif // NN_AIDL_V4_OR_ABOVE + namespace android::nn { namespace aidl_hal = ::aidl::android::hardware::neuralnetworks; diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/PreparedModel.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/PreparedModel.h index 4035764ea4..24cd681658 100644 --- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/PreparedModel.h +++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/PreparedModel.h @@ -41,10 +41,11 @@ class PreparedModel final : public nn::IPreparedModel, public: static nn::GeneralResult<std::shared_ptr<const PreparedModel>> create( - std::shared_ptr<aidl_hal::IPreparedModel> preparedModel); + std::shared_ptr<aidl_hal::IPreparedModel> preparedModel, nn::Version featureLevel); PreparedModel(PrivateConstructorTag tag, - std::shared_ptr<aidl_hal::IPreparedModel> preparedModel); + std::shared_ptr<aidl_hal::IPreparedModel> preparedModel, + nn::Version featureLevel); nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> execute( const nn::Request& request, nn::MeasureTiming measure, @@ -78,6 +79,7 @@ class PreparedModel final : public nn::IPreparedModel, private: const std::shared_ptr<aidl_hal::IPreparedModel> kPreparedModel; + const nn::Version kFeatureLevel; }; } // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h index a27487e17c..beca38b1ee 100644 --- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h +++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h @@ -38,6 +38,8 @@ constexpr std::optional<nn::Version> aidlVersionToCanonicalVersion(int aidlVersi return nn::kVersionFeatureLevel6; case 3: return nn::kVersionFeatureLevel7; + case 4: + return nn::kVersionFeatureLevel8; default: return std::nullopt; } diff --git a/neuralnetworks/aidl/utils/src/Callbacks.cpp b/neuralnetworks/aidl/utils/src/Callbacks.cpp index 8084970690..554f3faa73 100644 --- a/neuralnetworks/aidl/utils/src/Callbacks.cpp +++ b/neuralnetworks/aidl/utils/src/Callbacks.cpp @@ -38,16 +38,17 @@ namespace { // nn::kVersionFeatureLevel5. On failure, this function returns with the appropriate // nn::GeneralError. nn::GeneralResult<nn::SharedPreparedModel> prepareModelCallback( - ErrorStatus status, const std::shared_ptr<IPreparedModel>& preparedModel) { + ErrorStatus status, const std::shared_ptr<IPreparedModel>& preparedModel, + nn::Version featureLevel) { HANDLE_STATUS_AIDL(status) << "model preparation failed with " << toString(status); - return NN_TRY(PreparedModel::create(preparedModel)); + return NN_TRY(PreparedModel::create(preparedModel, featureLevel)); } } // namespace ndk::ScopedAStatus PreparedModelCallback::notify( ErrorStatus status, const std::shared_ptr<IPreparedModel>& preparedModel) { - mData.put(prepareModelCallback(status, preparedModel)); + mData.put(prepareModelCallback(status, preparedModel, kFeatureLevel)); return ndk::ScopedAStatus::ok(); } diff --git a/neuralnetworks/aidl/utils/src/Conversions.cpp b/neuralnetworks/aidl/utils/src/Conversions.cpp index 45628c8e73..113d2da955 100644 --- a/neuralnetworks/aidl/utils/src/Conversions.cpp +++ b/neuralnetworks/aidl/utils/src/Conversions.cpp @@ -551,6 +551,10 @@ GeneralResult<SharedHandle> convert(const ndk::ScopedFileDescriptor& handle) { return validatedConvert(handle); } +GeneralResult<BufferDesc> convert(const aidl_hal::BufferDesc& bufferDesc) { + return validatedConvert(bufferDesc); +} + GeneralResult<std::vector<Extension>> convert(const std::vector<aidl_hal::Extension>& extension) { return validatedConvert(extension); } @@ -564,6 +568,15 @@ GeneralResult<std::vector<OutputShape>> convert( return validatedConvert(outputShapes); } +GeneralResult<std::vector<SharedHandle>> convert( + const std::vector<ndk::ScopedFileDescriptor>& handles) { + return validatedConvert(handles); +} + +GeneralResult<std::vector<BufferRole>> convert(const std::vector<aidl_hal::BufferRole>& roles) { + return validatedConvert(roles); +} + GeneralResult<std::vector<uint32_t>> toUnsigned(const std::vector<int32_t>& vec) { if (!std::all_of(vec.begin(), vec.end(), [](int32_t v) { return v >= 0; })) { return NN_ERROR() << "Negative value passed to conversion from signed to unsigned"; @@ -576,42 +589,7 @@ GeneralResult<std::vector<uint32_t>> toUnsigned(const std::vector<int32_t>& vec) namespace aidl::android::hardware::neuralnetworks::utils { namespace { -template <typename Input> -using UnvalidatedConvertOutput = - std::decay_t<decltype(unvalidatedConvert(std::declval<Input>()).value())>; - -template <typename Type> -nn::GeneralResult<std::vector<UnvalidatedConvertOutput<Type>>> unvalidatedConvertVec( - const std::vector<Type>& arguments) { - std::vector<UnvalidatedConvertOutput<Type>> halObject; - halObject.reserve(arguments.size()); - for (const auto& argument : arguments) { - halObject.push_back(NN_TRY(unvalidatedConvert(argument))); - } - return halObject; -} - -template <typename Type> -nn::GeneralResult<std::vector<UnvalidatedConvertOutput<Type>>> unvalidatedConvert( - const std::vector<Type>& arguments) { - return unvalidatedConvertVec(arguments); -} - -template <typename Type> -nn::GeneralResult<UnvalidatedConvertOutput<Type>> validatedConvert(const Type& canonical) { - NN_TRY(compliantVersion(canonical)); - return utils::unvalidatedConvert(canonical); -} - -template <typename Type> -nn::GeneralResult<std::vector<UnvalidatedConvertOutput<Type>>> validatedConvert( - const std::vector<Type>& arguments) { - std::vector<UnvalidatedConvertOutput<Type>> halObject(arguments.size()); - for (size_t i = 0; i < arguments.size(); ++i) { - halObject[i] = NN_TRY(validatedConvert(arguments[i])); - } - return halObject; -} +using utils::unvalidatedConvert; // Helper template for std::visit template <class... Ts> @@ -721,6 +699,74 @@ nn::GeneralResult<Memory> unvalidatedConvert(const nn::Memory::Unknown& /*memory operator nn::GeneralResult<Memory>(); } +nn::GeneralResult<PerformanceInfo> unvalidatedConvert( + const nn::Capabilities::PerformanceInfo& info) { + return PerformanceInfo{.execTime = info.execTime, .powerUsage = info.powerUsage}; +} + +nn::GeneralResult<OperandPerformance> unvalidatedConvert( + const nn::Capabilities::OperandPerformance& operandPerformance) { + return OperandPerformance{.type = NN_TRY(unvalidatedConvert(operandPerformance.type)), + .info = NN_TRY(unvalidatedConvert(operandPerformance.info))}; +} + +nn::GeneralResult<std::vector<OperandPerformance>> unvalidatedConvert( + const nn::Capabilities::OperandPerformanceTable& table) { + std::vector<OperandPerformance> operandPerformances; + operandPerformances.reserve(table.asVector().size()); + for (const auto& operandPerformance : table.asVector()) { + operandPerformances.push_back(NN_TRY(unvalidatedConvert(operandPerformance))); + } + return operandPerformances; +} + +nn::GeneralResult<ExtensionOperandTypeInformation> unvalidatedConvert( + const nn::Extension::OperandTypeInformation& info) { + return ExtensionOperandTypeInformation{.type = info.type, + .isTensor = info.isTensor, + .byteSize = static_cast<int32_t>(info.byteSize)}; +} + +nn::GeneralResult<int64_t> unvalidatedConvert(const nn::Duration& duration) { + if (duration < nn::Duration::zero()) { + return NN_ERROR() << "Unable to convert invalid (negative) duration"; + } + constexpr std::chrono::nanoseconds::rep kIntMax = std::numeric_limits<int64_t>::max(); + const auto count = duration.count(); + return static_cast<int64_t>(std::min(count, kIntMax)); +} + +template <typename Input> +using UnvalidatedConvertOutput = + std::decay_t<decltype(unvalidatedConvert(std::declval<Input>()).value())>; + +template <typename Type> +nn::GeneralResult<std::vector<UnvalidatedConvertOutput<Type>>> unvalidatedConvert( + const std::vector<Type>& arguments) { + std::vector<UnvalidatedConvertOutput<Type>> halObject; + halObject.reserve(arguments.size()); + for (const auto& argument : arguments) { + halObject.push_back(NN_TRY(unvalidatedConvert(argument))); + } + return halObject; +} + +template <typename Type> +nn::GeneralResult<UnvalidatedConvertOutput<Type>> validatedConvert(const Type& canonical) { + NN_TRY(compliantVersion(canonical)); + return utils::unvalidatedConvert(canonical); +} + +template <typename Type> +nn::GeneralResult<std::vector<UnvalidatedConvertOutput<Type>>> validatedConvert( + const std::vector<Type>& arguments) { + std::vector<UnvalidatedConvertOutput<Type>> halObject(arguments.size()); + for (size_t i = 0; i < arguments.size(); ++i) { + halObject[i] = NN_TRY(validatedConvert(arguments[i])); + } + return halObject; +} + } // namespace nn::GeneralResult<std::vector<uint8_t>> unvalidatedConvert(const nn::CacheToken& cacheToken) { @@ -743,6 +789,19 @@ nn::GeneralResult<BufferRole> unvalidatedConvert(const nn::BufferRole& bufferRol }; } +nn::GeneralResult<DeviceType> unvalidatedConvert(const nn::DeviceType& deviceType) { + switch (deviceType) { + case nn::DeviceType::UNKNOWN: + break; + case nn::DeviceType::OTHER: + case nn::DeviceType::CPU: + case nn::DeviceType::GPU: + case nn::DeviceType::ACCELERATOR: + return static_cast<DeviceType>(deviceType); + } + return NN_ERROR() << "Invalid DeviceType " << deviceType; +} + nn::GeneralResult<bool> unvalidatedConvert(const nn::MeasureTiming& measureTiming) { return measureTiming == nn::MeasureTiming::YES; } @@ -956,15 +1015,6 @@ nn::GeneralResult<Timing> unvalidatedConvert(const nn::Timing& timing) { }; } -nn::GeneralResult<int64_t> unvalidatedConvert(const nn::Duration& duration) { - if (duration < nn::Duration::zero()) { - return NN_ERROR() << "Unable to convert invalid (negative) duration"; - } - constexpr std::chrono::nanoseconds::rep kIntMax = std::numeric_limits<int64_t>::max(); - const auto count = duration.count(); - return static_cast<int64_t>(std::min(count, kIntMax)); -} - nn::GeneralResult<int64_t> unvalidatedConvert(const nn::OptionalDuration& optionalDuration) { if (!optionalDuration.has_value()) { return kNoTiming; @@ -989,6 +1039,23 @@ nn::GeneralResult<ndk::ScopedFileDescriptor> unvalidatedConvert(const nn::Shared return ndk::ScopedFileDescriptor(duplicatedFd.release()); } +nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities) { + return Capabilities{ + .relaxedFloat32toFloat16PerformanceTensor = NN_TRY( + unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)), + .relaxedFloat32toFloat16PerformanceScalar = NN_TRY( + unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)), + .operandPerformance = NN_TRY(unvalidatedConvert(capabilities.operandPerformance)), + .ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance)), + .whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance)), + }; +} + +nn::GeneralResult<Extension> unvalidatedConvert(const nn::Extension& extension) { + return Extension{.name = extension.name, + .operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes))}; +} + nn::GeneralResult<std::vector<uint8_t>> convert(const nn::CacheToken& cacheToken) { return validatedConvert(cacheToken); } @@ -997,6 +1064,10 @@ nn::GeneralResult<BufferDesc> convert(const nn::BufferDesc& bufferDesc) { return validatedConvert(bufferDesc); } +nn::GeneralResult<DeviceType> convert(const nn::DeviceType& deviceType) { + return validatedConvert(deviceType); +} + nn::GeneralResult<bool> convert(const nn::MeasureTiming& measureTiming) { return validatedConvert(measureTiming); } @@ -1037,6 +1108,14 @@ nn::GeneralResult<int64_t> convert(const nn::OptionalTimePoint& outputShapes) { return validatedConvert(outputShapes); } +nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities) { + return validatedConvert(capabilities); +} + +nn::GeneralResult<Extension> convert(const nn::Extension& extension) { + return validatedConvert(extension); +} + nn::GeneralResult<std::vector<BufferRole>> convert(const std::vector<nn::BufferRole>& bufferRoles) { return validatedConvert(bufferRoles); } @@ -1056,6 +1135,10 @@ nn::GeneralResult<std::vector<ndk::ScopedFileDescriptor>> convert( return validatedConvert(syncFences); } +nn::GeneralResult<std::vector<Extension>> convert(const std::vector<nn::Extension>& extensions) { + return validatedConvert(extensions); +} + nn::GeneralResult<std::vector<int32_t>> toSigned(const std::vector<uint32_t>& vec) { if (!std::all_of(vec.begin(), vec.end(), [](uint32_t v) { return v <= std::numeric_limits<int32_t>::max(); })) { diff --git a/neuralnetworks/aidl/utils/src/Device.cpp b/neuralnetworks/aidl/utils/src/Device.cpp index 5b7ec4ebd7..bad10ed347 100644 --- a/neuralnetworks/aidl/utils/src/Device.cpp +++ b/neuralnetworks/aidl/utils/src/Device.cpp @@ -229,7 +229,7 @@ nn::GeneralResult<nn::SharedPreparedModel> Device::prepareModel( const auto aidlDataCache = NN_TRY(convert(dataCache)); const auto aidlToken = NN_TRY(convert(token)); - const auto cb = ndk::SharedRefBase::make<PreparedModelCallback>(); + const auto cb = ndk::SharedRefBase::make<PreparedModelCallback>(kFeatureLevel); const auto scoped = kDeathHandler.protectCallback(cb.get()); const auto ret = kDevice->prepareModel(aidlModel, aidlPreference, aidlPriority, aidlDeadline, @@ -247,7 +247,7 @@ nn::GeneralResult<nn::SharedPreparedModel> Device::prepareModelFromCache( const auto aidlDataCache = NN_TRY(convert(dataCache)); const auto aidlToken = NN_TRY(convert(token)); - const auto cb = ndk::SharedRefBase::make<PreparedModelCallback>(); + const auto cb = ndk::SharedRefBase::make<PreparedModelCallback>(kFeatureLevel); const auto scoped = kDeathHandler.protectCallback(cb.get()); const auto ret = kDevice->prepareModelFromCache(aidlDeadline, aidlModelCache, aidlDataCache, diff --git a/neuralnetworks/aidl/utils/src/Execution.cpp b/neuralnetworks/aidl/utils/src/Execution.cpp index 94edd90c89..c4add636e5 100644 --- a/neuralnetworks/aidl/utils/src/Execution.cpp +++ b/neuralnetworks/aidl/utils/src/Execution.cpp @@ -35,36 +35,39 @@ namespace aidl::android::hardware::neuralnetworks::utils { -nn::GeneralResult<std::shared_ptr<const Execution>> Execution::create( - std::shared_ptr<const PreparedModel> preparedModel, Request request, - hal::utils::RequestRelocation relocation, bool measure, int64_t loopTimeoutDuration) { +nn::GeneralResult<std::shared_ptr<const ExecutionWithCachedRequest>> +ExecutionWithCachedRequest::create(std::shared_ptr<const PreparedModel> preparedModel, + Request request, hal::utils::RequestRelocation relocation, + bool measure, int64_t loopTimeoutDuration) { if (preparedModel == nullptr) { - return NN_ERROR() << "aidl::utils::Execution::create must have non-null preparedModel"; + return NN_ERROR() << "aidl::utils::ExecutionWithCachedRequest::create must have non-null " + "preparedModel"; } - return std::make_shared<const Execution>(PrivateConstructorTag{}, std::move(preparedModel), - std::move(request), std::move(relocation), measure, - loopTimeoutDuration); + return std::make_shared<const ExecutionWithCachedRequest>( + PrivateConstructorTag{}, std::move(preparedModel), std::move(request), + std::move(relocation), measure, loopTimeoutDuration); } -Execution::Execution(PrivateConstructorTag /*tag*/, - std::shared_ptr<const PreparedModel> preparedModel, Request request, - hal::utils::RequestRelocation relocation, bool measure, - int64_t loopTimeoutDuration) +ExecutionWithCachedRequest::ExecutionWithCachedRequest( + PrivateConstructorTag /*tag*/, std::shared_ptr<const PreparedModel> preparedModel, + Request request, hal::utils::RequestRelocation relocation, bool measure, + int64_t loopTimeoutDuration) : kPreparedModel(std::move(preparedModel)), kRequest(std::move(request)), kRelocation(std::move(relocation)), kMeasure(measure), kLoopTimeoutDuration(loopTimeoutDuration) {} -nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> Execution::compute( - const nn::OptionalTimePoint& deadline) const { +nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> +ExecutionWithCachedRequest::compute(const nn::OptionalTimePoint& deadline) const { const auto aidlDeadline = NN_TRY(convert(deadline)); return kPreparedModel->executeInternal(kRequest, kMeasure, aidlDeadline, kLoopTimeoutDuration, kRelocation); } -nn::GeneralResult<std::pair<nn::SyncFence, nn::ExecuteFencedInfoCallback>> Execution::computeFenced( +nn::GeneralResult<std::pair<nn::SyncFence, nn::ExecuteFencedInfoCallback>> +ExecutionWithCachedRequest::computeFenced( const std::vector<nn::SyncFence>& waitFor, const nn::OptionalTimePoint& deadline, const nn::OptionalDuration& timeoutDurationAfterFence) const { const auto aidlWaitFor = NN_TRY(convert(waitFor)); @@ -75,4 +78,18 @@ nn::GeneralResult<std::pair<nn::SyncFence, nn::ExecuteFencedInfoCallback>> Execu aidlTimeoutDurationAfterFence, kRelocation); } +nn::GeneralResult<std::shared_ptr<const Execution>> Execution::create( + std::shared_ptr<aidl_hal::IExecution> execution, hal::utils::RequestRelocation relocation) { + if (execution == nullptr) { + return NN_ERROR() << "aidl::utils::Execution::create must have non-null execution"; + } + + return std::make_shared<const Execution>(PrivateConstructorTag{}, std::move(execution), + std::move(relocation)); +} + +Execution::Execution(PrivateConstructorTag /*tag*/, std::shared_ptr<aidl_hal::IExecution> execution, + hal::utils::RequestRelocation relocation) + : kExecution(std::move(execution)), kRelocation(std::move(relocation)) {} + } // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/aidl/utils/src/PreparedModel.cpp b/neuralnetworks/aidl/utils/src/PreparedModel.cpp index f25c2c8825..6d1de569d0 100644 --- a/neuralnetworks/aidl/utils/src/PreparedModel.cpp +++ b/neuralnetworks/aidl/utils/src/PreparedModel.cpp @@ -54,21 +54,77 @@ nn::GeneralResult<std::pair<nn::Timing, nn::Timing>> convertFencedExecutionResul return std::make_pair(NN_TRY(nn::convert(timingLaunched)), NN_TRY(nn::convert(timingFenced))); } +nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> handleExecutionResult( + const ExecutionResult& result, const hal::utils::RequestRelocation& relocation) { + if (!result.outputSufficientSize) { + auto canonicalOutputShapes = + nn::convert(result.outputShapes).value_or(std::vector<nn::OutputShape>{}); + return NN_ERROR(nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE, std::move(canonicalOutputShapes)) + << "execution failed with " << nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE; + } + auto [outputShapes, timing] = + NN_TRY(convertExecutionResults(result.outputShapes, result.timing)); + + if (relocation.output) { + relocation.output->flush(); + } + return std::make_pair(std::move(outputShapes), timing); +} + +nn::GeneralResult<std::pair<nn::SyncFence, nn::ExecuteFencedInfoCallback>> +handleFencedExecutionResult(const FencedExecutionResult& result, + const hal::utils::RequestRelocation& relocation) { + auto resultSyncFence = nn::SyncFence::createAsSignaled(); + if (result.syncFence.get() != -1) { + resultSyncFence = nn::SyncFence::create(NN_TRY(nn::convert(result.syncFence))).value(); + } + + auto callback = result.callback; + if (callback == nullptr) { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "callback is null"; + } + + // If computeFenced required the request memory to be moved into shared memory, block here until + // the fenced execution has completed and flush the memory back. + if (relocation.output) { + const auto state = resultSyncFence.syncWait({}); + if (state != nn::SyncFence::FenceState::SIGNALED) { + return NN_ERROR() << "syncWait failed with " << state; + } + relocation.output->flush(); + } + + // Create callback which can be used to retrieve the execution error status and timings. + nn::ExecuteFencedInfoCallback resultCallback = + [callback]() -> nn::GeneralResult<std::pair<nn::Timing, nn::Timing>> { + ErrorStatus errorStatus; + Timing timingLaunched; + Timing timingFenced; + const auto ret = callback->getExecutionInfo(&timingLaunched, &timingFenced, &errorStatus); + HANDLE_ASTATUS(ret) << "fenced execution callback getExecutionInfo failed"; + return convertFencedExecutionResults(errorStatus, timingLaunched, timingFenced); + }; + + return std::make_pair(std::move(resultSyncFence), std::move(resultCallback)); +} + } // namespace nn::GeneralResult<std::shared_ptr<const PreparedModel>> PreparedModel::create( - std::shared_ptr<aidl_hal::IPreparedModel> preparedModel) { + std::shared_ptr<aidl_hal::IPreparedModel> preparedModel, nn::Version featureLevel) { if (preparedModel == nullptr) { return NN_ERROR() << "aidl_hal::utils::PreparedModel::create must have non-null preparedModel"; } - return std::make_shared<const PreparedModel>(PrivateConstructorTag{}, std::move(preparedModel)); + return std::make_shared<const PreparedModel>(PrivateConstructorTag{}, std::move(preparedModel), + featureLevel); } PreparedModel::PreparedModel(PrivateConstructorTag /*tag*/, - std::shared_ptr<aidl_hal::IPreparedModel> preparedModel) - : kPreparedModel(std::move(preparedModel)) {} + std::shared_ptr<aidl_hal::IPreparedModel> preparedModel, + nn::Version featureLevel) + : kPreparedModel(std::move(preparedModel)), kFeatureLevel(featureLevel) {} nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> PreparedModel::execute( const nn::Request& request, nn::MeasureTiming measure, @@ -101,19 +157,7 @@ PreparedModel::executeInternal(const Request& request, bool measure, int64_t dea const auto ret = kPreparedModel->executeSynchronously(request, measure, deadline, loopTimeoutDuration, &executionResult); HANDLE_ASTATUS(ret) << "executeSynchronously failed"; - if (!executionResult.outputSufficientSize) { - auto canonicalOutputShapes = - nn::convert(executionResult.outputShapes).value_or(std::vector<nn::OutputShape>{}); - return NN_ERROR(nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE, std::move(canonicalOutputShapes)) - << "execution failed with " << nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE; - } - auto [outputShapes, timing] = - NN_TRY(convertExecutionResults(executionResult.outputShapes, executionResult.timing)); - - if (relocation.output) { - relocation.output->flush(); - } - return std::make_pair(std::move(outputShapes), timing); + return handleExecutionResult(executionResult, relocation); } nn::GeneralResult<std::pair<nn::SyncFence, nn::ExecuteFencedInfoCallback>> @@ -154,39 +198,7 @@ PreparedModel::executeFencedInternal(const Request& request, kPreparedModel->executeFenced(request, waitFor, measure, deadline, loopTimeoutDuration, timeoutDurationAfterFence, &result); HANDLE_ASTATUS(ret) << "executeFenced failed"; - - auto resultSyncFence = nn::SyncFence::createAsSignaled(); - if (result.syncFence.get() != -1) { - resultSyncFence = nn::SyncFence::create(NN_TRY(nn::convert(result.syncFence))).value(); - } - - auto callback = result.callback; - if (callback == nullptr) { - return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "callback is null"; - } - - // If executeFenced required the request memory to be moved into shared memory, block here until - // the fenced execution has completed and flush the memory back. - if (relocation.output) { - const auto state = resultSyncFence.syncWait({}); - if (state != nn::SyncFence::FenceState::SIGNALED) { - return NN_ERROR() << "syncWait failed with " << state; - } - relocation.output->flush(); - } - - // Create callback which can be used to retrieve the execution error status and timings. - nn::ExecuteFencedInfoCallback resultCallback = - [callback]() -> nn::GeneralResult<std::pair<nn::Timing, nn::Timing>> { - ErrorStatus errorStatus; - Timing timingLaunched; - Timing timingFenced; - const auto ret = callback->getExecutionInfo(&timingLaunched, &timingFenced, &errorStatus); - HANDLE_ASTATUS(ret) << "fenced execution callback getExecutionInfo failed"; - return convertFencedExecutionResults(errorStatus, timingLaunched, timingFenced); - }; - - return std::make_pair(std::move(resultSyncFence), std::move(resultCallback)); + return handleFencedExecutionResult(result, relocation); } nn::GeneralResult<nn::SharedExecution> PreparedModel::createReusableExecution( @@ -202,8 +214,18 @@ nn::GeneralResult<nn::SharedExecution> PreparedModel::createReusableExecution( auto aidlRequest = NN_TRY(convert(requestInShared)); auto aidlMeasure = NN_TRY(convert(measure)); auto aidlLoopTimeoutDuration = NN_TRY(convert(loopTimeoutDuration)); - return Execution::create(shared_from_this(), std::move(aidlRequest), std::move(relocation), - aidlMeasure, aidlLoopTimeoutDuration); + + if (kFeatureLevel.level >= nn::Version::Level::FEATURE_LEVEL_8) { + std::shared_ptr<IExecution> execution; + const auto ret = kPreparedModel->createReusableExecution( + aidlRequest, aidlMeasure, aidlLoopTimeoutDuration, &execution); + HANDLE_ASTATUS(ret) << "createReusableExecution failed"; + return Execution::create(std::move(execution), std::move(relocation)); + } + + return ExecutionWithCachedRequest::create(shared_from_this(), std::move(aidlRequest), + std::move(relocation), aidlMeasure, + aidlLoopTimeoutDuration); } nn::GeneralResult<nn::SharedBurst> PreparedModel::configureExecutionBurst() const { @@ -218,4 +240,36 @@ std::any PreparedModel::getUnderlyingResource() const { return resource; } +nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> Execution::compute( + const nn::OptionalTimePoint& deadline) const { + const auto aidlDeadline = NN_TRY(convert(deadline)); + + if (kRelocation.input) { + kRelocation.input->flush(); + } + + ExecutionResult executionResult; + auto ret = kExecution->executeSynchronously(aidlDeadline, &executionResult); + HANDLE_ASTATUS(ret) << "executeSynchronously failed"; + return handleExecutionResult(executionResult, kRelocation); +} + +nn::GeneralResult<std::pair<nn::SyncFence, nn::ExecuteFencedInfoCallback>> Execution::computeFenced( + const std::vector<nn::SyncFence>& waitFor, const nn::OptionalTimePoint& deadline, + const nn::OptionalDuration& timeoutDurationAfterFence) const { + const auto aidlWaitFor = NN_TRY(convert(waitFor)); + const auto aidlDeadline = NN_TRY(convert(deadline)); + const auto aidlTimeoutDurationAfterFence = NN_TRY(convert(timeoutDurationAfterFence)); + + if (kRelocation.input) { + kRelocation.input->flush(); + } + + FencedExecutionResult result; + const auto ret = kExecution->executeFenced(aidlWaitFor, aidlDeadline, + aidlTimeoutDurationAfterFence, &result); + HANDLE_ASTATUS(ret) << "executeFenced failed"; + return handleFencedExecutionResult(result, kRelocation); +} + } // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/aidl/utils/test/DeviceTest.cpp b/neuralnetworks/aidl/utils/test/DeviceTest.cpp index 0366e7dff0..fb13af8d9f 100644 --- a/neuralnetworks/aidl/utils/test/DeviceTest.cpp +++ b/neuralnetworks/aidl/utils/test/DeviceTest.cpp @@ -17,6 +17,7 @@ #include "MockBuffer.h" #include "MockDevice.h" #include "MockPreparedModel.h" +#include "TestUtils.h" #include <aidl/android/hardware/neuralnetworks/BnDevice.h> #include <android/binder_auto_utils.h> @@ -146,26 +147,7 @@ constexpr auto makeDeadObjectFailure = [] { return ndk::ScopedAStatus::fromStatus(STATUS_DEAD_OBJECT); }; -class DeviceTest : public ::testing::TestWithParam<nn::Version> { - protected: - const nn::Version kVersion = GetParam(); -}; - -std::string printDeviceTest(const testing::TestParamInfo<nn::Version>& info) { - const nn::Version version = info.param; - CHECK(!version.runtimeOnlyFeatures); - switch (version.level) { - case nn::Version::Level::FEATURE_LEVEL_5: - return "v1"; - case nn::Version::Level::FEATURE_LEVEL_6: - return "v2"; - case nn::Version::Level::FEATURE_LEVEL_7: - return "v3"; - default: - LOG(FATAL) << "Invalid AIDL version: " << version; - return "invalid"; - } -} +class DeviceTest : public VersionedAidlUtilsTestBase {}; } // namespace @@ -894,9 +876,6 @@ TEST_P(DeviceTest, allocateDeadObject) { EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); } -INSTANTIATE_TEST_SUITE_P(TestDevice, DeviceTest, - ::testing::Values(nn::kVersionFeatureLevel5, nn::kVersionFeatureLevel6, - nn::kVersionFeatureLevel7), - printDeviceTest); +INSTANTIATE_VERSIONED_AIDL_UTILS_TEST(DeviceTest, kAllAidlVersions); } // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/aidl/utils/test/ExecutionTest.cpp b/neuralnetworks/aidl/utils/test/ExecutionTest.cpp new file mode 100644 index 0000000000..8519290145 --- /dev/null +++ b/neuralnetworks/aidl/utils/test/ExecutionTest.cpp @@ -0,0 +1,254 @@ +/* + * 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 "MockExecution.h" +#include "MockFencedExecutionCallback.h" + +#include <aidl/android/hardware/neuralnetworks/IFencedExecutionCallback.h> +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include <nnapi/IExecution.h> +#include <nnapi/TypeUtils.h> +#include <nnapi/Types.h> +#include <nnapi/hal/aidl/Execution.h> + +#include <functional> +#include <memory> + +namespace aidl::android::hardware::neuralnetworks::utils { +namespace { + +using ::testing::_; +using ::testing::DoAll; +using ::testing::Invoke; +using ::testing::InvokeWithoutArgs; +using ::testing::SetArgPointee; + +const std::shared_ptr<IExecution> kInvalidExecution; +constexpr auto kNoTiming = Timing{.timeOnDeviceNs = -1, .timeInDriverNs = -1}; + +constexpr auto makeStatusOk = [] { return ndk::ScopedAStatus::ok(); }; + +constexpr auto makeGeneralFailure = [] { + return ndk::ScopedAStatus::fromServiceSpecificError( + static_cast<int32_t>(ErrorStatus::GENERAL_FAILURE)); +}; +constexpr auto makeGeneralTransportFailure = [] { + return ndk::ScopedAStatus::fromStatus(STATUS_NO_MEMORY); +}; +constexpr auto makeDeadObjectFailure = [] { + return ndk::ScopedAStatus::fromStatus(STATUS_DEAD_OBJECT); +}; + +auto makeFencedExecutionResult(const std::shared_ptr<MockFencedExecutionCallback>& callback) { + return [callback](const std::vector<ndk::ScopedFileDescriptor>& /*waitFor*/, + int64_t /*deadline*/, int64_t /*duration*/, + FencedExecutionResult* fencedExecutionResult) { + *fencedExecutionResult = FencedExecutionResult{.callback = callback, + .syncFence = ndk::ScopedFileDescriptor(-1)}; + return ndk::ScopedAStatus::ok(); + }; +} + +} // namespace + +TEST(ExecutionTest, invalidExecution) { + // run test + const auto result = Execution::create(kInvalidExecution, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ExecutionTest, executeSync) { + // setup call + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + const auto mockExecutionResult = ExecutionResult{ + .outputSufficientSize = true, + .outputShapes = {}, + .timing = kNoTiming, + }; + EXPECT_CALL(*mockExecution, executeSynchronously(_, _)) + .Times(1) + .WillOnce( + DoAll(SetArgPointee<1>(mockExecutionResult), InvokeWithoutArgs(makeStatusOk))); + + // run test + const auto result = execution->compute({}); + + // verify result + EXPECT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ExecutionTest, executeSyncError) { + // setup test + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + EXPECT_CALL(*mockExecution, executeSynchronously(_, _)) + .Times(1) + .WillOnce(Invoke(makeGeneralFailure)); + + // run test + const auto result = execution->compute({}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ExecutionTest, executeSyncTransportFailure) { + // setup test + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + EXPECT_CALL(*mockExecution, executeSynchronously(_, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = execution->compute({}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ExecutionTest, executeSyncDeadObject) { + // setup test + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + EXPECT_CALL(*mockExecution, executeSynchronously(_, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = execution->compute({}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(ExecutionTest, executeFenced) { + // setup call + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + const auto mockCallback = MockFencedExecutionCallback::create(); + EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _)) + .Times(1) + .WillOnce(DoAll(SetArgPointee<0>(kNoTiming), SetArgPointee<1>(kNoTiming), + SetArgPointee<2>(ErrorStatus::NONE), Invoke(makeStatusOk))); + EXPECT_CALL(*mockExecution, executeFenced(_, _, _, _)) + .Times(1) + .WillOnce(Invoke(makeFencedExecutionResult(mockCallback))); + + // run test + const auto result = execution->computeFenced({}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + const auto& [syncFence, callback] = result.value(); + EXPECT_EQ(syncFence.syncWait({}), nn::SyncFence::FenceState::SIGNALED); + ASSERT_NE(callback, nullptr); + + // get results from callback + const auto callbackResult = callback(); + ASSERT_TRUE(callbackResult.has_value()) << "Failed with " << callbackResult.error().code << ": " + << callbackResult.error().message; +} + +TEST(ExecutionTest, executeFencedCallbackError) { + // setup call + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + const auto mockCallback = MockFencedExecutionCallback::create(); + EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _)) + .Times(1) + .WillOnce(Invoke(DoAll(SetArgPointee<0>(kNoTiming), SetArgPointee<1>(kNoTiming), + SetArgPointee<2>(ErrorStatus::GENERAL_FAILURE), + Invoke(makeStatusOk)))); + EXPECT_CALL(*mockExecution, executeFenced(_, _, _, _)) + .Times(1) + .WillOnce(Invoke(makeFencedExecutionResult(mockCallback))); + + // run test + const auto result = execution->computeFenced({}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + const auto& [syncFence, callback] = result.value(); + EXPECT_NE(syncFence.syncWait({}), nn::SyncFence::FenceState::ACTIVE); + ASSERT_NE(callback, nullptr); + + // verify callback failure + const auto callbackResult = callback(); + ASSERT_FALSE(callbackResult.has_value()); + EXPECT_EQ(callbackResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ExecutionTest, executeFencedError) { + // setup test + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + EXPECT_CALL(*mockExecution, executeFenced(_, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralFailure)); + + // run test + const auto result = execution->computeFenced({}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ExecutionTest, executeFencedTransportFailure) { + // setup test + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + EXPECT_CALL(*mockExecution, executeFenced(_, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = execution->computeFenced({}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ExecutionTest, executeFencedDeadObject) { + // setup test + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + EXPECT_CALL(*mockExecution, executeFenced(_, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = execution->computeFenced({}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +} // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/aidl/utils/test/MockExecution.h b/neuralnetworks/aidl/utils/test/MockExecution.h new file mode 100644 index 0000000000..216f569abc --- /dev/null +++ b/neuralnetworks/aidl/utils/test/MockExecution.h @@ -0,0 +1,47 @@ +/* + * 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. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_MOCK_EXECUTION_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_MOCK_EXECUTION_H + +#include <aidl/android/hardware/neuralnetworks/BnExecution.h> +#include <android/binder_interface_utils.h> +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include <hidl/HidlSupport.h> +#include <hidl/Status.h> + +namespace aidl::android::hardware::neuralnetworks::utils { + +class MockExecution final : public BnExecution { + public: + static std::shared_ptr<MockExecution> create(); + + MOCK_METHOD(ndk::ScopedAStatus, executeSynchronously, + (int64_t deadline, ExecutionResult* executionResult), (override)); + MOCK_METHOD(ndk::ScopedAStatus, executeFenced, + (const std::vector<ndk::ScopedFileDescriptor>& waitFor, int64_t deadline, + int64_t duration, FencedExecutionResult* fencedExecutionResult), + (override)); +}; + +inline std::shared_ptr<MockExecution> MockExecution::create() { + return ndk::SharedRefBase::make<MockExecution>(); +} + +} // namespace aidl::android::hardware::neuralnetworks::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_MOCK_EXECUTION_H diff --git a/neuralnetworks/aidl/utils/test/MockPreparedModel.h b/neuralnetworks/aidl/utils/test/MockPreparedModel.h index a4ae2b778a..0ed9af9929 100644 --- a/neuralnetworks/aidl/utils/test/MockPreparedModel.h +++ b/neuralnetworks/aidl/utils/test/MockPreparedModel.h @@ -17,6 +17,7 @@ #ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_MOCK_PREPARED_MODEL_H #define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_MOCK_PREPARED_MODEL_H +#include <aidl/android/hardware/neuralnetworks/BnExecution.h> #include <aidl/android/hardware/neuralnetworks/BnPreparedModel.h> #include <android/binder_interface_utils.h> #include <gmock/gmock.h> @@ -41,6 +42,10 @@ class MockPreparedModel final : public BnPreparedModel { (override)); MOCK_METHOD(ndk::ScopedAStatus, configureExecutionBurst, (std::shared_ptr<IBurst> * burst), (override)); + MOCK_METHOD(ndk::ScopedAStatus, createReusableExecution, + (const Request& request, bool measureTiming, int64_t loopTimeoutDuration, + std::shared_ptr<IExecution>* execution), + (override)); }; inline std::shared_ptr<MockPreparedModel> MockPreparedModel::create() { diff --git a/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp b/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp index 8bb5c90d1e..8cfb7c123a 100644 --- a/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp +++ b/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp @@ -15,8 +15,10 @@ */ #include "MockBurst.h" +#include "MockExecution.h" #include "MockFencedExecutionCallback.h" #include "MockPreparedModel.h" +#include "TestUtils.h" #include <aidl/android/hardware/neuralnetworks/IFencedExecutionCallback.h> #include <gmock/gmock.h> @@ -66,21 +68,23 @@ auto makeFencedExecutionResult(const std::shared_ptr<MockFencedExecutionCallback }; } +class PreparedModelTest : public VersionedAidlUtilsTestBase {}; + } // namespace -TEST(PreparedModelTest, invalidPreparedModel) { +TEST_P(PreparedModelTest, invalidPreparedModel) { // run test - const auto result = PreparedModel::create(kInvalidPreparedModel); + const auto result = PreparedModel::create(kInvalidPreparedModel, kVersion); // verify result ASSERT_FALSE(result.has_value()); EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, executeSync) { +TEST_P(PreparedModelTest, executeSync) { // setup call const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); const auto mockExecutionResult = ExecutionResult{ .outputSufficientSize = true, .outputShapes = {}, @@ -99,10 +103,10 @@ TEST(PreparedModelTest, executeSync) { << "Failed with " << result.error().code << ": " << result.error().message; } -TEST(PreparedModelTest, executeSyncError) { +TEST_P(PreparedModelTest, executeSyncError) { // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _)) .Times(1) .WillOnce(Invoke(makeGeneralFailure)); @@ -115,10 +119,10 @@ TEST(PreparedModelTest, executeSyncError) { EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, executeSyncTransportFailure) { +TEST_P(PreparedModelTest, executeSyncTransportFailure) { // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _)) .Times(1) .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); @@ -131,10 +135,10 @@ TEST(PreparedModelTest, executeSyncTransportFailure) { EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, executeSyncDeadObject) { +TEST_P(PreparedModelTest, executeSyncDeadObject) { // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _)) .Times(1) .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); @@ -147,10 +151,10 @@ TEST(PreparedModelTest, executeSyncDeadObject) { EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); } -TEST(PreparedModelTest, executeFenced) { +TEST_P(PreparedModelTest, executeFenced) { // setup call const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); const auto mockCallback = MockFencedExecutionCallback::create(); EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _)) .Times(1) @@ -176,10 +180,10 @@ TEST(PreparedModelTest, executeFenced) { << callbackResult.error().message; } -TEST(PreparedModelTest, executeFencedCallbackError) { +TEST_P(PreparedModelTest, executeFencedCallbackError) { // setup call const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); const auto mockCallback = MockFencedExecutionCallback::create(); EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _)) .Times(1) @@ -206,10 +210,10 @@ TEST(PreparedModelTest, executeFencedCallbackError) { EXPECT_EQ(callbackResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, executeFencedError) { +TEST_P(PreparedModelTest, executeFencedError) { // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) .Times(1) .WillOnce(InvokeWithoutArgs(makeGeneralFailure)); @@ -222,10 +226,10 @@ TEST(PreparedModelTest, executeFencedError) { EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, executeFencedTransportFailure) { +TEST_P(PreparedModelTest, executeFencedTransportFailure) { // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) .Times(1) .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); @@ -238,10 +242,10 @@ TEST(PreparedModelTest, executeFencedTransportFailure) { EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, executeFencedDeadObject) { +TEST_P(PreparedModelTest, executeFencedDeadObject) { // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) .Times(1) .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); @@ -254,11 +258,13 @@ TEST(PreparedModelTest, executeFencedDeadObject) { EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); } -TEST(PreparedModelTest, reusableExecuteSync) { +TEST_P(PreparedModelTest, reusableExecuteSync) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup call const uint32_t kNumberOfComputations = 2; const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); const auto mockExecutionResult = ExecutionResult{ .outputSufficientSize = true, .outputShapes = {}, @@ -283,10 +289,12 @@ TEST(PreparedModelTest, reusableExecuteSync) { } } -TEST(PreparedModelTest, reusableExecuteSyncError) { +TEST_P(PreparedModelTest, reusableExecuteSyncError) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _)) .Times(1) .WillOnce(Invoke(makeGeneralFailure)); @@ -303,10 +311,12 @@ TEST(PreparedModelTest, reusableExecuteSyncError) { EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, reusableExecuteSyncTransportFailure) { +TEST_P(PreparedModelTest, reusableExecuteSyncTransportFailure) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _)) .Times(1) .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); @@ -323,10 +333,12 @@ TEST(PreparedModelTest, reusableExecuteSyncTransportFailure) { EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, reusableExecuteSyncDeadObject) { +TEST_P(PreparedModelTest, reusableExecuteSyncDeadObject) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _)) .Times(1) .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); @@ -343,11 +355,13 @@ TEST(PreparedModelTest, reusableExecuteSyncDeadObject) { EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::DEAD_OBJECT); } -TEST(PreparedModelTest, reusableExecuteFenced) { +TEST_P(PreparedModelTest, reusableExecuteFenced) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup call const uint32_t kNumberOfComputations = 2; const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); const auto mockCallback = MockFencedExecutionCallback::create(); EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _)) .Times(kNumberOfComputations) @@ -379,10 +393,12 @@ TEST(PreparedModelTest, reusableExecuteFenced) { } } -TEST(PreparedModelTest, reusableExecuteFencedCallbackError) { +TEST_P(PreparedModelTest, reusableExecuteFencedCallbackError) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup call const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); const auto mockCallback = MockFencedExecutionCallback::create(); EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _)) .Times(1) @@ -413,10 +429,12 @@ TEST(PreparedModelTest, reusableExecuteFencedCallbackError) { EXPECT_EQ(callbackResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, reusableExecuteFencedError) { +TEST_P(PreparedModelTest, reusableExecuteFencedError) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) .Times(1) .WillOnce(InvokeWithoutArgs(makeGeneralFailure)); @@ -433,10 +451,12 @@ TEST(PreparedModelTest, reusableExecuteFencedError) { EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, reusableExecuteFencedTransportFailure) { +TEST_P(PreparedModelTest, reusableExecuteFencedTransportFailure) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) .Times(1) .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); @@ -453,10 +473,12 @@ TEST(PreparedModelTest, reusableExecuteFencedTransportFailure) { EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, reusableExecuteFencedDeadObject) { +TEST_P(PreparedModelTest, reusableExecuteFencedDeadObject) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) .Times(1) .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); @@ -473,14 +495,14 @@ TEST(PreparedModelTest, reusableExecuteFencedDeadObject) { EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::DEAD_OBJECT); } -TEST(PreparedModelTest, configureExecutionBurst) { +TEST_P(PreparedModelTest, configureExecutionBurst) { // setup test const auto mockPreparedModel = MockPreparedModel::create(); const auto mockBurst = ndk::SharedRefBase::make<MockBurst>(); EXPECT_CALL(*mockPreparedModel, configureExecutionBurst(_)) .Times(1) .WillOnce(DoAll(SetArgPointee<0>(mockBurst), Invoke(makeStatusOk))); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); // run test const auto result = preparedModel->configureExecutionBurst(); @@ -491,13 +513,13 @@ TEST(PreparedModelTest, configureExecutionBurst) { EXPECT_NE(result.value(), nullptr); } -TEST(PreparedModelTest, configureExecutionBurstError) { +TEST_P(PreparedModelTest, configureExecutionBurstError) { // setup test const auto mockPreparedModel = MockPreparedModel::create(); EXPECT_CALL(*mockPreparedModel, configureExecutionBurst(_)) .Times(1) .WillOnce(InvokeWithoutArgs(makeGeneralFailure)); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); // run test const auto result = preparedModel->configureExecutionBurst(); @@ -507,13 +529,13 @@ TEST(PreparedModelTest, configureExecutionBurstError) { EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, configureExecutionBurstTransportFailure) { +TEST_P(PreparedModelTest, configureExecutionBurstTransportFailure) { // setup test const auto mockPreparedModel = MockPreparedModel::create(); EXPECT_CALL(*mockPreparedModel, configureExecutionBurst(_)) .Times(1) .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); // run test const auto result = preparedModel->configureExecutionBurst(); @@ -523,13 +545,13 @@ TEST(PreparedModelTest, configureExecutionBurstTransportFailure) { EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, configureExecutionBurstDeadObject) { +TEST_P(PreparedModelTest, configureExecutionBurstDeadObject) { // setup test const auto mockPreparedModel = MockPreparedModel::create(); EXPECT_CALL(*mockPreparedModel, configureExecutionBurst(_)) .Times(1) .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); // run test const auto result = preparedModel->configureExecutionBurst(); @@ -539,10 +561,84 @@ TEST(PreparedModelTest, configureExecutionBurstDeadObject) { EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); } -TEST(PreparedModelTest, getUnderlyingResource) { +TEST_P(PreparedModelTest, createReusableExecution) { + if (kVersion.level < nn::Version::Level::FEATURE_LEVEL_8) return; + + // setup test + const auto mockPreparedModel = MockPreparedModel::create(); + const auto mockExecution = ndk::SharedRefBase::make<MockExecution>(); + EXPECT_CALL(*mockPreparedModel, createReusableExecution(_, _, _, _)) + .Times(1) + .WillOnce(DoAll(SetArgPointee<3>(mockExecution), Invoke(makeStatusOk))); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); + + // run test + const auto result = preparedModel->createReusableExecution({}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_NE(result.value(), nullptr); +} + +TEST_P(PreparedModelTest, createReusableExecutionError) { + if (kVersion.level < nn::Version::Level::FEATURE_LEVEL_8) return; + // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + EXPECT_CALL(*mockPreparedModel, createReusableExecution(_, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralFailure)); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); + + // run test + const auto result = preparedModel->createReusableExecution({}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST_P(PreparedModelTest, createReusableExecutionTransportFailure) { + if (kVersion.level < nn::Version::Level::FEATURE_LEVEL_8) return; + + // setup test + const auto mockPreparedModel = MockPreparedModel::create(); + EXPECT_CALL(*mockPreparedModel, createReusableExecution(_, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); + + // run test + const auto result = preparedModel->createReusableExecution({}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST_P(PreparedModelTest, createReusableExecutionDeadObject) { + if (kVersion.level < nn::Version::Level::FEATURE_LEVEL_8) return; + + // setup test + const auto mockPreparedModel = MockPreparedModel::create(); + EXPECT_CALL(*mockPreparedModel, createReusableExecution(_, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); + + // run test + const auto result = preparedModel->createReusableExecution({}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST_P(PreparedModelTest, getUnderlyingResource) { + // setup test + const auto mockPreparedModel = MockPreparedModel::create(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); // run test const auto resource = preparedModel->getUnderlyingResource(); @@ -554,4 +650,6 @@ TEST(PreparedModelTest, getUnderlyingResource) { EXPECT_EQ(maybeMock->get(), mockPreparedModel.get()); } +INSTANTIATE_VERSIONED_AIDL_UTILS_TEST(PreparedModelTest, kAllAidlVersions); + } // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/aidl/utils/test/TestUtils.cpp b/neuralnetworks/aidl/utils/test/TestUtils.cpp new file mode 100644 index 0000000000..9abec883a6 --- /dev/null +++ b/neuralnetworks/aidl/utils/test/TestUtils.cpp @@ -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. + */ + +#include "TestUtils.h" + +#include <android-base/logging.h> +#include <gtest/gtest.h> +#include <nnapi/TypeUtils.h> +#include <nnapi/Types.h> +#include <nnapi/hal/CommonUtils.h> +#include <string> + +namespace aidl::android::hardware::neuralnetworks::utils { + +std::string printTestVersion(const testing::TestParamInfo<nn::Version>& info) { + switch (info.param.level) { + case nn::Version::Level::FEATURE_LEVEL_5: + return "v1"; + case nn::Version::Level::FEATURE_LEVEL_6: + return "v2"; + case nn::Version::Level::FEATURE_LEVEL_7: + return "v3"; + case nn::Version::Level::FEATURE_LEVEL_8: + return "v4"; + default: + LOG(FATAL) << "Invalid AIDL version: " << info.param; + return "invalid"; + } +} + +} // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/aidl/utils/test/TestUtils.h b/neuralnetworks/aidl/utils/test/TestUtils.h new file mode 100644 index 0000000000..23f734a47a --- /dev/null +++ b/neuralnetworks/aidl/utils/test/TestUtils.h @@ -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. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_TEST_UTILS_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_TEST_UTILS_H + +#include <gtest/gtest.h> +#include <nnapi/Types.h> +#include <nnapi/hal/CommonUtils.h> +#include <string> + +namespace aidl::android::hardware::neuralnetworks::utils { + +class VersionedAidlUtilsTestBase : public ::testing::TestWithParam<nn::Version> { + protected: + const nn::Version kVersion = GetParam(); +}; + +std::string printTestVersion(const testing::TestParamInfo<nn::Version>& info); + +inline const auto kAllAidlVersions = + ::testing::Values(nn::kVersionFeatureLevel5, nn::kVersionFeatureLevel6, + nn::kVersionFeatureLevel7, nn::kVersionFeatureLevel8); + +#define INSTANTIATE_VERSIONED_AIDL_UTILS_TEST(TestSuite, versions) \ + INSTANTIATE_TEST_SUITE_P(Versioned, TestSuite, versions, printTestVersion) + +} // namespace aidl::android::hardware::neuralnetworks::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_TEST_UTILS_H diff --git a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp index f67fd34383..2460fbad86 100644 --- a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp +++ b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp @@ -58,25 +58,52 @@ struct TestConfig { bool measureTiming; OutputType outputType; MemoryType memoryType; + bool reusable; // `reportSkipping` indicates if a test should print an info message in case // it is skipped. The field is set to true by default and is set to false in // quantization coupling tests to suppress skipping a test bool reportSkipping; - TestConfig(Executor executor, bool measureTiming, OutputType outputType, MemoryType memoryType) + TestConfig(Executor executor, bool measureTiming, OutputType outputType, MemoryType memoryType, + bool reusable) : executor(executor), measureTiming(measureTiming), outputType(outputType), memoryType(memoryType), + reusable(reusable), reportSkipping(true) {} TestConfig(Executor executor, bool measureTiming, OutputType outputType, MemoryType memoryType, - bool reportSkipping) + bool reusable, bool reportSkipping) : executor(executor), measureTiming(measureTiming), outputType(outputType), memoryType(memoryType), + reusable(reusable), reportSkipping(reportSkipping) {} }; +std::string toString(OutputType type) { + switch (type) { + case OutputType::FULLY_SPECIFIED: + return "FULLY_SPECIFIED"; + case OutputType::UNSPECIFIED: + return "UNSPECIFIED"; + case OutputType::INSUFFICIENT: + return "INSUFFICIENT"; + case OutputType::MISSED_DEADLINE: + return "MISSED_DEADLINE"; + } +} + +std::string toString(const TestConfig& config) { + std::stringstream ss; + ss << "TestConfig{.executor=" << toString(config.executor) + << ", .measureTiming=" << (config.measureTiming ? "true" : "false") + << ", .outputType=" << toString(config.outputType) + << ", .memoryType=" << toString(config.memoryType) + << ", .reusable=" << (config.reusable ? "true" : "false") << "}"; + return ss.str(); +} + enum class IOType { INPUT, OUTPUT }; class DeviceMemoryAllocator { @@ -558,209 +585,241 @@ void EvaluatePreparedModel(const std::shared_ptr<IDevice>& device, loopTimeoutDurationNs = 1 * kMillisecond; } - ErrorStatus executionStatus; - std::vector<OutputShape> outputShapes; - Timing timing = kNoTiming; - switch (testConfig.executor) { - case Executor::SYNC: { - SCOPED_TRACE("synchronous"); - - ExecutionResult executionResult; - // execute - const auto ret = preparedModel->executeSynchronously(request, testConfig.measureTiming, - kNoDeadline, loopTimeoutDurationNs, - &executionResult); - ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC) - << ret.getDescription(); - if (ret.isOk()) { - executionStatus = executionResult.outputSufficientSize - ? ErrorStatus::NONE - : ErrorStatus::OUTPUT_INSUFFICIENT_SIZE; - outputShapes = std::move(executionResult.outputShapes); - timing = executionResult.timing; - } else { - executionStatus = static_cast<ErrorStatus>(ret.getServiceSpecificError()); - } - break; - } - case Executor::BURST: { - SCOPED_TRACE("burst"); - - // create burst - std::shared_ptr<IBurst> burst; - auto ret = preparedModel->configureExecutionBurst(&burst); - ASSERT_TRUE(ret.isOk()) << ret.getDescription(); - ASSERT_NE(nullptr, burst.get()); - - // associate a unique slot with each memory pool - int64_t currentSlot = 0; - std::vector<int64_t> slots; - slots.reserve(request.pools.size()); - for (const auto& pool : request.pools) { - if (pool.getTag() == RequestMemoryPool::Tag::pool) { - slots.push_back(currentSlot++); + std::shared_ptr<IExecution> execution; + if (testConfig.reusable) { + const auto ret = preparedModel->createReusableExecution(request, testConfig.measureTiming, + loopTimeoutDurationNs, &execution); + ASSERT_TRUE(ret.isOk()) << static_cast<nn::ErrorStatus>(ret.getServiceSpecificError()); + ASSERT_NE(nullptr, execution.get()); + } + + const auto executeAndCheckResults = [&preparedModel, &execution, &testConfig, &testModel, + &context, &request, loopTimeoutDurationNs, skipped]() { + ErrorStatus executionStatus; + std::vector<OutputShape> outputShapes; + Timing timing = kNoTiming; + switch (testConfig.executor) { + case Executor::SYNC: { + SCOPED_TRACE("synchronous"); + + ExecutionResult executionResult; + // execute + ::ndk::ScopedAStatus ret; + if (testConfig.reusable) { + ret = execution->executeSynchronously(kNoDeadline, &executionResult); } else { - EXPECT_EQ(pool.getTag(), RequestMemoryPool::Tag::token); - slots.push_back(-1); + ret = preparedModel->executeSynchronously(request, testConfig.measureTiming, + kNoDeadline, loopTimeoutDurationNs, + &executionResult); } + ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC) + << ret.getDescription(); + if (ret.isOk()) { + executionStatus = executionResult.outputSufficientSize + ? ErrorStatus::NONE + : ErrorStatus::OUTPUT_INSUFFICIENT_SIZE; + outputShapes = std::move(executionResult.outputShapes); + timing = executionResult.timing; + } else { + executionStatus = static_cast<ErrorStatus>(ret.getServiceSpecificError()); + } + break; } + case Executor::BURST: { + SCOPED_TRACE("burst"); - ExecutionResult executionResult; - // execute - ret = burst->executeSynchronously(request, slots, testConfig.measureTiming, kNoDeadline, - loopTimeoutDurationNs, &executionResult); - ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC) - << ret.getDescription(); - if (ret.isOk()) { - executionStatus = executionResult.outputSufficientSize - ? ErrorStatus::NONE - : ErrorStatus::OUTPUT_INSUFFICIENT_SIZE; - outputShapes = std::move(executionResult.outputShapes); - timing = executionResult.timing; - } else { - executionStatus = static_cast<ErrorStatus>(ret.getServiceSpecificError()); - } - - // Mark each slot as unused after the execution. This is unnecessary because the burst - // is freed after this scope ends, but this is here to test the functionality. - for (int64_t slot : slots) { - ret = burst->releaseMemoryResource(slot); + // create burst + std::shared_ptr<IBurst> burst; + auto ret = preparedModel->configureExecutionBurst(&burst); ASSERT_TRUE(ret.isOk()) << ret.getDescription(); - } + ASSERT_NE(nullptr, burst.get()); + + // associate a unique slot with each memory pool + int64_t currentSlot = 0; + std::vector<int64_t> slots; + slots.reserve(request.pools.size()); + for (const auto& pool : request.pools) { + if (pool.getTag() == RequestMemoryPool::Tag::pool) { + slots.push_back(currentSlot++); + } else { + EXPECT_EQ(pool.getTag(), RequestMemoryPool::Tag::token); + slots.push_back(-1); + } + } - break; - } - case Executor::FENCED: { - SCOPED_TRACE("fenced"); - ErrorStatus result = ErrorStatus::NONE; - FencedExecutionResult executionResult; - auto ret = preparedModel->executeFenced(request, {}, testConfig.measureTiming, - kNoDeadline, loopTimeoutDurationNs, kNoDuration, - &executionResult); - ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC) - << ret.getDescription(); - if (!ret.isOk()) { - result = static_cast<ErrorStatus>(ret.getServiceSpecificError()); - executionStatus = result; - } else if (executionResult.syncFence.get() != -1) { - std::vector<ndk::ScopedFileDescriptor> waitFor; - auto dupFd = dup(executionResult.syncFence.get()); - ASSERT_NE(dupFd, -1); - waitFor.emplace_back(dupFd); - // If a sync fence is returned, try start another run waiting for the sync fence. - ret = preparedModel->executeFenced(request, waitFor, testConfig.measureTiming, - kNoDeadline, loopTimeoutDurationNs, kNoDuration, - &executionResult); - ASSERT_TRUE(ret.isOk()); - waitForSyncFence(executionResult.syncFence.get()); + ExecutionResult executionResult; + // execute + ret = burst->executeSynchronously(request, slots, testConfig.measureTiming, + kNoDeadline, loopTimeoutDurationNs, + &executionResult); + ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC) + << ret.getDescription(); + if (ret.isOk()) { + executionStatus = executionResult.outputSufficientSize + ? ErrorStatus::NONE + : ErrorStatus::OUTPUT_INSUFFICIENT_SIZE; + outputShapes = std::move(executionResult.outputShapes); + timing = executionResult.timing; + } else { + executionStatus = static_cast<ErrorStatus>(ret.getServiceSpecificError()); + } + + // Mark each slot as unused after the execution. This is unnecessary because the + // burst is freed after this scope ends, but this is here to test the functionality. + for (int64_t slot : slots) { + ret = burst->releaseMemoryResource(slot); + ASSERT_TRUE(ret.isOk()) << ret.getDescription(); + } + + break; } - if (result == ErrorStatus::NONE) { - ASSERT_NE(executionResult.callback, nullptr); - Timing timingFenced; - auto ret = executionResult.callback->getExecutionInfo(&timing, &timingFenced, - &executionStatus); - ASSERT_TRUE(ret.isOk()); + case Executor::FENCED: { + SCOPED_TRACE("fenced"); + ErrorStatus result = ErrorStatus::NONE; + FencedExecutionResult executionResult; + ::ndk::ScopedAStatus ret; + if (testConfig.reusable) { + ret = execution->executeFenced({}, kNoDeadline, kNoDuration, &executionResult); + } else { + ret = preparedModel->executeFenced(request, {}, testConfig.measureTiming, + kNoDeadline, loopTimeoutDurationNs, + kNoDuration, &executionResult); + } + ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC) + << ret.getDescription(); + if (!ret.isOk()) { + result = static_cast<ErrorStatus>(ret.getServiceSpecificError()); + executionStatus = result; + } else if (executionResult.syncFence.get() != -1) { + std::vector<ndk::ScopedFileDescriptor> waitFor; + auto dupFd = dup(executionResult.syncFence.get()); + ASSERT_NE(dupFd, -1); + waitFor.emplace_back(dupFd); + // If a sync fence is returned, try start another run waiting for the sync + // fence. + ret = preparedModel->executeFenced(request, waitFor, testConfig.measureTiming, + kNoDeadline, loopTimeoutDurationNs, + kNoDuration, &executionResult); + ASSERT_TRUE(ret.isOk()); + waitForSyncFence(executionResult.syncFence.get()); + } + if (result == ErrorStatus::NONE) { + ASSERT_NE(executionResult.callback, nullptr); + Timing timingFenced; + auto ret = executionResult.callback->getExecutionInfo(&timing, &timingFenced, + &executionStatus); + ASSERT_TRUE(ret.isOk()); + } + break; + } + default: { + FAIL() << "Unsupported execution mode for AIDL interface."; } - break; - } - default: { - FAIL() << "Unsupported execution mode for AIDL interface."; - } - } - - if (testConfig.outputType != OutputType::FULLY_SPECIFIED && - executionStatus == ErrorStatus::GENERAL_FAILURE) { - if (skipped != nullptr) { - *skipped = true; - } - if (!testConfig.reportSkipping) { - return; - } - LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot " - "execute model that it does not support."; - std::cout << "[ ] Early termination of test because vendor service cannot " - "execute model that it does not support." - << std::endl; - GTEST_SKIP(); - } - if (!testConfig.measureTiming) { - EXPECT_EQ(timing, kNoTiming); - } else { - if (timing.timeOnDeviceNs != -1 && timing.timeInDriverNs != -1) { - EXPECT_LE(timing.timeOnDeviceNs, timing.timeInDriverNs); } - } - switch (testConfig.outputType) { - case OutputType::FULLY_SPECIFIED: - if (testConfig.executor == Executor::FENCED && hasZeroSizedOutput(testModel)) { - // Executor::FENCED does not support zero-sized output. - ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, executionStatus); - return; + if (testConfig.outputType != OutputType::FULLY_SPECIFIED && + executionStatus == ErrorStatus::GENERAL_FAILURE) { + if (skipped != nullptr) { + *skipped = true; } - // If the model output operands are fully specified, outputShapes must be either - // either empty, or have the same number of elements as the number of outputs. - ASSERT_EQ(ErrorStatus::NONE, executionStatus); - ASSERT_TRUE(outputShapes.size() == 0 || - outputShapes.size() == testModel.main.outputIndexes.size()); - break; - case OutputType::UNSPECIFIED: - if (testConfig.executor == Executor::FENCED) { - // For Executor::FENCED, the output shape must be fully specified. - ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, executionStatus); + if (!testConfig.reportSkipping) { return; } - // If the model output operands are not fully specified, outputShapes must have - // the same number of elements as the number of outputs. - ASSERT_EQ(ErrorStatus::NONE, executionStatus); - ASSERT_EQ(outputShapes.size(), testModel.main.outputIndexes.size()); - break; - case OutputType::INSUFFICIENT: - if (testConfig.executor == Executor::FENCED) { - // For Executor::FENCED, the output shape must be fully specified. - ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, executionStatus); - return; + LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot " + "execute model that it does not support."; + std::cout << "[ ] Early termination of test because vendor service cannot " + "execute model that it does not support." + << std::endl; + GTEST_SKIP(); + } + if (!testConfig.measureTiming) { + EXPECT_EQ(timing, kNoTiming); + } else { + if (timing.timeOnDeviceNs != -1 && timing.timeInDriverNs != -1) { + EXPECT_LE(timing.timeOnDeviceNs, timing.timeInDriverNs); } - ASSERT_EQ(ErrorStatus::OUTPUT_INSUFFICIENT_SIZE, executionStatus); - ASSERT_EQ(outputShapes.size(), testModel.main.outputIndexes.size()); - // Check that all returned output dimensions are at least as fully specified as the - // union of the information about the corresponding operand in the model and in the - // request. In this test, all model outputs have known rank with all dimensions - // unspecified, and no dimensional information is provided in the request. - for (uint32_t i = 0; i < outputShapes.size(); i++) { - ASSERT_EQ(outputShapes[i].isSufficient, i != kInsufficientOutputIndex); - const auto& actual = outputShapes[i].dimensions; - const auto& golden = - testModel.main.operands[testModel.main.outputIndexes[i]].dimensions; - ASSERT_EQ(actual.size(), golden.size()); - for (uint32_t j = 0; j < actual.size(); j++) { - if (actual[j] == 0) continue; - EXPECT_EQ(actual[j], golden[j]) << "index: " << j; + } + + switch (testConfig.outputType) { + case OutputType::FULLY_SPECIFIED: + if (testConfig.executor == Executor::FENCED && hasZeroSizedOutput(testModel)) { + // Executor::FENCED does not support zero-sized output. + ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, executionStatus); + return; } - } - return; - case OutputType::MISSED_DEADLINE: - ASSERT_TRUE(executionStatus == ErrorStatus::MISSED_DEADLINE_TRANSIENT || - executionStatus == ErrorStatus::MISSED_DEADLINE_PERSISTENT) - << "executionStatus = " << executionStatus; - return; - } + // If the model output operands are fully specified, outputShapes must be either + // either empty, or have the same number of elements as the number of outputs. + ASSERT_EQ(ErrorStatus::NONE, executionStatus); + ASSERT_TRUE(outputShapes.size() == 0 || + outputShapes.size() == testModel.main.outputIndexes.size()); + break; + case OutputType::UNSPECIFIED: + if (testConfig.executor == Executor::FENCED) { + // For Executor::FENCED, the output shape must be fully specified. + ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, executionStatus); + return; + } + // If the model output operands are not fully specified, outputShapes must have + // the same number of elements as the number of outputs. + ASSERT_EQ(ErrorStatus::NONE, executionStatus); + ASSERT_EQ(outputShapes.size(), testModel.main.outputIndexes.size()); + break; + case OutputType::INSUFFICIENT: + if (testConfig.executor == Executor::FENCED) { + // For Executor::FENCED, the output shape must be fully specified. + ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, executionStatus); + return; + } + ASSERT_EQ(ErrorStatus::OUTPUT_INSUFFICIENT_SIZE, executionStatus); + ASSERT_EQ(outputShapes.size(), testModel.main.outputIndexes.size()); + // Check that all returned output dimensions are at least as fully specified as the + // union of the information about the corresponding operand in the model and in the + // request. In this test, all model outputs have known rank with all dimensions + // unspecified, and no dimensional information is provided in the request. + for (uint32_t i = 0; i < outputShapes.size(); i++) { + ASSERT_EQ(outputShapes[i].isSufficient, i != kInsufficientOutputIndex); + const auto& actual = outputShapes[i].dimensions; + const auto& golden = + testModel.main.operands[testModel.main.outputIndexes[i]].dimensions; + ASSERT_EQ(actual.size(), golden.size()); + for (uint32_t j = 0; j < actual.size(); j++) { + if (actual[j] == 0) continue; + EXPECT_EQ(actual[j], golden[j]) << "index: " << j; + } + } + return; + case OutputType::MISSED_DEADLINE: + ASSERT_TRUE(executionStatus == ErrorStatus::MISSED_DEADLINE_TRANSIENT || + executionStatus == ErrorStatus::MISSED_DEADLINE_PERSISTENT) + << "executionStatus = " << executionStatus; + return; + } - // Go through all outputs, check returned output shapes. - for (uint32_t i = 0; i < outputShapes.size(); i++) { - EXPECT_TRUE(outputShapes[i].isSufficient); - const auto& expect = testModel.main.operands[testModel.main.outputIndexes[i]].dimensions; - const auto unsignedActual = nn::toUnsigned(outputShapes[i].dimensions); - ASSERT_TRUE(unsignedActual.has_value()); - const std::vector<uint32_t>& actual = unsignedActual.value(); - EXPECT_EQ(expect, actual); - } + // Go through all outputs, check returned output shapes. + for (uint32_t i = 0; i < outputShapes.size(); i++) { + EXPECT_TRUE(outputShapes[i].isSufficient); + const auto& expect = + testModel.main.operands[testModel.main.outputIndexes[i]].dimensions; + const auto unsignedActual = nn::toUnsigned(outputShapes[i].dimensions); + ASSERT_TRUE(unsignedActual.has_value()); + const std::vector<uint32_t>& actual = unsignedActual.value(); + EXPECT_EQ(expect, actual); + } + + // Retrieve execution results. + const std::vector<TestBuffer> outputs = context.getOutputBuffers(testModel, request); - // Retrieve execution results. - const std::vector<TestBuffer> outputs = context.getOutputBuffers(testModel, request); + // We want "close-enough" results. + checkResults(testModel, outputs); + }; - // We want "close-enough" results. - checkResults(testModel, outputs); + executeAndCheckResults(); + + // For reusable execution tests, run the execution twice. + if (testConfig.reusable) { + SCOPED_TRACE("Second execution"); + executeAndCheckResults(); + } } void EvaluatePreparedModel(const std::shared_ptr<IDevice>& device, @@ -770,6 +829,13 @@ void EvaluatePreparedModel(const std::shared_ptr<IDevice>& device, std::vector<bool> measureTimingList; std::vector<Executor> executorList; std::vector<MemoryType> memoryTypeList; + std::vector<bool> reusableList = {false}; + + int deviceVersion; + ASSERT_TRUE(device->getInterfaceVersion(&deviceVersion).isOk()); + if (deviceVersion >= kMinAidlLevelForFL8) { + reusableList.push_back(true); + } switch (testKind) { case TestKind::GENERAL: { @@ -812,8 +878,13 @@ void EvaluatePreparedModel(const std::shared_ptr<IDevice>& device, for (const bool measureTiming : measureTimingList) { for (const Executor executor : executorList) { for (const MemoryType memoryType : memoryTypeList) { - const TestConfig testConfig(executor, measureTiming, outputType, memoryType); - EvaluatePreparedModel(device, preparedModel, testModel, testConfig); + for (const bool reusable : reusableList) { + if (executor == Executor::BURST && reusable) continue; + const TestConfig testConfig(executor, measureTiming, outputType, memoryType, + reusable); + SCOPED_TRACE(toString(testConfig)); + EvaluatePreparedModel(device, preparedModel, testModel, testConfig); + } } } } @@ -833,7 +904,7 @@ void EvaluatePreparedCoupledModels(const std::shared_ptr<IDevice>& device, for (const bool measureTiming : measureTimingList) { for (const Executor executor : executorList) { const TestConfig testConfig(executor, measureTiming, outputType, MemoryType::ASHMEM, - /*reportSkipping=*/false); + /*reusable=*/false, /*reportSkipping=*/false); bool baseSkipped = false; EvaluatePreparedModel(device, preparedModel, testModel, testConfig, &baseSkipped); bool coupledSkipped = false; diff --git a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp index cd5475c0d3..b3e9c633e3 100644 --- a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp +++ b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp @@ -208,6 +208,11 @@ class InvalidPreparedModel : public BnPreparedModel { return ndk::ScopedAStatus::fromServiceSpecificError( static_cast<int32_t>(ErrorStatus::GENERAL_FAILURE)); } + ndk::ScopedAStatus createReusableExecution(const aidl_hal::Request&, bool, int64_t, + std::shared_ptr<aidl_hal::IExecution>*) override { + return ndk::ScopedAStatus::fromServiceSpecificError( + static_cast<int32_t>(ErrorStatus::GENERAL_FAILURE)); + } }; template <typename... Args> diff --git a/neuralnetworks/aidl/vts/functional/Utils.cpp b/neuralnetworks/aidl/vts/functional/Utils.cpp index 325a436f79..efd5bca517 100644 --- a/neuralnetworks/aidl/vts/functional/Utils.cpp +++ b/neuralnetworks/aidl/vts/functional/Utils.cpp @@ -177,6 +177,17 @@ std::string gtestCompliantName(std::string name) { return os << toString(errorStatus); } +std::string toString(MemoryType type) { + switch (type) { + case MemoryType::ASHMEM: + return "ASHMEM"; + case MemoryType::BLOB_AHWB: + return "BLOB_AHWB"; + case MemoryType::DEVICE: + return "DEVICE"; + } +} + Request ExecutionContext::createRequest(const TestModel& testModel, MemoryType memoryType) { CHECK(memoryType == MemoryType::ASHMEM || memoryType == MemoryType::BLOB_AHWB); diff --git a/neuralnetworks/aidl/vts/functional/Utils.h b/neuralnetworks/aidl/vts/functional/Utils.h index ca81418417..0db3f8c7f8 100644 --- a/neuralnetworks/aidl/vts/functional/Utils.h +++ b/neuralnetworks/aidl/vts/functional/Utils.h @@ -111,6 +111,8 @@ class TestBlobAHWB : public TestMemoryBase { enum class MemoryType { ASHMEM, BLOB_AHWB, DEVICE }; +std::string toString(MemoryType type); + // Manages the lifetime of memory resources used in an execution. class ExecutionContext { DISALLOW_COPY_AND_ASSIGN(ExecutionContext); diff --git a/neuralnetworks/aidl/vts/functional/ValidateRequest.cpp b/neuralnetworks/aidl/vts/functional/ValidateRequest.cpp index 29e2471777..e8debf704c 100644 --- a/neuralnetworks/aidl/vts/functional/ValidateRequest.cpp +++ b/neuralnetworks/aidl/vts/functional/ValidateRequest.cpp @@ -36,6 +36,51 @@ using ExecutionMutation = std::function<void(Request*)>; ///////////////////////// UTILITY FUNCTIONS ///////////////////////// +// Test request validation with reusable execution. +static void validateReusableExecution(const std::shared_ptr<IPreparedModel>& preparedModel, + const std::string& message, const Request& request, + bool measure) { + // createReusableExecution + std::shared_ptr<IExecution> execution; + { + SCOPED_TRACE(message + " [createReusableExecution]"); + const auto createStatus = preparedModel->createReusableExecution( + request, measure, kOmittedTimeoutDuration, &execution); + if (!createStatus.isOk()) { + ASSERT_EQ(createStatus.getExceptionCode(), EX_SERVICE_SPECIFIC); + ASSERT_EQ(static_cast<ErrorStatus>(createStatus.getServiceSpecificError()), + ErrorStatus::INVALID_ARGUMENT); + ASSERT_EQ(nullptr, execution); + return; + } else { + ASSERT_NE(nullptr, execution); + } + } + + // synchronous + { + SCOPED_TRACE(message + " [executeSynchronously]"); + ExecutionResult executionResult; + const auto executeStatus = execution->executeSynchronously(kNoDeadline, &executionResult); + ASSERT_FALSE(executeStatus.isOk()); + ASSERT_EQ(executeStatus.getExceptionCode(), EX_SERVICE_SPECIFIC); + ASSERT_EQ(static_cast<ErrorStatus>(executeStatus.getServiceSpecificError()), + ErrorStatus::INVALID_ARGUMENT); + } + + // fenced + { + SCOPED_TRACE(message + " [executeFenced]"); + FencedExecutionResult executionResult; + const auto executeStatus = + execution->executeFenced({}, kNoDeadline, kNoDuration, &executionResult); + ASSERT_FALSE(executeStatus.isOk()); + ASSERT_EQ(executeStatus.getExceptionCode(), EX_SERVICE_SPECIFIC); + ASSERT_EQ(static_cast<ErrorStatus>(executeStatus.getServiceSpecificError()), + ErrorStatus::INVALID_ARGUMENT); + } +} + // Primary validation function. This function will take a valid request, apply a // mutation to it to invalidate the request, then pass it to interface calls // that use the request. @@ -101,6 +146,14 @@ static void validate(const std::shared_ptr<IPreparedModel>& preparedModel, ASSERT_EQ(static_cast<ErrorStatus>(executeStatus.getServiceSpecificError()), ErrorStatus::INVALID_ARGUMENT); } + + int32_t aidlVersion; + ASSERT_TRUE(preparedModel->getInterfaceVersion(&aidlVersion).isOk()); + + // validate reusable execution + if (aidlVersion >= kMinAidlLevelForFL8) { + validateReusableExecution(preparedModel, message, request, measure); + } } std::shared_ptr<IBurst> createBurst(const std::shared_ptr<IPreparedModel>& preparedModel) { diff --git a/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.h b/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.h index 4312d3a4a1..a900590791 100644 --- a/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.h +++ b/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.h @@ -30,6 +30,8 @@ namespace aidl::android::hardware::neuralnetworks::vts::functional { using NamedDevice = Named<std::shared_ptr<IDevice>>; using NeuralNetworksAidlTestParam = NamedDevice; +constexpr int kMinAidlLevelForFL8 = 4; + class NeuralNetworksAidlTest : public testing::TestWithParam<NeuralNetworksAidlTestParam> { protected: void SetUp() override; diff --git a/neuralnetworks/utils/adapter/aidl/Android.bp b/neuralnetworks/utils/adapter/aidl/Android.bp new file mode 100644 index 0000000000..8269a3d4aa --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/Android.bp @@ -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. +// + +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: "neuralnetworks_utils_hal_adapter_aidl", + defaults: [ + "neuralnetworks_use_latest_utils_hal_aidl", + "neuralnetworks_utils_defaults", + ], + srcs: ["src/*"], + local_include_dirs: ["include/nnapi/hal/aidl/"], + export_include_dirs: ["include"], + static_libs: [ + "neuralnetworks_types", + "neuralnetworks_utils_hal_common", + ], + shared_libs: [ + "libbinder_ndk", + ], +} diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Adapter.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Adapter.h new file mode 100644 index 0000000000..4c0b3286de --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Adapter.h @@ -0,0 +1,73 @@ +/* + * 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. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_ADAPTER_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_ADAPTER_H + +#include <aidl/android/hardware/neuralnetworks/BnDevice.h> +#include <nnapi/IDevice.h> +#include <nnapi/Types.h> + +#include <functional> +#include <memory> + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface +// lifetimes across processes and for protecting asynchronous calls across AIDL. + +namespace aidl::android::hardware::neuralnetworks::adapter { + +/** + * A self-contained unit of work to be executed. + */ +using Task = std::function<void()>; + +/** + * A type-erased executor which executes a task asynchronously. + * + * This executor is also provided an optional deadline for when the caller expects is the upper + * bound for the amount of time to complete the task. If needed, the Executor can retrieve the + * Application ID (Android User ID) by calling AIBinder_getCallingUid in android/binder_ibinder.h. + */ +using Executor = std::function<void(Task, ::android::nn::OptionalTimePoint)>; + +/** + * Adapt an NNAPI canonical interface object to a AIDL NN HAL interface object. + * + * The IPreparedModel object created from IDevice::prepareModel or IDevice::preparedModelFromCache + * must return "const nn::Model*" from IPreparedModel::getUnderlyingResource(). + * + * @param device NNAPI canonical IDevice interface object to be adapted. + * @param executor Type-erased executor to handle executing tasks asynchronously. + * @return AIDL NN HAL IDevice interface object. + */ +std::shared_ptr<BnDevice> adapt(::android::nn::SharedDevice device, Executor executor); + +/** + * Adapt an NNAPI canonical interface object to a AIDL NN HAL interface object. + * + * The IPreparedModel object created from IDevice::prepareModel or IDevice::preparedModelFromCache + * must return "const nn::Model*" from IPreparedModel::getUnderlyingResource(). + * + * This function uses a default executor, which will execute tasks from a detached thread. + * + * @param device NNAPI canonical IDevice interface object to be adapted. + * @return AIDL NN HAL IDevice interface object. + */ +std::shared_ptr<BnDevice> adapt(::android::nn::SharedDevice device); + +} // namespace aidl::android::hardware::neuralnetworks::adapter + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_ADAPTER_H diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Buffer.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Buffer.h new file mode 100644 index 0000000000..701e43eb01 --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Buffer.h @@ -0,0 +1,47 @@ +/* + * 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. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BUFFER_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BUFFER_H + +#include <aidl/android/hardware/neuralnetworks/BnBuffer.h> +#include <aidl/android/hardware/neuralnetworks/Memory.h> +#include <android/binder_auto_utils.h> +#include <nnapi/IBuffer.h> + +#include <memory> +#include <vector> + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface +// lifetimes across processes and for protecting asynchronous calls across AIDL. + +namespace aidl::android::hardware::neuralnetworks::adapter { + +// Class that adapts nn::IBuffer to BnBuffer. +class Buffer : public BnBuffer { + public: + explicit Buffer(::android::nn::SharedBuffer buffer); + + ndk::ScopedAStatus copyFrom(const Memory& src, const std::vector<int32_t>& dimensions) override; + ndk::ScopedAStatus copyTo(const Memory& dst) override; + + private: + const ::android::nn::SharedBuffer kBuffer; +}; + +} // namespace aidl::android::hardware::neuralnetworks::adapter + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BUFFER_H diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Burst.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Burst.h new file mode 100644 index 0000000000..f2687c4a69 --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Burst.h @@ -0,0 +1,72 @@ +/* + * 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. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BURST_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BURST_H + +#include <aidl/android/hardware/neuralnetworks/BnBurst.h> +#include <aidl/android/hardware/neuralnetworks/ExecutionResult.h> +#include <aidl/android/hardware/neuralnetworks/Request.h> +#include <android-base/thread_annotations.h> +#include <android/binder_auto_utils.h> +#include <nnapi/IBurst.h> +#include <nnapi/Types.h> + +#include <memory> +#include <mutex> +#include <unordered_map> +#include <vector> + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface +// lifetimes across processes and for protecting asynchronous calls across AIDL. + +namespace aidl::android::hardware::neuralnetworks::adapter { + +// Class that adapts nn::Burst to BnBurst. +class Burst : public BnBurst { + public: + // Precondition: burst != nullptr + explicit Burst(::android::nn::SharedBurst burst); + + ndk::ScopedAStatus executeSynchronously(const Request& request, + const std::vector<int64_t>& memoryIdentifierTokens, + bool measureTiming, int64_t deadlineNs, + int64_t loopTimeoutDurationNs, + ExecutionResult* executionResult) override; + ndk::ScopedAStatus releaseMemoryResource(int64_t memoryIdentifierToken) override; + + class ThreadSafeMemoryCache { + public: + using Value = + std::pair<::android::nn::SharedMemory, ::android::nn::IBurst::OptionalCacheHold>; + + Value add(int64_t token, const ::android::nn::SharedMemory& memory, + const ::android::nn::IBurst& burst) const; + void remove(int64_t token) const; + + private: + mutable std::mutex mMutex; + mutable std::unordered_map<int64_t, Value> mCache GUARDED_BY(mMutex); + }; + + private: + const ::android::nn::SharedBurst kBurst; + const ThreadSafeMemoryCache kMemoryCache; +}; + +} // namespace aidl::android::hardware::neuralnetworks::adapter + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BURST_H diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Device.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Device.h new file mode 100644 index 0000000000..aa29d63b6b --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Device.h @@ -0,0 +1,83 @@ +/* + * 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. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_DEVICE_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_DEVICE_H + +#include "nnapi/hal/aidl/Adapter.h" + +#include <aidl/android/hardware/neuralnetworks/BnDevice.h> +#include <aidl/android/hardware/neuralnetworks/BufferDesc.h> +#include <aidl/android/hardware/neuralnetworks/BufferRole.h> +#include <aidl/android/hardware/neuralnetworks/Capabilities.h> +#include <aidl/android/hardware/neuralnetworks/DeviceBuffer.h> +#include <aidl/android/hardware/neuralnetworks/DeviceType.h> +#include <aidl/android/hardware/neuralnetworks/ExecutionPreference.h> +#include <aidl/android/hardware/neuralnetworks/Extension.h> +#include <aidl/android/hardware/neuralnetworks/IPreparedModelCallback.h> +#include <aidl/android/hardware/neuralnetworks/IPreparedModelParcel.h> +#include <aidl/android/hardware/neuralnetworks/Model.h> +#include <aidl/android/hardware/neuralnetworks/NumberOfCacheFiles.h> +#include <aidl/android/hardware/neuralnetworks/Priority.h> +#include <android/binder_auto_utils.h> +#include <nnapi/IDevice.h> + +#include <memory> +#include <string> +#include <vector> + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface +// lifetimes across processes and for protecting asynchronous calls across AIDL. + +namespace aidl::android::hardware::neuralnetworks::adapter { + +// Class that adapts nn::IDevice to BnDevice. +class Device : public BnDevice { + public: + Device(::android::nn::SharedDevice device, Executor executor); + + ndk::ScopedAStatus allocate(const BufferDesc& desc, + const std::vector<IPreparedModelParcel>& preparedModels, + const std::vector<BufferRole>& inputRoles, + const std::vector<BufferRole>& outputRoles, + DeviceBuffer* buffer) override; + ndk::ScopedAStatus getCapabilities(Capabilities* capabilities) override; + ndk::ScopedAStatus getNumberOfCacheFilesNeeded(NumberOfCacheFiles* numberOfCacheFiles) override; + ndk::ScopedAStatus getSupportedExtensions(std::vector<Extension>* extensions) override; + ndk::ScopedAStatus getSupportedOperations(const Model& model, + std::vector<bool>* supported) override; + ndk::ScopedAStatus getType(DeviceType* deviceType) override; + ndk::ScopedAStatus getVersionString(std::string* version) override; + ndk::ScopedAStatus prepareModel( + const Model& model, ExecutionPreference preference, Priority priority, + int64_t deadlineNs, const std::vector<ndk::ScopedFileDescriptor>& modelCache, + const std::vector<ndk::ScopedFileDescriptor>& dataCache, + const std::vector<uint8_t>& token, + const std::shared_ptr<IPreparedModelCallback>& callback) override; + ndk::ScopedAStatus prepareModelFromCache( + int64_t deadlineNs, const std::vector<ndk::ScopedFileDescriptor>& modelCache, + const std::vector<ndk::ScopedFileDescriptor>& dataCache, + const std::vector<uint8_t>& token, + const std::shared_ptr<IPreparedModelCallback>& callback) override; + + protected: + const ::android::nn::SharedDevice kDevice; + const Executor kExecutor; +}; + +} // namespace aidl::android::hardware::neuralnetworks::adapter + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_DEVICE_H diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Execution.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Execution.h new file mode 100644 index 0000000000..6a9ac57fbe --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Execution.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_EXECUTION_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_EXECUTION_H + +#include "nnapi/hal/aidl/Adapter.h" + +#include <aidl/android/hardware/neuralnetworks/BnExecution.h> +#include <aidl/android/hardware/neuralnetworks/ExecutionResult.h> +#include <aidl/android/hardware/neuralnetworks/FencedExecutionResult.h> +#include <aidl/android/hardware/neuralnetworks/IExecution.h> +#include <aidl/android/hardware/neuralnetworks/Request.h> +#include <android/binder_auto_utils.h> +#include <nnapi/IExecution.h> +#include <nnapi/Types.h> + +#include <memory> +#include <vector> + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface +// lifetimes across processes and for protecting asynchronous calls across AIDL. + +namespace aidl::android::hardware::neuralnetworks::adapter { + +// Class that adapts nn::IExecution to BnExecution. +class Execution : public BnExecution { + public: + explicit Execution(::android::nn::SharedExecution execution); + + ndk::ScopedAStatus executeSynchronously(int64_t deadlineNs, + ExecutionResult* executionResult) override; + ndk::ScopedAStatus executeFenced(const std::vector<ndk::ScopedFileDescriptor>& waitFor, + int64_t deadlineNs, int64_t durationNs, + FencedExecutionResult* fencedExecutionResult) override; + + protected: + const ::android::nn::SharedExecution kExecution; +}; + +} // namespace aidl::android::hardware::neuralnetworks::adapter + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_EXECUTION_H diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/PreparedModel.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/PreparedModel.h new file mode 100644 index 0000000000..f92b0bc783 --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/PreparedModel.h @@ -0,0 +1,66 @@ +/* + * 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. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_PREPARED_MDOEL_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_PREPARED_MDOEL_H + +#include "nnapi/hal/aidl/Adapter.h" + +#include <aidl/android/hardware/neuralnetworks/BnPreparedModel.h> +#include <aidl/android/hardware/neuralnetworks/ExecutionResult.h> +#include <aidl/android/hardware/neuralnetworks/FencedExecutionResult.h> +#include <aidl/android/hardware/neuralnetworks/IBurst.h> +#include <aidl/android/hardware/neuralnetworks/IExecution.h> +#include <aidl/android/hardware/neuralnetworks/Request.h> +#include <android/binder_auto_utils.h> +#include <nnapi/IPreparedModel.h> +#include <nnapi/Types.h> + +#include <memory> +#include <vector> + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface +// lifetimes across processes and for protecting asynchronous calls across AIDL. + +namespace aidl::android::hardware::neuralnetworks::adapter { + +// Class that adapts nn::IPreparedModel to BnPreparedModel. +class PreparedModel : public BnPreparedModel { + public: + explicit PreparedModel(::android::nn::SharedPreparedModel preparedModel); + + ndk::ScopedAStatus executeSynchronously(const Request& request, bool measureTiming, + int64_t deadlineNs, int64_t loopTimeoutDurationNs, + ExecutionResult* executionResult) override; + ndk::ScopedAStatus executeFenced(const Request& request, + const std::vector<ndk::ScopedFileDescriptor>& waitFor, + bool measureTiming, int64_t deadlineNs, + int64_t loopTimeoutDurationNs, int64_t durationNs, + FencedExecutionResult* executionResult) override; + ndk::ScopedAStatus configureExecutionBurst(std::shared_ptr<IBurst>* burst) override; + ndk::ScopedAStatus createReusableExecution(const Request& request, bool measureTiming, + int64_t loopTimeoutDurationNs, + std::shared_ptr<IExecution>* execution) override; + + ::android::nn::SharedPreparedModel getUnderlyingPreparedModel() const; + + protected: + const ::android::nn::SharedPreparedModel kPreparedModel; +}; + +} // namespace aidl::android::hardware::neuralnetworks::adapter + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_PREPARED_MDOEL_H diff --git a/neuralnetworks/utils/adapter/aidl/src/Adapter.cpp b/neuralnetworks/utils/adapter/aidl/src/Adapter.cpp new file mode 100644 index 0000000000..d0b56e89cc --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/src/Adapter.cpp @@ -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. + */ + +#include "Adapter.h" + +#include "Device.h" + +#include <aidl/android/hardware/neuralnetworks/BnDevice.h> +#include <android/binder_interface_utils.h> +#include <nnapi/IDevice.h> +#include <nnapi/Types.h> + +#include <functional> +#include <memory> +#include <thread> + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface +// lifetimes across processes and for protecting asynchronous calls across AIDL. + +namespace aidl::android::hardware::neuralnetworks::adapter { + +std::shared_ptr<BnDevice> adapt(::android::nn::SharedDevice device, Executor executor) { + return ndk::SharedRefBase::make<Device>(std::move(device), std::move(executor)); +} + +std::shared_ptr<BnDevice> adapt(::android::nn::SharedDevice device) { + Executor defaultExecutor = [](Task task, ::android::nn::OptionalTimePoint /*deadline*/) { + std::thread(std::move(task)).detach(); + }; + return adapt(std::move(device), std::move(defaultExecutor)); +} + +} // namespace aidl::android::hardware::neuralnetworks::adapter diff --git a/neuralnetworks/utils/adapter/aidl/src/Buffer.cpp b/neuralnetworks/utils/adapter/aidl/src/Buffer.cpp new file mode 100644 index 0000000000..c15ab659c5 --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/src/Buffer.cpp @@ -0,0 +1,88 @@ +/* + * 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 "Buffer.h" + +#include <aidl/android/hardware/neuralnetworks/BnBuffer.h> +#include <aidl/android/hardware/neuralnetworks/Memory.h> +#include <android-base/logging.h> +#include <android/binder_auto_utils.h> +#include <nnapi/IBuffer.h> +#include <nnapi/Result.h> +#include <nnapi/Types.h> +#include <nnapi/hal/aidl/Conversions.h> + +namespace aidl::android::hardware::neuralnetworks::adapter { +namespace { + +template <typename Type> +auto convertInput(const Type& object) -> decltype(nn::convert(std::declval<Type>())) { + auto result = nn::convert(object); + if (!result.has_value()) { + result.error().code = nn::ErrorStatus::INVALID_ARGUMENT; + } + return result; +} + +nn::GeneralResult<std::vector<uint32_t>> inputToUnsigned(const std::vector<int32_t>& dims) { + auto result = nn::toUnsigned(dims); + if (!result.has_value()) { + result.error().code = nn::ErrorStatus::INVALID_ARGUMENT; + } + return result; +} + +nn::GeneralResult<void> copyTo(const nn::IBuffer& buffer, const Memory& dst) { + const auto nnDst = NN_TRY(convertInput(dst)); + return buffer.copyTo(nnDst); +} + +nn::GeneralResult<void> copyFrom(const nn::IBuffer& buffer, const Memory& src, + const std::vector<int32_t>& dimensions) { + const auto nnSrc = NN_TRY(convertInput(src)); + const auto nnDims = NN_TRY(inputToUnsigned(dimensions)); + return buffer.copyFrom(nnSrc, nnDims); +} + +} // namespace + +Buffer::Buffer(nn::SharedBuffer buffer) : kBuffer(std::move(buffer)) { + CHECK(kBuffer != nullptr); +} + +ndk::ScopedAStatus Buffer::copyTo(const Memory& dst) { + const auto result = adapter::copyTo(*kBuffer, dst); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast<int32_t>(aidlCode), message.c_str()); + } + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Buffer::copyFrom(const Memory& src, const std::vector<int32_t>& dimensions) { + const auto result = adapter::copyFrom(*kBuffer, src, dimensions); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast<int32_t>(aidlCode), message.c_str()); + } + return ndk::ScopedAStatus::ok(); +} + +} // namespace aidl::android::hardware::neuralnetworks::adapter diff --git a/neuralnetworks/utils/adapter/aidl/src/Burst.cpp b/neuralnetworks/utils/adapter/aidl/src/Burst.cpp new file mode 100644 index 0000000000..4fabb20635 --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/src/Burst.cpp @@ -0,0 +1,179 @@ +/* + * 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 "Burst.h" + +#include <android-base/logging.h> +#include <android-base/thread_annotations.h> +#include <android/binder_auto_utils.h> +#include <nnapi/IBurst.h> +#include <nnapi/Result.h> +#include <nnapi/Types.h> +#include <nnapi/Validation.h> +#include <nnapi/hal/aidl/Conversions.h> +#include <nnapi/hal/aidl/Utils.h> + +#include <algorithm> +#include <chrono> +#include <memory> +#include <mutex> +#include <unordered_map> +#include <utility> +#include <variant> + +namespace aidl::android::hardware::neuralnetworks::adapter { +namespace { + +using Value = Burst::ThreadSafeMemoryCache::Value; + +template <typename Type> +auto convertInput(const Type& object) -> decltype(nn::convert(std::declval<Type>())) { + auto result = nn::convert(object); + if (!result.has_value()) { + result.error().code = nn::ErrorStatus::INVALID_ARGUMENT; + } + return result; +} + +nn::Duration makeDuration(int64_t durationNs) { + return nn::Duration(std::chrono::nanoseconds(durationNs)); +} + +nn::GeneralResult<nn::OptionalDuration> makeOptionalDuration(int64_t durationNs) { + if (durationNs < -1) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid duration " << durationNs; + } + return durationNs < 0 ? nn::OptionalDuration{} : makeDuration(durationNs); +} + +nn::GeneralResult<nn::OptionalTimePoint> makeOptionalTimePoint(int64_t durationNs) { + if (durationNs < -1) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid time point " << durationNs; + } + return durationNs < 0 ? nn::OptionalTimePoint{} : nn::TimePoint(makeDuration(durationNs)); +} + +std::vector<nn::IBurst::OptionalCacheHold> ensureAllMemoriesAreCached( + nn::Request* request, const std::vector<int64_t>& memoryIdentifierTokens, + const nn::IBurst& burst, const Burst::ThreadSafeMemoryCache& cache) { + std::vector<nn::IBurst::OptionalCacheHold> holds; + holds.reserve(memoryIdentifierTokens.size()); + + for (size_t i = 0; i < memoryIdentifierTokens.size(); ++i) { + const auto& pool = request->pools[i]; + const auto token = memoryIdentifierTokens[i]; + constexpr int64_t kNoToken = -1; + if (token == kNoToken || !std::holds_alternative<nn::SharedMemory>(pool)) { + continue; + } + + const auto& memory = std::get<nn::SharedMemory>(pool); + auto [storedMemory, hold] = cache.add(token, memory, burst); + + request->pools[i] = std::move(storedMemory); + holds.push_back(std::move(hold)); + } + + return holds; +} + +nn::ExecutionResult<ExecutionResult> executeSynchronously( + const nn::IBurst& burst, const Burst::ThreadSafeMemoryCache& cache, const Request& request, + const std::vector<int64_t>& memoryIdentifierTokens, bool measureTiming, int64_t deadlineNs, + int64_t loopTimeoutDurationNs) { + if (request.pools.size() != memoryIdentifierTokens.size()) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "request.pools.size() != memoryIdentifierTokens.size()"; + } + if (!std::all_of(memoryIdentifierTokens.begin(), memoryIdentifierTokens.end(), + [](int64_t token) { return token >= -1; })) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid memoryIdentifierTokens"; + } + + auto nnRequest = NN_TRY(convertInput(request)); + const auto nnMeasureTiming = measureTiming ? nn::MeasureTiming::YES : nn::MeasureTiming::NO; + const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs)); + const auto nnLoopTimeoutDuration = NN_TRY(makeOptionalDuration(loopTimeoutDurationNs)); + + const auto hold = ensureAllMemoriesAreCached(&nnRequest, memoryIdentifierTokens, burst, cache); + + const auto result = + burst.execute(nnRequest, nnMeasureTiming, nnDeadline, nnLoopTimeoutDuration); + + if (!result.ok() && result.error().code == nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE) { + const auto& [message, code, outputShapes] = result.error(); + return ExecutionResult{.outputSufficientSize = false, + .outputShapes = utils::convert(outputShapes).value(), + .timing = {.timeInDriverNs = -1, .timeOnDeviceNs = -1}}; + } + + const auto& [outputShapes, timing] = NN_TRY(result); + return ExecutionResult{.outputSufficientSize = true, + .outputShapes = utils::convert(outputShapes).value(), + .timing = utils::convert(timing).value()}; +} + +} // namespace + +Value Burst::ThreadSafeMemoryCache::add(int64_t token, const nn::SharedMemory& memory, + const nn::IBurst& burst) const { + std::lock_guard guard(mMutex); + if (const auto it = mCache.find(token); it != mCache.end()) { + return it->second; + } + auto hold = burst.cacheMemory(memory); + auto [it, _] = mCache.emplace(token, std::make_pair(memory, std::move(hold))); + return it->second; +} + +void Burst::ThreadSafeMemoryCache::remove(int64_t token) const { + std::lock_guard guard(mMutex); + mCache.erase(token); +} + +Burst::Burst(nn::SharedBurst burst) : kBurst(std::move(burst)) { + CHECK(kBurst != nullptr); +} + +ndk::ScopedAStatus Burst::executeSynchronously(const Request& request, + const std::vector<int64_t>& memoryIdentifierTokens, + bool measureTiming, int64_t deadlineNs, + int64_t loopTimeoutDurationNs, + ExecutionResult* executionResult) { + auto result = + adapter::executeSynchronously(*kBurst, kMemoryCache, request, memoryIdentifierTokens, + measureTiming, deadlineNs, loopTimeoutDurationNs); + if (!result.has_value()) { + auto [message, code, _] = std::move(result).error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast<int32_t>(aidlCode), message.c_str()); + } + *executionResult = std::move(result).value(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Burst::releaseMemoryResource(int64_t memoryIdentifierToken) { + if (memoryIdentifierToken < -1) { + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast<int32_t>(ErrorStatus::INVALID_ARGUMENT), + "Invalid memoryIdentifierToken"); + } + kMemoryCache.remove(memoryIdentifierToken); + return ndk::ScopedAStatus::ok(); +} + +} // namespace aidl::android::hardware::neuralnetworks::adapter diff --git a/neuralnetworks/utils/adapter/aidl/src/Device.cpp b/neuralnetworks/utils/adapter/aidl/src/Device.cpp new file mode 100644 index 0000000000..763be7f3fa --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/src/Device.cpp @@ -0,0 +1,304 @@ +/* + * 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 "Device.h" + +#include "Adapter.h" +#include "Buffer.h" +#include "PreparedModel.h" + +#include <aidl/android/hardware/neuralnetworks/BnDevice.h> +#include <aidl/android/hardware/neuralnetworks/BufferDesc.h> +#include <aidl/android/hardware/neuralnetworks/BufferRole.h> +#include <aidl/android/hardware/neuralnetworks/DeviceBuffer.h> +#include <aidl/android/hardware/neuralnetworks/DeviceType.h> +#include <aidl/android/hardware/neuralnetworks/ErrorStatus.h> +#include <aidl/android/hardware/neuralnetworks/ExecutionPreference.h> +#include <aidl/android/hardware/neuralnetworks/Extension.h> +#include <aidl/android/hardware/neuralnetworks/IPreparedModelCallback.h> +#include <aidl/android/hardware/neuralnetworks/IPreparedModelParcel.h> +#include <aidl/android/hardware/neuralnetworks/Model.h> +#include <aidl/android/hardware/neuralnetworks/NumberOfCacheFiles.h> +#include <aidl/android/hardware/neuralnetworks/Priority.h> +#include <android-base/logging.h> +#include <android/binder_auto_utils.h> +#include <android/binder_interface_utils.h> +#include <nnapi/IDevice.h> +#include <nnapi/Result.h> +#include <nnapi/TypeUtils.h> +#include <nnapi/Types.h> +#include <nnapi/hal/aidl/Conversions.h> + +#include <chrono> +#include <memory> +#include <string> +#include <vector> + +namespace aidl::android::hardware::neuralnetworks::adapter { +namespace { + +template <typename Type> +auto convertInput(const Type& object) -> decltype(nn::convert(std::declval<Type>())) { + auto result = nn::convert(object); + if (!result.has_value()) { + result.error().code = nn::ErrorStatus::INVALID_ARGUMENT; + } + return result; +} + +nn::Duration makeDuration(int64_t durationNs) { + return nn::Duration(std::chrono::nanoseconds(durationNs)); +} + +nn::GeneralResult<nn::OptionalTimePoint> makeOptionalTimePoint(int64_t durationNs) { + if (durationNs < -1) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid time point " << durationNs; + } + return durationNs < 0 ? nn::OptionalTimePoint{} : nn::TimePoint(makeDuration(durationNs)); +} + +nn::GeneralResult<nn::CacheToken> convertCacheToken(const std::vector<uint8_t>& token) { + nn::CacheToken nnToken; + if (token.size() != nnToken.size()) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid token"; + } + std::copy(token.begin(), token.end(), nnToken.begin()); + return nnToken; +} + +nn::GeneralResult<nn::SharedPreparedModel> downcast(const IPreparedModelParcel& preparedModel) { + if (preparedModel.preparedModel == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "preparedModel is nullptr"; + } + if (preparedModel.preparedModel->isRemote()) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Cannot convert remote models"; + } + + // This static_cast is safe because adapter::PreparedModel is the only class that implements + // the IPreparedModel interface in the adapter service code. + const auto* casted = static_cast<const PreparedModel*>(preparedModel.preparedModel.get()); + return casted->getUnderlyingPreparedModel(); +} + +nn::GeneralResult<std::vector<nn::SharedPreparedModel>> downcastAll( + const std::vector<IPreparedModelParcel>& preparedModels) { + std::vector<nn::SharedPreparedModel> canonical; + canonical.reserve(preparedModels.size()); + for (const auto& preparedModel : preparedModels) { + canonical.push_back(NN_TRY(downcast(preparedModel))); + } + return canonical; +} + +nn::GeneralResult<DeviceBuffer> allocate(const nn::IDevice& device, const BufferDesc& desc, + const std::vector<IPreparedModelParcel>& preparedModels, + const std::vector<BufferRole>& inputRoles, + const std::vector<BufferRole>& outputRoles) { + auto nnDesc = NN_TRY(convertInput(desc)); + auto nnPreparedModels = NN_TRY(downcastAll(preparedModels)); + auto nnInputRoles = NN_TRY(convertInput(inputRoles)); + auto nnOutputRoles = NN_TRY(convertInput(outputRoles)); + + auto buffer = NN_TRY(device.allocate(nnDesc, nnPreparedModels, nnInputRoles, nnOutputRoles)); + CHECK(buffer != nullptr); + + const nn::Request::MemoryDomainToken token = buffer->getToken(); + auto aidlBuffer = ndk::SharedRefBase::make<Buffer>(std::move(buffer)); + return DeviceBuffer{.buffer = std::move(aidlBuffer), .token = static_cast<int32_t>(token)}; +} + +nn::GeneralResult<std::vector<bool>> getSupportedOperations(const nn::IDevice& device, + const Model& model) { + const auto nnModel = NN_TRY(convertInput(model)); + return device.getSupportedOperations(nnModel); +} + +using PrepareModelResult = nn::GeneralResult<nn::SharedPreparedModel>; + +std::shared_ptr<PreparedModel> adaptPreparedModel(nn::SharedPreparedModel preparedModel) { + if (preparedModel == nullptr) { + return nullptr; + } + return ndk::SharedRefBase::make<PreparedModel>(std::move(preparedModel)); +} + +void notify(IPreparedModelCallback* callback, PrepareModelResult result) { + if (!result.has_value()) { + const auto& [message, status] = result.error(); + LOG(ERROR) << message; + const auto aidlCode = utils::convert(status).value_or(ErrorStatus::GENERAL_FAILURE); + callback->notify(aidlCode, nullptr); + } else { + auto preparedModel = std::move(result).value(); + auto aidlPreparedModel = adaptPreparedModel(std::move(preparedModel)); + callback->notify(ErrorStatus::NONE, std::move(aidlPreparedModel)); + } +} + +nn::GeneralResult<void> prepareModel(const nn::SharedDevice& device, const Executor& executor, + const Model& model, ExecutionPreference preference, + Priority priority, int64_t deadlineNs, + const std::vector<ndk::ScopedFileDescriptor>& modelCache, + const std::vector<ndk::ScopedFileDescriptor>& dataCache, + const std::vector<uint8_t>& token, + const std::shared_ptr<IPreparedModelCallback>& callback) { + if (callback.get() == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback"; + } + + auto nnModel = NN_TRY(convertInput(model)); + const auto nnPreference = NN_TRY(convertInput(preference)); + const auto nnPriority = NN_TRY(convertInput(priority)); + const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs)); + auto nnModelCache = NN_TRY(convertInput(modelCache)); + auto nnDataCache = NN_TRY(convertInput(dataCache)); + const auto nnToken = NN_TRY(convertCacheToken(token)); + + Task task = [device, nnModel = std::move(nnModel), nnPreference, nnPriority, nnDeadline, + nnModelCache = std::move(nnModelCache), nnDataCache = std::move(nnDataCache), + nnToken, callback] { + auto result = device->prepareModel(nnModel, nnPreference, nnPriority, nnDeadline, + nnModelCache, nnDataCache, nnToken); + notify(callback.get(), std::move(result)); + }; + executor(std::move(task), nnDeadline); + + return {}; +} + +nn::GeneralResult<void> prepareModelFromCache( + const nn::SharedDevice& device, const Executor& executor, int64_t deadlineNs, + const std::vector<ndk::ScopedFileDescriptor>& modelCache, + const std::vector<ndk::ScopedFileDescriptor>& dataCache, const std::vector<uint8_t>& token, + const std::shared_ptr<IPreparedModelCallback>& callback) { + if (callback.get() == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback"; + } + + const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs)); + auto nnModelCache = NN_TRY(convertInput(modelCache)); + auto nnDataCache = NN_TRY(convertInput(dataCache)); + const auto nnToken = NN_TRY(convertCacheToken(token)); + + auto task = [device, nnDeadline, nnModelCache = std::move(nnModelCache), + nnDataCache = std::move(nnDataCache), nnToken, callback] { + auto result = device->prepareModelFromCache(nnDeadline, nnModelCache, nnDataCache, nnToken); + notify(callback.get(), std::move(result)); + }; + executor(std::move(task), nnDeadline); + + return {}; +} + +} // namespace + +Device::Device(::android::nn::SharedDevice device, Executor executor) + : kDevice(std::move(device)), kExecutor(std::move(executor)) { + CHECK(kDevice != nullptr); + CHECK(kExecutor != nullptr); +} + +ndk::ScopedAStatus Device::allocate(const BufferDesc& desc, + const std::vector<IPreparedModelParcel>& preparedModels, + const std::vector<BufferRole>& inputRoles, + const std::vector<BufferRole>& outputRoles, + DeviceBuffer* buffer) { + auto result = adapter::allocate(*kDevice, desc, preparedModels, inputRoles, outputRoles); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast<int32_t>(aidlCode), message.c_str()); + } + *buffer = std::move(result).value(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Device::getCapabilities(Capabilities* capabilities) { + *capabilities = utils::convert(kDevice->getCapabilities()).value(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Device::getNumberOfCacheFilesNeeded(NumberOfCacheFiles* numberOfCacheFiles) { + const auto [numModelCache, numDataCache] = kDevice->getNumberOfCacheFilesNeeded(); + *numberOfCacheFiles = NumberOfCacheFiles{.numModelCache = static_cast<int32_t>(numModelCache), + .numDataCache = static_cast<int32_t>(numDataCache)}; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Device::getSupportedExtensions(std::vector<Extension>* extensions) { + *extensions = utils::convert(kDevice->getSupportedExtensions()).value(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Device::getSupportedOperations(const Model& model, + std::vector<bool>* supported) { + auto result = adapter::getSupportedOperations(*kDevice, model); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast<int32_t>(aidlCode), message.c_str()); + } + *supported = std::move(result).value(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Device::getType(DeviceType* deviceType) { + *deviceType = utils::convert(kDevice->getType()).value(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Device::getVersionString(std::string* version) { + *version = kDevice->getVersionString(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Device::prepareModel(const Model& model, ExecutionPreference preference, + Priority priority, int64_t deadlineNs, + const std::vector<ndk::ScopedFileDescriptor>& modelCache, + const std::vector<ndk::ScopedFileDescriptor>& dataCache, + const std::vector<uint8_t>& token, + const std::shared_ptr<IPreparedModelCallback>& callback) { + const auto result = adapter::prepareModel(kDevice, kExecutor, model, preference, priority, + deadlineNs, modelCache, dataCache, token, callback); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + callback->notify(aidlCode, nullptr); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast<int32_t>(aidlCode), message.c_str()); + } + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Device::prepareModelFromCache( + int64_t deadlineNs, const std::vector<ndk::ScopedFileDescriptor>& modelCache, + const std::vector<ndk::ScopedFileDescriptor>& dataCache, const std::vector<uint8_t>& token, + const std::shared_ptr<IPreparedModelCallback>& callback) { + const auto result = adapter::prepareModelFromCache(kDevice, kExecutor, deadlineNs, modelCache, + dataCache, token, callback); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + callback->notify(aidlCode, nullptr); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast<int32_t>(aidlCode), message.c_str()); + } + return ndk::ScopedAStatus::ok(); +} + +} // namespace aidl::android::hardware::neuralnetworks::adapter diff --git a/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp b/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp new file mode 100644 index 0000000000..5cab62c625 --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp @@ -0,0 +1,324 @@ +/* + * 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 "PreparedModel.h" + +#include "Burst.h" +#include "Execution.h" + +#include <aidl/android/hardware/neuralnetworks/BnFencedExecutionCallback.h> +#include <aidl/android/hardware/neuralnetworks/BnPreparedModel.h> +#include <aidl/android/hardware/neuralnetworks/ExecutionResult.h> +#include <aidl/android/hardware/neuralnetworks/FencedExecutionResult.h> +#include <aidl/android/hardware/neuralnetworks/IBurst.h> +#include <aidl/android/hardware/neuralnetworks/Request.h> +#include <android-base/logging.h> +#include <android/binder_auto_utils.h> +#include <nnapi/IExecution.h> +#include <nnapi/IPreparedModel.h> +#include <nnapi/Result.h> +#include <nnapi/SharedMemory.h> +#include <nnapi/Types.h> +#include <nnapi/Validation.h> +#include <nnapi/hal/aidl/Conversions.h> +#include <nnapi/hal/aidl/Utils.h> + +#include <memory> +#include <utility> +#include <vector> + +namespace aidl::android::hardware::neuralnetworks::adapter { +namespace { + +class FencedExecutionCallback : public BnFencedExecutionCallback { + public: + FencedExecutionCallback(nn::ExecuteFencedInfoCallback callback) + : kCallback(std::move(callback)) {} + + ndk::ScopedAStatus getExecutionInfo(Timing* timingLaunched, Timing* timingFenced, + ErrorStatus* errorStatus) override { + const auto result = kCallback(); + if (result.ok()) { + const auto& [nnTimingLaunched, nnTimingFenced] = result.value(); + *timingLaunched = utils::convert(nnTimingLaunched).value(); + *timingFenced = utils::convert(nnTimingFenced).value(); + *errorStatus = ErrorStatus::NONE; + } else { + constexpr auto kNoTiming = Timing{.timeOnDeviceNs = -1, .timeInDriverNs = -1}; + const auto& [message, code] = result.error(); + LOG(ERROR) << "getExecutionInfo failed with " << code << ": " << message; + const auto aidlStatus = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + *timingLaunched = kNoTiming; + *timingFenced = kNoTiming; + *errorStatus = aidlStatus; + } + return ndk::ScopedAStatus::ok(); + } + + private: + const nn::ExecuteFencedInfoCallback kCallback; +}; + +template <typename Type> +auto convertInput(const Type& object) -> decltype(nn::convert(std::declval<Type>())) { + auto result = nn::convert(object); + if (!result.has_value()) { + result.error().code = nn::ErrorStatus::INVALID_ARGUMENT; + } + return result; +} + +nn::GeneralResult<std::vector<nn::SyncFence>> convertSyncFences( + const std::vector<ndk::ScopedFileDescriptor>& waitFor) { + auto handles = NN_TRY(convertInput(waitFor)); + + constexpr auto valid = [](const nn::SharedHandle& handle) { + return handle != nullptr && handle->ok(); + }; + if (!std::all_of(handles.begin(), handles.end(), valid)) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid sync fence"; + } + + std::vector<nn::SyncFence> syncFences; + syncFences.reserve(waitFor.size()); + for (auto& handle : handles) { + syncFences.push_back(nn::SyncFence::create(std::move(handle)).value()); + } + return syncFences; +} + +nn::Duration makeDuration(int64_t durationNs) { + return nn::Duration(std::chrono::nanoseconds(durationNs)); +} + +nn::GeneralResult<nn::OptionalDuration> makeOptionalDuration(int64_t durationNs) { + if (durationNs < -1) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid duration " << durationNs; + } + return durationNs < 0 ? nn::OptionalDuration{} : makeDuration(durationNs); +} + +nn::GeneralResult<nn::OptionalTimePoint> makeOptionalTimePoint(int64_t durationNs) { + if (durationNs < -1) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid time point " << durationNs; + } + return durationNs < 0 ? nn::OptionalTimePoint{} : nn::TimePoint(makeDuration(durationNs)); +} + +nn::ExecutionResult<ExecutionResult> executeSynchronously(const nn::IPreparedModel& preparedModel, + const Request& request, + bool measureTiming, int64_t deadlineNs, + int64_t loopTimeoutDurationNs) { + const auto nnRequest = NN_TRY(convertInput(request)); + const auto nnMeasureTiming = measureTiming ? nn::MeasureTiming::YES : nn::MeasureTiming::NO; + const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs)); + const auto nnLoopTimeoutDuration = NN_TRY(makeOptionalDuration(loopTimeoutDurationNs)); + + const auto result = + preparedModel.execute(nnRequest, nnMeasureTiming, nnDeadline, nnLoopTimeoutDuration); + + if (!result.ok() && result.error().code == nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE) { + const auto& [message, code, outputShapes] = result.error(); + LOG(ERROR) << "executeSynchronously failed with " << code << ": " << message; + return ExecutionResult{.outputSufficientSize = false, + .outputShapes = utils::convert(outputShapes).value(), + .timing = {.timeInDriverNs = -1, .timeOnDeviceNs = -1}}; + } + + const auto& [outputShapes, timing] = NN_TRY(result); + return ExecutionResult{.outputSufficientSize = true, + .outputShapes = utils::convert(outputShapes).value(), + .timing = utils::convert(timing).value()}; +} + +nn::GeneralResult<FencedExecutionResult> executeFenced( + const nn::IPreparedModel& preparedModel, const Request& request, + const std::vector<ndk::ScopedFileDescriptor>& waitFor, bool measureTiming, + int64_t deadlineNs, int64_t loopTimeoutDurationNs, int64_t durationNs) { + const auto nnRequest = NN_TRY(convertInput(request)); + const auto nnWaitFor = NN_TRY(convertSyncFences(waitFor)); + const auto nnMeasureTiming = measureTiming ? nn::MeasureTiming::YES : nn::MeasureTiming::NO; + const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs)); + const auto nnLoopTimeoutDuration = NN_TRY(makeOptionalDuration(loopTimeoutDurationNs)); + const auto nnDuration = NN_TRY(makeOptionalDuration(durationNs)); + + auto [syncFence, executeFencedInfoCallback] = NN_TRY(preparedModel.executeFenced( + nnRequest, nnWaitFor, nnMeasureTiming, nnDeadline, nnLoopTimeoutDuration, nnDuration)); + + ndk::ScopedFileDescriptor fileDescriptor; + if (syncFence.hasFd()) { + auto uniqueFd = NN_TRY(nn::dupFd(syncFence.getFd())); + fileDescriptor = ndk::ScopedFileDescriptor(uniqueFd.release()); + } + + return FencedExecutionResult{.callback = ndk::SharedRefBase::make<FencedExecutionCallback>( + std::move(executeFencedInfoCallback)), + .syncFence = std::move(fileDescriptor)}; +} + +nn::GeneralResult<nn::SharedExecution> createReusableExecution( + const nn::IPreparedModel& preparedModel, const Request& request, bool measureTiming, + int64_t loopTimeoutDurationNs) { + const auto nnRequest = NN_TRY(convertInput(request)); + const auto nnMeasureTiming = measureTiming ? nn::MeasureTiming::YES : nn::MeasureTiming::NO; + const auto nnLoopTimeoutDuration = NN_TRY(makeOptionalDuration(loopTimeoutDurationNs)); + return preparedModel.createReusableExecution(nnRequest, nnMeasureTiming, nnLoopTimeoutDuration); +} + +nn::ExecutionResult<ExecutionResult> executeSynchronously(const nn::IExecution& execution, + int64_t deadlineNs) { + const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs)); + + const auto result = execution.compute(nnDeadline); + + if (!result.ok() && result.error().code == nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE) { + const auto& [message, code, outputShapes] = result.error(); + LOG(ERROR) << "executeSynchronously failed with " << code << ": " << message; + return ExecutionResult{.outputSufficientSize = false, + .outputShapes = utils::convert(outputShapes).value(), + .timing = {.timeInDriverNs = -1, .timeOnDeviceNs = -1}}; + } + + const auto& [outputShapes, timing] = NN_TRY(result); + return ExecutionResult{.outputSufficientSize = true, + .outputShapes = utils::convert(outputShapes).value(), + .timing = utils::convert(timing).value()}; +} + +nn::GeneralResult<FencedExecutionResult> executeFenced( + const nn::IExecution& execution, const std::vector<ndk::ScopedFileDescriptor>& waitFor, + int64_t deadlineNs, int64_t durationNs) { + const auto nnWaitFor = NN_TRY(convertSyncFences(waitFor)); + const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs)); + const auto nnDuration = NN_TRY(makeOptionalDuration(durationNs)); + + auto [syncFence, executeFencedInfoCallback] = + NN_TRY(execution.computeFenced(nnWaitFor, nnDeadline, nnDuration)); + + ndk::ScopedFileDescriptor fileDescriptor; + if (syncFence.hasFd()) { + auto uniqueFd = NN_TRY(nn::dupFd(syncFence.getFd())); + fileDescriptor = ndk::ScopedFileDescriptor(uniqueFd.release()); + } + + return FencedExecutionResult{.callback = ndk::SharedRefBase::make<FencedExecutionCallback>( + std::move(executeFencedInfoCallback)), + .syncFence = std::move(fileDescriptor)}; +} + +} // namespace + +PreparedModel::PreparedModel(nn::SharedPreparedModel preparedModel) + : kPreparedModel(std::move(preparedModel)) { + CHECK(kPreparedModel != nullptr); +} + +ndk::ScopedAStatus PreparedModel::executeSynchronously(const Request& request, bool measureTiming, + int64_t deadlineNs, + int64_t loopTimeoutDurationNs, + ExecutionResult* executionResult) { + auto result = adapter::executeSynchronously(*kPreparedModel, request, measureTiming, deadlineNs, + loopTimeoutDurationNs); + if (!result.has_value()) { + const auto& [message, code, _] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast<int32_t>(aidlCode), message.c_str()); + } + *executionResult = std::move(result).value(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus PreparedModel::executeFenced( + const Request& request, const std::vector<ndk::ScopedFileDescriptor>& waitFor, + bool measureTiming, int64_t deadlineNs, int64_t loopTimeoutDurationNs, int64_t durationNs, + FencedExecutionResult* executionResult) { + auto result = adapter::executeFenced(*kPreparedModel, request, waitFor, measureTiming, + deadlineNs, loopTimeoutDurationNs, durationNs); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast<int32_t>(aidlCode), message.c_str()); + } + *executionResult = std::move(result).value(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus PreparedModel::configureExecutionBurst(std::shared_ptr<IBurst>* burst) { + auto result = kPreparedModel->configureExecutionBurst(); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast<int32_t>(aidlCode), message.c_str()); + } + *burst = ndk::SharedRefBase::make<Burst>(std::move(result).value()); + return ndk::ScopedAStatus::ok(); +} + +nn::SharedPreparedModel PreparedModel::getUnderlyingPreparedModel() const { + return kPreparedModel; +} + +ndk::ScopedAStatus PreparedModel::createReusableExecution(const Request& request, + bool measureTiming, + int64_t loopTimeoutDurationNs, + std::shared_ptr<IExecution>* execution) { + auto result = adapter::createReusableExecution(*kPreparedModel, request, measureTiming, + loopTimeoutDurationNs); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast<int32_t>(aidlCode), message.c_str()); + } + *execution = ndk::SharedRefBase::make<Execution>(std::move(result).value()); + return ndk::ScopedAStatus::ok(); +} + +Execution::Execution(nn::SharedExecution execution) : kExecution(std::move(execution)) { + CHECK(kExecution != nullptr); +} + +ndk::ScopedAStatus Execution::executeSynchronously(int64_t deadlineNs, + ExecutionResult* executionResult) { + auto result = adapter::executeSynchronously(*kExecution, deadlineNs); + if (!result.has_value()) { + const auto& [message, code, _] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast<int32_t>(aidlCode), message.c_str()); + } + *executionResult = std::move(result).value(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Execution::executeFenced(const std::vector<ndk::ScopedFileDescriptor>& waitFor, + int64_t deadlineNs, int64_t durationNs, + FencedExecutionResult* executionResult) { + auto result = adapter::executeFenced(*kExecution, waitFor, deadlineNs, durationNs); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast<int32_t>(aidlCode), message.c_str()); + } + *executionResult = std::move(result).value(); + return ndk::ScopedAStatus::ok(); +} + +} // namespace aidl::android::hardware::neuralnetworks::adapter diff --git a/neuralnetworks/utils/adapter/Android.bp b/neuralnetworks/utils/adapter/hidl/Android.bp index d073106a5f..d073106a5f 100644 --- a/neuralnetworks/utils/adapter/Android.bp +++ b/neuralnetworks/utils/adapter/hidl/Android.bp diff --git a/neuralnetworks/utils/adapter/include/nnapi/hal/Adapter.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Adapter.h index da00a090ed..6fba4abe7d 100644 --- a/neuralnetworks/utils/adapter/include/nnapi/hal/Adapter.h +++ b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Adapter.h @@ -20,7 +20,6 @@ #include <android/hardware/neuralnetworks/1.3/IDevice.h> #include <nnapi/IDevice.h> #include <nnapi/Types.h> -#include <sys/types.h> #include <functional> #include <memory> @@ -37,10 +36,12 @@ using Task = std::function<void()>; /** * A type-erased executor which executes a task asynchronously. * - * This executor is also provided with an Application ID (Android User ID) and an optional deadline - * for when the caller expects is the upper bound for the amount of time to complete the task. + * This executor is also provided an optional deadline for when the caller expects is the upper + * bound for the amount of time to complete the task. If needed, the Executor can retrieve the + * Application ID (Android User ID) by calling IPCThreadState::self()->getCallingUid() in + * hwbinder/IPCThreadState.h. */ -using Executor = std::function<void(Task, uid_t, nn::OptionalTimePoint)>; +using Executor = std::function<void(Task, nn::OptionalTimePoint)>; /** * Adapt an NNAPI canonical interface object to a HIDL NN HAL interface object. diff --git a/neuralnetworks/utils/adapter/include/nnapi/hal/Buffer.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Buffer.h index e53c7d4f09..e53c7d4f09 100644 --- a/neuralnetworks/utils/adapter/include/nnapi/hal/Buffer.h +++ b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Buffer.h diff --git a/neuralnetworks/utils/adapter/include/nnapi/hal/Burst.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Burst.h index a3aa706a0c..a3aa706a0c 100644 --- a/neuralnetworks/utils/adapter/include/nnapi/hal/Burst.h +++ b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Burst.h diff --git a/neuralnetworks/utils/adapter/include/nnapi/hal/Device.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Device.h index 148d0a0341..148d0a0341 100644 --- a/neuralnetworks/utils/adapter/include/nnapi/hal/Device.h +++ b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Device.h diff --git a/neuralnetworks/utils/adapter/include/nnapi/hal/PreparedModel.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/PreparedModel.h index 65763b8d19..9482b0d512 100644 --- a/neuralnetworks/utils/adapter/include/nnapi/hal/PreparedModel.h +++ b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/PreparedModel.h @@ -39,7 +39,7 @@ namespace android::hardware::neuralnetworks::adapter { // Class that adapts nn::IPreparedModel to V1_3::IPreparedModel. class PreparedModel final : public V1_3::IPreparedModel { public: - PreparedModel(nn::SharedPreparedModel preparedModel, Executor executor, uid_t userId); + PreparedModel(nn::SharedPreparedModel preparedModel, Executor executor); Return<V1_0::ErrorStatus> execute(const V1_0::Request& request, const sp<V1_0::IExecutionCallback>& callback) override; @@ -71,7 +71,6 @@ class PreparedModel final : public V1_3::IPreparedModel { private: const nn::SharedPreparedModel kPreparedModel; const Executor kExecutor; - const uid_t kUserId; }; } // namespace android::hardware::neuralnetworks::adapter diff --git a/neuralnetworks/utils/adapter/src/Adapter.cpp b/neuralnetworks/utils/adapter/hidl/src/Adapter.cpp index d6f53f05a5..782e815a83 100644 --- a/neuralnetworks/utils/adapter/src/Adapter.cpp +++ b/neuralnetworks/utils/adapter/hidl/src/Adapter.cpp @@ -21,7 +21,6 @@ #include <android/hardware/neuralnetworks/1.3/IDevice.h> #include <nnapi/IDevice.h> #include <nnapi/Types.h> -#include <sys/types.h> #include <functional> #include <memory> @@ -37,7 +36,7 @@ sp<V1_3::IDevice> adapt(nn::SharedDevice device, Executor executor) { } sp<V1_3::IDevice> adapt(nn::SharedDevice device) { - Executor defaultExecutor = [](Task task, uid_t /*uid*/, nn::OptionalTimePoint /*deadline*/) { + Executor defaultExecutor = [](Task task, nn::OptionalTimePoint /*deadline*/) { std::thread(std::move(task)).detach(); }; return adapt(std::move(device), std::move(defaultExecutor)); diff --git a/neuralnetworks/utils/adapter/src/Buffer.cpp b/neuralnetworks/utils/adapter/hidl/src/Buffer.cpp index 3a04bf6b79..3a04bf6b79 100644 --- a/neuralnetworks/utils/adapter/src/Buffer.cpp +++ b/neuralnetworks/utils/adapter/hidl/src/Buffer.cpp diff --git a/neuralnetworks/utils/adapter/src/Burst.cpp b/neuralnetworks/utils/adapter/hidl/src/Burst.cpp index 8b2e1dd465..8b2e1dd465 100644 --- a/neuralnetworks/utils/adapter/src/Burst.cpp +++ b/neuralnetworks/utils/adapter/hidl/src/Burst.cpp diff --git a/neuralnetworks/utils/adapter/src/Device.cpp b/neuralnetworks/utils/adapter/hidl/src/Device.cpp index 96142c3577..4993a80a93 100644 --- a/neuralnetworks/utils/adapter/src/Device.cpp +++ b/neuralnetworks/utils/adapter/hidl/src/Device.cpp @@ -28,7 +28,6 @@ #include <android/hardware/neuralnetworks/1.3/IDevice.h> #include <android/hardware/neuralnetworks/1.3/IPreparedModelCallback.h> #include <android/hardware/neuralnetworks/1.3/types.h> -#include <hwbinder/IPCThreadState.h> #include <nnapi/IBuffer.h> #include <nnapi/IDevice.h> #include <nnapi/IPreparedModel.h> @@ -43,7 +42,6 @@ #include <nnapi/hal/1.2/Utils.h> #include <nnapi/hal/1.3/Conversions.h> #include <nnapi/hal/1.3/Utils.h> -#include <sys/types.h> #include <memory> @@ -64,12 +62,11 @@ auto convertInput(const Type& object) -> decltype(nn::convert(std::declval<Type> using PrepareModelResult = nn::GeneralResult<nn::SharedPreparedModel>; -sp<PreparedModel> adaptPreparedModel(nn::SharedPreparedModel preparedModel, Executor executor, - uid_t userId) { +sp<PreparedModel> adaptPreparedModel(nn::SharedPreparedModel preparedModel, Executor executor) { if (preparedModel == nullptr) { return nullptr; } - return sp<PreparedModel>::make(std::move(preparedModel), std::move(executor), userId); + return sp<PreparedModel>::make(std::move(preparedModel), std::move(executor)); } void notify(V1_0::IPreparedModelCallback* callback, nn::ErrorStatus status, @@ -108,15 +105,14 @@ void notify(V1_3::IPreparedModelCallback* callback, nn::ErrorStatus status, } template <typename CallbackType> -void notify(CallbackType* callback, PrepareModelResult result, Executor executor, uid_t userId) { +void notify(CallbackType* callback, PrepareModelResult result, Executor executor) { if (!result.has_value()) { const auto [message, status] = std::move(result).error(); LOG(ERROR) << message; notify(callback, status, nullptr); } else { auto preparedModel = std::move(result).value(); - auto hidlPreparedModel = - adaptPreparedModel(std::move(preparedModel), std::move(executor), userId); + auto hidlPreparedModel = adaptPreparedModel(std::move(preparedModel), std::move(executor)); notify(callback, nn::ErrorStatus::NONE, std::move(hidlPreparedModel)); } } @@ -137,13 +133,12 @@ nn::GeneralResult<void> prepareModel(const nn::SharedDevice& device, const Execu auto nnModel = NN_TRY(convertInput(model)); - const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); - Task task = [device, nnModel = std::move(nnModel), userId, executor, callback] { + Task task = [device, nnModel = std::move(nnModel), executor, callback] { auto result = device->prepareModel(nnModel, nn::ExecutionPreference::DEFAULT, nn::Priority::DEFAULT, {}, {}, {}, {}); - notify(callback.get(), std::move(result), executor, userId); + notify(callback.get(), std::move(result), executor); }; - executor(std::move(task), userId, {}); + executor(std::move(task), {}); return {}; } @@ -159,13 +154,12 @@ nn::GeneralResult<void> prepareModel_1_1(const nn::SharedDevice& device, const E auto nnModel = NN_TRY(convertInput(model)); const auto nnPreference = NN_TRY(convertInput(preference)); - const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); - Task task = [device, nnModel = std::move(nnModel), nnPreference, userId, executor, callback] { + Task task = [device, nnModel = std::move(nnModel), nnPreference, executor, callback] { auto result = device->prepareModel(nnModel, nnPreference, nn::Priority::DEFAULT, {}, {}, {}, {}); - notify(callback.get(), std::move(result), executor, userId); + notify(callback.get(), std::move(result), executor); }; - executor(std::move(task), userId, {}); + executor(std::move(task), {}); return {}; } @@ -187,15 +181,14 @@ nn::GeneralResult<void> prepareModel_1_2(const nn::SharedDevice& device, const E auto nnDataCache = NN_TRY(convertInput(dataCache)); const auto nnToken = nn::CacheToken(token); - const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); Task task = [device, nnModel = std::move(nnModel), nnPreference, nnModelCache = std::move(nnModelCache), nnDataCache = std::move(nnDataCache), - nnToken, userId, executor, callback] { + nnToken, executor, callback] { auto result = device->prepareModel(nnModel, nnPreference, nn::Priority::DEFAULT, {}, nnModelCache, nnDataCache, nnToken); - notify(callback.get(), std::move(result), executor, userId); + notify(callback.get(), std::move(result), executor); }; - executor(std::move(task), userId, {}); + executor(std::move(task), {}); return {}; } @@ -218,15 +211,14 @@ nn::GeneralResult<void> prepareModel_1_3( auto nnDataCache = NN_TRY(convertInput(dataCache)); const auto nnToken = nn::CacheToken(token); - const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); Task task = [device, nnModel = std::move(nnModel), nnPreference, nnPriority, nnDeadline, nnModelCache = std::move(nnModelCache), nnDataCache = std::move(nnDataCache), - nnToken, userId, executor, callback] { + nnToken, executor, callback] { auto result = device->prepareModel(nnModel, nnPreference, nnPriority, nnDeadline, nnModelCache, nnDataCache, nnToken); - notify(callback.get(), std::move(result), executor, userId); + notify(callback.get(), std::move(result), executor); }; - executor(std::move(task), userId, nnDeadline); + executor(std::move(task), nnDeadline); return {}; } @@ -245,13 +237,12 @@ nn::GeneralResult<void> prepareModelFromCache(const nn::SharedDevice& device, auto nnDataCache = NN_TRY(convertInput(dataCache)); const auto nnToken = nn::CacheToken(token); - const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); Task task = [device, nnModelCache = std::move(nnModelCache), - nnDataCache = std::move(nnDataCache), nnToken, userId, executor, callback] { + nnDataCache = std::move(nnDataCache), nnToken, executor, callback] { auto result = device->prepareModelFromCache({}, nnModelCache, nnDataCache, nnToken); - notify(callback.get(), std::move(result), executor, userId); + notify(callback.get(), std::move(result), executor); }; - executor(std::move(task), userId, {}); + executor(std::move(task), {}); return {}; } @@ -270,13 +261,12 @@ nn::GeneralResult<void> prepareModelFromCache_1_3( auto nnDataCache = NN_TRY(convertInput(dataCache)); const auto nnToken = nn::CacheToken(token); - const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); auto task = [device, nnDeadline, nnModelCache = std::move(nnModelCache), - nnDataCache = std::move(nnDataCache), nnToken, userId, executor, callback] { + nnDataCache = std::move(nnDataCache), nnToken, executor, callback] { auto result = device->prepareModelFromCache(nnDeadline, nnModelCache, nnDataCache, nnToken); - notify(callback.get(), std::move(result), executor, userId); + notify(callback.get(), std::move(result), executor); }; - executor(std::move(task), userId, nnDeadline); + executor(std::move(task), nnDeadline); return {}; } diff --git a/neuralnetworks/utils/adapter/src/PreparedModel.cpp b/neuralnetworks/utils/adapter/hidl/src/PreparedModel.cpp index a14e782b9b..71060d5ca7 100644 --- a/neuralnetworks/utils/adapter/src/PreparedModel.cpp +++ b/neuralnetworks/utils/adapter/hidl/src/PreparedModel.cpp @@ -28,7 +28,6 @@ #include <android/hardware/neuralnetworks/1.3/IFencedExecutionCallback.h> #include <android/hardware/neuralnetworks/1.3/IPreparedModel.h> #include <android/hardware/neuralnetworks/1.3/types.h> -#include <hwbinder/IPCThreadState.h> #include <nnapi/IPreparedModel.h> #include <nnapi/TypeUtils.h> #include <nnapi/Types.h> @@ -37,7 +36,6 @@ #include <nnapi/hal/1.2/Utils.h> #include <nnapi/hal/1.3/Conversions.h> #include <nnapi/hal/1.3/Utils.h> -#include <sys/types.h> #include <memory> #include <thread> @@ -145,7 +143,7 @@ void notify(CallbackType* callback, ExecutionResult result) { } } -nn::GeneralResult<void> execute(const nn::SharedPreparedModel& preparedModel, uid_t userId, +nn::GeneralResult<void> execute(const nn::SharedPreparedModel& preparedModel, const Executor& executor, const V1_0::Request& request, const sp<V1_0::IExecutionCallback>& callback) { if (callback.get() == nullptr) { @@ -164,12 +162,12 @@ nn::GeneralResult<void> execute(const nn::SharedPreparedModel& preparedModel, ui auto result = preparedModel->execute(nnRequest, nn::MeasureTiming::NO, {}, {}); notify(callback.get(), std::move(result)); }; - executor(std::move(task), userId, {}); + executor(std::move(task), {}); return {}; } -nn::GeneralResult<void> execute_1_2(const nn::SharedPreparedModel& preparedModel, uid_t userId, +nn::GeneralResult<void> execute_1_2(const nn::SharedPreparedModel& preparedModel, const Executor& executor, const V1_0::Request& request, V1_2::MeasureTiming measure, const sp<V1_2::IExecutionCallback>& callback) { @@ -190,12 +188,12 @@ nn::GeneralResult<void> execute_1_2(const nn::SharedPreparedModel& preparedModel auto result = preparedModel->execute(nnRequest, nnMeasure, {}, {}); notify(callback.get(), std::move(result)); }; - executor(std::move(task), userId, {}); + executor(std::move(task), {}); return {}; } -nn::GeneralResult<void> execute_1_3(const nn::SharedPreparedModel& preparedModel, uid_t userId, +nn::GeneralResult<void> execute_1_3(const nn::SharedPreparedModel& preparedModel, const Executor& executor, const V1_3::Request& request, V1_2::MeasureTiming measure, const V1_3::OptionalTimePoint& deadline, @@ -222,7 +220,7 @@ nn::GeneralResult<void> execute_1_3(const nn::SharedPreparedModel& preparedModel preparedModel->execute(nnRequest, nnMeasure, nnDeadline, nnLoopTimeoutDuration); notify(callback.get(), std::move(result)); }; - executor(std::move(task), userId, nnDeadline); + executor(std::move(task), nnDeadline); return {}; } @@ -305,8 +303,8 @@ nn::GeneralResult<std::pair<hidl_handle, sp<V1_3::IFencedExecutionCallback>>> ex } // namespace -PreparedModel::PreparedModel(nn::SharedPreparedModel preparedModel, Executor executor, uid_t userId) - : kPreparedModel(std::move(preparedModel)), kExecutor(std::move(executor)), kUserId(userId) { +PreparedModel::PreparedModel(nn::SharedPreparedModel preparedModel, Executor executor) + : kPreparedModel(std::move(preparedModel)), kExecutor(std::move(executor)) { CHECK(kPreparedModel != nullptr); CHECK(kExecutor != nullptr); } @@ -317,7 +315,7 @@ nn::SharedPreparedModel PreparedModel::getUnderlyingPreparedModel() const { Return<V1_0::ErrorStatus> PreparedModel::execute(const V1_0::Request& request, const sp<V1_0::IExecutionCallback>& callback) { - auto result = adapter::execute(kPreparedModel, kUserId, kExecutor, request, callback); + auto result = adapter::execute(kPreparedModel, kExecutor, request, callback); if (!result.has_value()) { auto [message, code] = std::move(result).error(); LOG(ERROR) << "adapter::PreparedModel::execute failed with " << code << ": " << message; @@ -330,8 +328,7 @@ Return<V1_0::ErrorStatus> PreparedModel::execute(const V1_0::Request& request, Return<V1_0::ErrorStatus> PreparedModel::execute_1_2(const V1_0::Request& request, V1_2::MeasureTiming measure, const sp<V1_2::IExecutionCallback>& callback) { - auto result = - adapter::execute_1_2(kPreparedModel, kUserId, kExecutor, request, measure, callback); + auto result = adapter::execute_1_2(kPreparedModel, kExecutor, request, measure, callback); if (!result.has_value()) { auto [message, code] = std::move(result).error(); LOG(ERROR) << "adapter::PreparedModel::execute_1_2 failed with " << code << ": " << message; @@ -346,8 +343,8 @@ Return<V1_3::ErrorStatus> PreparedModel::execute_1_3( const V1_3::OptionalTimePoint& deadline, const V1_3::OptionalTimeoutDuration& loopTimeoutDuration, const sp<V1_3::IExecutionCallback>& callback) { - auto result = adapter::execute_1_3(kPreparedModel, kUserId, kExecutor, request, measure, - deadline, loopTimeoutDuration, callback); + auto result = adapter::execute_1_3(kPreparedModel, kExecutor, request, measure, deadline, + loopTimeoutDuration, callback); if (!result.has_value()) { auto [message, code] = std::move(result).error(); LOG(ERROR) << "adapter::PreparedModel::execute_1_3 failed with " << code << ": " << message; diff --git a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp index d108951c0e..152858f6a8 100644 --- a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp @@ -1271,8 +1271,12 @@ TEST_P(RadioHidlTest_v1_5, getBarringInfo) { EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial); int32_t firstApiLevel = android::base::GetIntProperty<int32_t>("ro.product.first_api_level", 0); + int32_t boardApiLevel = android::base::GetIntProperty<int32_t>("ro.board.first_api_level", 0); // Allow devices shipping with Radio::1_5 and Android 11 to not support barring info. - if (firstApiLevel > 0 && firstApiLevel <= 30) { + // b/212384410 Some GRF targets lauched with S release but with vendor R release + // do not support getBarringInfo API. Allow these devices to not support barring info. + if ((firstApiLevel > 0 && firstApiLevel <= 30) || + (boardApiLevel > 0 && boardApiLevel <= 30)) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error, {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED})); // Early exit for devices that don't support barring info. diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl index 6982d404bd..980b042cdf 100644 --- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl @@ -47,4 +47,7 @@ enum ApnTypes { EMERGENCY = 512, MCX = 1024, XCAP = 2048, + VSIM = 4096, + BIP = 8192, + ENTERPRISE = 16384, } diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataIndication.aidl index b0cc1eb189..0ffa1f7ddf 100644 --- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataIndication.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataIndication.aidl @@ -38,4 +38,5 @@ interface IRadioDataIndication { oneway void keepaliveStatus(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.KeepaliveStatus status); oneway void pcoData(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.PcoDataInfo pco); oneway void unthrottleApn(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.DataProfileInfo dataProfileInfo); + oneway void slicingConfigChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.SlicingConfig slicingConfig); } diff --git a/radio/aidl/android/hardware/radio/data/ApnTypes.aidl b/radio/aidl/android/hardware/radio/data/ApnTypes.aidl index e780d8ee6b..ae103fc7e5 100644 --- a/radio/aidl/android/hardware/radio/data/ApnTypes.aidl +++ b/radio/aidl/android/hardware/radio/data/ApnTypes.aidl @@ -73,4 +73,16 @@ enum ApnTypes { * APN type for XCAP */ XCAP = 1 << 11, + /** + * APN type for VSIM. + */ + VSIM = 1 << 12, + /** + * APN type for BIP. + */ + BIP = 1 << 13, + /** + * APN type for ENTERPRISE + */ + ENTERPRISE = 1 << 14 } diff --git a/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl b/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl index 1772c8859f..938c695fd4 100644 --- a/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl +++ b/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl @@ -21,6 +21,7 @@ import android.hardware.radio.data.DataProfileInfo; import android.hardware.radio.data.KeepaliveStatus; import android.hardware.radio.data.PcoDataInfo; import android.hardware.radio.data.SetupDataCallResult; +import android.hardware.radio.data.SlicingConfig; /** * Interface declaring unsolicited radio indications for data APIs. @@ -72,4 +73,17 @@ oneway interface IRadioDataIndication { * @param dataProfileInfo Data profile info. */ void unthrottleApn(in RadioIndicationType type, in DataProfileInfo dataProfileInfo); + + /** + * Indicates the current slicing configuration including URSP rules and NSSAIs + * (configured, allowed and rejected). URSP stands for UE route selection policy and is defined + * in 3GPP TS 24.526 Section 4.2. An NSSAI is a collection of network slices. Each network slice + * is identified by an S-NSSAI and is represented by the struct SliceInfo. NSSAI and S-NSSAI + * are defined in 3GPP TS 24.501. + * + * @param type Type of radio indication + * @param slicingConfig Current slicing configuration + * + */ + void slicingConfigChanged(in RadioIndicationType type, in SlicingConfig slicingConfig); } diff --git a/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp b/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp index 1d367d2025..602bb39390 100644 --- a/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp +++ b/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp @@ -85,4 +85,11 @@ Return<void> RadioIndication::unthrottleApn(V1_0::RadioIndicationType type, return {}; } +Return<void> RadioIndication::slicingConfigChanged(V1_0::RadioIndicationType type, + const V1_6::SlicingConfig& slicingConfig) { + LOG_CALL << type; + dataCb()->slicingConfigChanged(toAidl(type), toAidl(slicingConfig)); + return {}; +} + } // namespace android::hardware::radio::compat diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h index c668af5dce..6cfd59c6a3 100644 --- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h +++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h @@ -186,6 +186,8 @@ class RadioIndication : public V1_6::IRadioIndication { V1_0::RadioIndicationType type, const hidl_vec<V1_6::SetupDataCallResult>& dcList) override; Return<void> unthrottleApn(V1_0::RadioIndicationType type, const hidl_string& apn) override; + Return<void> slicingConfigChanged(V1_0::RadioIndicationType type, + const V1_6::SlicingConfig& slicingConfig); Return<void> currentLinkCapacityEstimate_1_6(V1_0::RadioIndicationType type, const V1_6::LinkCapacityEstimate& lce) override; Return<void> currentSignalStrength_1_6(V1_0::RadioIndicationType type, diff --git a/radio/aidl/vts/radio_data_indication.cpp b/radio/aidl/vts/radio_data_indication.cpp index 4d3c539d91..61e079e532 100644 --- a/radio/aidl/vts/radio_data_indication.cpp +++ b/radio/aidl/vts/radio_data_indication.cpp @@ -37,3 +37,8 @@ ndk::ScopedAStatus RadioDataIndication::unthrottleApn(RadioIndicationType /*type const DataProfileInfo& /*dataProfileInfo*/) { return ndk::ScopedAStatus::ok(); } + +ndk::ScopedAStatus RadioDataIndication::slicingConfigChanged( + RadioIndicationType /*type*/, const SlicingConfig& /*slicingConfig*/) { + return ndk::ScopedAStatus::ok(); +} diff --git a/radio/aidl/vts/radio_data_utils.h b/radio/aidl/vts/radio_data_utils.h index 50c7878a2c..fb91ef61d5 100644 --- a/radio/aidl/vts/radio_data_utils.h +++ b/radio/aidl/vts/radio_data_utils.h @@ -95,6 +95,8 @@ class RadioDataIndication : public BnRadioDataIndication { virtual ndk::ScopedAStatus unthrottleApn(RadioIndicationType type, const DataProfileInfo& dataProfile) override; + virtual ndk::ScopedAStatus slicingConfigChanged(RadioIndicationType type, + const SlicingConfig& slicingConfig) override; }; // The main test class for Radio AIDL Data. diff --git a/security/dice/aidl/Android.bp b/security/dice/aidl/Android.bp index af9dd33c3b..01bc91e5eb 100644 --- a/security/dice/aidl/Android.bp +++ b/security/dice/aidl/Android.bp @@ -41,6 +41,10 @@ aidl_interface { }, rust: { enabled: true, + apex_available: [ + "//apex_available:platform", + "com.android.compos", + ], }, }, // versions: ["1"], diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/BccHandover.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/BccHandover.aidl index ab50c369a7..8baca94ce8 100644 --- a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/BccHandover.aidl +++ b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/BccHandover.aidl @@ -35,7 +35,7 @@ package android.hardware.security.dice; /* @hide */ @RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability parcelable BccHandover { - byte[] cdiAttest; - byte[] cdiSeal; + byte[32] cdiAttest; + byte[32] cdiSeal; android.hardware.security.dice.Bcc bcc; } diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/InputValues.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/InputValues.aidl index 79583fbb98..e43c4292e4 100644 --- a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/InputValues.aidl +++ b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/InputValues.aidl @@ -35,10 +35,10 @@ package android.hardware.security.dice; /* @hide */ @RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability parcelable InputValues { - byte[] codeHash; + byte[64] codeHash; android.hardware.security.dice.Config config; - byte[] authorityHash; + byte[64] authorityHash; @nullable byte[] authorityDescriptor; android.hardware.security.dice.Mode mode = android.hardware.security.dice.Mode.NOT_INITIALIZED; - byte[] hidden; + byte[64] hidden; } diff --git a/security/dice/aidl/android/hardware/security/dice/BccHandover.aidl b/security/dice/aidl/android/hardware/security/dice/BccHandover.aidl index d522cef7a4..6ca862cdf9 100644 --- a/security/dice/aidl/android/hardware/security/dice/BccHandover.aidl +++ b/security/dice/aidl/android/hardware/security/dice/BccHandover.aidl @@ -27,13 +27,13 @@ import android.hardware.security.dice.Bcc; @RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true) parcelable BccHandover { /** - * CDI_attest. Must a exactly 32 bytes of data. + * CDI_attest. Must be exactly 32 bytes of data. */ - byte[] cdiAttest; + byte[32] cdiAttest; /** - * CDI_seal. Must a exactly 32 bytes of data. + * CDI_seal. Must be exactly 32 bytes of data. */ - byte[] cdiSeal; + byte[32] cdiSeal; /** * CBOR encoded BCC. * diff --git a/security/dice/aidl/android/hardware/security/dice/InputValues.aidl b/security/dice/aidl/android/hardware/security/dice/InputValues.aidl index e44ef22365..711d5232c5 100644 --- a/security/dice/aidl/android/hardware/security/dice/InputValues.aidl +++ b/security/dice/aidl/android/hardware/security/dice/InputValues.aidl @@ -34,7 +34,7 @@ parcelable InputValues { /** * The target code hash. Must be exactly 64 bytes. */ - byte[] codeHash; + byte[64] codeHash; /** * The configuration data. */ @@ -42,7 +42,7 @@ parcelable InputValues { /** * The authority hash. Must be exactly 64 bytes. Must be all zero if unused. */ - byte[] authorityHash; + byte[64] authorityHash; /** * Optional free form authorityDescriptor. */ @@ -54,5 +54,5 @@ parcelable InputValues { /** * Optional hidden values. Must be exactly 64 bytes. Must be all zero if unused. */ - byte[] hidden; + byte[64] hidden; } diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl index ce83044d0e..ca8955552e 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl @@ -227,7 +227,8 @@ interface IKeyMintOperation { * o PaddingMode::RSA_PSS. For PSS-padded signature operations, the PSS salt length must match * the size of the PSS digest selected. The digest specified with Tag::DIGEST in params * on begin() must be used as the PSS digest algorithm, MGF1 must be used as the mask - * generation function and SHA1 must be used as the MGF1 digest algorithm. + * generation function and the digest specified with Tag:DIGEST in params on begin() must also + * be used as the MGF1 digest algorithm. * * -- ECDSA keys -- * diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index 3695f1e094..374f2da7a8 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -537,6 +537,9 @@ ErrorCode KeyMintAidlTestBase::Update(const string& input, string* output) { 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); @@ -809,6 +812,7 @@ void KeyMintAidlTestBase::LocalVerifyMessage(const string& message, const string if (padding == PaddingMode::RSA_PSS) { EXPECT_GT(EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING), 0); EXPECT_GT(EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, EVP_MD_size(md)), 0); + EXPECT_GT(EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, md), 0); } ASSERT_EQ(1, EVP_DigestVerifyUpdate(&digest_ctx, diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp index dd3719bc7d..340010fec3 100644 --- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp @@ -4608,8 +4608,10 @@ TEST_P(EncryptionOperationsTest, AesEcbPkcs7Padding) { auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7); // Try various message lengths; all should work. - for (size_t i = 0; i < 32; ++i) { - string message(i, 'a'); + for (size_t i = 0; i <= 48; i++) { + SCOPED_TRACE(testing::Message() << "i = " << i); + // Edge case: '\t' (0x09) is also a valid PKCS7 padding character. + string message(i, '\t'); string ciphertext = EncryptMessage(message, params); EXPECT_EQ(i + 16 - (i % 16), ciphertext.size()); string plaintext = DecryptMessage(ciphertext, params); @@ -4633,7 +4635,7 @@ TEST_P(EncryptionOperationsTest, AesEcbWrongPadding) { auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7); // Try various message lengths; all should fail - for (size_t i = 0; i < 32; ++i) { + for (size_t i = 0; i <= 48; i++) { string message(i, 'a'); EXPECT_EQ(ErrorCode::INCOMPATIBLE_PADDING_MODE, Begin(KeyPurpose::ENCRYPT, params)); } @@ -5818,8 +5820,8 @@ TEST_P(EncryptionOperationsTest, TripleDesCbcRoundTripSuccess) { ASSERT_GT(key_blob_.size(), 0U); - // Two-block message. - string message = "1234567890123456"; + // Four-block message. + string message = "12345678901234561234567890123456"; vector<uint8_t> iv1; string ciphertext1 = EncryptMessage(message, BlockMode::CBC, PaddingMode::NONE, &iv1); EXPECT_EQ(message.size(), ciphertext1.size()); @@ -5979,8 +5981,10 @@ TEST_P(EncryptionOperationsTest, TripleDesCbcPkcs7Padding) { .Padding(PaddingMode::PKCS7))); // Try various message lengths; all should work. - for (size_t i = 0; i < 32; ++i) { - string message(i, 'a'); + for (size_t i = 0; i <= 32; i++) { + SCOPED_TRACE(testing::Message() << "i = " << i); + // Edge case: '\t' (0x09) is also a valid PKCS7 padding character, albeit not for 3DES. + string message(i, '\t'); vector<uint8_t> iv; string ciphertext = EncryptMessage(message, BlockMode::CBC, PaddingMode::PKCS7, &iv); EXPECT_EQ(i + 8 - (i % 8), ciphertext.size()); @@ -6002,7 +6006,7 @@ TEST_P(EncryptionOperationsTest, TripleDesCbcNoPaddingKeyWithPkcs7Padding) { .Padding(PaddingMode::NONE))); // Try various message lengths; all should fail. - for (size_t i = 0; i < 32; ++i) { + for (size_t i = 0; i <= 32; i++) { auto begin_params = AuthorizationSetBuilder().BlockMode(BlockMode::CBC).Padding(PaddingMode::PKCS7); EXPECT_EQ(ErrorCode::INCOMPATIBLE_PADDING_MODE, Begin(KeyPurpose::ENCRYPT, begin_params)); @@ -6033,6 +6037,7 @@ TEST_P(EncryptionOperationsTest, TripleDesCbcPkcs7PaddingCorrupted) { .Authorization(TAG_NONCE, iv); for (size_t i = 0; i < kMaxPaddingCorruptionRetries; ++i) { + SCOPED_TRACE(testing::Message() << "i = " << i); ++ciphertext[ciphertext.size() / 2]; EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params)); string plaintext; diff --git a/sensors/aidl/Android.bp b/sensors/aidl/Android.bp index fd1ac441e2..92b7ad03d8 100644 --- a/sensors/aidl/Android.bp +++ b/sensors/aidl/Android.bp @@ -1,4 +1,11 @@ -// This is the expected build file, but it may not be right in all cases +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.sensors", diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/Event.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/Event.aidl index 186b2be8b3..c92ab1ab0c 100644 --- a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/Event.aidl +++ b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/Event.aidl @@ -51,6 +51,7 @@ parcelable Event { android.hardware.sensors.DynamicSensorInfo dynamic; android.hardware.sensors.AdditionalInfo additional; android.hardware.sensors.Event.EventPayload.Data data; + android.hardware.sensors.Event.EventPayload.HeadTracker headTracker; @FixedSize @VintfStability parcelable Vec4 { float x; @@ -75,6 +76,16 @@ parcelable Event { float zBias; } @FixedSize @VintfStability + parcelable HeadTracker { + float rx; + float ry; + float rz; + float vx; + float vy; + float vz; + int discontinuityCount; + } + @FixedSize @VintfStability parcelable HeartRate { float bpm; android.hardware.sensors.SensorStatus status; diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorType.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorType.aidl index 4f3b5b2e79..3d7ab45cd8 100644 --- a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorType.aidl +++ b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorType.aidl @@ -70,5 +70,6 @@ enum SensorType { LOW_LATENCY_OFFBODY_DETECT = 34, ACCELEROMETER_UNCALIBRATED = 35, HINGE_ANGLE = 36, + HEAD_TRACKER = 37, DEVICE_PRIVATE_BASE = 65536, } diff --git a/sensors/aidl/android/hardware/sensors/Event.aidl b/sensors/aidl/android/hardware/sensors/Event.aidl index 6ef9acbbda..fd6a8cc4ba 100644 --- a/sensors/aidl/android/hardware/sensors/Event.aidl +++ b/sensors/aidl/android/hardware/sensors/Event.aidl @@ -127,6 +127,11 @@ parcelable Event { */ Data data; + /** + * SensorType::HEAD_TRACKER + */ + HeadTracker headTracker; + @FixedSize @VintfStability parcelable Vec4 { @@ -156,6 +161,46 @@ parcelable Event { float zBias; } + /** + * Payload of the HEAD_TRACKER sensor type. Note that the axis + * definition of this sensor type differs from the rest of Android. See + * SensorType::HEAD_TRACKER for more information. + */ + @FixedSize + @VintfStability + parcelable HeadTracker { + /** + * An Euler vector (rotation vector, i.e. a vector whose direction + * indicates the axis of rotation and magnitude indicates the angle + * to rotate around that axis) representing the transform from + * the (arbitrary, possibly slowly drifting) reference frame to the + * head frame. Expressed in radians. Magnitude of the vector must be + * in the range [0, pi], while the value of individual axes are + * in the range [-pi, pi]. + */ + float rx; + float ry; + float rz; + + /** + * An Euler vector (rotation vector) representing the angular + * velocity of the head (relative to itself), in radians per second. + * The direction of this vector indicates the axis of rotation, and + * the magnitude indicates the rate of rotation. + */ + float vx; + float vy; + float vz; + + /** + * This value increments (or wraps around to 0) each time the + * reference frame is suddenly and significantly changed, for + * example if an orientation filter algorithm used for determining + * the orientation has had its state reset. + */ + int discontinuityCount; + } + @FixedSize @VintfStability parcelable HeartRate { diff --git a/sensors/aidl/android/hardware/sensors/SensorType.aidl b/sensors/aidl/android/hardware/sensors/SensorType.aidl index 95c7a6a2ad..01e6bee1d5 100644 --- a/sensors/aidl/android/hardware/sensors/SensorType.aidl +++ b/sensors/aidl/android/hardware/sensors/SensorType.aidl @@ -142,6 +142,10 @@ enum SensorType { * The rotation vector symbolizes the orientation of the device relative to * the East-North-Up coordinates frame. * + * Note that despite the name, SensorType::ROTATION_VECTOR uses + * quaternion representation, rather than the rotation vector representation + * (aka Euler vector) seen in SensorType::HEAD_TRACKER. + * * Implement the non-wake-up version of this sensor and implement the * wake-up version if the system possesses a wake up fifo. */ @@ -634,6 +638,35 @@ enum SensorType { HINGE_ANGLE = 36, /** + * HEAD_TRACKER + * reporting-mode: continuous + * + * A sensor of this type measures the orientation of a user's head relative + * to an arbitrary reference frame, and the rate of rotation. + * + * Events produced by this sensor follow a special head-centric coordinate + * frame, where: + * - The X axis crosses through the user's ears, with the positive X + * direction extending out of the user's right ear + * - The Y axis crosses from the back of the user's head through their + * nose, with the positive direction extending out of the nose, and the + * X/Y plane being nominally parallel to the ground when the user is + * upright and looking straight ahead + * - The Z axis crosses from the neck through the top of the user's head, + * with the positive direction extending out from the top of the head + * + * When this sensor type is exposed as a dynamic sensor through a + * communications channel that uses HID, such as Bluetooth or USB, as part + * of a device with audio output capability (e.g. headphones), then the + * DynamicSensorInfo::uuid field shall be set to contents of the HID + * Persistent Unique ID to permit association between the sensor and audio + * device. Accordingly, the HID Persistent Unique ID (Sensors Page 0x20, + * Usage ID 0x302) must be populated as a UUID in binary representation, + * following RFC 4122 byte order. + */ + HEAD_TRACKER = 37, + + /** * Base for device manufacturers private sensor types. * These sensor types can't be exposed in the SDK. */ diff --git a/sensors/aidl/default/multihal/Android.bp b/sensors/aidl/default/multihal/Android.bp new file mode 100644 index 0000000000..eee10625bb --- /dev/null +++ b/sensors/aidl/default/multihal/Android.bp @@ -0,0 +1,58 @@ +// +// 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 { + // 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: "android.hardware.sensors@aidl-multihal", + vendor: true, + header_libs: [ + "android.hardware.sensors@2.X-multihal.header", + "android.hardware.sensors@2.X-shared-utils", + ], + shared_libs: [ + "libfmq", + "libpower", + "libbase", + "libbinder_ndk", + "android.hardware.sensors@1.0", + "android.hardware.sensors@2.0", + "android.hardware.sensors@2.1", + "android.hardware.sensors-V1-ndk", + ], + export_include_dirs: ["include"], + srcs: [ + "HalProxyAidl.cpp", + "ConvertUtils.cpp", + ], + visibility: [ + ":__subpackages__", + "//hardware/interfaces/sensors/aidl/multihal:__subpackages__", + "//hardware/interfaces/tests/extension/sensors:__subpackages__", + ], + static_libs: [ + "android.hardware.sensors@1.0-convert", + "android.hardware.sensors@2.X-multihal", + "libaidlcommonsupport", + ], +} diff --git a/sensors/aidl/default/multihal/ConvertUtils.cpp b/sensors/aidl/default/multihal/ConvertUtils.cpp new file mode 100644 index 0000000000..509bbb0e7b --- /dev/null +++ b/sensors/aidl/default/multihal/ConvertUtils.cpp @@ -0,0 +1,321 @@ +/* + * 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 "ConvertUtils.h" +#include <android-base/logging.h> +#include <log/log.h> + +using AidlSensorInfo = ::aidl::android::hardware::sensors::SensorInfo; +using AidlSensorType = ::aidl::android::hardware::sensors::SensorType; +using AidlEvent = ::aidl::android::hardware::sensors::Event; +using AidlSensorStatus = ::aidl::android::hardware::sensors::SensorStatus; +using ::aidl::android::hardware::sensors::AdditionalInfo; +using ::aidl::android::hardware::sensors::DynamicSensorInfo; +using ::android::hardware::sensors::V1_0::MetaDataEventType; +using V1_0SensorStatus = ::android::hardware::sensors::V1_0::SensorStatus; +using ::android::hardware::sensors::V1_0::AdditionalInfoType; +using V2_1SensorInfo = ::android::hardware::sensors::V2_1::SensorInfo; +using V2_1Event = ::android::hardware::sensors::V2_1::Event; +using V2_1SensorType = ::android::hardware::sensors::V2_1::SensorType; + +namespace aidl { +namespace android { +namespace hardware { +namespace sensors { +namespace implementation { + +AidlSensorInfo convertSensorInfo(const V2_1SensorInfo& sensorInfo) { + AidlSensorInfo aidlSensorInfo; + aidlSensorInfo.sensorHandle = sensorInfo.sensorHandle; + aidlSensorInfo.name = sensorInfo.name; + aidlSensorInfo.vendor = sensorInfo.vendor; + aidlSensorInfo.version = sensorInfo.version; + aidlSensorInfo.type = (AidlSensorType)sensorInfo.type; + aidlSensorInfo.typeAsString = sensorInfo.typeAsString; + aidlSensorInfo.maxRange = sensorInfo.maxRange; + aidlSensorInfo.resolution = sensorInfo.resolution; + aidlSensorInfo.power = sensorInfo.power; + aidlSensorInfo.minDelayUs = sensorInfo.minDelay; + aidlSensorInfo.fifoReservedEventCount = sensorInfo.fifoReservedEventCount; + aidlSensorInfo.fifoMaxEventCount = sensorInfo.fifoMaxEventCount; + aidlSensorInfo.requiredPermission = sensorInfo.requiredPermission; + aidlSensorInfo.maxDelayUs = sensorInfo.maxDelay; + aidlSensorInfo.flags = sensorInfo.flags; + return aidlSensorInfo; +} + +void convertToHidlEvent(const AidlEvent& aidlEvent, V2_1Event* hidlEvent) { + hidlEvent->timestamp = aidlEvent.timestamp; + hidlEvent->sensorHandle = aidlEvent.sensorHandle; + hidlEvent->sensorType = (V2_1SensorType)aidlEvent.sensorType; + + switch (aidlEvent.sensorType) { + case AidlSensorType::META_DATA: + hidlEvent->u.meta.what = + (MetaDataEventType)aidlEvent.payload.get<Event::EventPayload::meta>().what; + break; + case AidlSensorType::ACCELEROMETER: + case AidlSensorType::MAGNETIC_FIELD: + case AidlSensorType::ORIENTATION: + case AidlSensorType::GYROSCOPE: + case AidlSensorType::GRAVITY: + case AidlSensorType::LINEAR_ACCELERATION: + hidlEvent->u.vec3.x = aidlEvent.payload.get<Event::EventPayload::vec3>().x; + hidlEvent->u.vec3.y = aidlEvent.payload.get<Event::EventPayload::vec3>().y; + hidlEvent->u.vec3.z = aidlEvent.payload.get<Event::EventPayload::vec3>().z; + break; + case AidlSensorType::GAME_ROTATION_VECTOR: + hidlEvent->u.vec4.x = aidlEvent.payload.get<Event::EventPayload::vec4>().x; + hidlEvent->u.vec4.y = aidlEvent.payload.get<Event::EventPayload::vec4>().y; + hidlEvent->u.vec4.z = aidlEvent.payload.get<Event::EventPayload::vec4>().z; + hidlEvent->u.vec4.w = aidlEvent.payload.get<Event::EventPayload::vec4>().w; + break; + case AidlSensorType::ROTATION_VECTOR: + case AidlSensorType::GEOMAGNETIC_ROTATION_VECTOR: + std::copy(aidlEvent.payload.get<Event::EventPayload::data>().values.data(), + aidlEvent.payload.get<Event::EventPayload::data>().values.data() + 5, + hidlEvent->u.data.data()); + break; + case AidlSensorType::ACCELEROMETER_UNCALIBRATED: + case AidlSensorType::MAGNETIC_FIELD_UNCALIBRATED: + case AidlSensorType::GYROSCOPE_UNCALIBRATED: + hidlEvent->u.uncal.x = aidlEvent.payload.get<Event::EventPayload::uncal>().x; + hidlEvent->u.uncal.y = aidlEvent.payload.get<Event::EventPayload::uncal>().y; + hidlEvent->u.uncal.z = aidlEvent.payload.get<Event::EventPayload::uncal>().z; + hidlEvent->u.uncal.x_bias = aidlEvent.payload.get<Event::EventPayload::uncal>().xBias; + hidlEvent->u.uncal.y_bias = aidlEvent.payload.get<Event::EventPayload::uncal>().yBias; + hidlEvent->u.uncal.z_bias = aidlEvent.payload.get<Event::EventPayload::uncal>().zBias; + break; + case AidlSensorType::DEVICE_ORIENTATION: + case AidlSensorType::LIGHT: + case AidlSensorType::PRESSURE: + case AidlSensorType::PROXIMITY: + case AidlSensorType::RELATIVE_HUMIDITY: + case AidlSensorType::AMBIENT_TEMPERATURE: + case AidlSensorType::SIGNIFICANT_MOTION: + case AidlSensorType::STEP_DETECTOR: + case AidlSensorType::TILT_DETECTOR: + case AidlSensorType::WAKE_GESTURE: + case AidlSensorType::GLANCE_GESTURE: + case AidlSensorType::PICK_UP_GESTURE: + case AidlSensorType::WRIST_TILT_GESTURE: + case AidlSensorType::STATIONARY_DETECT: + case AidlSensorType::MOTION_DETECT: + case AidlSensorType::HEART_BEAT: + case AidlSensorType::LOW_LATENCY_OFFBODY_DETECT: + case AidlSensorType::HINGE_ANGLE: + hidlEvent->u.scalar = aidlEvent.payload.get<Event::EventPayload::scalar>(); + break; + case AidlSensorType::STEP_COUNTER: + hidlEvent->u.stepCount = aidlEvent.payload.get<AidlEvent::EventPayload::stepCount>(); + break; + case AidlSensorType::HEART_RATE: + hidlEvent->u.heartRate.bpm = + aidlEvent.payload.get<AidlEvent::EventPayload::heartRate>().bpm; + hidlEvent->u.heartRate.status = + (V1_0SensorStatus)aidlEvent.payload.get<Event::EventPayload::heartRate>() + .status; + break; + case AidlSensorType::POSE_6DOF: + std::copy(std::begin(aidlEvent.payload.get<AidlEvent::EventPayload::pose6DOF>().values), + std::end(aidlEvent.payload.get<AidlEvent::EventPayload::pose6DOF>().values), + hidlEvent->u.pose6DOF.data()); + break; + case AidlSensorType::DYNAMIC_SENSOR_META: + hidlEvent->u.dynamic.connected = + aidlEvent.payload.get<Event::EventPayload::dynamic>().connected; + hidlEvent->u.dynamic.sensorHandle = + aidlEvent.payload.get<Event::EventPayload::dynamic>().sensorHandle; + std::copy( + std::begin( + aidlEvent.payload.get<AidlEvent::EventPayload::dynamic>().uuid.values), + std::end(aidlEvent.payload.get<AidlEvent::EventPayload::dynamic>().uuid.values), + hidlEvent->u.dynamic.uuid.data()); + break; + case AidlSensorType::ADDITIONAL_INFO: { + const AdditionalInfo& additionalInfo = + aidlEvent.payload.get<AidlEvent::EventPayload::additional>(); + hidlEvent->u.additional.type = (AdditionalInfoType)additionalInfo.type; + hidlEvent->u.additional.serial = additionalInfo.serial; + + switch (additionalInfo.payload.getTag()) { + case AdditionalInfo::AdditionalInfoPayload::Tag::dataInt32: { + const auto& aidlData = + additionalInfo.payload + .get<AdditionalInfo::AdditionalInfoPayload::dataInt32>() + .values; + std::copy(std::begin(aidlData), std::end(aidlData), + hidlEvent->u.additional.u.data_int32.data()); + break; + } + case AdditionalInfo::AdditionalInfoPayload::Tag::dataFloat: { + const auto& aidlData = + additionalInfo.payload + .get<AdditionalInfo::AdditionalInfoPayload::dataFloat>() + .values; + std::copy(std::begin(aidlData), std::end(aidlData), + hidlEvent->u.additional.u.data_float.data()); + break; + } + default: + ALOGE("Invalid sensor additioanl info tag: %d", + additionalInfo.payload.getTag()); + break; + } + break; + } + default: + CHECK_GE((int32_t)aidlEvent.sensorType, (int32_t)SensorType::DEVICE_PRIVATE_BASE); + std::copy(std::begin(aidlEvent.payload.get<AidlEvent::EventPayload::data>().values), + std::end(aidlEvent.payload.get<AidlEvent::EventPayload::data>().values), + hidlEvent->u.data.data()); + break; + } +} + +void convertToAidlEvent(const V2_1Event& hidlEvent, AidlEvent* aidlEvent) { + aidlEvent->timestamp = hidlEvent.timestamp; + aidlEvent->sensorHandle = hidlEvent.sensorHandle; + aidlEvent->sensorType = (AidlSensorType)hidlEvent.sensorType; + switch (hidlEvent.sensorType) { + case V2_1SensorType::META_DATA: { + AidlEvent::EventPayload::MetaData meta; + meta.what = (Event::EventPayload::MetaData::MetaDataEventType)hidlEvent.u.meta.what; + aidlEvent->payload.set<Event::EventPayload::meta>(meta); + break; + } + case V2_1SensorType::ACCELEROMETER: + case V2_1SensorType::MAGNETIC_FIELD: + case V2_1SensorType::ORIENTATION: + case V2_1SensorType::GYROSCOPE: + case V2_1SensorType::GRAVITY: + case V2_1SensorType::LINEAR_ACCELERATION: { + AidlEvent::EventPayload::Vec3 vec3; + vec3.x = hidlEvent.u.vec3.x; + vec3.y = hidlEvent.u.vec3.y; + vec3.z = hidlEvent.u.vec3.z; + aidlEvent->payload.set<Event::EventPayload::vec3>(vec3); + break; + } + case V2_1SensorType::GAME_ROTATION_VECTOR: { + AidlEvent::EventPayload::Vec4 vec4; + vec4.x = hidlEvent.u.vec4.x; + vec4.y = hidlEvent.u.vec4.y; + vec4.z = hidlEvent.u.vec4.z; + vec4.w = hidlEvent.u.vec4.w; + aidlEvent->payload.set<Event::EventPayload::vec4>(vec4); + break; + } + case V2_1SensorType::ROTATION_VECTOR: + case V2_1SensorType::GEOMAGNETIC_ROTATION_VECTOR: { + AidlEvent::EventPayload::Data data; + std::copy(hidlEvent.u.data.data(), hidlEvent.u.data.data() + 5, + std::begin(data.values)); + aidlEvent->payload.set<Event::EventPayload::data>(data); + break; + } + case V2_1SensorType::MAGNETIC_FIELD_UNCALIBRATED: + case V2_1SensorType::GYROSCOPE_UNCALIBRATED: + case V2_1SensorType::ACCELEROMETER_UNCALIBRATED: { + AidlEvent::EventPayload::Uncal uncal; + uncal.x = hidlEvent.u.uncal.x; + uncal.y = hidlEvent.u.uncal.y; + uncal.z = hidlEvent.u.uncal.z; + uncal.xBias = hidlEvent.u.uncal.x_bias; + uncal.yBias = hidlEvent.u.uncal.y_bias; + uncal.zBias = hidlEvent.u.uncal.z_bias; + aidlEvent->payload.set<Event::EventPayload::uncal>(uncal); + break; + } + case V2_1SensorType::DEVICE_ORIENTATION: + case V2_1SensorType::LIGHT: + case V2_1SensorType::PRESSURE: + case V2_1SensorType::PROXIMITY: + case V2_1SensorType::RELATIVE_HUMIDITY: + case V2_1SensorType::AMBIENT_TEMPERATURE: + case V2_1SensorType::SIGNIFICANT_MOTION: + case V2_1SensorType::STEP_DETECTOR: + case V2_1SensorType::TILT_DETECTOR: + case V2_1SensorType::WAKE_GESTURE: + case V2_1SensorType::GLANCE_GESTURE: + case V2_1SensorType::PICK_UP_GESTURE: + case V2_1SensorType::WRIST_TILT_GESTURE: + case V2_1SensorType::STATIONARY_DETECT: + case V2_1SensorType::MOTION_DETECT: + case V2_1SensorType::HEART_BEAT: + case V2_1SensorType::LOW_LATENCY_OFFBODY_DETECT: + case V2_1SensorType::HINGE_ANGLE: + aidlEvent->payload.set<Event::EventPayload::scalar>(hidlEvent.u.scalar); + break; + case V2_1SensorType::STEP_COUNTER: + aidlEvent->payload.set<Event::EventPayload::stepCount>(hidlEvent.u.stepCount); + break; + case V2_1SensorType::HEART_RATE: { + AidlEvent::EventPayload::HeartRate heartRate; + heartRate.bpm = hidlEvent.u.heartRate.bpm; + heartRate.status = (SensorStatus)hidlEvent.u.heartRate.status; + aidlEvent->payload.set<Event::EventPayload::heartRate>(heartRate); + break; + } + case V2_1SensorType::POSE_6DOF: { + AidlEvent::EventPayload::Pose6Dof pose6Dof; + std::copy(hidlEvent.u.pose6DOF.data(), + hidlEvent.u.pose6DOF.data() + hidlEvent.u.pose6DOF.size(), + std::begin(pose6Dof.values)); + aidlEvent->payload.set<Event::EventPayload::pose6DOF>(pose6Dof); + break; + } + case V2_1SensorType::DYNAMIC_SENSOR_META: { + DynamicSensorInfo dynamicSensorInfo; + dynamicSensorInfo.connected = hidlEvent.u.dynamic.connected; + dynamicSensorInfo.sensorHandle = hidlEvent.u.dynamic.sensorHandle; + std::copy(hidlEvent.u.dynamic.uuid.data(), + hidlEvent.u.dynamic.uuid.data() + hidlEvent.u.dynamic.uuid.size(), + std::begin(dynamicSensorInfo.uuid.values)); + aidlEvent->payload.set<Event::EventPayload::dynamic>(dynamicSensorInfo); + break; + } + case V2_1SensorType::ADDITIONAL_INFO: { + AdditionalInfo additionalInfo; + additionalInfo.type = (AdditionalInfo::AdditionalInfoType)hidlEvent.u.additional.type; + additionalInfo.serial = hidlEvent.u.additional.serial; + + AdditionalInfo::AdditionalInfoPayload::Int32Values int32Values; + std::copy(hidlEvent.u.additional.u.data_int32.data(), + hidlEvent.u.additional.u.data_int32.data() + + hidlEvent.u.additional.u.data_int32.size(), + std::begin(int32Values.values)); + additionalInfo.payload.set<AdditionalInfo::AdditionalInfoPayload::dataInt32>( + int32Values); + aidlEvent->payload.set<Event::EventPayload::additional>(additionalInfo); + break; + } + default: { + CHECK_GE((int32_t)hidlEvent.sensorType, (int32_t)V2_1SensorType::DEVICE_PRIVATE_BASE); + AidlEvent::EventPayload::Data data; + std::copy(hidlEvent.u.data.data(), hidlEvent.u.data.data() + hidlEvent.u.data.size(), + std::begin(data.values)); + aidlEvent->payload.set<Event::EventPayload::data>(data); + break; + } + } +} + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/sensors/aidl/default/multihal/HalProxyAidl.cpp b/sensors/aidl/default/multihal/HalProxyAidl.cpp new file mode 100644 index 0000000000..64805e6638 --- /dev/null +++ b/sensors/aidl/default/multihal/HalProxyAidl.cpp @@ -0,0 +1,213 @@ +/* + * 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 "HalProxyAidl.h" +#include <aidlcommonsupport/NativeHandle.h> +#include <fmq/AidlMessageQueue.h> +#include <hidl/Status.h> +#include "ConvertUtils.h" +#include "EventMessageQueueWrapperAidl.h" +#include "ISensorsCallbackWrapperAidl.h" +#include "WakeLockMessageQueueWrapperAidl.h" +#include "convertV2_1.h" + +using ::aidl::android::hardware::common::fmq::MQDescriptor; +using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite; +using ::aidl::android::hardware::sensors::ISensors; +using ::aidl::android::hardware::sensors::ISensorsCallback; +using ::android::hardware::sensors::V2_1::implementation::convertToOldEvent; + +namespace aidl { +namespace android { +namespace hardware { +namespace sensors { +namespace implementation { + +static binder_status_t resultToBinderStatus(::android::hardware::sensors::V1_0::Result result) { + switch (result) { + case ::android::hardware::sensors::V1_0::Result::OK: + return STATUS_OK; + case ::android::hardware::sensors::V1_0::Result::PERMISSION_DENIED: + return STATUS_PERMISSION_DENIED; + case ::android::hardware::sensors::V1_0::Result::NO_MEMORY: + return STATUS_NO_MEMORY; + case ::android::hardware::sensors::V1_0::Result::BAD_VALUE: + return STATUS_BAD_VALUE; + case ::android::hardware::sensors::V1_0::Result::INVALID_OPERATION: + return STATUS_INVALID_OPERATION; + } +} + +static ::android::hardware::sensors::V1_0::RateLevel convertRateLevel( + ISensors::RateLevel rateLevel) { + switch (rateLevel) { + case ISensors::RateLevel::STOP: + return ::android::hardware::sensors::V1_0::RateLevel::STOP; + case ISensors::RateLevel::NORMAL: + return ::android::hardware::sensors::V1_0::RateLevel::NORMAL; + case ISensors::RateLevel::FAST: + return ::android::hardware::sensors::V1_0::RateLevel::FAST; + case ISensors::RateLevel::VERY_FAST: + return ::android::hardware::sensors::V1_0::RateLevel::VERY_FAST; + } +} + +static ::android::hardware::sensors::V1_0::OperationMode convertOperationMode( + ISensors::OperationMode operationMode) { + switch (operationMode) { + case ISensors::OperationMode::NORMAL: + return ::android::hardware::sensors::V1_0::OperationMode::NORMAL; + case ISensors::OperationMode::DATA_INJECTION: + return ::android::hardware::sensors::V1_0::OperationMode::DATA_INJECTION; + } +} + +static ::android::hardware::sensors::V1_0::SharedMemType convertSharedMemType( + ISensors::SharedMemInfo::SharedMemType sharedMemType) { + switch (sharedMemType) { + case ISensors::SharedMemInfo::SharedMemType::ASHMEM: + return ::android::hardware::sensors::V1_0::SharedMemType::ASHMEM; + case ISensors::SharedMemInfo::SharedMemType::GRALLOC: + return ::android::hardware::sensors::V1_0::SharedMemType::GRALLOC; + } +} + +static ::android::hardware::sensors::V1_0::SharedMemFormat convertSharedMemFormat( + ISensors::SharedMemInfo::SharedMemFormat sharedMemFormat) { + switch (sharedMemFormat) { + case ISensors::SharedMemInfo::SharedMemFormat::SENSORS_EVENT: + return ::android::hardware::sensors::V1_0::SharedMemFormat::SENSORS_EVENT; + } +} + +static ::android::hardware::sensors::V1_0::SharedMemInfo convertSharedMemInfo( + const ISensors::SharedMemInfo& sharedMemInfo) { + ::android::hardware::sensors::V1_0::SharedMemInfo v1SharedMemInfo; + v1SharedMemInfo.type = convertSharedMemType(sharedMemInfo.type); + v1SharedMemInfo.format = convertSharedMemFormat(sharedMemInfo.format); + v1SharedMemInfo.size = sharedMemInfo.size; + v1SharedMemInfo.memoryHandle = + ::android::hardware::hidl_handle(::android::makeFromAidl(sharedMemInfo.memoryHandle)); + return v1SharedMemInfo; +} + +::ndk::ScopedAStatus HalProxyAidl::activate(int32_t in_sensorHandle, bool in_enabled) { + return ndk::ScopedAStatus::fromStatus( + resultToBinderStatus(HalProxy::activate(in_sensorHandle, in_enabled))); +} + +::ndk::ScopedAStatus HalProxyAidl::batch(int32_t in_sensorHandle, int64_t in_samplingPeriodNs, + int64_t in_maxReportLatencyNs) { + return ndk::ScopedAStatus::fromStatus(resultToBinderStatus( + HalProxy::batch(in_sensorHandle, in_samplingPeriodNs, in_maxReportLatencyNs))); +} + +::ndk::ScopedAStatus HalProxyAidl::configDirectReport(int32_t in_sensorHandle, + int32_t in_channelHandle, + ISensors::RateLevel in_rate, + int32_t* _aidl_return) { + binder_status_t binderStatus; + HalProxy::configDirectReport( + in_sensorHandle, in_channelHandle, convertRateLevel(in_rate), + [&binderStatus, _aidl_return](::android::hardware::sensors::V1_0::Result result, + int32_t reportToken) { + binderStatus = resultToBinderStatus(result); + *_aidl_return = reportToken; + }); + return ndk::ScopedAStatus::fromStatus(binderStatus); +} + +::ndk::ScopedAStatus HalProxyAidl::flush(int32_t in_sensorHandle) { + return ndk::ScopedAStatus::fromStatus(resultToBinderStatus(HalProxy::flush(in_sensorHandle))); +} + +::ndk::ScopedAStatus HalProxyAidl::getSensorsList( + std::vector<::aidl::android::hardware::sensors::SensorInfo>* _aidl_return) { + for (const auto& sensor : HalProxy::getSensors()) { + _aidl_return->push_back(convertSensorInfo(sensor.second)); + } + return ndk::ScopedAStatus::ok(); +} + +::ndk::ScopedAStatus HalProxyAidl::initialize( + const MQDescriptor<::aidl::android::hardware::sensors::Event, SynchronizedReadWrite>& + in_eventQueueDescriptor, + const MQDescriptor<int32_t, SynchronizedReadWrite>& in_wakeLockDescriptor, + const std::shared_ptr<ISensorsCallback>& in_sensorsCallback) { + ::android::sp<::android::hardware::sensors::V2_1::implementation::ISensorsCallbackWrapperBase> + dynamicCallback = new ISensorsCallbackWrapperAidl(in_sensorsCallback); + + auto aidlEventQueue = + std::make_unique<::android::AidlMessageQueue<::aidl::android::hardware::sensors::Event, + SynchronizedReadWrite>>( + in_eventQueueDescriptor, true /* resetPointers */); + std::unique_ptr< + ::android::hardware::sensors::V2_1::implementation::EventMessageQueueWrapperBase> + eventQueue = std::make_unique<EventMessageQueueWrapperAidl>(aidlEventQueue); + + auto aidlWakeLockQueue = + std::make_unique<::android::AidlMessageQueue<int32_t, SynchronizedReadWrite>>( + in_wakeLockDescriptor, true /* resetPointers */); + std::unique_ptr< + ::android::hardware::sensors::V2_1::implementation::WakeLockMessageQueueWrapperBase> + wakeLockQueue = std::make_unique<WakeLockMessageQueueWrapperAidl>(aidlWakeLockQueue); + + return ndk::ScopedAStatus::fromStatus( + resultToBinderStatus(initializeCommon(eventQueue, wakeLockQueue, dynamicCallback))); +} + +::ndk::ScopedAStatus HalProxyAidl::injectSensorData( + const ::aidl::android::hardware::sensors::Event& in_event) { + ::android::hardware::sensors::V2_1::Event hidlEvent; + convertToHidlEvent(in_event, &hidlEvent); + return ndk::ScopedAStatus::fromStatus( + resultToBinderStatus(HalProxy::injectSensorData(convertToOldEvent(hidlEvent)))); +} + +::ndk::ScopedAStatus HalProxyAidl::registerDirectChannel(const ISensors::SharedMemInfo& in_mem, + int32_t* _aidl_return) { + binder_status_t binderStatus; + ::android::hardware::sensors::V1_0::SharedMemInfo sharedMemInfo = convertSharedMemInfo(in_mem); + + HalProxy::registerDirectChannel( + sharedMemInfo, + [&binderStatus, _aidl_return](::android::hardware::sensors::V1_0::Result result, + int32_t reportToken) { + binderStatus = resultToBinderStatus(result); + *_aidl_return = reportToken; + }); + + native_handle_delete( + const_cast<native_handle_t*>(sharedMemInfo.memoryHandle.getNativeHandle())); + return ndk::ScopedAStatus::fromStatus(binderStatus); +} + +::ndk::ScopedAStatus HalProxyAidl::setOperationMode( + ::aidl::android::hardware::sensors::ISensors::OperationMode in_mode) { + return ndk::ScopedAStatus::fromStatus( + resultToBinderStatus(HalProxy::setOperationMode(convertOperationMode(in_mode)))); +} + +::ndk::ScopedAStatus HalProxyAidl::unregisterDirectChannel(int32_t in_channelHandle) { + return ndk::ScopedAStatus::fromStatus( + resultToBinderStatus(HalProxy::unregisterDirectChannel(in_channelHandle))); +} + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl
\ No newline at end of file diff --git a/sensors/aidl/default/multihal/include/ConvertUtils.h b/sensors/aidl/default/multihal/include/ConvertUtils.h new file mode 100644 index 0000000000..91dfabde3a --- /dev/null +++ b/sensors/aidl/default/multihal/include/ConvertUtils.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <aidl/android/hardware/sensors/BnSensors.h> +#include <android/hardware/sensors/2.1/types.h> + +namespace aidl { +namespace android { +namespace hardware { +namespace sensors { +namespace implementation { + +/** + * Generates an AIDL SensorInfo instance from the passed HIDL V2.1 SensorInfo instance. + */ +::aidl::android::hardware::sensors::SensorInfo convertSensorInfo( + const ::android::hardware::sensors::V2_1::SensorInfo& sensorInfo); + +/** + * Populates a HIDL V2.1 Event instance based on an AIDL Event instance. + */ +void convertToHidlEvent(const ::aidl::android::hardware::sensors::Event& aidlEvent, + ::android::hardware::sensors::V2_1::Event* hidlEvent); + +/** + * Populates an AIDL Event instance based on a HIDL V2.1 Event instance. + */ +void convertToAidlEvent(const ::android::hardware::sensors::V2_1::Event& hidlEvent, + ::aidl::android::hardware::sensors::Event* aidlEvent); + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl
\ No newline at end of file diff --git a/sensors/aidl/default/multihal/include/EventMessageQueueWrapperAidl.h b/sensors/aidl/default/multihal/include/EventMessageQueueWrapperAidl.h new file mode 100644 index 0000000000..3eaa1d4335 --- /dev/null +++ b/sensors/aidl/default/multihal/include/EventMessageQueueWrapperAidl.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <android/hardware/sensors/2.1/types.h> +#include <fmq/AidlMessageQueue.h> +#include "ConvertUtils.h" +#include "EventMessageQueueWrapper.h" +#include "ISensorsWrapper.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace sensors { +namespace implementation { + +class EventMessageQueueWrapperAidl + : public ::android::hardware::sensors::V2_1::implementation::EventMessageQueueWrapperBase { + public: + EventMessageQueueWrapperAidl( + std::unique_ptr<::android::AidlMessageQueue< + ::aidl::android::hardware::sensors::Event, + ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>>& queue) + : mQueue(std::move(queue)) {} + + virtual std::atomic<uint32_t>* getEventFlagWord() override { + return mQueue->getEventFlagWord(); + } + + virtual size_t availableToRead() override { return mQueue->availableToRead(); } + + size_t availableToWrite() override { return mQueue->availableToWrite(); } + + virtual bool read(::android::hardware::sensors::V2_1::Event* events, + size_t numToRead) override { + bool success = mQueue->read(mIntermediateEventBuffer.data(), numToRead); + for (int i = 0; i < numToRead; ++i) { + convertToHidlEvent(mIntermediateEventBuffer[i], &events[i]); + } + return success; + } + + bool write(const ::android::hardware::sensors::V2_1::Event* events, + size_t numToWrite) override { + for (int i = 0; i < numToWrite; ++i) { + convertToAidlEvent(events[i], &mIntermediateEventBuffer[i]); + } + return mQueue->write(mIntermediateEventBuffer.data(), numToWrite); + } + + virtual bool write( + const std::vector<::android::hardware::sensors::V2_1::Event>& events) override { + for (int i = 0; i < events.size(); ++i) { + convertToAidlEvent(events[i], &mIntermediateEventBuffer[i]); + } + return mQueue->write(mIntermediateEventBuffer.data(), events.size()); + } + + bool writeBlocking(const ::android::hardware::sensors::V2_1::Event* events, size_t count, + uint32_t readNotification, uint32_t writeNotification, int64_t timeOutNanos, + ::android::hardware::EventFlag* evFlag) override { + for (int i = 0; i < count; ++i) { + convertToAidlEvent(events[i], &mIntermediateEventBuffer[i]); + } + return mQueue->writeBlocking(mIntermediateEventBuffer.data(), count, readNotification, + writeNotification, timeOutNanos, evFlag); + } + + size_t getQuantumCount() override { return mQueue->getQuantumCount(); } + + private: + std::unique_ptr<::android::AidlMessageQueue< + ::aidl::android::hardware::sensors::Event, + ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>> + mQueue; + std::array<::aidl::android::hardware::sensors::Event, + ::android::hardware::sensors::V2_1::implementation::MAX_RECEIVE_BUFFER_EVENT_COUNT> + mIntermediateEventBuffer; +}; + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/sensors/aidl/default/multihal/include/HalProxyAidl.h b/sensors/aidl/default/multihal/include/HalProxyAidl.h new file mode 100644 index 0000000000..7401726cf9 --- /dev/null +++ b/sensors/aidl/default/multihal/include/HalProxyAidl.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <aidl/android/hardware/sensors/BnSensors.h> +#include "HalProxy.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace sensors { +namespace implementation { + +class HalProxyAidl : public ::android::hardware::sensors::V2_1::implementation::HalProxy, + public ::aidl::android::hardware::sensors::BnSensors { + ::ndk::ScopedAStatus activate(int32_t in_sensorHandle, bool in_enabled) override; + ::ndk::ScopedAStatus batch(int32_t in_sensorHandle, int64_t in_samplingPeriodNs, + int64_t in_maxReportLatencyNs) override; + ::ndk::ScopedAStatus configDirectReport( + int32_t in_sensorHandle, int32_t in_channelHandle, + ::aidl::android::hardware::sensors::ISensors::RateLevel in_rate, + int32_t* _aidl_return) override; + ::ndk::ScopedAStatus flush(int32_t in_sensorHandle) override; + ::ndk::ScopedAStatus getSensorsList( + std::vector<::aidl::android::hardware::sensors::SensorInfo>* _aidl_return) override; + ::ndk::ScopedAStatus initialize( + const ::aidl::android::hardware::common::fmq::MQDescriptor< + ::aidl::android::hardware::sensors::Event, + ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>& + in_eventQueueDescriptor, + const ::aidl::android::hardware::common::fmq::MQDescriptor< + int32_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>& + in_wakeLockDescriptor, + const std::shared_ptr<::aidl::android::hardware::sensors::ISensorsCallback>& + in_sensorsCallback) override; + ::ndk::ScopedAStatus injectSensorData( + const ::aidl::android::hardware::sensors::Event& in_event) override; + ::ndk::ScopedAStatus registerDirectChannel( + const ::aidl::android::hardware::sensors::ISensors::SharedMemInfo& in_mem, + int32_t* _aidl_return) override; + ::ndk::ScopedAStatus setOperationMode( + ::aidl::android::hardware::sensors::ISensors::OperationMode in_mode) override; + ::ndk::ScopedAStatus unregisterDirectChannel(int32_t in_channelHandle) override; +}; + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/sensors/aidl/default/multihal/include/ISensorsCallbackWrapperAidl.h b/sensors/aidl/default/multihal/include/ISensorsCallbackWrapperAidl.h new file mode 100644 index 0000000000..6ef6c6398d --- /dev/null +++ b/sensors/aidl/default/multihal/include/ISensorsCallbackWrapperAidl.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "ConvertUtils.h" +#include "ISensorsCallbackWrapper.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace sensors { +namespace implementation { + +static std::vector<::aidl::android::hardware::sensors::SensorInfo> convertToAidlSensorInfos( + const ::android::hardware::hidl_vec<::android::hardware::sensors::V2_1::SensorInfo>& + sensorInfos) { + std::vector<::aidl::android::hardware::sensors::SensorInfo> aidlSensorInfos; + for (const auto& sensorInfo : sensorInfos) { + aidlSensorInfos.push_back(convertSensorInfo(sensorInfo)); + } + return aidlSensorInfos; +} + +class ISensorsCallbackWrapperAidl + : public ::android::hardware::sensors::V2_1::implementation::ISensorsCallbackWrapperBase { + public: + ISensorsCallbackWrapperAidl( + std::shared_ptr<::aidl::android::hardware::sensors::ISensorsCallback> sensorsCallback) + : mSensorsCallback(sensorsCallback) {} + + ::android::hardware::Return<void> onDynamicSensorsConnected( + const ::android::hardware::hidl_vec<::android::hardware::sensors::V2_1::SensorInfo>& + sensorInfos) override { + mSensorsCallback->onDynamicSensorsConnected(convertToAidlSensorInfos(sensorInfos)); + return ::android::hardware::Void(); + } + + ::android::hardware::Return<void> onDynamicSensorsDisconnected( + const ::android::hardware::hidl_vec<int32_t>& sensorHandles) override { + mSensorsCallback->onDynamicSensorsDisconnected(sensorHandles); + return ::android::hardware::Void(); + } + + private: + std::shared_ptr<::aidl::android::hardware::sensors::ISensorsCallback> mSensorsCallback; +}; + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl
\ No newline at end of file diff --git a/sensors/aidl/default/multihal/include/WakeLockMessageQueueWrapperAidl.h b/sensors/aidl/default/multihal/include/WakeLockMessageQueueWrapperAidl.h new file mode 100644 index 0000000000..6be0b69aa3 --- /dev/null +++ b/sensors/aidl/default/multihal/include/WakeLockMessageQueueWrapperAidl.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <android/hardware/sensors/2.1/types.h> +#include <fmq/AidlMessageQueue.h> +#include "WakeLockMessageQueueWrapper.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace sensors { +namespace implementation { + +class WakeLockMessageQueueWrapperAidl + : public ::android::hardware::sensors::V2_1::implementation::WakeLockMessageQueueWrapperBase { + public: + WakeLockMessageQueueWrapperAidl( + std::unique_ptr<::android::AidlMessageQueue< + int32_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>>& queue) + : mQueue(std::move(queue)) {} + + virtual std::atomic<uint32_t>* getEventFlagWord() override { + return mQueue->getEventFlagWord(); + } + + bool readBlocking(uint32_t* wakeLocks, size_t numToRead, uint32_t readNotification, + uint32_t writeNotification, int64_t timeOutNanos, + ::android::hardware::EventFlag* evFlag) override { + return mQueue->readBlocking(reinterpret_cast<int32_t*>(wakeLocks), numToRead, + readNotification, writeNotification, timeOutNanos, evFlag); + } + + bool write(const uint32_t* wakeLock) override { + return mQueue->write(reinterpret_cast<const int32_t*>(wakeLock)); + } + + private: + std::unique_ptr<::android::AidlMessageQueue< + int32_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>> + mQueue; +}; + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/sensors/aidl/multihal/Android.bp b/sensors/aidl/multihal/Android.bp new file mode 100644 index 0000000000..6d35dafd6d --- /dev/null +++ b/sensors/aidl/multihal/Android.bp @@ -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 { + // 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.sensors-service.multihal", + vendor: true, + relative_install_path: "hw", + srcs: [ + "service.cpp", + ], + header_libs: [ + "android.hardware.sensors@2.X-multihal.header", + "android.hardware.sensors@2.X-shared-utils", + ], + init_rc: ["android.hardware.sensors-service-multihal.rc"], + vintf_fragments: ["android.hardware.sensors-multihal.xml"], + shared_libs: [ + "android.hardware.sensors@2.0-ScopedWakelock", + "android.hardware.sensors@2.0", + "android.hardware.sensors@2.1", + "android.hardware.sensors-V1-ndk", + "libbase", + "libcutils", + "libfmq", + "liblog", + "libpower", + "libutils", + "libbinder_ndk", + "libhidlbase", + ], + static_libs: [ + "libaidlcommonsupport", + "android.hardware.sensors@1.0-convert", + "android.hardware.sensors@2.X-multihal", + "android.hardware.sensors@aidl-multihal", + ], +} diff --git a/sensors/aidl/multihal/OWNERS b/sensors/aidl/multihal/OWNERS new file mode 100644 index 0000000000..e9556700d6 --- /dev/null +++ b/sensors/aidl/multihal/OWNERS @@ -0,0 +1,3 @@ +arthuri@google.com +bduddie@google.com +stange@google.com
\ No newline at end of file diff --git a/sensors/aidl/multihal/android.hardware.sensors-multihal.xml b/sensors/aidl/multihal/android.hardware.sensors-multihal.xml new file mode 100644 index 0000000000..d78edffaf9 --- /dev/null +++ b/sensors/aidl/multihal/android.hardware.sensors-multihal.xml @@ -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. + --> + +<manifest version="1.0" type="device"> + <hal format="aidl"> + <name>android.hardware.sensors</name> + <version>1</version> + <fqname>ISensors/default</fqname> + </hal> +</manifest> diff --git a/sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc b/sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc new file mode 100644 index 0000000000..3f91a0a04a --- /dev/null +++ b/sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc @@ -0,0 +1,7 @@ +service vendor.sensors-hal-multihal /vendor/bin/hw/android.hardware.sensors-service.multihal + class hal + user system + group system wakelock context_hub + task_profiles ServiceCapacityLow + capabilities BLOCK_SUSPEND + rlimit rtprio 10 10
\ No newline at end of file diff --git a/sensors/aidl/multihal/service.cpp b/sensors/aidl/multihal/service.cpp new file mode 100644 index 0000000000..11c108a395 --- /dev/null +++ b/sensors/aidl/multihal/service.cpp @@ -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. + */ + +#include <android-base/logging.h> +#include <android/binder_manager.h> +#include <android/binder_process.h> +#include "HalProxyAidl.h" + +using ::aidl::android::hardware::sensors::implementation::HalProxyAidl; + +int main() { + ABinderProcess_setThreadPoolMaxThreadCount(0); + + // Make a default multihal sensors service + auto halProxy = ndk::SharedRefBase::make<HalProxyAidl>(); + const std::string halProxyName = std::string() + HalProxyAidl::descriptor + "/default"; + binder_status_t status = + AServiceManager_addService(halProxy->asBinder().get(), halProxyName.c_str()); + CHECK_EQ(status, STATUS_OK); + + ABinderProcess_joinThreadPool(); + return EXIT_FAILURE; // should not reach +} diff --git a/sensors/aidl/vts/Android.bp b/sensors/aidl/vts/Android.bp index 5a519a5a1e..b5a5f15691 100644 --- a/sensors/aidl/vts/Android.bp +++ b/sensors/aidl/vts/Android.bp @@ -34,6 +34,7 @@ cc_test { shared_libs: [ "libbinder", "libbinder_ndk", + "libvndksupport", "libfmq", "android.hardware.common-V2-ndk", "android.hardware.common.fmq-V1-ndk", @@ -41,6 +42,7 @@ cc_test { static_libs: [ "android.hardware.sensors-V1-ndk", "VtsHalSensorsTargetTestUtils", + "libaidlcommonsupport", ], test_suites: [ "general-tests", diff --git a/sensors/aidl/vts/SensorsAidlTestSharedMemory.h b/sensors/aidl/vts/SensorsAidlTestSharedMemory.h new file mode 100644 index 0000000000..4b5916a0d7 --- /dev/null +++ b/sensors/aidl/vts/SensorsAidlTestSharedMemory.h @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_SENSORS_AIDL_TEST_SHARED_MEMORY_H +#define ANDROID_SENSORS_AIDL_TEST_SHARED_MEMORY_H + +#include "sensors-vts-utils/GrallocWrapper.h" + +#include <aidlcommonsupport/NativeHandle.h> +#include <android-base/macros.h> +#include <log/log.h> + +#include <sys/mman.h> +#include <cinttypes> + +#include <cutils/ashmem.h> + +using ::aidl::android::hardware::sensors::BnSensors; +using ::aidl::android::hardware::sensors::Event; +using ::aidl::android::hardware::sensors::ISensors; +using ::aidl::android::hardware::sensors::SensorType; + +template <class SensorType, class Event> +class SensorsAidlTestSharedMemory { + public: + static SensorsAidlTestSharedMemory* create(ISensors::SharedMemInfo::SharedMemType type, + size_t size) { + constexpr size_t kMaxSize = + 128 * 1024 * 1024; // sensor test should not need more than 128M + if (size == 0 || size >= kMaxSize) { + return nullptr; + } + + auto m = new SensorsAidlTestSharedMemory<SensorType, Event>(type, size); + if (m->mSize != size || m->mBuffer == nullptr) { + delete m; + m = nullptr; + } + return m; + } + + ISensors::SharedMemInfo getSharedMemInfo() const { + ISensors::SharedMemInfo mem = { + .type = mType, + .format = ISensors::SharedMemInfo::SharedMemFormat::SENSORS_EVENT, + .size = static_cast<int32_t>(mSize), + .memoryHandle = android::dupToAidl(mNativeHandle)}; + return mem; + } + char* getBuffer() const { return mBuffer; } + size_t getSize() const { return mSize; } + std::vector<Event> parseEvents(int64_t lastCounter = -1, size_t offset = 0) const { + constexpr size_t kEventSize = + static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_TOTAL_LENGTH); + constexpr size_t kOffsetSize = + static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_FIELD); + constexpr size_t kOffsetToken = + static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_REPORT_TOKEN); + constexpr size_t kOffsetType = + static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_SENSOR_TYPE); + constexpr size_t kOffsetAtomicCounter = static_cast<size_t>( + BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_ATOMIC_COUNTER); + constexpr size_t kOffsetTimestamp = + static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_TIMESTAMP); + constexpr size_t kOffsetData = + static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_DATA); + + std::vector<Event> events; + std::vector<float> data(16); + + while (offset + kEventSize <= mSize) { + int64_t atomicCounter = + *reinterpret_cast<uint32_t*>(mBuffer + offset + kOffsetAtomicCounter); + if (atomicCounter <= lastCounter) { + ALOGV("atomicCounter = %" PRId64 ", lastCounter = %" PRId64, atomicCounter, + lastCounter); + break; + } + + int32_t size = *reinterpret_cast<int32_t*>(mBuffer + offset + kOffsetSize); + if (size != kEventSize) { + // unknown error, events parsed may be wrong, remove all + events.clear(); + break; + } + + int32_t token = *reinterpret_cast<int32_t*>(mBuffer + offset + kOffsetToken); + int32_t type = *reinterpret_cast<int32_t*>(mBuffer + offset + kOffsetType); + int64_t timestamp = *reinterpret_cast<int64_t*>(mBuffer + offset + kOffsetTimestamp); + + ALOGV("offset = %zu, cnt %" PRId64 ", token %" PRId32 ", type %" PRId32 + ", timestamp %" PRId64, + offset, atomicCounter, token, type, timestamp); + + Event event = { + .timestamp = timestamp, + .sensorHandle = token, + .sensorType = type, + }; + + event.set<Event::Data>(reinterpret_cast<float*>(mBuffer + offset + kOffsetData)); + // event.u.data = android::hardware::hidl_array<float, + // 16>(reinterpret_cast<float*>(mBuffer + offset + kOffsetData)); + + events.push_back(event); + + lastCounter = atomicCounter; + offset += kEventSize; + } + + return events; + } + + virtual ~SensorsAidlTestSharedMemory() { + switch (mType) { + case ISensors::SharedMemInfo::SharedMemType::ASHMEM: { + if (mSize != 0) { + ::munmap(mBuffer, mSize); + mBuffer = nullptr; + + ::native_handle_close(mNativeHandle); + ::native_handle_delete(mNativeHandle); + + mNativeHandle = nullptr; + mSize = 0; + } + break; + } + case ISensors::SharedMemInfo::SharedMemType::GRALLOC: { + if (mSize != 0) { + mGrallocWrapper->freeBuffer(mNativeHandle); + mNativeHandle = nullptr; + mSize = 0; + } + break; + } + default: { + if (mNativeHandle != nullptr || mSize != 0 || mBuffer != nullptr) { + ALOGE("SensorsAidlTestSharedMemory %p not properly destructed: " + "type %d, native handle %p, size %zu, buffer %p", + this, static_cast<int>(mType), mNativeHandle, mSize, mBuffer); + } + break; + } + } + } + + private: + SensorsAidlTestSharedMemory(ISensors::SharedMemInfo::SharedMemType type, size_t size) + : mType(type), mSize(0), mBuffer(nullptr) { + native_handle_t* handle = nullptr; + char* buffer = nullptr; + switch (type) { + case ISensors::SharedMemInfo::SharedMemType::ASHMEM: { + int fd; + handle = ::native_handle_create(1 /*nFds*/, 0 /*nInts*/); + if (handle != nullptr) { + handle->data[0] = fd = + ::ashmem_create_region("SensorsAidlTestSharedMemory", size); + if (handle->data[0] > 0) { + // memory is pinned by default + buffer = static_cast<char*>( + ::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); + if (buffer != reinterpret_cast<char*>(MAP_FAILED)) { + break; + } + ::native_handle_close(handle); + } + ::native_handle_delete(handle); + handle = nullptr; + } + break; + } + case ISensors::SharedMemInfo::SharedMemType::GRALLOC: { + mGrallocWrapper = std::make_unique<::android::GrallocWrapper>(); + if (!mGrallocWrapper->isInitialized()) { + break; + } + + std::pair<native_handle_t*, void*> buf = mGrallocWrapper->allocate(size); + handle = buf.first; + buffer = static_cast<char*>(buf.second); + break; + } + default: + break; + } + + if (buffer != nullptr) { + mNativeHandle = handle; + mSize = size; + mBuffer = buffer; + } + } + + ISensors::SharedMemInfo::SharedMemType mType; + native_handle_t* mNativeHandle; + size_t mSize; + char* mBuffer; + std::unique_ptr<::android::GrallocWrapper> mGrallocWrapper; + + DISALLOW_COPY_AND_ASSIGN(SensorsAidlTestSharedMemory); +}; + +#endif // ANDROID_SENSORS_TEST_SHARED_MEMORY_H diff --git a/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp b/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp index 33645b2a95..1bc7263048 100644 --- a/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp +++ b/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp @@ -26,6 +26,7 @@ #include <utils/SystemClock.h> #include "SensorsAidlEnvironment.h" +#include "SensorsAidlTestSharedMemory.h" #include "sensors-vts-utils/SensorsVtsEnvironmentBase.h" #include <cinttypes> @@ -43,6 +44,9 @@ using aidl::android::hardware::sensors::SensorType; using android::ProcessState; using std::chrono::duration_cast; +constexpr size_t kEventSize = + static_cast<size_t>(ISensors::DIRECT_REPORT_SENSOR_EVENT_TOTAL_LENGTH); + namespace { static void assertTypeMatchStringType(SensorType type, const std::string& stringType) { @@ -97,6 +101,24 @@ static void assertTypeMatchStringType(SensorType type, const std::string& string } } +bool isDirectChannelTypeSupported(SensorInfo sensor, ISensors::SharedMemInfo::SharedMemType type) { + switch (type) { + case ISensors::SharedMemInfo::SharedMemType::ASHMEM: + return (sensor.flags & SensorInfo::SENSOR_FLAG_BITS_DIRECT_CHANNEL_ASHMEM) != 0; + case ISensors::SharedMemInfo::SharedMemType::GRALLOC: + return (sensor.flags & SensorInfo::SENSOR_FLAG_BITS_DIRECT_CHANNEL_GRALLOC) != 0; + default: + return false; + } +} + +bool isDirectReportRateSupported(SensorInfo sensor, ISensors::RateLevel rate) { + unsigned int r = static_cast<unsigned int>(sensor.flags & + SensorInfo::SENSOR_FLAG_BITS_MASK_DIRECT_REPORT) >> + static_cast<unsigned int>(SensorInfo::SENSOR_FLAG_SHIFT_DIRECT_REPORT); + return r >= static_cast<unsigned int>(rate); +} + int expectedReportModeForType(SensorType type) { switch (type) { case SensorType::ACCELEROMETER: @@ -286,6 +308,24 @@ class SensorsAidlTest : public testing::TestWithParam<std::string> { std::vector<SensorInfo> getOneShotSensors(); std::vector<SensorInfo> getInjectEventSensors(); + void verifyDirectChannel(ISensors::SharedMemInfo::SharedMemType memType); + + void verifyRegisterDirectChannel( + std::shared_ptr<SensorsAidlTestSharedMemory<SensorType, Event>> mem, + int32_t* directChannelHandle, bool supportsSharedMemType, + bool supportsAnyDirectChannel); + + void verifyConfigure(const SensorInfo& sensor, ISensors::SharedMemInfo::SharedMemType memType, + int32_t directChannelHandle, bool directChannelSupported); + + void queryDirectChannelSupport(ISensors::SharedMemInfo::SharedMemType memType, + bool* supportsSharedMemType, bool* supportsAnyDirectChannel); + + void verifyUnregisterDirectChannel(int32_t* directChannelHandle, bool supportsAnyDirectChannel); + + void checkRateLevel(const SensorInfo& sensor, int32_t directChannelHandle, + ISensors::RateLevel rateLevel, int32_t* reportToken); + inline std::shared_ptr<ISensors>& getSensors() { return mEnvironment->mSensors; } inline SensorsAidlEnvironment* getEnvironment() { return mEnvironment; } @@ -313,6 +353,18 @@ class SensorsAidlTest : public testing::TestWithParam<std::string> { ndk::ScopedAStatus flush(int32_t sensorHandle) { return getSensors()->flush(sensorHandle); } + ndk::ScopedAStatus registerDirectChannel(const ISensors::SharedMemInfo& mem, + int32_t* aidlReturn); + + ndk::ScopedAStatus unregisterDirectChannel(int32_t* channelHandle) { + return getSensors()->unregisterDirectChannel(*channelHandle); + } + + ndk::ScopedAStatus configDirectReport(int32_t sensorHandle, int32_t channelHandle, + ISensors::RateLevel rate, int32_t* reportToken) { + return getSensors()->configDirectReport(sensorHandle, channelHandle, rate, reportToken); + } + void runSingleFlushTest(const std::vector<SensorInfo>& sensors, bool activateSensor, int32_t expectedFlushCount, bool expectedResult); @@ -334,6 +386,19 @@ class SensorsAidlTest : public testing::TestWithParam<std::string> { SensorsAidlEnvironment* mEnvironment; }; +ndk::ScopedAStatus SensorsAidlTest::registerDirectChannel(const ISensors::SharedMemInfo& mem, + int32_t* aidlReturn) { + // If registeration of a channel succeeds, add the handle of channel to a set so that it can be + // unregistered when test fails. Unregister a channel does not remove the handle on purpose. + // Unregistering a channel more than once should not have negative effect. + + ndk::ScopedAStatus status = getSensors()->registerDirectChannel(mem, aidlReturn); + if (status.isOk()) { + mDirectChannelHandles.insert(*aidlReturn); + } + return status; +} + std::vector<SensorInfo> SensorsAidlTest::getSensorsList() { std::vector<SensorInfo> sensorInfoList; checkIsOk(getSensors()->getSensorsList(&sensorInfoList)); @@ -850,12 +915,141 @@ TEST_P(SensorsAidlTest, NoStaleEvents) { } } +void SensorsAidlTest::checkRateLevel(const SensorInfo& sensor, int32_t directChannelHandle, + ISensors::RateLevel rateLevel, int32_t* reportToken) { + ndk::ScopedAStatus status = + configDirectReport(sensor.sensorHandle, directChannelHandle, rateLevel, reportToken); + + SCOPED_TRACE(::testing::Message() + << " handle=0x" << std::hex << std::setw(8) << std::setfill('0') + << sensor.sensorHandle << std::dec << " type=" << static_cast<int>(sensor.type) + << " name=" << sensor.name); + + if (isDirectReportRateSupported(sensor, rateLevel)) { + ASSERT_TRUE(status.isOk()); + if (rateLevel != ISensors::RateLevel::STOP) { + ASSERT_GT(*reportToken, 0); + } else { + ASSERT_EQ(status.getExceptionCode(), EX_ILLEGAL_ARGUMENT); + } + } +} + +void SensorsAidlTest::queryDirectChannelSupport(ISensors::SharedMemInfo::SharedMemType memType, + bool* supportsSharedMemType, + bool* supportsAnyDirectChannel) { + *supportsSharedMemType = false; + *supportsAnyDirectChannel = false; + for (const SensorInfo& curSensor : getSensorsList()) { + if (isDirectChannelTypeSupported(curSensor, memType)) { + *supportsSharedMemType = true; + } + if (isDirectChannelTypeSupported(curSensor, + ISensors::SharedMemInfo::SharedMemType::ASHMEM) || + isDirectChannelTypeSupported(curSensor, + ISensors::SharedMemInfo::SharedMemType::GRALLOC)) { + *supportsAnyDirectChannel = true; + } + + if (*supportsSharedMemType && *supportsAnyDirectChannel) { + break; + } + } +} + +void SensorsAidlTest::verifyRegisterDirectChannel( + std::shared_ptr<SensorsAidlTestSharedMemory<SensorType, Event>> mem, + int32_t* directChannelHandle, bool supportsSharedMemType, bool supportsAnyDirectChannel) { + char* buffer = mem->getBuffer(); + size_t size = mem->getSize(); + + if (supportsSharedMemType) { + memset(buffer, 0xff, size); + } + + int32_t channelHandle; + + ::ndk::ScopedAStatus status = registerDirectChannel(mem->getSharedMemInfo(), &channelHandle); + if (supportsSharedMemType) { + ASSERT_TRUE(status.isOk()); + ASSERT_EQ(channelHandle, 0); + } else { + int32_t error = supportsAnyDirectChannel ? EX_ILLEGAL_ARGUMENT : EX_UNSUPPORTED_OPERATION; + ASSERT_EQ(status.getExceptionCode(), error); + ASSERT_EQ(channelHandle, -1); + } + *directChannelHandle = channelHandle; +} + +void SensorsAidlTest::verifyUnregisterDirectChannel(int32_t* channelHandle, + bool supportsAnyDirectChannel) { + int result = supportsAnyDirectChannel ? EX_NONE : EX_UNSUPPORTED_OPERATION; + ndk::ScopedAStatus status = unregisterDirectChannel(channelHandle); + ASSERT_EQ(status.getExceptionCode(), result); +} + +void SensorsAidlTest::verifyDirectChannel(ISensors::SharedMemInfo::SharedMemType memType) { + constexpr size_t kNumEvents = 1; + constexpr size_t kMemSize = kNumEvents * kEventSize; + + std::shared_ptr<SensorsAidlTestSharedMemory<SensorType, Event>> mem( + SensorsAidlTestSharedMemory<SensorType, Event>::create(memType, kMemSize)); + ASSERT_NE(mem, nullptr); + + bool supportsSharedMemType; + bool supportsAnyDirectChannel; + queryDirectChannelSupport(memType, &supportsSharedMemType, &supportsAnyDirectChannel); + + for (const SensorInfo& sensor : getSensorsList()) { + int32_t directChannelHandle = 0; + verifyRegisterDirectChannel(mem, &directChannelHandle, supportsSharedMemType, + supportsAnyDirectChannel); + verifyConfigure(sensor, memType, directChannelHandle, supportsAnyDirectChannel); + verifyUnregisterDirectChannel(&directChannelHandle, supportsAnyDirectChannel); + } +} + +void SensorsAidlTest::verifyConfigure(const SensorInfo& sensor, + ISensors::SharedMemInfo::SharedMemType memType, + int32_t directChannelHandle, bool supportsAnyDirectChannel) { + SCOPED_TRACE(::testing::Message() + << " handle=0x" << std::hex << std::setw(8) << std::setfill('0') + << sensor.sensorHandle << std::dec << " type=" << static_cast<int>(sensor.type) + << " name=" << sensor.name); + + int32_t reportToken = 0; + if (isDirectChannelTypeSupported(sensor, memType)) { + // Verify that each rate level is properly supported + checkRateLevel(sensor, directChannelHandle, ISensors::RateLevel::NORMAL, &reportToken); + checkRateLevel(sensor, directChannelHandle, ISensors::RateLevel::FAST, &reportToken); + checkRateLevel(sensor, directChannelHandle, ISensors::RateLevel::VERY_FAST, &reportToken); + checkRateLevel(sensor, directChannelHandle, ISensors::RateLevel::STOP, &reportToken); + + // Verify that a sensor handle of -1 is only acceptable when using RateLevel::STOP + ndk::ScopedAStatus status = configDirectReport(-1 /* sensorHandle */, directChannelHandle, + ISensors::RateLevel::NORMAL, &reportToken); + ASSERT_EQ(status.getServiceSpecificError(), android::BAD_VALUE); + + status = configDirectReport(-1 /* sensorHandle */, directChannelHandle, + ISensors::RateLevel::STOP, &reportToken); + ASSERT_TRUE(status.isOk()); + } else { + // directChannelHandle will be -1 here, HAL should either reject it as a bad value if there + // is some level of direct channel report, otherwise return INVALID_OPERATION if direct + // channel is not supported at all + int error = supportsAnyDirectChannel ? EX_ILLEGAL_ARGUMENT : EX_UNSUPPORTED_OPERATION; + ndk::ScopedAStatus status = configDirectReport(sensor.sensorHandle, directChannelHandle, + ISensors::RateLevel::NORMAL, &reportToken); + ASSERT_EQ(status.getExceptionCode(), error); + } +} + TEST_P(SensorsAidlTest, DirectChannelAshmem) { - // TODO(b/195593357): Implement this + verifyDirectChannel(ISensors::SharedMemInfo::SharedMemType::ASHMEM); } TEST_P(SensorsAidlTest, DirectChannelGralloc) { - // TODO(b/195593357): Implement this + verifyDirectChannel(ISensors::SharedMemInfo::SharedMemType::GRALLOC); } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SensorsAidlTest); diff --git a/sensors/common/default/2.X/multihal/HalProxy.cpp b/sensors/common/default/2.X/multihal/HalProxy.cpp index f5fc066820..73b0594f06 100644 --- a/sensors/common/default/2.X/multihal/HalProxy.cpp +++ b/sensors/common/default/2.X/multihal/HalProxy.cpp @@ -176,7 +176,13 @@ Return<Result> HalProxy::initialize_2_1( std::unique_ptr<EventMessageQueueWrapperBase> queue = std::make_unique<EventMessageQueueWrapperV2_1>(eventQueue); - return initializeCommon(queue, wakeLockDescriptor, dynamicCallback); + // Create the Wake Lock FMQ from the wakeLockDescriptor. Reset the read/write positions. + auto hidlWakeLockQueue = + std::make_unique<WakeLockMessageQueue>(wakeLockDescriptor, true /* resetPointers */); + std::unique_ptr<WakeLockMessageQueueWrapperBase> wakeLockQueue = + std::make_unique<WakeLockMessageQueueWrapperHidl>(hidlWakeLockQueue); + + return initializeCommon(queue, wakeLockQueue, dynamicCallback); } Return<Result> HalProxy::initialize( @@ -192,12 +198,18 @@ Return<Result> HalProxy::initialize( std::unique_ptr<EventMessageQueueWrapperBase> queue = std::make_unique<EventMessageQueueWrapperV1_0>(eventQueue); - return initializeCommon(queue, wakeLockDescriptor, dynamicCallback); + // Create the Wake Lock FMQ from the wakeLockDescriptor. Reset the read/write positions. + auto hidlWakeLockQueue = + std::make_unique<WakeLockMessageQueue>(wakeLockDescriptor, true /* resetPointers */); + std::unique_ptr<WakeLockMessageQueueWrapperBase> wakeLockQueue = + std::make_unique<WakeLockMessageQueueWrapperHidl>(hidlWakeLockQueue); + + return initializeCommon(queue, wakeLockQueue, dynamicCallback); } Return<Result> HalProxy::initializeCommon( std::unique_ptr<EventMessageQueueWrapperBase>& eventQueue, - const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor, + std::unique_ptr<WakeLockMessageQueueWrapperBase>& wakeLockQueue, const sp<ISensorsCallbackWrapperBase>& sensorsCallback) { Result result = Result::OK; @@ -222,8 +234,7 @@ Return<Result> HalProxy::initializeCommon( // Create the Wake Lock FMQ that is used by the framework to communicate whenever WAKE_UP // events have been successfully read and handled by the framework. - mWakeLockQueue = - std::make_unique<WakeLockMessageQueue>(wakeLockDescriptor, true /* resetPointers */); + mWakeLockQueue = std::move(wakeLockQueue); if (mEventQueueFlag != nullptr) { EventFlag::deleteEventFlag(&mEventQueueFlag); diff --git a/sensors/common/default/2.X/multihal/include/HalProxy.h b/sensors/common/default/2.X/multihal/include/HalProxy.h index 35d7c8bae1..61745281f8 100644 --- a/sensors/common/default/2.X/multihal/include/HalProxy.h +++ b/sensors/common/default/2.X/multihal/include/HalProxy.h @@ -23,6 +23,7 @@ #include "V2_0/ScopedWakelock.h" #include "V2_0/SubHal.h" #include "V2_1/SubHal.h" +#include "WakeLockMessageQueueWrapper.h" #include "convertV2_1.h" #include <android/hardware/sensors/2.1/ISensors.h> @@ -98,10 +99,9 @@ class HalProxy : public V2_0::implementation::IScopedWakelockRefCounter, const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor, const sp<V2_0::ISensorsCallback>& sensorsCallback); - Return<Result> initializeCommon( - std::unique_ptr<EventMessageQueueWrapperBase>& eventQueue, - const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor, - const sp<ISensorsCallbackWrapperBase>& sensorsCallback); + Return<Result> initializeCommon(std::unique_ptr<EventMessageQueueWrapperBase>& eventQueue, + std::unique_ptr<WakeLockMessageQueueWrapperBase>& wakeLockQueue, + const sp<ISensorsCallbackWrapperBase>& sensorsCallback); Return<Result> batch(int32_t sensorHandle, int64_t samplingPeriodNs, int64_t maxReportLatencyNs); @@ -141,6 +141,8 @@ class HalProxy : public V2_0::implementation::IScopedWakelockRefCounter, void decrementRefCountAndMaybeReleaseWakelock(size_t delta, int64_t timeoutStart = -1) override; + const std::map<int32_t, SensorInfo>& getSensors() { return mSensors; } + private: using EventMessageQueueV2_1 = MessageQueue<V2_1::Event, kSynchronizedReadWrite>; using EventMessageQueueV2_0 = MessageQueue<V1_0::Event, kSynchronizedReadWrite>; @@ -154,7 +156,7 @@ class HalProxy : public V2_0::implementation::IScopedWakelockRefCounter, /** * The Wake Lock FMQ that is read to determine when the framework has handled WAKE_UP events */ - std::unique_ptr<WakeLockMessageQueue> mWakeLockQueue; + std::unique_ptr<WakeLockMessageQueueWrapperBase> mWakeLockQueue; /** * Event Flag to signal to the framework when sensor events are available to be read and to diff --git a/sensors/common/utils/WakeLockMessageQueueWrapper.h b/sensors/common/utils/WakeLockMessageQueueWrapper.h new file mode 100644 index 0000000000..3a219cffbe --- /dev/null +++ b/sensors/common/utils/WakeLockMessageQueueWrapper.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "convertV2_1.h" + +#include <android/hardware/sensors/2.1/types.h> +#include <fmq/MessageQueue.h> +#include <hidl/MQDescriptor.h> +#include <hidl/Status.h> +#include <log/log.h> + +#include <atomic> + +namespace android { +namespace hardware { +namespace sensors { +namespace V2_1 { +namespace implementation { + +class WakeLockMessageQueueWrapperBase { + public: + virtual ~WakeLockMessageQueueWrapperBase() {} + + virtual std::atomic<uint32_t>* getEventFlagWord() = 0; + virtual bool readBlocking(uint32_t* events, size_t numToRead, uint32_t readNotification, + uint32_t writeNotification, int64_t timeOutNanos, + ::android::hardware::EventFlag* evFlag = nullptr) = 0; + virtual bool write(const uint32_t* wakeLock) = 0; +}; + +class WakeLockMessageQueueWrapperHidl : public WakeLockMessageQueueWrapperBase { + public: + WakeLockMessageQueueWrapperHidl( + std::unique_ptr<::android::hardware::MessageQueue<uint32_t, kSynchronizedReadWrite>>& + queue) + : mQueue(std::move(queue)) {} + + std::atomic<uint32_t>* getEventFlagWord() override { return mQueue->getEventFlagWord(); } + + bool readBlocking(uint32_t* wakeLocks, size_t numToRead, uint32_t readNotification, + uint32_t writeNotification, int64_t timeOutNanos, + ::android::hardware::EventFlag* evFlag) override { + return mQueue->readBlocking(wakeLocks, numToRead, readNotification, writeNotification, + timeOutNanos, evFlag); + } + + bool write(const uint32_t* wakeLock) override { return mQueue->write(wakeLock); } + + private: + std::unique_ptr<::android::hardware::MessageQueue<uint32_t, kSynchronizedReadWrite>> mQueue; +}; + +} // namespace implementation +} // namespace V2_1 +} // namespace sensors +} // namespace hardware +} // namespace android diff --git a/tv/tuner/1.0/default/Lnb.cpp b/tv/tuner/1.0/default/Lnb.cpp index 6025339ba7..c770e91145 100644 --- a/tv/tuner/1.0/default/Lnb.cpp +++ b/tv/tuner/1.0/default/Lnb.cpp @@ -33,9 +33,10 @@ Lnb::Lnb(int id) { Lnb::~Lnb() {} -Return<Result> Lnb::setCallback(const sp<ILnbCallback>& /* callback */) { +Return<Result> Lnb::setCallback(const sp<ILnbCallback>& callback) { ALOGV("%s", __FUNCTION__); + mCallback = callback; return Result::SUCCESS; } @@ -57,9 +58,16 @@ Return<Result> Lnb::setSatellitePosition(LnbPosition /* position */) { return Result::SUCCESS; } -Return<Result> Lnb::sendDiseqcMessage(const hidl_vec<uint8_t>& /* diseqcMessage */) { +Return<Result> Lnb::sendDiseqcMessage(const hidl_vec<uint8_t>& diseqcMessage) { ALOGV("%s", __FUNCTION__); + if (mCallback != nullptr) { + // The correct implementation should be to return the response from the + // device via onDiseqcMessage(). The below implementation is only to enable + // testing for LnbCallbacks. + ALOGV("[hidl] %s - this is for test purpose only, and must be replaced!", __FUNCTION__); + mCallback->onDiseqcMessage(diseqcMessage); + } return Result::SUCCESS; } diff --git a/tv/tuner/1.0/default/Lnb.h b/tv/tuner/1.0/default/Lnb.h index 1e97214430..c14bbd8735 100644 --- a/tv/tuner/1.0/default/Lnb.h +++ b/tv/tuner/1.0/default/Lnb.h @@ -57,6 +57,7 @@ class Lnb : public ILnb { private: int mId; virtual ~Lnb(); + sp<ILnbCallback> mCallback; }; } // namespace implementation diff --git a/tv/tuner/1.1/default/Lnb.cpp b/tv/tuner/1.1/default/Lnb.cpp index 044727ff54..5dd01472d5 100644 --- a/tv/tuner/1.1/default/Lnb.cpp +++ b/tv/tuner/1.1/default/Lnb.cpp @@ -33,9 +33,10 @@ Lnb::Lnb(int id) { Lnb::~Lnb() {} -Return<Result> Lnb::setCallback(const sp<ILnbCallback>& /* callback */) { +Return<Result> Lnb::setCallback(const sp<ILnbCallback>& callback) { ALOGV("%s", __FUNCTION__); + mCallback = callback; return Result::SUCCESS; } @@ -57,9 +58,16 @@ Return<Result> Lnb::setSatellitePosition(LnbPosition /* position */) { return Result::SUCCESS; } -Return<Result> Lnb::sendDiseqcMessage(const hidl_vec<uint8_t>& /* diseqcMessage */) { +Return<Result> Lnb::sendDiseqcMessage(const hidl_vec<uint8_t>& diseqcMessage) { ALOGV("%s", __FUNCTION__); + if (mCallback != nullptr) { + // The correct implementation should be to return the response from the + // device via onDiseqcMessage(). The below implementation is only to enable + // testing for LnbCallbacks. + ALOGV("[hidl] %s - this is for test purpose only, and must be replaced!", __FUNCTION__); + mCallback->onDiseqcMessage(diseqcMessage); + } return Result::SUCCESS; } diff --git a/tv/tuner/1.1/default/Lnb.h b/tv/tuner/1.1/default/Lnb.h index 70a8e41b8b..b34ca396ca 100644 --- a/tv/tuner/1.1/default/Lnb.h +++ b/tv/tuner/1.1/default/Lnb.h @@ -51,6 +51,7 @@ class Lnb : public ILnb { private: int mId; virtual ~Lnb(); + sp<ILnbCallback> mCallback; }; } // namespace implementation diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl index 2858565099..7936e59001 100644 --- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl +++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl @@ -39,4 +39,5 @@ parcelable DemuxFilterSectionSettings { boolean isCheckCrc; boolean isRepeat; boolean isRaw; + int bitWidthOfLengthField; } diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl index f6788ee131..aa30175823 100644 --- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl +++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl @@ -19,7 +19,7 @@ package android.hardware.tv.tuner; import android.hardware.tv.tuner.DemuxFilterSectionSettingsCondition; /** - * Filter Settings for Section data according to ISO/IEC 13818-1. + * Filter Settings for Section data according to ISO/IEC 13818-1 and ISO/IEC 23008-1. * @hide */ @VintfStability @@ -49,4 +49,12 @@ parcelable DemuxFilterSectionSettings { * true if the filter send onFilterStatus instead of onFilterEvent. */ boolean isRaw; + + /** + * The bit width of the MMTP (MPEG Media Transport Protocol) section message's length field + * according to ISO/IEC 23008-1. + * + * The filter uses this for CRC checking when isCheckCrc is true. + */ + int bitWidthOfLengthField; } diff --git a/tv/tuner/aidl/default/Lnb.cpp b/tv/tuner/aidl/default/Lnb.cpp index 35d2da6310..f9343ae6c8 100644 --- a/tv/tuner/aidl/default/Lnb.cpp +++ b/tv/tuner/aidl/default/Lnb.cpp @@ -34,9 +34,11 @@ Lnb::Lnb(int id) { Lnb::~Lnb() {} -::ndk::ScopedAStatus Lnb::setCallback(const std::shared_ptr<ILnbCallback>& /* in_callback */) { +::ndk::ScopedAStatus Lnb::setCallback(const std::shared_ptr<ILnbCallback>& in_callback) { ALOGV("%s", __FUNCTION__); + mCallback = in_callback; + return ::ndk::ScopedAStatus::ok(); } @@ -58,9 +60,17 @@ Lnb::~Lnb() {} return ::ndk::ScopedAStatus::ok(); } -::ndk::ScopedAStatus Lnb::sendDiseqcMessage(const std::vector<uint8_t>& /* in_diseqcMessage */) { +::ndk::ScopedAStatus Lnb::sendDiseqcMessage(const std::vector<uint8_t>& in_diseqcMessage) { ALOGV("%s", __FUNCTION__); + if (mCallback != nullptr) { + // The correct implementation should be to return the response from the + // device via onDiseqcMessage(). The below implementation is only to enable + // testing for LnbCallbacks. + ALOGV("[aidl] %s - this is for test purpose only, and must be replaced!", __FUNCTION__); + mCallback->onDiseqcMessage(in_diseqcMessage); + } + return ::ndk::ScopedAStatus::ok(); } diff --git a/tv/tuner/aidl/default/Lnb.h b/tv/tuner/aidl/default/Lnb.h index bfe3097ddc..464f9a453f 100644 --- a/tv/tuner/aidl/default/Lnb.h +++ b/tv/tuner/aidl/default/Lnb.h @@ -44,6 +44,7 @@ class Lnb : public BnLnb { private: int mId; virtual ~Lnb(); + std::shared_ptr<ILnbCallback> mCallback; }; } // namespace tuner diff --git a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h index b6cc5f80b0..b73d59411b 100644 --- a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h +++ b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h @@ -954,6 +954,7 @@ struct TunerTestingConfigAidlReader1_0 { settings.isCheckCrc = section->getIsCheckCrc(); settings.isRepeat = section->getIsRepeat(); settings.isRaw = section->getIsRaw(); + settings.bitWidthOfLengthField = section->getBitWidthOfLengthField(); return settings; } diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt index db1d076e10..4d519d7cb5 100644 --- a/tv/tuner/config/api/current.txt +++ b/tv/tuner/config/api/current.txt @@ -477,9 +477,11 @@ package android.media.tuner.testing.configuration.V1_0 { public class SectionFilterSettings { ctor public SectionFilterSettings(); + method @Nullable public java.math.BigInteger getBitWidthOfLengthField(); method @Nullable public boolean getIsCheckCrc(); method @Nullable public boolean getIsRaw(); method @Nullable public boolean getIsRepeat(); + method public void setBitWidthOfLengthField(@Nullable java.math.BigInteger); method public void setIsCheckCrc(@Nullable boolean); method public void setIsRaw(@Nullable boolean); method public void setIsRepeat(@Nullable boolean); diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd index 54cedfcf6b..94f108b43a 100644 --- a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd +++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd @@ -226,6 +226,7 @@ <xs:attribute name="isCheckCrc" type="xs:boolean" use="required"/> <xs:attribute name="isRepeat" type="xs:boolean" use="required"/> <xs:attribute name="isRaw" type="xs:boolean" use="required"/> + <xs:attribute name="bitWidthOfLengthField" type="xs:nonNegativeInteger" use="required"/> </xs:complexType> <xs:complexType name="recordFilterSettings"> <xs:attribute name="tsIndexMask" type="tsIndexMask" use="required"/> diff --git a/wifi/1.5/default/hidl_struct_util.h b/wifi/1.5/default/hidl_struct_util.h deleted file mode 100644 index 352f213664..0000000000 --- a/wifi/1.5/default/hidl_struct_util.h +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef HIDL_STRUCT_UTIL_H_ -#define HIDL_STRUCT_UTIL_H_ - -#include <vector> - -#include <android/hardware/wifi/1.0/IWifiChip.h> -#include <android/hardware/wifi/1.0/types.h> -#include <android/hardware/wifi/1.2/types.h> -#include <android/hardware/wifi/1.3/types.h> -#include <android/hardware/wifi/1.4/IWifiChipEventCallback.h> -#include <android/hardware/wifi/1.4/types.h> -#include <android/hardware/wifi/1.5/IWifiChip.h> -#include <android/hardware/wifi/1.5/types.h> - -#include "wifi_legacy_hal.h" - -/** - * This file contains a bunch of functions to convert structs from the legacy - * HAL to HIDL and vice versa. - * TODO(b/32093047): Add unit tests for these conversion methods in the VTS test - * suite. - */ -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace hidl_struct_util { -using namespace android::hardware::wifi::V1_0; - -// Chip conversion methods. -bool convertLegacyFeaturesToHidlChipCapabilities( - uint64_t legacy_feature_set, uint32_t legacy_logger_feature_set, - uint32_t* hidl_caps); -bool convertLegacyDebugRingBufferStatusToHidl( - const legacy_hal::wifi_ring_buffer_status& legacy_status, - WifiDebugRingBufferStatus* hidl_status); -bool convertLegacyVectorOfDebugRingBufferStatusToHidl( - const std::vector<legacy_hal::wifi_ring_buffer_status>& legacy_status_vec, - std::vector<WifiDebugRingBufferStatus>* hidl_status_vec); -bool convertLegacyWakeReasonStatsToHidl( - const legacy_hal::WakeReasonStats& legacy_stats, - WifiDebugHostWakeReasonStats* hidl_stats); -legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy( - V1_1::IWifiChip::TxPowerScenario hidl_scenario); -legacy_hal::wifi_latency_mode convertHidlLatencyModeToLegacy( - V1_3::IWifiChip::LatencyMode hidl_latency_mode); -legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy_1_2( - V1_2::IWifiChip::TxPowerScenario hidl_scenario); -bool convertLegacyWifiMacInfosToHidl( - const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos, - std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo>* - hidl_radio_mode_infos); -legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy( - IfaceType hidl_interface_type); -legacy_hal::wifi_multi_sta_use_case convertHidlMultiStaUseCaseToLegacy( - IWifiChip::MultiStaUseCase use_case); -bool convertHidlCoexUnsafeChannelToLegacy( - const IWifiChip::CoexUnsafeChannel& hidl_unsafe_channel, - legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel); -bool convertHidlVectorOfCoexUnsafeChannelToLegacy( - const std::vector<IWifiChip::CoexUnsafeChannel>& hidl_unsafe_channels, - std::vector<legacy_hal::wifi_coex_unsafe_channel>* legacy_unsafe_channels); - -// STA iface conversion methods. -bool convertLegacyFeaturesToHidlStaCapabilities( - uint64_t legacy_feature_set, uint32_t legacy_logger_feature_set, - uint32_t* hidl_caps); -bool convertLegacyApfCapabilitiesToHidl( - const legacy_hal::PacketFilterCapabilities& legacy_caps, - StaApfPacketFilterCapabilities* hidl_caps); -bool convertLegacyGscanCapabilitiesToHidl( - const legacy_hal::wifi_gscan_capabilities& legacy_caps, - StaBackgroundScanCapabilities* hidl_caps); -legacy_hal::wifi_band convertHidlWifiBandToLegacy(V1_0::WifiBand band); -bool convertHidlGscanParamsToLegacy( - const StaBackgroundScanParameters& hidl_scan_params, - legacy_hal::wifi_scan_cmd_params* legacy_scan_params); -// |has_ie_data| indicates whether or not the wifi_scan_result includes 802.11 -// Information Elements (IEs) -bool convertLegacyGscanResultToHidl( - const legacy_hal::wifi_scan_result& legacy_scan_result, bool has_ie_data, - StaScanResult* hidl_scan_result); -// |cached_results| is assumed to not include IEs. -bool convertLegacyVectorOfCachedGscanResultsToHidl( - const std::vector<legacy_hal::wifi_cached_scan_results>& - legacy_cached_scan_results, - std::vector<StaScanData>* hidl_scan_datas); -bool convertLegacyLinkLayerStatsToHidl( - const legacy_hal::LinkLayerStats& legacy_stats, - StaLinkLayerStats* hidl_stats); -bool convertLegacyRoamingCapabilitiesToHidl( - const legacy_hal::wifi_roaming_capabilities& legacy_caps, - StaRoamingCapabilities* hidl_caps); -bool convertHidlRoamingConfigToLegacy( - const StaRoamingConfig& hidl_config, - legacy_hal::wifi_roaming_config* legacy_config); -legacy_hal::fw_roaming_state_t convertHidlRoamingStateToLegacy( - StaRoamingState state); -bool convertLegacyVectorOfDebugTxPacketFateToHidl( - const std::vector<legacy_hal::wifi_tx_report>& legacy_fates, - std::vector<WifiDebugTxPacketFateReport>* hidl_fates); -bool convertLegacyVectorOfDebugRxPacketFateToHidl( - const std::vector<legacy_hal::wifi_rx_report>& legacy_fates, - std::vector<WifiDebugRxPacketFateReport>* hidl_fates); - -// NAN iface conversion methods. -void convertToWifiNanStatus(legacy_hal::NanStatusType type, const char* str, - size_t max_len, WifiNanStatus* wifiNanStatus); -bool convertHidlNanEnableRequestToLegacy( - const V1_4::NanEnableRequest& hidl_request, - legacy_hal::NanEnableRequest* legacy_request); -bool convertHidlNanConfigRequestToLegacy( - const V1_4::NanConfigRequest& hidl_request, - legacy_hal::NanConfigRequest* legacy_request); -bool convertHidlNanEnableRequest_1_4ToLegacy( - const V1_4::NanEnableRequest& hidl_request1, - const NanConfigRequestSupplemental& hidl_request2, - legacy_hal::NanEnableRequest* legacy_request); -bool convertHidlNanConfigRequest_1_4ToLegacy( - const V1_4::NanConfigRequest& hidl_request1, - const NanConfigRequestSupplemental& hidl_request2, - legacy_hal::NanConfigRequest* legacy_request); -bool convertHidlNanEnableRequest_1_5ToLegacy( - const V1_4::NanEnableRequest& hidl_request1, - const NanConfigRequestSupplemental& hidl_request2, - legacy_hal::NanEnableRequest* legacy_request); -bool convertHidlNanConfigRequest_1_5ToLegacy( - const V1_4::NanConfigRequest& hidl_request1, - const NanConfigRequestSupplemental& hidl_request2, - legacy_hal::NanConfigRequest* legacy_request); -bool convertHidlNanPublishRequestToLegacy( - const NanPublishRequest& hidl_request, - legacy_hal::NanPublishRequest* legacy_request); -bool convertHidlNanSubscribeRequestToLegacy( - const NanSubscribeRequest& hidl_request, - legacy_hal::NanSubscribeRequest* legacy_request); -bool convertHidlNanTransmitFollowupRequestToLegacy( - const NanTransmitFollowupRequest& hidl_request, - legacy_hal::NanTransmitFollowupRequest* legacy_request); -bool convertHidlNanDataPathInitiatorRequestToLegacy( - const NanInitiateDataPathRequest& hidl_request, - legacy_hal::NanDataPathInitiatorRequest* legacy_request); -bool convertHidlNanDataPathIndicationResponseToLegacy( - const NanRespondToDataPathIndicationRequest& hidl_response, - legacy_hal::NanDataPathIndicationResponse* legacy_response); -bool convertLegacyNanResponseHeaderToHidl( - const legacy_hal::NanResponseMsg& legacy_response, - WifiNanStatus* wifiNanStatus); -bool convertLegacyNanCapabilitiesResponseToHidl( - const legacy_hal::NanCapabilities& legacy_response, - NanCapabilities* hidl_response); -bool convertLegacyNanMatchIndToHidl(const legacy_hal::NanMatchInd& legacy_ind, - NanMatchInd* hidl_ind); -bool convertLegacyNanFollowupIndToHidl( - const legacy_hal::NanFollowupInd& legacy_ind, - NanFollowupReceivedInd* hidl_ind); -bool convertLegacyNanDataPathRequestIndToHidl( - const legacy_hal::NanDataPathRequestInd& legacy_ind, - NanDataPathRequestInd* hidl_ind); -bool convertLegacyNanDataPathConfirmIndToHidl( - const legacy_hal::NanDataPathConfirmInd& legacy_ind, - V1_2::NanDataPathConfirmInd* hidl_ind); -bool convertLegacyNanDataPathScheduleUpdateIndToHidl( - const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind, - V1_2::NanDataPathScheduleUpdateInd* hidl_ind); - -// RTT controller conversion methods. -bool convertHidlVectorOfRttConfigToLegacy( - const std::vector<V1_4::RttConfig>& hidl_configs, - std::vector<legacy_hal::wifi_rtt_config>* legacy_configs); -bool convertHidlRttLciInformationToLegacy( - const RttLciInformation& hidl_info, - legacy_hal::wifi_lci_information* legacy_info); -bool convertHidlRttLcrInformationToLegacy( - const RttLcrInformation& hidl_info, - legacy_hal::wifi_lcr_information* legacy_info); -bool convertHidlRttResponderToLegacy( - const V1_4::RttResponder& hidl_responder, - legacy_hal::wifi_rtt_responder* legacy_responder); -bool convertHidlWifiChannelInfoToLegacy( - const WifiChannelInfo& hidl_info, - legacy_hal::wifi_channel_info* legacy_info); -bool convertLegacyRttResponderToHidl( - const legacy_hal::wifi_rtt_responder& legacy_responder, - V1_4::RttResponder* hidl_responder); -bool convertLegacyRttCapabilitiesToHidl( - const legacy_hal::wifi_rtt_capabilities& legacy_capabilities, - V1_4::RttCapabilities* hidl_capabilities); -bool convertLegacyVectorOfRttResultToHidl( - const std::vector<const legacy_hal::wifi_rtt_result*>& legacy_results, - std::vector<V1_4::RttResult>* hidl_results); -uint32_t convertHidlWifiBandToLegacyMacBand(V1_5::WifiBand band); -uint32_t convertHidlWifiIfaceModeToLegacy(uint32_t hidl_iface_mask); -uint32_t convertHidlUsableChannelFilterToLegacy(uint32_t hidl_filter_mask); -bool convertLegacyWifiUsableChannelsToHidl( - const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels, - std::vector<V1_5::WifiUsableChannel>* hidl_usable_channels); -bool convertLegacyPeerInfoStatsToHidl( - const legacy_hal::WifiPeerInfo& legacy_peer_info_stats, - StaPeerInfo* hidl_peer_info_stats); -bool convertLegacyWifiRateInfoToHidl(const legacy_hal::wifi_rate& legacy_rate, - V1_4::WifiRateInfo* hidl_rate); -} // namespace hidl_struct_util -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android - -#endif // HIDL_STRUCT_UTIL_H_ diff --git a/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp b/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp deleted file mode 100644 index 32da55ec2b..0000000000 --- a/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <android-base/logging.h> -#include <android-base/macros.h> -#include <cutils/properties.h> -#include <gmock/gmock.h> - -#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38 -#include "wifi_nan_iface.h" - -#include "mock_interface_tool.h" -#include "mock_wifi_feature_flags.h" -#include "mock_wifi_iface_util.h" -#include "mock_wifi_legacy_hal.h" - -using testing::NiceMock; -using testing::Return; -using testing::Test; - -namespace { -constexpr char kIfaceName[] = "mockWlan0"; -} // namespace - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { - -using android::hardware::wifi::V1_2::NanDataPathConfirmInd; - -bool CaptureIfaceEventHandlers( - const std::string& /* iface_name*/, - iface_util::IfaceEventHandlers in_iface_event_handlers, - iface_util::IfaceEventHandlers* out_iface_event_handlers) { - *out_iface_event_handlers = in_iface_event_handlers; - return true; -} - -class MockNanIfaceEventCallback : public IWifiNanIfaceEventCallback { - public: - MockNanIfaceEventCallback() = default; - - MOCK_METHOD3( - notifyCapabilitiesResponse, - Return<void>(uint16_t, const WifiNanStatus&, - const android::hardware::wifi::V1_0::NanCapabilities&)); - MOCK_METHOD2(notifyEnableResponse, - Return<void>(uint16_t, const WifiNanStatus&)); - MOCK_METHOD2(notifyConfigResponse, - Return<void>(uint16_t, const WifiNanStatus&)); - MOCK_METHOD2(notifyDisableResponse, - Return<void>(uint16_t, const WifiNanStatus&)); - MOCK_METHOD3(notifyStartPublishResponse, - Return<void>(uint16_t, const WifiNanStatus&, uint8_t)); - MOCK_METHOD2(notifyStopPublishResponse, - Return<void>(uint16_t, const WifiNanStatus&)); - MOCK_METHOD3(notifyStartSubscribeResponse, - Return<void>(uint16_t, const WifiNanStatus&, uint8_t)); - MOCK_METHOD2(notifyStopSubscribeResponse, - Return<void>(uint16_t, const WifiNanStatus&)); - MOCK_METHOD2(notifyTransmitFollowupResponse, - Return<void>(uint16_t, const WifiNanStatus&)); - MOCK_METHOD2(notifyCreateDataInterfaceResponse, - Return<void>(uint16_t, const WifiNanStatus&)); - MOCK_METHOD2(notifyDeleteDataInterfaceResponse, - Return<void>(uint16_t, const WifiNanStatus&)); - MOCK_METHOD3(notifyInitiateDataPathResponse, - Return<void>(uint16_t, const WifiNanStatus&, uint32_t)); - MOCK_METHOD2(notifyRespondToDataPathIndicationResponse, - Return<void>(uint16_t, const WifiNanStatus&)); - MOCK_METHOD2(notifyTerminateDataPathResponse, - Return<void>(uint16_t, const WifiNanStatus&)); - MOCK_METHOD1(eventClusterEvent, Return<void>(const NanClusterEventInd&)); - MOCK_METHOD1(eventDisabled, Return<void>(const WifiNanStatus&)); - MOCK_METHOD2(eventPublishTerminated, - Return<void>(uint8_t, const WifiNanStatus&)); - MOCK_METHOD2(eventSubscribeTerminated, - Return<void>(uint8_t, const WifiNanStatus&)); - MOCK_METHOD1(eventMatch, Return<void>(const NanMatchInd&)); - MOCK_METHOD2(eventMatchExpired, Return<void>(uint8_t, uint32_t)); - MOCK_METHOD1(eventFollowupReceived, - Return<void>(const NanFollowupReceivedInd&)); - MOCK_METHOD2(eventTransmitFollowup, - Return<void>(uint16_t, const WifiNanStatus&)); - MOCK_METHOD1(eventDataPathRequest, - Return<void>(const NanDataPathRequestInd&)); - MOCK_METHOD1( - eventDataPathConfirm, - Return<void>( - const android::hardware::wifi::V1_0::NanDataPathConfirmInd&)); - MOCK_METHOD1(eventDataPathTerminated, Return<void>(uint32_t)); - MOCK_METHOD1(eventDataPathConfirm_1_2, - Return<void>(const NanDataPathConfirmInd&)); - MOCK_METHOD1(eventDataPathScheduleUpdate, - Return<void>(const NanDataPathScheduleUpdateInd&)); - MOCK_METHOD3(notifyCapabilitiesResponse_1_5, - Return<void>(uint16_t, const WifiNanStatus&, - const NanCapabilities&)); -}; - -class WifiNanIfaceTest : public Test { - protected: - legacy_hal::wifi_hal_fn fake_func_table_; - std::shared_ptr<NiceMock<wifi_system::MockInterfaceTool>> iface_tool_{ - new NiceMock<wifi_system::MockInterfaceTool>}; - std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{ - new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_, - fake_func_table_, true)}; - std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{ - new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_, legacy_hal_)}; -}; - -TEST_F(WifiNanIfaceTest, IfacEventHandlers_OnStateToggleOffOn) { - iface_util::IfaceEventHandlers captured_iface_event_handlers = {}; - EXPECT_CALL(*legacy_hal_, - nanRegisterCallbackHandlers(testing::_, testing::_)) - .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); - EXPECT_CALL(*iface_util_, - registerIfaceEventHandlers(testing::_, testing::_)) - .WillOnce(testing::Invoke( - bind(CaptureIfaceEventHandlers, std::placeholders::_1, - std::placeholders::_2, &captured_iface_event_handlers))); - sp<WifiNanIface> nan_iface = - new WifiNanIface(kIfaceName, false, legacy_hal_, iface_util_); - - // Register a mock nan event callback. - sp<NiceMock<MockNanIfaceEventCallback>> mock_event_callback{ - new NiceMock<MockNanIfaceEventCallback>}; - nan_iface->registerEventCallback( - mock_event_callback, [](const WifiStatus& status) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - }); - // Ensure that the eventDisabled() function in mock callback will be - // invoked. - WifiNanStatus expected_nan_status = { - NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""}; - EXPECT_CALL(*mock_event_callback, eventDisabled(expected_nan_status)) - .Times(1); - - // Trigger the iface state toggle callback. - captured_iface_event_handlers.on_state_toggle_off_on(kIfaceName); -} -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/wifi_nan_iface.cpp b/wifi/1.5/default/wifi_nan_iface.cpp deleted file mode 100644 index 0cc6cd5fce..0000000000 --- a/wifi/1.5/default/wifi_nan_iface.cpp +++ /dev/null @@ -1,1003 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <android-base/logging.h> - -#include "hidl_return_util.h" -#include "hidl_struct_util.h" -#include "wifi_nan_iface.h" -#include "wifi_status_util.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -using hidl_return_util::validateAndCall; - -WifiNanIface::WifiNanIface( - const std::string& ifname, bool is_dedicated_iface, - const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal, - const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util) - : ifname_(ifname), - is_dedicated_iface_(is_dedicated_iface), - legacy_hal_(legacy_hal), - iface_util_(iface_util), - is_valid_(true) { - if (is_dedicated_iface_) { - // If using a dedicated iface, set the iface up first. - if (!iface_util_.lock()->setUpState(ifname_, true)) { - // Fatal failure, invalidate the iface object. - invalidate(); - return; - } - } - // Register all the callbacks here. these should be valid for the lifetime - // of the object. Whenever the mode changes legacy HAL will remove - // all of these callbacks. - legacy_hal::NanCallbackHandlers callback_handlers; - android::wp<WifiNanIface> weak_ptr_this(this); - - // Callback for response. - callback_handlers - .on_notify_response = [weak_ptr_this]( - legacy_hal::transaction_id id, - const legacy_hal::NanResponseMsg& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - WifiNanStatus wifiNanStatus; - if (!hidl_struct_util::convertLegacyNanResponseHeaderToHidl( - msg, &wifiNanStatus)) { - LOG(ERROR) << "Failed to convert nan response header"; - return; - } - - switch (msg.response_type) { - case legacy_hal::NAN_RESPONSE_ENABLED: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback->notifyEnableResponse(id, wifiNanStatus) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_RESPONSE_DISABLED: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback->notifyDisableResponse(id, wifiNanStatus) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_RESPONSE_PUBLISH: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback - ->notifyStartPublishResponse( - id, wifiNanStatus, - msg.body.publish_response.publish_id) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_RESPONSE_PUBLISH_CANCEL: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback->notifyStopPublishResponse(id, wifiNanStatus) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_RESPONSE_TRANSMIT_FOLLOWUP: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback - ->notifyTransmitFollowupResponse(id, wifiNanStatus) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_RESPONSE_SUBSCRIBE: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback - ->notifyStartSubscribeResponse( - id, wifiNanStatus, - msg.body.subscribe_response.subscribe_id) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_RESPONSE_SUBSCRIBE_CANCEL: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback - ->notifyStopSubscribeResponse(id, wifiNanStatus) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_RESPONSE_CONFIG: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback->notifyConfigResponse(id, wifiNanStatus) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_GET_CAPABILITIES: { - NanCapabilities hidl_struct; - if (!hidl_struct_util:: - convertLegacyNanCapabilitiesResponseToHidl( - msg.body.nan_capabilities, &hidl_struct)) { - LOG(ERROR) << "Failed to convert nan capabilities response"; - return; - } - for (const auto& callback : - shared_ptr_this->getEventCallbacks_1_5()) { - if (!callback - ->notifyCapabilitiesResponse_1_5(id, wifiNanStatus, - hidl_struct) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_DP_INTERFACE_CREATE: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback - ->notifyCreateDataInterfaceResponse(id, - wifiNanStatus) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_DP_INTERFACE_DELETE: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback - ->notifyDeleteDataInterfaceResponse(id, - wifiNanStatus) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_DP_INITIATOR_RESPONSE: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback - ->notifyInitiateDataPathResponse( - id, wifiNanStatus, - msg.body.data_request_response.ndp_instance_id) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_DP_RESPONDER_RESPONSE: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback - ->notifyRespondToDataPathIndicationResponse( - id, wifiNanStatus) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_DP_END: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback - ->notifyTerminateDataPathResponse(id, - wifiNanStatus) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_RESPONSE_BEACON_SDF_PAYLOAD: - /* fall through */ - case legacy_hal::NAN_RESPONSE_TCA: - /* fall through */ - case legacy_hal::NAN_RESPONSE_STATS: - /* fall through */ - case legacy_hal::NAN_RESPONSE_ERROR: - /* fall through */ - default: - LOG(ERROR) << "Unknown or unhandled response type: " - << msg.response_type; - return; - } - }; - - callback_handlers.on_event_disc_eng_event = - [weak_ptr_this](const legacy_hal::NanDiscEngEventInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - NanClusterEventInd hidl_struct; - // event types defined identically - hence can be cast - hidl_struct.eventType = (NanClusterEventType)msg.event_type; - hidl_struct.addr = msg.data.mac_addr.addr; - - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->eventClusterEvent(hidl_struct).isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - - callback_handlers.on_event_disabled = - [weak_ptr_this](const legacy_hal::NanDisabledInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - WifiNanStatus status; - hidl_struct_util::convertToWifiNanStatus( - msg.reason, msg.nan_reason, sizeof(msg.nan_reason), &status); - - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->eventDisabled(status).isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - - callback_handlers.on_event_publish_terminated = - [weak_ptr_this](const legacy_hal::NanPublishTerminatedInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - WifiNanStatus status; - hidl_struct_util::convertToWifiNanStatus( - msg.reason, msg.nan_reason, sizeof(msg.nan_reason), &status); - - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->eventPublishTerminated(msg.publish_id, status) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - - callback_handlers.on_event_subscribe_terminated = - [weak_ptr_this](const legacy_hal::NanSubscribeTerminatedInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - WifiNanStatus status; - hidl_struct_util::convertToWifiNanStatus( - msg.reason, msg.nan_reason, sizeof(msg.nan_reason), &status); - - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback - ->eventSubscribeTerminated(msg.subscribe_id, status) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - - callback_handlers.on_event_match = - [weak_ptr_this](const legacy_hal::NanMatchInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - NanMatchInd hidl_struct; - if (!hidl_struct_util::convertLegacyNanMatchIndToHidl( - msg, &hidl_struct)) { - LOG(ERROR) << "Failed to convert nan capabilities response"; - return; - } - - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->eventMatch(hidl_struct).isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - - callback_handlers.on_event_match_expired = - [weak_ptr_this](const legacy_hal::NanMatchExpiredInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback - ->eventMatchExpired(msg.publish_subscribe_id, - msg.requestor_instance_id) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - - callback_handlers.on_event_followup = - [weak_ptr_this](const legacy_hal::NanFollowupInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - NanFollowupReceivedInd hidl_struct; - if (!hidl_struct_util::convertLegacyNanFollowupIndToHidl( - msg, &hidl_struct)) { - LOG(ERROR) << "Failed to convert nan capabilities response"; - return; - } - - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->eventFollowupReceived(hidl_struct).isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - - callback_handlers.on_event_transmit_follow_up = - [weak_ptr_this](const legacy_hal::NanTransmitFollowupInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - WifiNanStatus status; - hidl_struct_util::convertToWifiNanStatus( - msg.reason, msg.nan_reason, sizeof(msg.nan_reason), &status); - - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->eventTransmitFollowup(msg.id, status).isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - - callback_handlers.on_event_data_path_request = - [weak_ptr_this](const legacy_hal::NanDataPathRequestInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - NanDataPathRequestInd hidl_struct; - if (!hidl_struct_util::convertLegacyNanDataPathRequestIndToHidl( - msg, &hidl_struct)) { - LOG(ERROR) << "Failed to convert nan capabilities response"; - return; - } - - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->eventDataPathRequest(hidl_struct).isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - - callback_handlers.on_event_data_path_confirm = - [weak_ptr_this](const legacy_hal::NanDataPathConfirmInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - V1_2::NanDataPathConfirmInd hidl_struct; - if (!hidl_struct_util::convertLegacyNanDataPathConfirmIndToHidl( - msg, &hidl_struct)) { - LOG(ERROR) << "Failed to convert nan capabilities response"; - return; - } - - for (const auto& callback : - shared_ptr_this->getEventCallbacks_1_2()) { - if (!callback->eventDataPathConfirm_1_2(hidl_struct).isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - - callback_handlers.on_event_data_path_end = - [weak_ptr_this](const legacy_hal::NanDataPathEndInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - for (int i = 0; i < msg.num_ndp_instances; ++i) { - if (!callback - ->eventDataPathTerminated(msg.ndp_instance_id[i]) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - } - }; - - callback_handlers.on_event_beacon_sdf_payload = - [weak_ptr_this](const legacy_hal::NanBeaconSdfPayloadInd& /* msg */) { - LOG(ERROR) << "on_event_beacon_sdf_payload - should not be called"; - }; - - callback_handlers.on_event_range_request = - [weak_ptr_this](const legacy_hal::NanRangeRequestInd& /* msg */) { - LOG(ERROR) << "on_event_range_request - should not be called"; - }; - - callback_handlers.on_event_range_report = - [weak_ptr_this](const legacy_hal::NanRangeReportInd& /* msg */) { - LOG(ERROR) << "on_event_range_report - should not be called"; - }; - - callback_handlers - .on_event_schedule_update = [weak_ptr_this]( - const legacy_hal:: - NanDataPathScheduleUpdateInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - V1_2::NanDataPathScheduleUpdateInd hidl_struct; - if (!hidl_struct_util::convertLegacyNanDataPathScheduleUpdateIndToHidl( - msg, &hidl_struct)) { - LOG(ERROR) << "Failed to convert nan capabilities response"; - return; - } - - for (const auto& callback : shared_ptr_this->getEventCallbacks_1_2()) { - if (!callback->eventDataPathScheduleUpdate(hidl_struct).isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanRegisterCallbackHandlers(ifname_, - callback_handlers); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to register nan callbacks. Invalidating object"; - invalidate(); - } - - // Register for iface state toggle events. - iface_util::IfaceEventHandlers event_handlers = {}; - event_handlers.on_state_toggle_off_on = - [weak_ptr_this](const std::string& /* iface_name */) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - // Tell framework that NAN has been disabled. - WifiNanStatus status = { - NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""}; - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->eventDisabled(status).isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - iface_util_.lock()->registerIfaceEventHandlers(ifname_, event_handlers); -} - -void WifiNanIface::invalidate() { - if (!isValid()) { - return; - } - // send commands to HAL to actually disable and destroy interfaces - legacy_hal_.lock()->nanDisableRequest(ifname_, 0xFFFF); - legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFE, "aware_data0"); - legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFD, "aware_data1"); - iface_util_.lock()->unregisterIfaceEventHandlers(ifname_); - legacy_hal_.reset(); - event_cb_handler_.invalidate(); - event_cb_handler_1_2_.invalidate(); - event_cb_handler_1_5_.invalidate(); - is_valid_ = false; - if (is_dedicated_iface_) { - // If using a dedicated iface, set the iface down. - iface_util_.lock()->setUpState(ifname_, false); - } -} - -bool WifiNanIface::isValid() { return is_valid_; } - -std::string WifiNanIface::getName() { return ifname_; } - -std::set<sp<V1_0::IWifiNanIfaceEventCallback>> -WifiNanIface::getEventCallbacks() { - return event_cb_handler_.getCallbacks(); -} - -std::set<sp<V1_2::IWifiNanIfaceEventCallback>> -WifiNanIface::getEventCallbacks_1_2() { - return event_cb_handler_1_2_.getCallbacks(); -} - -std::set<sp<IWifiNanIfaceEventCallback>> WifiNanIface::getEventCallbacks_1_5() { - return event_cb_handler_1_5_.getCallbacks(); -} - -Return<void> WifiNanIface::getName(getName_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::getNameInternal, hidl_status_cb); -} - -Return<void> WifiNanIface::getType(getType_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::getTypeInternal, hidl_status_cb); -} - -Return<void> WifiNanIface::registerEventCallback( - const sp<V1_0::IWifiNanIfaceEventCallback>& callback, - registerEventCallback_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::registerEventCallbackInternal, - hidl_status_cb, callback); -} - -Return<void> WifiNanIface::getCapabilitiesRequest( - uint16_t cmd_id, getCapabilitiesRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::getCapabilitiesRequestInternal, - hidl_status_cb, cmd_id); -} - -Return<void> WifiNanIface::enableRequest(uint16_t cmd_id, - const V1_0::NanEnableRequest& msg, - enableRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::enableRequestInternal, hidl_status_cb, - cmd_id, msg); -} - -Return<void> WifiNanIface::configRequest(uint16_t cmd_id, - const V1_0::NanConfigRequest& msg, - configRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::configRequestInternal, hidl_status_cb, - cmd_id, msg); -} - -Return<void> WifiNanIface::disableRequest(uint16_t cmd_id, - disableRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::disableRequestInternal, - hidl_status_cb, cmd_id); -} - -Return<void> WifiNanIface::startPublishRequest( - uint16_t cmd_id, const NanPublishRequest& msg, - startPublishRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::startPublishRequestInternal, - hidl_status_cb, cmd_id, msg); -} - -Return<void> WifiNanIface::stopPublishRequest( - uint16_t cmd_id, uint8_t sessionId, stopPublishRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::stopPublishRequestInternal, - hidl_status_cb, cmd_id, sessionId); -} - -Return<void> WifiNanIface::startSubscribeRequest( - uint16_t cmd_id, const NanSubscribeRequest& msg, - startSubscribeRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::startSubscribeRequestInternal, - hidl_status_cb, cmd_id, msg); -} - -Return<void> WifiNanIface::stopSubscribeRequest( - uint16_t cmd_id, uint8_t sessionId, - stopSubscribeRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::stopSubscribeRequestInternal, - hidl_status_cb, cmd_id, sessionId); -} - -Return<void> WifiNanIface::transmitFollowupRequest( - uint16_t cmd_id, const NanTransmitFollowupRequest& msg, - transmitFollowupRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::transmitFollowupRequestInternal, - hidl_status_cb, cmd_id, msg); -} - -Return<void> WifiNanIface::createDataInterfaceRequest( - uint16_t cmd_id, const hidl_string& iface_name, - createDataInterfaceRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::createDataInterfaceRequestInternal, - hidl_status_cb, cmd_id, iface_name); -} - -Return<void> WifiNanIface::deleteDataInterfaceRequest( - uint16_t cmd_id, const hidl_string& iface_name, - deleteDataInterfaceRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::deleteDataInterfaceRequestInternal, - hidl_status_cb, cmd_id, iface_name); -} - -Return<void> WifiNanIface::initiateDataPathRequest( - uint16_t cmd_id, const NanInitiateDataPathRequest& msg, - initiateDataPathRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::initiateDataPathRequestInternal, - hidl_status_cb, cmd_id, msg); -} - -Return<void> WifiNanIface::respondToDataPathIndicationRequest( - uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg, - respondToDataPathIndicationRequest_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::respondToDataPathIndicationRequestInternal, - hidl_status_cb, cmd_id, msg); -} - -Return<void> WifiNanIface::terminateDataPathRequest( - uint16_t cmd_id, uint32_t ndpInstanceId, - terminateDataPathRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::terminateDataPathRequestInternal, - hidl_status_cb, cmd_id, ndpInstanceId); -} - -Return<void> WifiNanIface::registerEventCallback_1_2( - const sp<V1_2::IWifiNanIfaceEventCallback>& callback, - registerEventCallback_1_2_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::registerEventCallback_1_2Internal, - hidl_status_cb, callback); -} - -Return<void> WifiNanIface::enableRequest_1_2( - uint16_t cmd_id, const V1_0::NanEnableRequest& msg1, - const V1_2::NanConfigRequestSupplemental& msg2, - enableRequest_1_2_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::enableRequest_1_2Internal, - hidl_status_cb, cmd_id, msg1, msg2); -} - -Return<void> WifiNanIface::configRequest_1_2( - uint16_t cmd_id, const V1_0::NanConfigRequest& msg1, - const V1_2::NanConfigRequestSupplemental& msg2, - configRequest_1_2_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::configRequest_1_2Internal, - hidl_status_cb, cmd_id, msg1, msg2); -} - -Return<void> WifiNanIface::enableRequest_1_4( - uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, - const V1_2::NanConfigRequestSupplemental& msg2, - enableRequest_1_4_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::enableRequest_1_4Internal, - hidl_status_cb, cmd_id, msg1, msg2); -} - -Return<void> WifiNanIface::configRequest_1_4( - uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, - const V1_2::NanConfigRequestSupplemental& msg2, - configRequest_1_4_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::configRequest_1_4Internal, - hidl_status_cb, cmd_id, msg1, msg2); -} - -Return<void> WifiNanIface::registerEventCallback_1_5( - const sp<IWifiNanIfaceEventCallback>& callback, - registerEventCallback_1_5_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::registerEventCallback_1_5Internal, - hidl_status_cb, callback); -} - -Return<void> WifiNanIface::enableRequest_1_5( - uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, - const NanConfigRequestSupplemental& msg2, - enableRequest_1_5_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::enableRequest_1_5Internal, - hidl_status_cb, cmd_id, msg1, msg2); -} - -Return<void> WifiNanIface::configRequest_1_5( - uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, - const NanConfigRequestSupplemental& msg2, - configRequest_1_5_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::configRequest_1_5Internal, - hidl_status_cb, cmd_id, msg1, msg2); -} - -Return<void> WifiNanIface::getCapabilitiesRequest_1_5( - uint16_t cmd_id, getCapabilitiesRequest_1_5_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::getCapabilitiesRequest_1_5Internal, - hidl_status_cb, cmd_id); -} - -std::pair<WifiStatus, std::string> WifiNanIface::getNameInternal() { - return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_}; -} - -std::pair<WifiStatus, IfaceType> WifiNanIface::getTypeInternal() { - return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::NAN}; -} - -WifiStatus WifiNanIface::registerEventCallbackInternal( - const sp<V1_0::IWifiNanIfaceEventCallback>& callback) { - if (!event_cb_handler_.addCallback(callback)) { - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -WifiStatus WifiNanIface::getCapabilitiesRequestInternal(uint16_t /* cmd_id */) { - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); -} - -WifiStatus WifiNanIface::enableRequestInternal( - uint16_t /* cmd_id */, const V1_0::NanEnableRequest& /* msg */) { - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); -} - -WifiStatus WifiNanIface::configRequestInternal( - uint16_t /* cmd_id */, const V1_0::NanConfigRequest& /* msg */) { - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); -} - -WifiStatus WifiNanIface::disableRequestInternal(uint16_t cmd_id) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanDisableRequest(ifname_, cmd_id); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiNanIface::startPublishRequestInternal( - uint16_t cmd_id, const NanPublishRequest& msg) { - legacy_hal::NanPublishRequest legacy_msg; - if (!hidl_struct_util::convertHidlNanPublishRequestToLegacy(msg, - &legacy_msg)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanPublishRequest(ifname_, cmd_id, legacy_msg); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiNanIface::stopPublishRequestInternal(uint16_t cmd_id, - uint8_t sessionId) { - legacy_hal::NanPublishCancelRequest legacy_msg; - legacy_msg.publish_id = sessionId; - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanPublishCancelRequest(ifname_, cmd_id, - legacy_msg); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiNanIface::startSubscribeRequestInternal( - uint16_t cmd_id, const NanSubscribeRequest& msg) { - legacy_hal::NanSubscribeRequest legacy_msg; - if (!hidl_struct_util::convertHidlNanSubscribeRequestToLegacy( - msg, &legacy_msg)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanSubscribeRequest(ifname_, cmd_id, legacy_msg); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiNanIface::stopSubscribeRequestInternal(uint16_t cmd_id, - uint8_t sessionId) { - legacy_hal::NanSubscribeCancelRequest legacy_msg; - legacy_msg.subscribe_id = sessionId; - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanSubscribeCancelRequest(ifname_, cmd_id, - legacy_msg); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiNanIface::transmitFollowupRequestInternal( - uint16_t cmd_id, const NanTransmitFollowupRequest& msg) { - legacy_hal::NanTransmitFollowupRequest legacy_msg; - if (!hidl_struct_util::convertHidlNanTransmitFollowupRequestToLegacy( - msg, &legacy_msg)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanTransmitFollowupRequest(ifname_, cmd_id, - legacy_msg); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiNanIface::createDataInterfaceRequestInternal( - uint16_t cmd_id, const std::string& iface_name) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanDataInterfaceCreate(ifname_, cmd_id, iface_name); - return createWifiStatusFromLegacyError(legacy_status); -} -WifiStatus WifiNanIface::deleteDataInterfaceRequestInternal( - uint16_t cmd_id, const std::string& iface_name) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, cmd_id, iface_name); - return createWifiStatusFromLegacyError(legacy_status); -} -WifiStatus WifiNanIface::initiateDataPathRequestInternal( - uint16_t cmd_id, const NanInitiateDataPathRequest& msg) { - legacy_hal::NanDataPathInitiatorRequest legacy_msg; - if (!hidl_struct_util::convertHidlNanDataPathInitiatorRequestToLegacy( - msg, &legacy_msg)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanDataRequestInitiator(ifname_, cmd_id, - legacy_msg); - return createWifiStatusFromLegacyError(legacy_status); -} -WifiStatus WifiNanIface::respondToDataPathIndicationRequestInternal( - uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg) { - legacy_hal::NanDataPathIndicationResponse legacy_msg; - if (!hidl_struct_util::convertHidlNanDataPathIndicationResponseToLegacy( - msg, &legacy_msg)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanDataIndicationResponse(ifname_, cmd_id, - legacy_msg); - return createWifiStatusFromLegacyError(legacy_status); -} -WifiStatus WifiNanIface::terminateDataPathRequestInternal( - uint16_t cmd_id, uint32_t ndpInstanceId) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanDataEnd(ifname_, cmd_id, ndpInstanceId); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiNanIface::registerEventCallback_1_2Internal( - const sp<V1_2::IWifiNanIfaceEventCallback>& callback) { - sp<V1_0::IWifiNanIfaceEventCallback> callback_1_0 = callback; - if (!event_cb_handler_.addCallback(callback_1_0)) { - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - if (!event_cb_handler_1_2_.addCallback(callback)) { - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -WifiStatus WifiNanIface::enableRequest_1_2Internal( - uint16_t /* cmd_id */, const V1_0::NanEnableRequest& /* msg1 */, - const V1_2::NanConfigRequestSupplemental& /* msg2 */) { - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); -} - -WifiStatus WifiNanIface::configRequest_1_2Internal( - uint16_t /* cmd_id */, const V1_0::NanConfigRequest& /* msg1 */, - const V1_2::NanConfigRequestSupplemental& /* msg2 */) { - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); -} - -WifiStatus WifiNanIface::enableRequest_1_4Internal( - uint16_t /* cmd_id */, const V1_4::NanEnableRequest& /* msg1 */, - const V1_2::NanConfigRequestSupplemental& /* msg2 */) { - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); -} - -WifiStatus WifiNanIface::configRequest_1_4Internal( - uint16_t /* cmd_id */, const V1_4::NanConfigRequest& /* msg1 */, - const V1_2::NanConfigRequestSupplemental& /* msg2 */) { - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); -} - -WifiStatus WifiNanIface::registerEventCallback_1_5Internal( - const sp<IWifiNanIfaceEventCallback>& callback) { - sp<V1_0::IWifiNanIfaceEventCallback> callback_1_0 = callback; - if (!event_cb_handler_.addCallback(callback_1_0)) { - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - sp<V1_2::IWifiNanIfaceEventCallback> callback_1_2 = callback; - if (!event_cb_handler_1_2_.addCallback(callback_1_2)) { - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - if (!event_cb_handler_1_5_.addCallback(callback)) { - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -WifiStatus WifiNanIface::getCapabilitiesRequest_1_5Internal(uint16_t cmd_id) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanGetCapabilities(ifname_, cmd_id); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiNanIface::enableRequest_1_5Internal( - uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, - const NanConfigRequestSupplemental& msg2) { - legacy_hal::NanEnableRequest legacy_msg; - if (!hidl_struct_util::convertHidlNanEnableRequest_1_5ToLegacy( - msg1, msg2, &legacy_msg)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanEnableRequest(ifname_, cmd_id, legacy_msg); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiNanIface::configRequest_1_5Internal( - uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, - const NanConfigRequestSupplemental& msg2) { - legacy_hal::NanConfigRequest legacy_msg; - if (!hidl_struct_util::convertHidlNanConfigRequest_1_5ToLegacy( - msg1, msg2, &legacy_msg)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanConfigRequest(ifname_, cmd_id, legacy_msg); - return createWifiStatusFromLegacyError(legacy_status); -} - -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/wifi_nan_iface.h b/wifi/1.5/default/wifi_nan_iface.h deleted file mode 100644 index fb9c047ff6..0000000000 --- a/wifi/1.5/default/wifi_nan_iface.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef WIFI_NAN_IFACE_H_ -#define WIFI_NAN_IFACE_H_ - -#include <android-base/macros.h> -#include <android/hardware/wifi/1.5/IWifiNanIface.h> -#include <android/hardware/wifi/1.5/IWifiNanIfaceEventCallback.h> - -#include "hidl_callback_util.h" -#include "wifi_iface_util.h" -#include "wifi_legacy_hal.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -using namespace android::hardware::wifi::V1_0; -using namespace android::hardware::wifi::V1_2; - -/** - * HIDL interface object used to control a NAN Iface instance. - */ -class WifiNanIface : public V1_5::IWifiNanIface { - public: - WifiNanIface(const std::string& ifname, bool is_dedicated_iface, - const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal, - const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util); - // Refer to |WifiChip::invalidate()|. - void invalidate(); - bool isValid(); - std::string getName(); - - // HIDL methods exposed. - Return<void> getName(getName_cb hidl_status_cb) override; - Return<void> getType(getType_cb hidl_status_cb) override; - Return<void> registerEventCallback( - const sp<V1_0::IWifiNanIfaceEventCallback>& callback, - registerEventCallback_cb hidl_status_cb) override; - Return<void> getCapabilitiesRequest( - uint16_t cmd_id, getCapabilitiesRequest_cb hidl_status_cb) override; - Return<void> enableRequest(uint16_t cmd_id, - const V1_0::NanEnableRequest& msg, - enableRequest_cb hidl_status_cb) override; - Return<void> configRequest(uint16_t cmd_id, - const V1_0::NanConfigRequest& msg, - configRequest_cb hidl_status_cb) override; - Return<void> disableRequest(uint16_t cmd_id, - disableRequest_cb hidl_status_cb) override; - Return<void> startPublishRequest( - uint16_t cmd_id, const NanPublishRequest& msg, - startPublishRequest_cb hidl_status_cb) override; - Return<void> stopPublishRequest( - uint16_t cmd_id, uint8_t sessionId, - stopPublishRequest_cb hidl_status_cb) override; - Return<void> startSubscribeRequest( - uint16_t cmd_id, const NanSubscribeRequest& msg, - startSubscribeRequest_cb hidl_status_cb) override; - Return<void> stopSubscribeRequest( - uint16_t cmd_id, uint8_t sessionId, - stopSubscribeRequest_cb hidl_status_cb) override; - Return<void> transmitFollowupRequest( - uint16_t cmd_id, const NanTransmitFollowupRequest& msg, - transmitFollowupRequest_cb hidl_status_cb) override; - Return<void> createDataInterfaceRequest( - uint16_t cmd_id, const hidl_string& iface_name, - createDataInterfaceRequest_cb hidl_status_cb) override; - Return<void> deleteDataInterfaceRequest( - uint16_t cmd_id, const hidl_string& iface_name, - deleteDataInterfaceRequest_cb hidl_status_cb) override; - Return<void> initiateDataPathRequest( - uint16_t cmd_id, const NanInitiateDataPathRequest& msg, - initiateDataPathRequest_cb hidl_status_cb) override; - Return<void> respondToDataPathIndicationRequest( - uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg, - respondToDataPathIndicationRequest_cb hidl_status_cb) override; - Return<void> terminateDataPathRequest( - uint16_t cmd_id, uint32_t ndpInstanceId, - terminateDataPathRequest_cb hidl_status_cb) override; - - Return<void> registerEventCallback_1_2( - const sp<V1_2::IWifiNanIfaceEventCallback>& callback, - registerEventCallback_1_2_cb hidl_status_cb) override; - Return<void> enableRequest_1_2( - uint16_t cmd_id, const V1_0::NanEnableRequest& msg1, - const V1_2::NanConfigRequestSupplemental& msg2, - enableRequest_1_2_cb hidl_status_cb) override; - Return<void> configRequest_1_2( - uint16_t cmd_id, const V1_0::NanConfigRequest& msg1, - const V1_2::NanConfigRequestSupplemental& msg2, - configRequest_1_2_cb hidl_status_cb) override; - Return<void> enableRequest_1_4( - uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, - const V1_2::NanConfigRequestSupplemental& msg2, - enableRequest_1_4_cb hidl_status_cb) override; - Return<void> configRequest_1_4( - uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, - const V1_2::NanConfigRequestSupplemental& msg2, - configRequest_1_4_cb hidl_status_cb) override; - Return<void> registerEventCallback_1_5( - const sp<IWifiNanIfaceEventCallback>& callback, - registerEventCallback_1_5_cb hidl_status_cb) override; - Return<void> enableRequest_1_5( - uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, - const NanConfigRequestSupplemental& msg2, - enableRequest_1_4_cb hidl_status_cb) override; - Return<void> configRequest_1_5( - uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, - const NanConfigRequestSupplemental& msg2, - configRequest_1_4_cb hidl_status_cb) override; - Return<void> getCapabilitiesRequest_1_5( - uint16_t cmd_id, getCapabilitiesRequest_cb hidl_status_cb) override; - - private: - // Corresponding worker functions for the HIDL methods. - std::pair<WifiStatus, std::string> getNameInternal(); - std::pair<WifiStatus, IfaceType> getTypeInternal(); - WifiStatus registerEventCallbackInternal( - const sp<V1_0::IWifiNanIfaceEventCallback>& callback); - WifiStatus getCapabilitiesRequestInternal(uint16_t cmd_id); - WifiStatus enableRequestInternal(uint16_t cmd_id, - const V1_0::NanEnableRequest& msg); - WifiStatus configRequestInternal(uint16_t cmd_id, - const V1_0::NanConfigRequest& msg); - WifiStatus disableRequestInternal(uint16_t cmd_id); - WifiStatus startPublishRequestInternal(uint16_t cmd_id, - const NanPublishRequest& msg); - WifiStatus stopPublishRequestInternal(uint16_t cmd_id, uint8_t sessionId); - WifiStatus startSubscribeRequestInternal(uint16_t cmd_id, - const NanSubscribeRequest& msg); - WifiStatus stopSubscribeRequestInternal(uint16_t cmd_id, uint8_t sessionId); - WifiStatus transmitFollowupRequestInternal( - uint16_t cmd_id, const NanTransmitFollowupRequest& msg); - WifiStatus createDataInterfaceRequestInternal( - uint16_t cmd_id, const std::string& iface_name); - WifiStatus deleteDataInterfaceRequestInternal( - uint16_t cmd_id, const std::string& iface_name); - WifiStatus initiateDataPathRequestInternal( - uint16_t cmd_id, const NanInitiateDataPathRequest& msg); - WifiStatus respondToDataPathIndicationRequestInternal( - uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg); - WifiStatus terminateDataPathRequestInternal(uint16_t cmd_id, - uint32_t ndpInstanceId); - - WifiStatus registerEventCallback_1_2Internal( - const sp<V1_2::IWifiNanIfaceEventCallback>& callback); - WifiStatus enableRequest_1_2Internal( - uint16_t cmd_id, const V1_0::NanEnableRequest& msg1, - const V1_2::NanConfigRequestSupplemental& msg2); - WifiStatus configRequest_1_2Internal( - uint16_t cmd_id, const V1_0::NanConfigRequest& msg, - const V1_2::NanConfigRequestSupplemental& msg2); - WifiStatus enableRequest_1_4Internal( - uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, - const V1_2::NanConfigRequestSupplemental& msg2); - WifiStatus configRequest_1_4Internal( - uint16_t cmd_id, const V1_4::NanConfigRequest& msg, - const V1_2::NanConfigRequestSupplemental& msg2); - WifiStatus registerEventCallback_1_5Internal( - const sp<IWifiNanIfaceEventCallback>& callback); - WifiStatus enableRequest_1_5Internal( - uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, - const NanConfigRequestSupplemental& msg2); - WifiStatus configRequest_1_5Internal( - uint16_t cmd_id, const V1_4::NanConfigRequest& msg, - const NanConfigRequestSupplemental& msg2); - WifiStatus getCapabilitiesRequest_1_5Internal(uint16_t cmd_id); - - // all 1_0 and descendant callbacks - std::set<sp<V1_0::IWifiNanIfaceEventCallback>> getEventCallbacks(); - // all 1_2 and descendant callbacks - std::set<sp<V1_2::IWifiNanIfaceEventCallback>> getEventCallbacks_1_2(); - // all 1_5 and descendant callbacks - std::set<sp<IWifiNanIfaceEventCallback>> getEventCallbacks_1_5(); - - std::string ifname_; - bool is_dedicated_iface_; - std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_; - std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_; - bool is_valid_; - hidl_callback_util::HidlCallbackHandler<V1_0::IWifiNanIfaceEventCallback> - event_cb_handler_; - hidl_callback_util::HidlCallbackHandler<V1_2::IWifiNanIfaceEventCallback> - event_cb_handler_1_2_; - hidl_callback_util::HidlCallbackHandler<IWifiNanIfaceEventCallback> - event_cb_handler_1_5_; - - DISALLOW_COPY_AND_ASSIGN(WifiNanIface); -}; - -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android - -#endif // WIFI_NAN_IFACE_H_ diff --git a/wifi/1.5/default/wifi_rtt_controller.cpp b/wifi/1.5/default/wifi_rtt_controller.cpp deleted file mode 100644 index a0f9969033..0000000000 --- a/wifi/1.5/default/wifi_rtt_controller.cpp +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <android-base/logging.h> - -#include "hidl_return_util.h" -#include "hidl_struct_util.h" -#include "wifi_rtt_controller.h" -#include "wifi_status_util.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -using hidl_return_util::validateAndCall; - -WifiRttController::WifiRttController( - const std::string& iface_name, const sp<IWifiIface>& bound_iface, - const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal) - : ifname_(iface_name), - bound_iface_(bound_iface), - legacy_hal_(legacy_hal), - is_valid_(true) {} - -void WifiRttController::invalidate() { - legacy_hal_.reset(); - event_callbacks_.clear(); - is_valid_ = false; -} - -bool WifiRttController::isValid() { return is_valid_; } - -std::vector<sp<V1_4::IWifiRttControllerEventCallback>> -WifiRttController::getEventCallbacks() { - return event_callbacks_; -} - -std::string WifiRttController::getIfaceName() { return ifname_; } - -Return<void> WifiRttController::getBoundIface(getBoundIface_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::getBoundIfaceInternal, hidl_status_cb); -} - -Return<void> WifiRttController::registerEventCallback( - const sp<V1_0::IWifiRttControllerEventCallback>& callback, - registerEventCallback_cb hidl_status_cb) { - return validateAndCall(this, - WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::registerEventCallbackInternal, - hidl_status_cb, callback); -} - -Return<void> WifiRttController::rangeRequest( - uint32_t cmd_id, const hidl_vec<V1_0::RttConfig>& rtt_configs, - rangeRequest_cb hidl_status_cb) { - return validateAndCall(this, - WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::rangeRequestInternal, - hidl_status_cb, cmd_id, rtt_configs); -} - -Return<void> WifiRttController::rangeCancel( - uint32_t cmd_id, const hidl_vec<hidl_array<uint8_t, 6>>& addrs, - rangeCancel_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::rangeCancelInternal, hidl_status_cb, cmd_id, addrs); -} - -Return<void> WifiRttController::getCapabilities( - getCapabilities_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::getCapabilitiesInternal, hidl_status_cb); -} - -Return<void> WifiRttController::setLci(uint32_t cmd_id, - const RttLciInformation& lci, - setLci_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::setLciInternal, hidl_status_cb, cmd_id, lci); -} - -Return<void> WifiRttController::setLcr(uint32_t cmd_id, - const RttLcrInformation& lcr, - setLcr_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::setLcrInternal, hidl_status_cb, cmd_id, lcr); -} - -Return<void> WifiRttController::getResponderInfo( - getResponderInfo_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::getResponderInfoInternal, hidl_status_cb); -} - -Return<void> WifiRttController::enableResponder( - uint32_t cmd_id, const WifiChannelInfo& channel_hint, - uint32_t max_duration_seconds, const V1_0::RttResponder& info, - enableResponder_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::enableResponderInternal, hidl_status_cb, cmd_id, - channel_hint, max_duration_seconds, info); -} - -Return<void> WifiRttController::disableResponder( - uint32_t cmd_id, disableResponder_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::disableResponderInternal, hidl_status_cb, cmd_id); -} - -Return<void> WifiRttController::registerEventCallback_1_4( - const sp<V1_4::IWifiRttControllerEventCallback>& callback, - registerEventCallback_1_4_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::registerEventCallbackInternal_1_4, hidl_status_cb, - callback); -} - -Return<void> WifiRttController::rangeRequest_1_4( - uint32_t cmd_id, const hidl_vec<V1_4::RttConfig>& rtt_configs, - rangeRequest_1_4_cb hidl_status_cb) { - return validateAndCall(this, - WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::rangeRequestInternal_1_4, - hidl_status_cb, cmd_id, rtt_configs); -} - -Return<void> WifiRttController::getCapabilities_1_4( - getCapabilities_1_4_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::getCapabilitiesInternal_1_4, hidl_status_cb); -} - -Return<void> WifiRttController::getResponderInfo_1_4( - getResponderInfo_1_4_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::getResponderInfoInternal_1_4, hidl_status_cb); -} - -Return<void> WifiRttController::enableResponder_1_4( - uint32_t cmd_id, const WifiChannelInfo& channel_hint, - uint32_t max_duration_seconds, const V1_4::RttResponder& info, - enableResponder_1_4_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::enableResponderInternal_1_4, hidl_status_cb, cmd_id, - channel_hint, max_duration_seconds, info); -} - -std::pair<WifiStatus, sp<IWifiIface>> -WifiRttController::getBoundIfaceInternal() { - return {createWifiStatus(WifiStatusCode::SUCCESS), bound_iface_}; -} - -WifiStatus WifiRttController::registerEventCallbackInternal( - const sp<V1_0::IWifiRttControllerEventCallback>& /* callback */) { - // Deprecated support for this api - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); -} - -WifiStatus WifiRttController::rangeRequestInternal( - uint32_t /* cmd_id */, - const std::vector<V1_0::RttConfig>& /* rtt_configs */) { - // Deprecated support for this api - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); -} - -WifiStatus WifiRttController::rangeCancelInternal( - uint32_t cmd_id, const std::vector<hidl_array<uint8_t, 6>>& addrs) { - std::vector<std::array<uint8_t, 6>> legacy_addrs; - for (const auto& addr : addrs) { - legacy_addrs.push_back(addr); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->cancelRttRangeRequest(ifname_, cmd_id, - legacy_addrs); - return createWifiStatusFromLegacyError(legacy_status); -} - -std::pair<WifiStatus, V1_0::RttCapabilities> -WifiRttController::getCapabilitiesInternal() { - // Deprecated support for this api - return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}}; -} - -WifiStatus WifiRttController::setLciInternal(uint32_t cmd_id, - const RttLciInformation& lci) { - legacy_hal::wifi_lci_information legacy_lci; - if (!hidl_struct_util::convertHidlRttLciInformationToLegacy(lci, - &legacy_lci)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->setRttLci(ifname_, cmd_id, legacy_lci); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiRttController::setLcrInternal(uint32_t cmd_id, - const RttLcrInformation& lcr) { - legacy_hal::wifi_lcr_information legacy_lcr; - if (!hidl_struct_util::convertHidlRttLcrInformationToLegacy(lcr, - &legacy_lcr)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->setRttLcr(ifname_, cmd_id, legacy_lcr); - return createWifiStatusFromLegacyError(legacy_status); -} - -std::pair<WifiStatus, V1_0::RttResponder> -WifiRttController::getResponderInfoInternal() { - // Deprecated support for this api - return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}}; -} - -WifiStatus WifiRttController::enableResponderInternal( - uint32_t /* cmd_id */, const WifiChannelInfo& /* channel_hint */, - uint32_t /* max_duration_seconds */, const V1_0::RttResponder& /* info */) { - // Deprecated support for this api - return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED)}; -} - -WifiStatus WifiRttController::disableResponderInternal(uint32_t cmd_id) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->disableRttResponder(ifname_, cmd_id); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiRttController::registerEventCallbackInternal_1_4( - const sp<V1_4::IWifiRttControllerEventCallback>& callback) { - // TODO(b/31632518): remove the callback when the client is destroyed - event_callbacks_.emplace_back(callback); - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -WifiStatus WifiRttController::rangeRequestInternal_1_4( - uint32_t cmd_id, const std::vector<V1_4::RttConfig>& rtt_configs) { - std::vector<legacy_hal::wifi_rtt_config> legacy_configs; - if (!hidl_struct_util::convertHidlVectorOfRttConfigToLegacy( - rtt_configs, &legacy_configs)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - android::wp<WifiRttController> weak_ptr_this(this); - const auto& on_results_callback = - [weak_ptr_this]( - legacy_hal::wifi_request_id id, - const std::vector<const legacy_hal::wifi_rtt_result*>& results) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - std::vector<V1_4::RttResult> hidl_results; - if (!hidl_struct_util::convertLegacyVectorOfRttResultToHidl( - results, &hidl_results)) { - LOG(ERROR) << "Failed to convert rtt results to HIDL structs"; - return; - } - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - callback->onResults_1_4(id, hidl_results); - } - }; - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->startRttRangeRequest( - ifname_, cmd_id, legacy_configs, on_results_callback); - return createWifiStatusFromLegacyError(legacy_status); -} - -std::pair<WifiStatus, V1_4::RttCapabilities> -WifiRttController::getCapabilitiesInternal_1_4() { - legacy_hal::wifi_error legacy_status; - legacy_hal::wifi_rtt_capabilities legacy_caps; - std::tie(legacy_status, legacy_caps) = - legacy_hal_.lock()->getRttCapabilities(ifname_); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - return {createWifiStatusFromLegacyError(legacy_status), {}}; - } - V1_4::RttCapabilities hidl_caps; - if (!hidl_struct_util::convertLegacyRttCapabilitiesToHidl(legacy_caps, - &hidl_caps)) { - return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps}; -} - -std::pair<WifiStatus, V1_4::RttResponder> -WifiRttController::getResponderInfoInternal_1_4() { - legacy_hal::wifi_error legacy_status; - legacy_hal::wifi_rtt_responder legacy_responder; - std::tie(legacy_status, legacy_responder) = - legacy_hal_.lock()->getRttResponderInfo(ifname_); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - return {createWifiStatusFromLegacyError(legacy_status), {}}; - } - V1_4::RttResponder hidl_responder; - if (!hidl_struct_util::convertLegacyRttResponderToHidl(legacy_responder, - &hidl_responder)) { - return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_responder}; -} - -WifiStatus WifiRttController::enableResponderInternal_1_4( - uint32_t cmd_id, const WifiChannelInfo& channel_hint, - uint32_t max_duration_seconds, const V1_4::RttResponder& info) { - legacy_hal::wifi_channel_info legacy_channel_info; - if (!hidl_struct_util::convertHidlWifiChannelInfoToLegacy( - channel_hint, &legacy_channel_info)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - legacy_hal::wifi_rtt_responder legacy_responder; - if (!hidl_struct_util::convertHidlRttResponderToLegacy(info, - &legacy_responder)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->enableRttResponder( - ifname_, cmd_id, legacy_channel_info, max_duration_seconds, - legacy_responder); - return createWifiStatusFromLegacyError(legacy_status); -} -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/wifi_sta_iface.h b/wifi/1.5/default/wifi_sta_iface.h deleted file mode 100644 index f9058b8af1..0000000000 --- a/wifi/1.5/default/wifi_sta_iface.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef WIFI_STA_IFACE_H_ -#define WIFI_STA_IFACE_H_ - -#include <android-base/macros.h> -#include <android/hardware/wifi/1.0/IWifiStaIfaceEventCallback.h> -#include <android/hardware/wifi/1.5/IWifiStaIface.h> - -#include "hidl_callback_util.h" -#include "wifi_iface_util.h" -#include "wifi_legacy_hal.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -using namespace android::hardware::wifi::V1_0; - -/** - * HIDL interface object used to control a STA Iface instance. - */ -class WifiStaIface : public V1_5::IWifiStaIface { - public: - WifiStaIface(const std::string& ifname, - const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal, - const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util); - // Refer to |WifiChip::invalidate()|. - void invalidate(); - bool isValid(); - std::set<sp<IWifiStaIfaceEventCallback>> getEventCallbacks(); - std::string getName(); - - // HIDL methods exposed. - Return<void> getName(getName_cb hidl_status_cb) override; - Return<void> getType(getType_cb hidl_status_cb) override; - Return<void> registerEventCallback( - const sp<IWifiStaIfaceEventCallback>& callback, - registerEventCallback_cb hidl_status_cb) override; - Return<void> getCapabilities(getCapabilities_cb hidl_status_cb) override; - Return<void> getApfPacketFilterCapabilities( - getApfPacketFilterCapabilities_cb hidl_status_cb) override; - Return<void> installApfPacketFilter( - uint32_t cmd_id, const hidl_vec<uint8_t>& program, - installApfPacketFilter_cb hidl_status_cb) override; - Return<void> readApfPacketFilterData( - readApfPacketFilterData_cb hidl_status_cb) override; - Return<void> getBackgroundScanCapabilities( - getBackgroundScanCapabilities_cb hidl_status_cb) override; - Return<void> getValidFrequenciesForBand( - V1_0::WifiBand band, - getValidFrequenciesForBand_cb hidl_status_cb) override; - Return<void> startBackgroundScan( - uint32_t cmd_id, const StaBackgroundScanParameters& params, - startBackgroundScan_cb hidl_status_cb) override; - Return<void> stopBackgroundScan( - uint32_t cmd_id, stopBackgroundScan_cb hidl_status_cb) override; - Return<void> enableLinkLayerStatsCollection( - bool debug, enableLinkLayerStatsCollection_cb hidl_status_cb) override; - Return<void> disableLinkLayerStatsCollection( - disableLinkLayerStatsCollection_cb hidl_status_cb) override; - Return<void> getLinkLayerStats( - getLinkLayerStats_cb hidl_status_cb) override; - Return<void> getLinkLayerStats_1_3( - getLinkLayerStats_1_3_cb hidl_status_cb) override; - Return<void> getLinkLayerStats_1_5( - getLinkLayerStats_1_5_cb hidl_status_cb) override; - Return<void> startRssiMonitoring( - uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi, - startRssiMonitoring_cb hidl_status_cb) override; - Return<void> stopRssiMonitoring( - uint32_t cmd_id, stopRssiMonitoring_cb hidl_status_cb) override; - Return<void> getRoamingCapabilities( - getRoamingCapabilities_cb hidl_status_cb) override; - Return<void> configureRoaming(const StaRoamingConfig& config, - configureRoaming_cb hidl_status_cb) override; - Return<void> setRoamingState(StaRoamingState state, - setRoamingState_cb hidl_status_cb) override; - Return<void> enableNdOffload(bool enable, - enableNdOffload_cb hidl_status_cb) override; - Return<void> startSendingKeepAlivePackets( - uint32_t cmd_id, const hidl_vec<uint8_t>& ip_packet_data, - uint16_t ether_type, const hidl_array<uint8_t, 6>& src_address, - const hidl_array<uint8_t, 6>& dst_address, uint32_t period_in_ms, - startSendingKeepAlivePackets_cb hidl_status_cb) override; - Return<void> stopSendingKeepAlivePackets( - uint32_t cmd_id, - stopSendingKeepAlivePackets_cb hidl_status_cb) override; - Return<void> setScanningMacOui( - const hidl_array<uint8_t, 3>& oui, - setScanningMacOui_cb hidl_status_cb) override; - Return<void> startDebugPacketFateMonitoring( - startDebugPacketFateMonitoring_cb hidl_status_cb) override; - Return<void> getDebugTxPacketFates( - getDebugTxPacketFates_cb hidl_status_cb) override; - Return<void> getDebugRxPacketFates( - getDebugRxPacketFates_cb hidl_status_cb) override; - Return<void> setMacAddress(const hidl_array<uint8_t, 6>& mac, - setMacAddress_cb hidl_status_cb) override; - Return<void> getFactoryMacAddress( - getFactoryMacAddress_cb hidl_status_cb) override; - Return<void> setScanMode(bool enable, - setScanMode_cb hidl_status_cb) override; - - private: - // Corresponding worker functions for the HIDL methods. - std::pair<WifiStatus, std::string> getNameInternal(); - std::pair<WifiStatus, IfaceType> getTypeInternal(); - WifiStatus registerEventCallbackInternal( - const sp<IWifiStaIfaceEventCallback>& callback); - std::pair<WifiStatus, uint32_t> getCapabilitiesInternal(); - std::pair<WifiStatus, StaApfPacketFilterCapabilities> - getApfPacketFilterCapabilitiesInternal(); - WifiStatus installApfPacketFilterInternal( - uint32_t cmd_id, const std::vector<uint8_t>& program); - std::pair<WifiStatus, std::vector<uint8_t>> - readApfPacketFilterDataInternal(); - std::pair<WifiStatus, StaBackgroundScanCapabilities> - getBackgroundScanCapabilitiesInternal(); - std::pair<WifiStatus, std::vector<WifiChannelInMhz>> - getValidFrequenciesForBandInternal(V1_0::WifiBand band); - WifiStatus startBackgroundScanInternal( - uint32_t cmd_id, const StaBackgroundScanParameters& params); - WifiStatus stopBackgroundScanInternal(uint32_t cmd_id); - WifiStatus enableLinkLayerStatsCollectionInternal(bool debug); - WifiStatus disableLinkLayerStatsCollectionInternal(); - std::pair<WifiStatus, V1_0::StaLinkLayerStats> getLinkLayerStatsInternal(); - std::pair<WifiStatus, V1_3::StaLinkLayerStats> - getLinkLayerStatsInternal_1_3(); - std::pair<WifiStatus, V1_5::StaLinkLayerStats> - getLinkLayerStatsInternal_1_5(); - WifiStatus startRssiMonitoringInternal(uint32_t cmd_id, int32_t max_rssi, - int32_t min_rssi); - WifiStatus stopRssiMonitoringInternal(uint32_t cmd_id); - std::pair<WifiStatus, StaRoamingCapabilities> - getRoamingCapabilitiesInternal(); - WifiStatus configureRoamingInternal(const StaRoamingConfig& config); - WifiStatus setRoamingStateInternal(StaRoamingState state); - WifiStatus enableNdOffloadInternal(bool enable); - WifiStatus startSendingKeepAlivePacketsInternal( - uint32_t cmd_id, const std::vector<uint8_t>& ip_packet_data, - uint16_t ether_type, const std::array<uint8_t, 6>& src_address, - const std::array<uint8_t, 6>& dst_address, uint32_t period_in_ms); - WifiStatus stopSendingKeepAlivePacketsInternal(uint32_t cmd_id); - WifiStatus setScanningMacOuiInternal(const std::array<uint8_t, 3>& oui); - WifiStatus startDebugPacketFateMonitoringInternal(); - std::pair<WifiStatus, std::vector<WifiDebugTxPacketFateReport>> - getDebugTxPacketFatesInternal(); - std::pair<WifiStatus, std::vector<WifiDebugRxPacketFateReport>> - getDebugRxPacketFatesInternal(); - WifiStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac); - std::pair<WifiStatus, std::array<uint8_t, 6>> - getFactoryMacAddressInternal(); - WifiStatus setScanModeInternal(bool enable); - - std::string ifname_; - std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_; - std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_; - bool is_valid_; - hidl_callback_util::HidlCallbackHandler<IWifiStaIfaceEventCallback> - event_cb_handler_; - - DISALLOW_COPY_AND_ASSIGN(WifiStaIface); -}; - -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android - -#endif // WIFI_STA_IFACE_H_ diff --git a/wifi/1.6/Android.bp b/wifi/1.6/Android.bp new file mode 100644 index 0000000000..d293c73a79 --- /dev/null +++ b/wifi/1.6/Android.bp @@ -0,0 +1,32 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +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"], +} + +hidl_interface { + name: "android.hardware.wifi@1.6", + root: "android.hardware", + srcs: [ + "IWifi.hal", + ], + interfaces: [ + "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", + "android.hidl.base@1.0", + ], + gen_java: true, + apex_available: [ + "//apex_available:platform", + "com.android.wifi", + ], +} diff --git a/wifi/1.6/IWifi.hal b/wifi/1.6/IWifi.hal new file mode 100644 index 0000000000..0123e6ca83 --- /dev/null +++ b/wifi/1.6/IWifi.hal @@ -0,0 +1,27 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.wifi@1.6; + +import @1.5::IWifi; + +/** + * This is the root of the HAL module and is the interface returned when + * loading an implementation of the Wi-Fi HAL. There must be at most one + * module loaded in the system. + * IWifi.getChip() must return @1.5::IWifiChip + */ +interface IWifi extends @1.5::IWifi {}; diff --git a/wifi/1.6/default/Android.bp b/wifi/1.6/default/Android.bp new file mode 100644 index 0000000000..d48d18332f --- /dev/null +++ b/wifi/1.6/default/Android.bp @@ -0,0 +1,107 @@ +// 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", + "android.hardware.wifi@1.6", + "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", + "android.hardware.wifi@1.6", + "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/1.5/default/Android.mk b/wifi/1.6/default/Android.mk index edb59bb085..ca1c022db1 100644 --- a/wifi/1.5/default/Android.mk +++ b/wifi/1.6/default/Android.mk @@ -42,12 +42,6 @@ endif ifdef WIFI_AVOID_IFACE_RESET_MAC_CHANGE LOCAL_CPPFLAGS += -DWIFI_AVOID_IFACE_RESET_MAC_CHANGE endif -ifdef QC_WIFI_HIDL_FEATURE_DUAL_AP -LOCAL_CPPFLAGS += -DQC_WIFI_HIDL_FEATURE_DUAL_AP -endif -ifdef QC_WIFI_HIDL_FEATURE_DUAL_STA -LOCAL_CPPFLAGS += -DQC_WIFI_HIDL_FEATURE_DUAL_STA -endif # Allow implicit fallthroughs in wifi_legacy_hal.cpp until they are fixed. LOCAL_CFLAGS += -Wno-error=implicit-fallthrough LOCAL_SRC_FILES := \ @@ -83,7 +77,8 @@ LOCAL_SHARED_LIBRARIES := \ android.hardware.wifi@1.2 \ android.hardware.wifi@1.3 \ android.hardware.wifi@1.4 \ - android.hardware.wifi@1.5 + android.hardware.wifi@1.5 \ + android.hardware.wifi@1.6 LOCAL_C_INCLUDES += $(TOP)/external/libxml2/include LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) include $(BUILD_STATIC_LIBRARY) @@ -100,10 +95,6 @@ LOCAL_VINTF_FRAGMENTS := android.hardware.wifi@1.0-service.xml LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_PROPRIETARY_MODULE := true LOCAL_CPPFLAGS := -Wall -Werror -Wextra -ifeq ($(TARGET_ARCH),arm) - LOCAL_CPPFLAGS += -DARCH_ARM_32 -endif - LOCAL_SRC_FILES := \ service.cpp LOCAL_SHARED_LIBRARIES := \ @@ -113,7 +104,6 @@ LOCAL_SHARED_LIBRARIES := \ liblog \ libnl \ libutils \ - libhwbinder \ libwifi-hal \ libwifi-system-iface \ libxml2 \ @@ -122,7 +112,8 @@ LOCAL_SHARED_LIBRARIES := \ android.hardware.wifi@1.2 \ android.hardware.wifi@1.3 \ android.hardware.wifi@1.4 \ - android.hardware.wifi@1.5 + android.hardware.wifi@1.5 \ + android.hardware.wifi@1.6 LOCAL_STATIC_LIBRARIES := \ android.hardware.wifi@1.0-service-lib LOCAL_INIT_RC := android.hardware.wifi@1.0-service.rc @@ -159,7 +150,8 @@ LOCAL_SHARED_LIBRARIES := \ android.hardware.wifi@1.2 \ android.hardware.wifi@1.3 \ android.hardware.wifi@1.4 \ - android.hardware.wifi@1.5 + android.hardware.wifi@1.5 \ + android.hardware.wifi@1.6 LOCAL_STATIC_LIBRARIES := \ android.hardware.wifi@1.0-service-lib LOCAL_INIT_RC := android.hardware.wifi@1.0-service-lazy.rc @@ -196,6 +188,7 @@ LOCAL_STATIC_LIBRARIES := \ android.hardware.wifi@1.3 \ android.hardware.wifi@1.4 \ android.hardware.wifi@1.5 \ + android.hardware.wifi@1.6 \ android.hardware.wifi@1.0-service-lib LOCAL_SHARED_LIBRARIES := \ libbase \ diff --git a/wifi/1.5/default/OWNERS b/wifi/1.6/default/OWNERS index cf81c79892..cf81c79892 100644 --- a/wifi/1.5/default/OWNERS +++ b/wifi/1.6/default/OWNERS diff --git a/wifi/1.5/default/THREADING.README b/wifi/1.6/default/THREADING.README index 8366ca0201..8366ca0201 100644 --- a/wifi/1.5/default/THREADING.README +++ b/wifi/1.6/default/THREADING.README diff --git a/wifi/1.5/default/android.hardware.wifi@1.0-service-lazy.rc b/wifi/1.6/default/android.hardware.wifi@1.0-service-lazy.rc index bc6bb6a7e6..ee8c818d90 100644 --- a/wifi/1.5/default/android.hardware.wifi@1.0-service-lazy.rc +++ b/wifi/1.6/default/android.hardware.wifi@1.0-service-lazy.rc @@ -5,6 +5,7 @@ service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi@1.0-service- interface android.hardware.wifi@1.3::IWifi default interface android.hardware.wifi@1.4::IWifi default interface android.hardware.wifi@1.5::IWifi default + interface android.hardware.wifi@1.6::IWifi default oneshot disabled class hal diff --git a/wifi/1.5/default/android.hardware.wifi@1.0-service.rc b/wifi/1.6/default/android.hardware.wifi@1.0-service.rc index 05706ef4f4..18f40d0bb5 100644 --- a/wifi/1.5/default/android.hardware.wifi@1.0-service.rc +++ b/wifi/1.6/default/android.hardware.wifi@1.0-service.rc @@ -5,6 +5,7 @@ service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi@1.0-service interface android.hardware.wifi@1.3::IWifi default interface android.hardware.wifi@1.4::IWifi default interface android.hardware.wifi@1.5::IWifi default + interface android.hardware.wifi@1.6::IWifi default class hal capabilities NET_ADMIN NET_RAW SYS_MODULE user wifi diff --git a/wifi/1.5/default/android.hardware.wifi@1.0-service.xml b/wifi/1.6/default/android.hardware.wifi@1.0-service.xml index 88dd1e3285..771fbaaf42 100644 --- a/wifi/1.5/default/android.hardware.wifi@1.0-service.xml +++ b/wifi/1.6/default/android.hardware.wifi@1.0-service.xml @@ -2,7 +2,7 @@ <hal format="hidl"> <name>android.hardware.wifi</name> <transport>hwbinder</transport> - <version>1.5</version> + <version>1.6</version> <interface> <name>IWifi</name> <instance>default</instance> diff --git a/wifi/1.5/default/hidl_callback_util.h b/wifi/1.6/default/hidl_callback_util.h index d144658750..3ac54c1666 100644 --- a/wifi/1.5/default/hidl_callback_util.h +++ b/wifi/1.6/default/hidl_callback_util.h @@ -29,20 +29,18 @@ using on_death_cb_function = std::function<void(uint64_t)>; // callbacks stored in HidlCallbackHandler. template <typename CallbackType> class HidlDeathHandler : public android::hardware::hidl_death_recipient { - public: + public: HidlDeathHandler(const on_death_cb_function& user_cb_function) : cb_function_(user_cb_function) {} ~HidlDeathHandler() = default; // Death notification for callbacks. - void serviceDied( - uint64_t cookie, - const android::wp<android::hidl::base::V1_0::IBase>& /* who */) - override { + void serviceDied(uint64_t cookie, + const android::wp<android::hidl::base::V1_0::IBase>& /* who */) override { cb_function_(cookie); } - private: + private: on_death_cb_function cb_function_; DISALLOW_COPY_AND_ASSIGN(HidlDeathHandler); @@ -52,18 +50,17 @@ class HidlDeathHandler : public android::hardware::hidl_death_recipient { namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace hidl_callback_util { template <typename CallbackType> // Provides a class to manage callbacks for the various HIDL interfaces and // handle the death of the process hosting each callback. class HidlCallbackHandler { - public: + public: HidlCallbackHandler() : death_handler_(new HidlDeathHandler<CallbackType>( - std::bind(&HidlCallbackHandler::onObjectDeath, this, - std::placeholders::_1))) {} + std::bind(&HidlCallbackHandler::onObjectDeath, this, std::placeholders::_1))) {} ~HidlCallbackHandler() = default; bool addCallback(const sp<CallbackType>& cb) { @@ -83,9 +80,7 @@ class HidlCallbackHandler { return true; } - const std::set<android::sp<CallbackType>>& getCallbacks() { - return cb_set_; - } + const std::set<android::sp<CallbackType>>& getCallbacks() { return cb_set_; } // Death notification for callbacks. void onObjectDeath(uint64_t cookie) { @@ -108,7 +103,7 @@ class HidlCallbackHandler { cb_set_.clear(); } - private: + private: std::set<sp<CallbackType>> cb_set_; sp<HidlDeathHandler<CallbackType>> death_handler_; @@ -117,7 +112,7 @@ class HidlCallbackHandler { } // namespace hidl_callback_util } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/hidl_return_util.h b/wifi/1.6/default/hidl_return_util.h index 4455185283..a0efac2c57 100644 --- a/wifi/1.5/default/hidl_return_util.h +++ b/wifi/1.6/default/hidl_return_util.h @@ -23,7 +23,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace hidl_return_util { using namespace android::hardware::wifi::V1_0; @@ -40,9 +40,9 @@ using namespace android::hardware::wifi::V1_0; */ // Use for HIDL methods which return only an instance of WifiStatus. template <typename ObjT, typename WorkFuncT, typename... Args> -Return<void> validateAndCall( - ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work, - const std::function<void(const WifiStatus&)>& hidl_cb, Args&&... args) { +Return<void> validateAndCall(ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work, + const std::function<void(const WifiStatus&)>& hidl_cb, + Args&&... args) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (obj->isValid()) { hidl_cb((obj->*work)(std::forward<Args>(args)...)); @@ -56,9 +56,10 @@ Return<void> validateAndCall( // This version passes the global lock acquired to the body of the method. // Note: Only used by IWifi::stop() currently. template <typename ObjT, typename WorkFuncT, typename... Args> -Return<void> validateAndCallWithLock( - ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work, - const std::function<void(const WifiStatus&)>& hidl_cb, Args&&... args) { +Return<void> validateAndCallWithLock(ObjT* obj, WifiStatusCode status_code_if_invalid, + WorkFuncT&& work, + const std::function<void(const WifiStatus&)>& hidl_cb, + Args&&... args) { auto lock = hidl_sync_util::acquireGlobalLock(); if (obj->isValid()) { hidl_cb((obj->*work)(&lock, std::forward<Args>(args)...)); @@ -71,10 +72,9 @@ Return<void> validateAndCallWithLock( // Use for HIDL methods which return instance of WifiStatus and a single return // value. template <typename ObjT, typename WorkFuncT, typename ReturnT, typename... Args> -Return<void> validateAndCall( - ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work, - const std::function<void(const WifiStatus&, ReturnT)>& hidl_cb, - Args&&... args) { +Return<void> validateAndCall(ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work, + const std::function<void(const WifiStatus&, ReturnT)>& hidl_cb, + Args&&... args) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (obj->isValid()) { const auto& ret_pair = (obj->*work)(std::forward<Args>(args)...); @@ -90,12 +90,10 @@ Return<void> validateAndCall( // Use for HIDL methods which return instance of WifiStatus and 2 return // values. -template <typename ObjT, typename WorkFuncT, typename ReturnT1, - typename ReturnT2, typename... Args> +template <typename ObjT, typename WorkFuncT, typename ReturnT1, typename ReturnT2, typename... Args> Return<void> validateAndCall( - ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work, - const std::function<void(const WifiStatus&, ReturnT1, ReturnT2)>& hidl_cb, - Args&&... args) { + ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work, + const std::function<void(const WifiStatus&, ReturnT1, ReturnT2)>& hidl_cb, Args&&... args) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (obj->isValid()) { const auto& ret_tuple = (obj->*work)(std::forward<Args>(args)...); @@ -113,7 +111,7 @@ Return<void> validateAndCall( } // namespace hidl_return_util } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/hidl_struct_util.cpp b/wifi/1.6/default/hidl_struct_util.cpp index 91974a33d3..3489c9e4d3 100644 --- a/wifi/1.5/default/hidl_struct_util.cpp +++ b/wifi/1.6/default/hidl_struct_util.cpp @@ -22,12 +22,13 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace hidl_struct_util { -WifiChannelWidthInMhz convertLegacyWifiChannelWidthToHidl( - legacy_hal::wifi_channel_width type); +using V1_5::NanConfigRequestSupplemental; + +WifiChannelWidthInMhz convertLegacyWifiChannelWidthToHidl(legacy_hal::wifi_channel_width type); hidl_string safeConvertChar(const char* str, size_t max_len) { const char* c = str; @@ -39,8 +40,7 @@ hidl_string safeConvertChar(const char* str, size_t max_len) { return hidl_string(str, size); } -IWifiChip::ChipCapabilityMask convertLegacyLoggerFeatureToHidlChipCapability( - uint32_t feature) { +IWifiChip::ChipCapabilityMask convertLegacyLoggerFeatureToHidlChipCapability(uint32_t feature) { using HidlChipCaps = IWifiChip::ChipCapabilityMask; switch (feature) { case legacy_hal::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED: @@ -52,14 +52,14 @@ IWifiChip::ChipCapabilityMask convertLegacyLoggerFeatureToHidlChipCapability( case legacy_hal::WIFI_LOGGER_POWER_EVENT_SUPPORTED: return HidlChipCaps::DEBUG_RING_BUFFER_POWER_EVENT; case legacy_hal::WIFI_LOGGER_WAKE_LOCK_SUPPORTED: - return HidlChipCaps::DEBUG_HOST_WAKE_REASON_STATS; + return HidlChipCaps::DEBUG_RING_BUFFER_WAKELOCK_EVENT; }; CHECK(false) << "Unknown legacy feature: " << feature; return {}; } -IWifiStaIface::StaIfaceCapabilityMask -convertLegacyLoggerFeatureToHidlStaIfaceCapability(uint32_t feature) { +IWifiStaIface::StaIfaceCapabilityMask convertLegacyLoggerFeatureToHidlStaIfaceCapability( + uint32_t feature) { using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask; switch (feature) { case legacy_hal::WIFI_LOGGER_PACKET_FATE_SUPPORTED: @@ -69,8 +69,7 @@ convertLegacyLoggerFeatureToHidlStaIfaceCapability(uint32_t feature) { return {}; } -V1_5::IWifiChip::ChipCapabilityMask convertLegacyFeatureToHidlChipCapability( - uint64_t feature) { +V1_5::IWifiChip::ChipCapabilityMask convertLegacyFeatureToHidlChipCapability(uint64_t feature) { using HidlChipCaps = V1_5::IWifiChip::ChipCapabilityMask; switch (feature) { case WIFI_FEATURE_SET_TX_POWER_LIMIT: @@ -92,8 +91,8 @@ V1_5::IWifiChip::ChipCapabilityMask convertLegacyFeatureToHidlChipCapability( return {}; } -IWifiStaIface::StaIfaceCapabilityMask -convertLegacyFeatureToHidlStaIfaceCapability(uint64_t feature) { +IWifiStaIface::StaIfaceCapabilityMask convertLegacyFeatureToHidlStaIfaceCapability( + uint64_t feature) { using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask; switch (feature) { case WIFI_FEATURE_GSCAN: @@ -127,9 +126,9 @@ convertLegacyFeatureToHidlStaIfaceCapability(uint64_t feature) { return {}; } -bool convertLegacyFeaturesToHidlChipCapabilities( - uint64_t legacy_feature_set, uint32_t legacy_logger_feature_set, - uint32_t* hidl_caps) { +bool convertLegacyFeaturesToHidlChipCapabilities(uint64_t legacy_feature_set, + uint32_t legacy_logger_feature_set, + uint32_t* hidl_caps) { if (!hidl_caps) { return false; } @@ -141,8 +140,7 @@ bool convertLegacyFeaturesToHidlChipCapabilities( legacy_hal::WIFI_LOGGER_POWER_EVENT_SUPPORTED, legacy_hal::WIFI_LOGGER_WAKE_LOCK_SUPPORTED}) { if (feature & legacy_logger_feature_set) { - *hidl_caps |= - convertLegacyLoggerFeatureToHidlChipCapability(feature); + *hidl_caps |= convertLegacyLoggerFeatureToHidlChipCapability(feature); } } std::vector<uint64_t> features = {WIFI_FEATURE_SET_TX_POWER_LIMIT, @@ -158,14 +156,15 @@ bool convertLegacyFeaturesToHidlChipCapabilities( } } - // There are no flags for these in the legacy feature set. Adding this to + // There are no flags for these 3 in the legacy feature set. Adding them to // the set because all the current devices support it. + *hidl_caps |= HidlChipCaps::DEBUG_RING_BUFFER_VENDOR_DATA; + *hidl_caps |= HidlChipCaps::DEBUG_HOST_WAKE_REASON_STATS; *hidl_caps |= HidlChipCaps::DEBUG_ERROR_ALERTS; return true; } -WifiDebugRingBufferFlags convertLegacyDebugRingBufferFlagsToHidl( - uint32_t flag) { +WifiDebugRingBufferFlags convertLegacyDebugRingBufferFlagsToHidl(uint32_t flag) { switch (flag) { case WIFI_RING_BUFFER_FLAG_HAS_BINARY_ENTRIES: return WifiDebugRingBufferFlags::HAS_BINARY_ENTRIES; @@ -177,22 +176,20 @@ WifiDebugRingBufferFlags convertLegacyDebugRingBufferFlagsToHidl( } bool convertLegacyDebugRingBufferStatusToHidl( - const legacy_hal::wifi_ring_buffer_status& legacy_status, - WifiDebugRingBufferStatus* hidl_status) { + const legacy_hal::wifi_ring_buffer_status& legacy_status, + WifiDebugRingBufferStatus* hidl_status) { if (!hidl_status) { return false; } *hidl_status = {}; - hidl_status->ringName = - safeConvertChar(reinterpret_cast<const char*>(legacy_status.name), - sizeof(legacy_status.name)); + hidl_status->ringName = safeConvertChar(reinterpret_cast<const char*>(legacy_status.name), + sizeof(legacy_status.name)); hidl_status->flags = 0; - for (const auto flag : {WIFI_RING_BUFFER_FLAG_HAS_BINARY_ENTRIES, - WIFI_RING_BUFFER_FLAG_HAS_ASCII_ENTRIES}) { + for (const auto flag : + {WIFI_RING_BUFFER_FLAG_HAS_BINARY_ENTRIES, WIFI_RING_BUFFER_FLAG_HAS_ASCII_ENTRIES}) { if (flag & legacy_status.flags) { - hidl_status->flags |= static_cast< - std::underlying_type<WifiDebugRingBufferFlags>::type>( - convertLegacyDebugRingBufferFlagsToHidl(flag)); + hidl_status->flags |= static_cast<std::underlying_type<WifiDebugRingBufferFlags>::type>( + convertLegacyDebugRingBufferFlagsToHidl(flag)); } } hidl_status->ringId = legacy_status.ring_id; @@ -200,28 +197,25 @@ bool convertLegacyDebugRingBufferStatusToHidl( // Calculate free size of the ring the buffer. We don't need to send the // exact read/write pointers that were there in the legacy HAL interface. if (legacy_status.written_bytes >= legacy_status.read_bytes) { - hidl_status->freeSizeInBytes = - legacy_status.ring_buffer_byte_size - - (legacy_status.written_bytes - legacy_status.read_bytes); + hidl_status->freeSizeInBytes = legacy_status.ring_buffer_byte_size - + (legacy_status.written_bytes - legacy_status.read_bytes); } else { - hidl_status->freeSizeInBytes = - legacy_status.read_bytes - legacy_status.written_bytes; + hidl_status->freeSizeInBytes = legacy_status.read_bytes - legacy_status.written_bytes; } hidl_status->verboseLevel = legacy_status.verbose_level; return true; } bool convertLegacyVectorOfDebugRingBufferStatusToHidl( - const std::vector<legacy_hal::wifi_ring_buffer_status>& legacy_status_vec, - std::vector<WifiDebugRingBufferStatus>* hidl_status_vec) { + const std::vector<legacy_hal::wifi_ring_buffer_status>& legacy_status_vec, + std::vector<WifiDebugRingBufferStatus>* hidl_status_vec) { if (!hidl_status_vec) { return false; } *hidl_status_vec = {}; for (const auto& legacy_status : legacy_status_vec) { WifiDebugRingBufferStatus hidl_status; - if (!convertLegacyDebugRingBufferStatusToHidl(legacy_status, - &hidl_status)) { + if (!convertLegacyDebugRingBufferStatusToHidl(legacy_status, &hidl_status)) { return false; } hidl_status_vec->push_back(hidl_status); @@ -229,52 +223,44 @@ bool convertLegacyVectorOfDebugRingBufferStatusToHidl( return true; } -bool convertLegacyWakeReasonStatsToHidl( - const legacy_hal::WakeReasonStats& legacy_stats, - WifiDebugHostWakeReasonStats* hidl_stats) { +bool convertLegacyWakeReasonStatsToHidl(const legacy_hal::WakeReasonStats& legacy_stats, + WifiDebugHostWakeReasonStats* hidl_stats) { if (!hidl_stats) { return false; } *hidl_stats = {}; - hidl_stats->totalCmdEventWakeCnt = - legacy_stats.wake_reason_cnt.total_cmd_event_wake; + hidl_stats->totalCmdEventWakeCnt = legacy_stats.wake_reason_cnt.total_cmd_event_wake; hidl_stats->cmdEventWakeCntPerType = legacy_stats.cmd_event_wake_cnt; - hidl_stats->totalDriverFwLocalWakeCnt = - legacy_stats.wake_reason_cnt.total_driver_fw_local_wake; - hidl_stats->driverFwLocalWakeCntPerType = - legacy_stats.driver_fw_local_wake_cnt; - hidl_stats->totalRxPacketWakeCnt = - legacy_stats.wake_reason_cnt.total_rx_data_wake; + hidl_stats->totalDriverFwLocalWakeCnt = legacy_stats.wake_reason_cnt.total_driver_fw_local_wake; + hidl_stats->driverFwLocalWakeCntPerType = legacy_stats.driver_fw_local_wake_cnt; + hidl_stats->totalRxPacketWakeCnt = legacy_stats.wake_reason_cnt.total_rx_data_wake; hidl_stats->rxPktWakeDetails.rxUnicastCnt = - legacy_stats.wake_reason_cnt.rx_wake_details.rx_unicast_cnt; + legacy_stats.wake_reason_cnt.rx_wake_details.rx_unicast_cnt; hidl_stats->rxPktWakeDetails.rxMulticastCnt = - legacy_stats.wake_reason_cnt.rx_wake_details.rx_multicast_cnt; + legacy_stats.wake_reason_cnt.rx_wake_details.rx_multicast_cnt; hidl_stats->rxPktWakeDetails.rxBroadcastCnt = - legacy_stats.wake_reason_cnt.rx_wake_details.rx_broadcast_cnt; + legacy_stats.wake_reason_cnt.rx_wake_details.rx_broadcast_cnt; hidl_stats->rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt = - legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info - .ipv4_rx_multicast_addr_cnt; + legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info.ipv4_rx_multicast_addr_cnt; hidl_stats->rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt = - legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info - .ipv6_rx_multicast_addr_cnt; + legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info.ipv6_rx_multicast_addr_cnt; hidl_stats->rxMulticastPkWakeDetails.otherRxMulticastAddrCnt = - legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info - .other_rx_multicast_addr_cnt; + legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info.other_rx_multicast_addr_cnt; hidl_stats->rxIcmpPkWakeDetails.icmpPkt = - legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp_pkt; + legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp_pkt; hidl_stats->rxIcmpPkWakeDetails.icmp6Pkt = - legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_pkt; + legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_pkt; hidl_stats->rxIcmpPkWakeDetails.icmp6Ra = - legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_ra; + legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_ra; hidl_stats->rxIcmpPkWakeDetails.icmp6Na = - legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_na; + legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_na; hidl_stats->rxIcmpPkWakeDetails.icmp6Ns = - legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_ns; + legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_ns; return true; } legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy( - V1_1::IWifiChip::TxPowerScenario hidl_scenario) { + V1_1::IWifiChip::TxPowerScenario hidl_scenario) { switch (hidl_scenario) { // This is the only supported scenario for V1_1 case V1_1::IWifiChip::TxPowerScenario::VOICE_CALL: @@ -284,7 +270,7 @@ legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy( } legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy_1_2( - V1_2::IWifiChip::TxPowerScenario hidl_scenario) { + V1_2::IWifiChip::TxPowerScenario hidl_scenario) { switch (hidl_scenario) { // This is the only supported scenario for V1_1 case V1_2::IWifiChip::TxPowerScenario::VOICE_CALL: @@ -303,7 +289,7 @@ legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy_1_2( } legacy_hal::wifi_latency_mode convertHidlLatencyModeToLegacy( - V1_3::IWifiChip::LatencyMode hidl_latency_mode) { + V1_3::IWifiChip::LatencyMode hidl_latency_mode) { switch (hidl_latency_mode) { case V1_3::IWifiChip::LatencyMode::NORMAL: return legacy_hal::WIFI_LATENCY_MODE_NORMAL; @@ -314,8 +300,8 @@ legacy_hal::wifi_latency_mode convertHidlLatencyModeToLegacy( } bool convertLegacyWifiMacInfoToHidl( - const legacy_hal::WifiMacInfo& legacy_mac_info, - V1_4::IWifiChipEventCallback::RadioModeInfo* hidl_radio_mode_info) { + const legacy_hal::WifiMacInfo& legacy_mac_info, + V1_4::IWifiChipEventCallback::RadioModeInfo* hidl_radio_mode_info) { if (!hidl_radio_mode_info) { return false; } @@ -364,24 +350,20 @@ uint32_t convertHidlWifiBandToLegacyMacBand(V1_5::WifiBand hidl_band) { return legacy_hal::WLAN_MAC_5_0_BAND; case V1_5::WifiBand::BAND_24GHZ_5GHZ: case V1_5::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS: - return (legacy_hal::WLAN_MAC_2_4_BAND | - legacy_hal::WLAN_MAC_5_0_BAND); + return (legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND); case V1_5::WifiBand::BAND_6GHZ: return legacy_hal::WLAN_MAC_6_0_BAND; case V1_5::WifiBand::BAND_5GHZ_6GHZ: - return (legacy_hal::WLAN_MAC_5_0_BAND | - legacy_hal::WLAN_MAC_6_0_BAND); + return (legacy_hal::WLAN_MAC_5_0_BAND | legacy_hal::WLAN_MAC_6_0_BAND); case V1_5::WifiBand::BAND_24GHZ_5GHZ_6GHZ: case V1_5::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS_6GHZ: - return (legacy_hal::WLAN_MAC_2_4_BAND | - legacy_hal::WLAN_MAC_5_0_BAND | + return (legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND | legacy_hal::WLAN_MAC_6_0_BAND); case V1_5::WifiBand::BAND_60GHZ: return legacy_hal::WLAN_MAC_60_0_BAND; default: - return ( - legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND | - legacy_hal::WLAN_MAC_6_0_BAND | legacy_hal::WLAN_MAC_60_0_BAND); + return (legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND | + legacy_hal::WLAN_MAC_6_0_BAND | legacy_hal::WLAN_MAC_60_0_BAND); } } @@ -445,45 +427,41 @@ uint32_t convertLegacyWifiInterfaceModeToHidl(uint32_t legacy_iface_mask) { uint32_t convertHidlUsableChannelFilterToLegacy(uint32_t hidl_filter_mask) { uint32_t legacy_filter_mask = 0; - if (hidl_filter_mask & - IWifiChip::UsableChannelFilter::CELLULAR_COEXISTENCE) { - legacy_filter_mask |= - legacy_hal::WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE; + if (hidl_filter_mask & V1_5::IWifiChip::UsableChannelFilter::CELLULAR_COEXISTENCE) { + legacy_filter_mask |= legacy_hal::WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE; } - if (hidl_filter_mask & IWifiChip::UsableChannelFilter::CONCURRENCY) { - legacy_filter_mask |= - legacy_hal::WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY; + if (hidl_filter_mask & V1_5::IWifiChip::UsableChannelFilter::CONCURRENCY) { + legacy_filter_mask |= legacy_hal::WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY; } return legacy_filter_mask; } bool convertLegacyWifiUsableChannelToHidl( - const legacy_hal::wifi_usable_channel& legacy_usable_channel, - V1_5::WifiUsableChannel* hidl_usable_channel) { + const legacy_hal::wifi_usable_channel& legacy_usable_channel, + V1_5::WifiUsableChannel* hidl_usable_channel) { if (!hidl_usable_channel) { return false; } *hidl_usable_channel = {}; hidl_usable_channel->channel = legacy_usable_channel.freq; hidl_usable_channel->channelBandwidth = - convertLegacyWifiChannelWidthToHidl(legacy_usable_channel.width); - hidl_usable_channel->ifaceModeMask = convertLegacyWifiInterfaceModeToHidl( - legacy_usable_channel.iface_mode_mask); + convertLegacyWifiChannelWidthToHidl(legacy_usable_channel.width); + hidl_usable_channel->ifaceModeMask = + convertLegacyWifiInterfaceModeToHidl(legacy_usable_channel.iface_mode_mask); return true; } bool convertLegacyWifiUsableChannelsToHidl( - const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels, - std::vector<V1_5::WifiUsableChannel>* hidl_usable_channels) { + const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels, + std::vector<V1_5::WifiUsableChannel>* hidl_usable_channels) { if (!hidl_usable_channels) { return false; } *hidl_usable_channels = {}; for (const auto& legacy_usable_channel : legacy_usable_channels) { V1_5::WifiUsableChannel hidl_usable_channel; - if (!convertLegacyWifiUsableChannelToHidl(legacy_usable_channel, - &hidl_usable_channel)) { + if (!convertLegacyWifiUsableChannelToHidl(legacy_usable_channel, &hidl_usable_channel)) { return false; } hidl_usable_channels->push_back(hidl_usable_channel); @@ -492,9 +470,8 @@ bool convertLegacyWifiUsableChannelsToHidl( } bool convertLegacyWifiMacInfosToHidl( - const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos, - std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo>* - hidl_radio_mode_infos) { + const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos, + std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo>* hidl_radio_mode_infos) { if (!hidl_radio_mode_infos) { return false; } @@ -502,8 +479,7 @@ bool convertLegacyWifiMacInfosToHidl( for (const auto& legacy_mac_info : legacy_mac_infos) { V1_4::IWifiChipEventCallback::RadioModeInfo hidl_radio_mode_info; - if (!convertLegacyWifiMacInfoToHidl(legacy_mac_info, - &hidl_radio_mode_info)) { + if (!convertLegacyWifiMacInfoToHidl(legacy_mac_info, &hidl_radio_mode_info)) { return false; } hidl_radio_mode_infos->push_back(hidl_radio_mode_info); @@ -511,9 +487,9 @@ bool convertLegacyWifiMacInfosToHidl( return true; } -bool convertLegacyFeaturesToHidlStaCapabilities( - uint64_t legacy_feature_set, uint32_t legacy_logger_feature_set, - uint32_t* hidl_caps) { +bool convertLegacyFeaturesToHidlStaCapabilities(uint64_t legacy_feature_set, + uint32_t legacy_logger_feature_set, + uint32_t* hidl_caps) { if (!hidl_caps) { return false; } @@ -521,17 +497,14 @@ bool convertLegacyFeaturesToHidlStaCapabilities( using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask; for (const auto feature : {legacy_hal::WIFI_LOGGER_PACKET_FATE_SUPPORTED}) { if (feature & legacy_logger_feature_set) { - *hidl_caps |= - convertLegacyLoggerFeatureToHidlStaIfaceCapability(feature); + *hidl_caps |= convertLegacyLoggerFeatureToHidlStaIfaceCapability(feature); } } for (const auto feature : - {WIFI_FEATURE_GSCAN, WIFI_FEATURE_LINK_LAYER_STATS, - WIFI_FEATURE_RSSI_MONITOR, WIFI_FEATURE_CONTROL_ROAMING, - WIFI_FEATURE_IE_WHITELIST, WIFI_FEATURE_SCAN_RAND, - WIFI_FEATURE_INFRA_5G, WIFI_FEATURE_HOTSPOT, WIFI_FEATURE_PNO, - WIFI_FEATURE_TDLS, WIFI_FEATURE_TDLS_OFFCHANNEL, - WIFI_FEATURE_CONFIG_NDO, WIFI_FEATURE_MKEEP_ALIVE}) { + {WIFI_FEATURE_GSCAN, WIFI_FEATURE_LINK_LAYER_STATS, WIFI_FEATURE_RSSI_MONITOR, + WIFI_FEATURE_CONTROL_ROAMING, WIFI_FEATURE_IE_WHITELIST, WIFI_FEATURE_SCAN_RAND, + WIFI_FEATURE_INFRA_5G, WIFI_FEATURE_HOTSPOT, WIFI_FEATURE_PNO, WIFI_FEATURE_TDLS, + WIFI_FEATURE_TDLS_OFFCHANNEL, WIFI_FEATURE_CONFIG_NDO, WIFI_FEATURE_MKEEP_ALIVE}) { if (feature & legacy_feature_set) { *hidl_caps |= convertLegacyFeatureToHidlStaIfaceCapability(feature); } @@ -542,9 +515,8 @@ bool convertLegacyFeaturesToHidlStaCapabilities( return true; } -bool convertLegacyApfCapabilitiesToHidl( - const legacy_hal::PacketFilterCapabilities& legacy_caps, - StaApfPacketFilterCapabilities* hidl_caps) { +bool convertLegacyApfCapabilitiesToHidl(const legacy_hal::PacketFilterCapabilities& legacy_caps, + StaApfPacketFilterCapabilities* hidl_caps) { if (!hidl_caps) { return false; } @@ -555,7 +527,7 @@ bool convertLegacyApfCapabilitiesToHidl( } uint8_t convertHidlGscanReportEventFlagToLegacy( - StaBackgroundScanBucketEventReportSchemeMask hidl_flag) { + StaBackgroundScanBucketEventReportSchemeMask hidl_flag) { using HidlFlag = StaBackgroundScanBucketEventReportSchemeMask; switch (hidl_flag) { case HidlFlag::EACH_SCAN: @@ -579,9 +551,8 @@ StaScanDataFlagMask convertLegacyGscanDataFlagToHidl(uint8_t legacy_flag) { return {}; } -bool convertLegacyGscanCapabilitiesToHidl( - const legacy_hal::wifi_gscan_capabilities& legacy_caps, - StaBackgroundScanCapabilities* hidl_caps) { +bool convertLegacyGscanCapabilitiesToHidl(const legacy_hal::wifi_gscan_capabilities& legacy_caps, + StaBackgroundScanCapabilities* hidl_caps) { if (!hidl_caps) { return false; } @@ -613,73 +584,61 @@ legacy_hal::wifi_band convertHidlWifiBandToLegacy(V1_0::WifiBand band) { CHECK(false); } -bool convertHidlGscanParamsToLegacy( - const StaBackgroundScanParameters& hidl_scan_params, - legacy_hal::wifi_scan_cmd_params* legacy_scan_params) { +bool convertHidlGscanParamsToLegacy(const StaBackgroundScanParameters& hidl_scan_params, + legacy_hal::wifi_scan_cmd_params* legacy_scan_params) { if (!legacy_scan_params) { return false; } *legacy_scan_params = {}; legacy_scan_params->base_period = hidl_scan_params.basePeriodInMs; legacy_scan_params->max_ap_per_scan = hidl_scan_params.maxApPerScan; - legacy_scan_params->report_threshold_percent = - hidl_scan_params.reportThresholdPercent; - legacy_scan_params->report_threshold_num_scans = - hidl_scan_params.reportThresholdNumScans; + legacy_scan_params->report_threshold_percent = hidl_scan_params.reportThresholdPercent; + legacy_scan_params->report_threshold_num_scans = hidl_scan_params.reportThresholdNumScans; if (hidl_scan_params.buckets.size() > MAX_BUCKETS) { return false; } legacy_scan_params->num_buckets = hidl_scan_params.buckets.size(); - for (uint32_t bucket_idx = 0; bucket_idx < hidl_scan_params.buckets.size(); - bucket_idx++) { + for (uint32_t bucket_idx = 0; bucket_idx < hidl_scan_params.buckets.size(); bucket_idx++) { const StaBackgroundScanBucketParameters& hidl_bucket_spec = - hidl_scan_params.buckets[bucket_idx]; + hidl_scan_params.buckets[bucket_idx]; legacy_hal::wifi_scan_bucket_spec& legacy_bucket_spec = - legacy_scan_params->buckets[bucket_idx]; + legacy_scan_params->buckets[bucket_idx]; if (hidl_bucket_spec.bucketIdx >= MAX_BUCKETS) { return false; } legacy_bucket_spec.bucket = hidl_bucket_spec.bucketIdx; - legacy_bucket_spec.band = - convertHidlWifiBandToLegacy(hidl_bucket_spec.band); + legacy_bucket_spec.band = convertHidlWifiBandToLegacy(hidl_bucket_spec.band); legacy_bucket_spec.period = hidl_bucket_spec.periodInMs; - legacy_bucket_spec.max_period = - hidl_bucket_spec.exponentialMaxPeriodInMs; + legacy_bucket_spec.max_period = hidl_bucket_spec.exponentialMaxPeriodInMs; legacy_bucket_spec.base = hidl_bucket_spec.exponentialBase; legacy_bucket_spec.step_count = hidl_bucket_spec.exponentialStepCount; legacy_bucket_spec.report_events = 0; using HidlFlag = StaBackgroundScanBucketEventReportSchemeMask; - for (const auto flag : {HidlFlag::EACH_SCAN, HidlFlag::FULL_RESULTS, - HidlFlag::NO_BATCH}) { + for (const auto flag : {HidlFlag::EACH_SCAN, HidlFlag::FULL_RESULTS, HidlFlag::NO_BATCH}) { if (hidl_bucket_spec.eventReportScheme & static_cast<std::underlying_type<HidlFlag>::type>(flag)) { - legacy_bucket_spec.report_events |= - convertHidlGscanReportEventFlagToLegacy(flag); + legacy_bucket_spec.report_events |= convertHidlGscanReportEventFlagToLegacy(flag); } } if (hidl_bucket_spec.frequencies.size() > MAX_CHANNELS) { return false; } legacy_bucket_spec.num_channels = hidl_bucket_spec.frequencies.size(); - for (uint32_t freq_idx = 0; - freq_idx < hidl_bucket_spec.frequencies.size(); freq_idx++) { - legacy_bucket_spec.channels[freq_idx].channel = - hidl_bucket_spec.frequencies[freq_idx]; + for (uint32_t freq_idx = 0; freq_idx < hidl_bucket_spec.frequencies.size(); freq_idx++) { + legacy_bucket_spec.channels[freq_idx].channel = hidl_bucket_spec.frequencies[freq_idx]; } } return true; } -bool convertLegacyIeToHidl( - const legacy_hal::wifi_information_element& legacy_ie, - WifiInformationElement* hidl_ie) { +bool convertLegacyIeToHidl(const legacy_hal::wifi_information_element& legacy_ie, + WifiInformationElement* hidl_ie) { if (!hidl_ie) { return false; } *hidl_ie = {}; hidl_ie->id = legacy_ie.id; - hidl_ie->data = - std::vector<uint8_t>(legacy_ie.data, legacy_ie.data + legacy_ie.len); + hidl_ie->data = std::vector<uint8_t>(legacy_ie.data, legacy_ie.data + legacy_ie.len); return true; } @@ -700,14 +659,12 @@ bool convertLegacyIeBlobToHidl(const uint8_t* ie_blob, uint32_t ie_blob_len, uint32_t curr_ie_len = kIeHeaderLen + legacy_ie.len; if (next_ie + curr_ie_len > ies_end) { LOG(ERROR) << "Error parsing IE blob. Next IE: " << (void*)next_ie - << ", Curr IE len: " << curr_ie_len - << ", IEs End: " << (void*)ies_end; + << ", Curr IE len: " << curr_ie_len << ", IEs End: " << (void*)ies_end; break; } WifiInformationElement hidl_ie; if (!convertLegacyIeToHidl(legacy_ie, &hidl_ie)) { - LOG(ERROR) << "Error converting IE. Id: " << legacy_ie.id - << ", len: " << legacy_ie.len; + LOG(ERROR) << "Error converting IE. Id: " << legacy_ie.id << ", len: " << legacy_ie.len; break; } hidl_ies->push_back(std::move(hidl_ie)); @@ -715,24 +672,23 @@ bool convertLegacyIeBlobToHidl(const uint8_t* ie_blob, uint32_t ie_blob_len, } // Check if the blob has been fully consumed. if (next_ie != ies_end) { - LOG(ERROR) << "Failed to fully parse IE blob. Next IE: " - << (void*)next_ie << ", IEs End: " << (void*)ies_end; + LOG(ERROR) << "Failed to fully parse IE blob. Next IE: " << (void*)next_ie + << ", IEs End: " << (void*)ies_end; } return true; } -bool convertLegacyGscanResultToHidl( - const legacy_hal::wifi_scan_result& legacy_scan_result, bool has_ie_data, - StaScanResult* hidl_scan_result) { +bool convertLegacyGscanResultToHidl(const legacy_hal::wifi_scan_result& legacy_scan_result, + bool has_ie_data, StaScanResult* hidl_scan_result) { if (!hidl_scan_result) { return false; } *hidl_scan_result = {}; hidl_scan_result->timeStampInUs = legacy_scan_result.ts; hidl_scan_result->ssid = std::vector<uint8_t>( - legacy_scan_result.ssid, - legacy_scan_result.ssid + strnlen(legacy_scan_result.ssid, - sizeof(legacy_scan_result.ssid) - 1)); + legacy_scan_result.ssid, + legacy_scan_result.ssid + + strnlen(legacy_scan_result.ssid, sizeof(legacy_scan_result.ssid) - 1)); memcpy(hidl_scan_result->bssid.data(), legacy_scan_result.bssid, hidl_scan_result->bssid.size()); hidl_scan_result->frequency = legacy_scan_result.channel; @@ -741,9 +697,8 @@ bool convertLegacyGscanResultToHidl( hidl_scan_result->capability = legacy_scan_result.capability; if (has_ie_data) { std::vector<WifiInformationElement> ies; - if (!convertLegacyIeBlobToHidl( - reinterpret_cast<const uint8_t*>(legacy_scan_result.ie_data), - legacy_scan_result.ie_length, &ies)) { + if (!convertLegacyIeBlobToHidl(reinterpret_cast<const uint8_t*>(legacy_scan_result.ie_data), + legacy_scan_result.ie_length, &ies)) { return false; } hidl_scan_result->informationElements = std::move(ies); @@ -752,8 +707,8 @@ bool convertLegacyGscanResultToHidl( } bool convertLegacyCachedGscanResultsToHidl( - const legacy_hal::wifi_cached_scan_results& legacy_cached_scan_result, - StaScanData* hidl_scan_data) { + const legacy_hal::wifi_cached_scan_results& legacy_cached_scan_result, + StaScanData* hidl_scan_data) { if (!hidl_scan_data) { return false; } @@ -761,8 +716,7 @@ bool convertLegacyCachedGscanResultsToHidl( hidl_scan_data->flags = 0; for (const auto flag : {legacy_hal::WIFI_SCAN_FLAG_INTERRUPTED}) { if (legacy_cached_scan_result.flags & flag) { - hidl_scan_data->flags |= - static_cast<std::underlying_type<StaScanDataFlagMask>::type>( + hidl_scan_data->flags |= static_cast<std::underlying_type<StaScanDataFlagMask>::type>( convertLegacyGscanDataFlagToHidl(flag)); } } @@ -771,12 +725,10 @@ bool convertLegacyCachedGscanResultsToHidl( CHECK(legacy_cached_scan_result.num_results >= 0 && legacy_cached_scan_result.num_results <= MAX_AP_CACHE_PER_SCAN); std::vector<StaScanResult> hidl_scan_results; - for (int32_t result_idx = 0; - result_idx < legacy_cached_scan_result.num_results; result_idx++) { + for (int32_t result_idx = 0; result_idx < legacy_cached_scan_result.num_results; result_idx++) { StaScanResult hidl_scan_result; - if (!convertLegacyGscanResultToHidl( - legacy_cached_scan_result.results[result_idx], false, - &hidl_scan_result)) { + if (!convertLegacyGscanResultToHidl(legacy_cached_scan_result.results[result_idx], false, + &hidl_scan_result)) { return false; } hidl_scan_results.push_back(hidl_scan_result); @@ -786,17 +738,15 @@ bool convertLegacyCachedGscanResultsToHidl( } bool convertLegacyVectorOfCachedGscanResultsToHidl( - const std::vector<legacy_hal::wifi_cached_scan_results>& - legacy_cached_scan_results, - std::vector<StaScanData>* hidl_scan_datas) { + const std::vector<legacy_hal::wifi_cached_scan_results>& legacy_cached_scan_results, + std::vector<StaScanData>* hidl_scan_datas) { if (!hidl_scan_datas) { return false; } *hidl_scan_datas = {}; for (const auto& legacy_cached_scan_result : legacy_cached_scan_results) { StaScanData hidl_scan_data; - if (!convertLegacyCachedGscanResultsToHidl(legacy_cached_scan_result, - &hidl_scan_data)) { + if (!convertLegacyCachedGscanResultsToHidl(legacy_cached_scan_result, &hidl_scan_data)) { return false; } hidl_scan_datas->push_back(hidl_scan_data); @@ -804,8 +754,7 @@ bool convertLegacyVectorOfCachedGscanResultsToHidl( return true; } -WifiDebugTxPacketFate convertLegacyDebugTxPacketFateToHidl( - legacy_hal::wifi_tx_packet_fate fate) { +WifiDebugTxPacketFate convertLegacyDebugTxPacketFateToHidl(legacy_hal::wifi_tx_packet_fate fate) { switch (fate) { case legacy_hal::TX_PKT_FATE_ACKED: return WifiDebugTxPacketFate::ACKED; @@ -831,8 +780,7 @@ WifiDebugTxPacketFate convertLegacyDebugTxPacketFateToHidl( CHECK(false) << "Unknown legacy fate type: " << fate; } -WifiDebugRxPacketFate convertLegacyDebugRxPacketFateToHidl( - legacy_hal::wifi_rx_packet_fate fate) { +WifiDebugRxPacketFate convertLegacyDebugRxPacketFateToHidl(legacy_hal::wifi_rx_packet_fate fate) { switch (fate) { case legacy_hal::RX_PKT_FATE_SUCCESS: return WifiDebugRxPacketFate::SUCCESS; @@ -861,7 +809,7 @@ WifiDebugRxPacketFate convertLegacyDebugRxPacketFateToHidl( } WifiDebugPacketFateFrameType convertLegacyDebugPacketFateFrameTypeToHidl( - legacy_hal::frame_type type) { + legacy_hal::frame_type type) { switch (type) { case legacy_hal::FRAME_TYPE_UNKNOWN: return WifiDebugPacketFateFrameType::UNKNOWN; @@ -873,40 +821,36 @@ WifiDebugPacketFateFrameType convertLegacyDebugPacketFateFrameTypeToHidl( CHECK(false) << "Unknown legacy frame type: " << type; } -bool convertLegacyDebugPacketFateFrameToHidl( - const legacy_hal::frame_info& legacy_frame, - WifiDebugPacketFateFrameInfo* hidl_frame) { +bool convertLegacyDebugPacketFateFrameToHidl(const legacy_hal::frame_info& legacy_frame, + WifiDebugPacketFateFrameInfo* hidl_frame) { if (!hidl_frame) { return false; } *hidl_frame = {}; - hidl_frame->frameType = - convertLegacyDebugPacketFateFrameTypeToHidl(legacy_frame.payload_type); + hidl_frame->frameType = convertLegacyDebugPacketFateFrameTypeToHidl(legacy_frame.payload_type); hidl_frame->frameLen = legacy_frame.frame_len; hidl_frame->driverTimestampUsec = legacy_frame.driver_timestamp_usec; hidl_frame->firmwareTimestampUsec = legacy_frame.firmware_timestamp_usec; - const uint8_t* frame_begin = reinterpret_cast<const uint8_t*>( - legacy_frame.frame_content.ethernet_ii_bytes); + const uint8_t* frame_begin = + reinterpret_cast<const uint8_t*>(legacy_frame.frame_content.ethernet_ii_bytes); hidl_frame->frameContent = - std::vector<uint8_t>(frame_begin, frame_begin + legacy_frame.frame_len); + std::vector<uint8_t>(frame_begin, frame_begin + legacy_frame.frame_len); return true; } -bool convertLegacyDebugTxPacketFateToHidl( - const legacy_hal::wifi_tx_report& legacy_fate, - WifiDebugTxPacketFateReport* hidl_fate) { +bool convertLegacyDebugTxPacketFateToHidl(const legacy_hal::wifi_tx_report& legacy_fate, + WifiDebugTxPacketFateReport* hidl_fate) { if (!hidl_fate) { return false; } *hidl_fate = {}; hidl_fate->fate = convertLegacyDebugTxPacketFateToHidl(legacy_fate.fate); - return convertLegacyDebugPacketFateFrameToHidl(legacy_fate.frame_inf, - &hidl_fate->frameInfo); + return convertLegacyDebugPacketFateFrameToHidl(legacy_fate.frame_inf, &hidl_fate->frameInfo); } bool convertLegacyVectorOfDebugTxPacketFateToHidl( - const std::vector<legacy_hal::wifi_tx_report>& legacy_fates, - std::vector<WifiDebugTxPacketFateReport>* hidl_fates) { + const std::vector<legacy_hal::wifi_tx_report>& legacy_fates, + std::vector<WifiDebugTxPacketFateReport>* hidl_fates) { if (!hidl_fates) { return false; } @@ -921,21 +865,19 @@ bool convertLegacyVectorOfDebugTxPacketFateToHidl( return true; } -bool convertLegacyDebugRxPacketFateToHidl( - const legacy_hal::wifi_rx_report& legacy_fate, - WifiDebugRxPacketFateReport* hidl_fate) { +bool convertLegacyDebugRxPacketFateToHidl(const legacy_hal::wifi_rx_report& legacy_fate, + WifiDebugRxPacketFateReport* hidl_fate) { if (!hidl_fate) { return false; } *hidl_fate = {}; hidl_fate->fate = convertLegacyDebugRxPacketFateToHidl(legacy_fate.fate); - return convertLegacyDebugPacketFateFrameToHidl(legacy_fate.frame_inf, - &hidl_fate->frameInfo); + return convertLegacyDebugPacketFateFrameToHidl(legacy_fate.frame_inf, &hidl_fate->frameInfo); } bool convertLegacyVectorOfDebugRxPacketFateToHidl( - const std::vector<legacy_hal::wifi_rx_report>& legacy_fates, - std::vector<WifiDebugRxPacketFateReport>* hidl_fates) { + const std::vector<legacy_hal::wifi_rx_report>& legacy_fates, + std::vector<WifiDebugRxPacketFateReport>* hidl_fates) { if (!hidl_fates) { return false; } @@ -951,8 +893,8 @@ bool convertLegacyVectorOfDebugRxPacketFateToHidl( } bool convertLegacyLinkLayerRadioStatsToHidl( - const legacy_hal::LinkLayerRadioStats& legacy_radio_stat, - V1_5::StaLinkLayerRadioStats* hidl_radio_stat) { + const legacy_hal::LinkLayerRadioStats& legacy_radio_stat, + V1_5::StaLinkLayerRadioStats* hidl_radio_stat) { if (!hidl_radio_stat) { return false; } @@ -962,20 +904,13 @@ bool convertLegacyLinkLayerRadioStatsToHidl( hidl_radio_stat->V1_3.V1_0.onTimeInMs = legacy_radio_stat.stats.on_time; hidl_radio_stat->V1_3.V1_0.txTimeInMs = legacy_radio_stat.stats.tx_time; hidl_radio_stat->V1_3.V1_0.rxTimeInMs = legacy_radio_stat.stats.rx_time; - hidl_radio_stat->V1_3.V1_0.onTimeInMsForScan = - legacy_radio_stat.stats.on_time_scan; - hidl_radio_stat->V1_3.V1_0.txTimeInMsPerLevel = - legacy_radio_stat.tx_time_per_levels; - hidl_radio_stat->V1_3.onTimeInMsForNanScan = - legacy_radio_stat.stats.on_time_nbd; - hidl_radio_stat->V1_3.onTimeInMsForBgScan = - legacy_radio_stat.stats.on_time_gscan; - hidl_radio_stat->V1_3.onTimeInMsForRoamScan = - legacy_radio_stat.stats.on_time_roam_scan; - hidl_radio_stat->V1_3.onTimeInMsForPnoScan = - legacy_radio_stat.stats.on_time_pno_scan; - hidl_radio_stat->V1_3.onTimeInMsForHs20Scan = - legacy_radio_stat.stats.on_time_hs20; + hidl_radio_stat->V1_3.V1_0.onTimeInMsForScan = legacy_radio_stat.stats.on_time_scan; + hidl_radio_stat->V1_3.V1_0.txTimeInMsPerLevel = legacy_radio_stat.tx_time_per_levels; + hidl_radio_stat->V1_3.onTimeInMsForNanScan = legacy_radio_stat.stats.on_time_nbd; + hidl_radio_stat->V1_3.onTimeInMsForBgScan = legacy_radio_stat.stats.on_time_gscan; + hidl_radio_stat->V1_3.onTimeInMsForRoamScan = legacy_radio_stat.stats.on_time_roam_scan; + hidl_radio_stat->V1_3.onTimeInMsForPnoScan = legacy_radio_stat.stats.on_time_pno_scan; + hidl_radio_stat->V1_3.onTimeInMsForHs20Scan = legacy_radio_stat.stats.on_time_hs20; std::vector<V1_3::WifiChannelStats> hidl_channel_stats; @@ -989,10 +924,8 @@ bool convertLegacyLinkLayerRadioStatsToHidl( */ hidl_channel_stat.channel.width = WifiChannelWidthInMhz::WIDTH_20; hidl_channel_stat.channel.centerFreq = channel_stat.channel.center_freq; - hidl_channel_stat.channel.centerFreq0 = - channel_stat.channel.center_freq0; - hidl_channel_stat.channel.centerFreq1 = - channel_stat.channel.center_freq1; + hidl_channel_stat.channel.centerFreq0 = channel_stat.channel.center_freq0; + hidl_channel_stat.channel.centerFreq1 = channel_stat.channel.center_freq1; hidl_channel_stats.push_back(hidl_channel_stat); } @@ -1001,9 +934,8 @@ bool convertLegacyLinkLayerRadioStatsToHidl( return true; } -bool convertLegacyLinkLayerStatsToHidl( - const legacy_hal::LinkLayerStats& legacy_stats, - StaLinkLayerStats* hidl_stats) { +bool convertLegacyLinkLayerStatsToHidl(const legacy_hal::LinkLayerStats& legacy_stats, + V1_5::StaLinkLayerStats* hidl_stats) { if (!hidl_stats) { return false; } @@ -1012,77 +944,76 @@ bool convertLegacyLinkLayerStatsToHidl( hidl_stats->iface.V1_0.beaconRx = legacy_stats.iface.beacon_rx; hidl_stats->iface.V1_0.avgRssiMgmt = legacy_stats.iface.rssi_mgmt; hidl_stats->iface.V1_0.wmeBePktStats.rxMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu; hidl_stats->iface.V1_0.wmeBePktStats.txMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu; hidl_stats->iface.V1_0.wmeBePktStats.lostMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost; hidl_stats->iface.V1_0.wmeBePktStats.retries = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries; hidl_stats->iface.wmeBeContentionTimeStats.contentionTimeMinInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min; hidl_stats->iface.wmeBeContentionTimeStats.contentionTimeMaxInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max; hidl_stats->iface.wmeBeContentionTimeStats.contentionTimeAvgInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg; hidl_stats->iface.wmeBeContentionTimeStats.contentionNumSamples = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples; hidl_stats->iface.V1_0.wmeBkPktStats.rxMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu; hidl_stats->iface.V1_0.wmeBkPktStats.txMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu; hidl_stats->iface.V1_0.wmeBkPktStats.lostMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost; hidl_stats->iface.V1_0.wmeBkPktStats.retries = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries; hidl_stats->iface.wmeBkContentionTimeStats.contentionTimeMinInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min; hidl_stats->iface.wmeBkContentionTimeStats.contentionTimeMaxInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max; hidl_stats->iface.wmeBkContentionTimeStats.contentionTimeAvgInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg; hidl_stats->iface.wmeBkContentionTimeStats.contentionNumSamples = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples; hidl_stats->iface.V1_0.wmeViPktStats.rxMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu; hidl_stats->iface.V1_0.wmeViPktStats.txMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu; hidl_stats->iface.V1_0.wmeViPktStats.lostMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost; hidl_stats->iface.V1_0.wmeViPktStats.retries = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries; hidl_stats->iface.wmeViContentionTimeStats.contentionTimeMinInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min; hidl_stats->iface.wmeViContentionTimeStats.contentionTimeMaxInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max; hidl_stats->iface.wmeViContentionTimeStats.contentionTimeAvgInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg; hidl_stats->iface.wmeViContentionTimeStats.contentionNumSamples = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples; hidl_stats->iface.V1_0.wmeVoPktStats.rxMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu; hidl_stats->iface.V1_0.wmeVoPktStats.txMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu; hidl_stats->iface.V1_0.wmeVoPktStats.lostMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost; hidl_stats->iface.V1_0.wmeVoPktStats.retries = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries; hidl_stats->iface.wmeVoContentionTimeStats.contentionTimeMinInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min; hidl_stats->iface.wmeVoContentionTimeStats.contentionTimeMaxInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max; hidl_stats->iface.wmeVoContentionTimeStats.contentionTimeAvgInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg; hidl_stats->iface.wmeVoContentionTimeStats.contentionNumSamples = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples; + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples; hidl_stats->iface.timeSliceDutyCycleInPercent = - legacy_stats.iface.info.time_slicing_duty_cycle_percent; + legacy_stats.iface.info.time_slicing_duty_cycle_percent; // peer info legacy_stats conversion. - std::vector<StaPeerInfo> hidl_peers_info_stats; + std::vector<V1_5::StaPeerInfo> hidl_peers_info_stats; for (const auto& legacy_peer_info_stats : legacy_stats.peers) { - StaPeerInfo hidl_peer_info_stats; - if (!convertLegacyPeerInfoStatsToHidl(legacy_peer_info_stats, - &hidl_peer_info_stats)) { + V1_5::StaPeerInfo hidl_peer_info_stats; + if (!convertLegacyPeerInfoStatsToHidl(legacy_peer_info_stats, &hidl_peer_info_stats)) { return false; } hidl_peers_info_stats.push_back(hidl_peer_info_stats); @@ -1092,8 +1023,7 @@ bool convertLegacyLinkLayerStatsToHidl( std::vector<V1_5::StaLinkLayerRadioStats> hidl_radios_stats; for (const auto& legacy_radio_stats : legacy_stats.radios) { V1_5::StaLinkLayerRadioStats hidl_radio_stats; - if (!convertLegacyLinkLayerRadioStatsToHidl(legacy_radio_stats, - &hidl_radio_stats)) { + if (!convertLegacyLinkLayerRadioStatsToHidl(legacy_radio_stats, &hidl_radio_stats)) { return false; } hidl_radios_stats.push_back(hidl_radio_stats); @@ -1105,23 +1035,19 @@ bool convertLegacyLinkLayerStatsToHidl( return true; } -bool convertLegacyPeerInfoStatsToHidl( - const legacy_hal::WifiPeerInfo& legacy_peer_info_stats, - StaPeerInfo* hidl_peer_info_stats) { +bool convertLegacyPeerInfoStatsToHidl(const legacy_hal::WifiPeerInfo& legacy_peer_info_stats, + V1_5::StaPeerInfo* hidl_peer_info_stats) { if (!hidl_peer_info_stats) { return false; } *hidl_peer_info_stats = {}; - hidl_peer_info_stats->staCount = - legacy_peer_info_stats.peer_info.bssload.sta_count; - hidl_peer_info_stats->chanUtil = - legacy_peer_info_stats.peer_info.bssload.chan_util; + hidl_peer_info_stats->staCount = legacy_peer_info_stats.peer_info.bssload.sta_count; + hidl_peer_info_stats->chanUtil = legacy_peer_info_stats.peer_info.bssload.chan_util; - std::vector<StaRateStat> hidlRateStats; + std::vector<V1_5::StaRateStat> hidlRateStats; for (const auto& legacy_rate_stats : legacy_peer_info_stats.rate_stats) { - StaRateStat rateStat; - if (!convertLegacyWifiRateInfoToHidl(legacy_rate_stats.rate, - &rateStat.rateInfo)) { + V1_5::StaRateStat rateStat; + if (!convertLegacyWifiRateInfoToHidl(legacy_rate_stats.rate, &rateStat.rateInfo)) { return false; } rateStat.txMpdu = legacy_rate_stats.tx_mpdu; @@ -1135,8 +1061,8 @@ bool convertLegacyPeerInfoStatsToHidl( } bool convertLegacyRoamingCapabilitiesToHidl( - const legacy_hal::wifi_roaming_capabilities& legacy_caps, - StaRoamingCapabilities* hidl_caps) { + const legacy_hal::wifi_roaming_capabilities& legacy_caps, + StaRoamingCapabilities* hidl_caps) { if (!hidl_caps) { return false; } @@ -1146,9 +1072,8 @@ bool convertLegacyRoamingCapabilitiesToHidl( return true; } -bool convertHidlRoamingConfigToLegacy( - const StaRoamingConfig& hidl_config, - legacy_hal::wifi_roaming_config* legacy_config) { +bool convertHidlRoamingConfigToLegacy(const StaRoamingConfig& hidl_config, + legacy_hal::wifi_roaming_config* legacy_config) { if (!legacy_config) { return false; } @@ -1168,15 +1093,13 @@ bool convertHidlRoamingConfigToLegacy( for (const auto& ssid : hidl_config.ssidWhitelist) { CHECK(ssid.size() <= sizeof(legacy_hal::ssid_t::ssid_str)); legacy_config->whitelist_ssid[i].length = ssid.size(); - memcpy(legacy_config->whitelist_ssid[i].ssid_str, ssid.data(), - ssid.size()); + memcpy(legacy_config->whitelist_ssid[i].ssid_str, ssid.data(), ssid.size()); i++; } return true; } -legacy_hal::fw_roaming_state_t convertHidlRoamingStateToLegacy( - StaRoamingState state) { +legacy_hal::fw_roaming_state_t convertHidlRoamingStateToLegacy(StaRoamingState state) { switch (state) { case StaRoamingState::ENABLED: return legacy_hal::ROAMING_ENABLE; @@ -1198,8 +1121,7 @@ legacy_hal::NanMatchAlg convertHidlNanMatchAlgToLegacy(NanMatchAlg type) { CHECK(false); } -legacy_hal::NanPublishType convertHidlNanPublishTypeToLegacy( - NanPublishType type) { +legacy_hal::NanPublishType convertHidlNanPublishTypeToLegacy(NanPublishType type) { switch (type) { case NanPublishType::UNSOLICITED: return legacy_hal::NAN_PUBLISH_TYPE_UNSOLICITED; @@ -1221,8 +1143,7 @@ legacy_hal::NanTxType convertHidlNanTxTypeToLegacy(NanTxType type) { CHECK(false); } -legacy_hal::NanSubscribeType convertHidlNanSubscribeTypeToLegacy( - NanSubscribeType type) { +legacy_hal::NanSubscribeType convertHidlNanSubscribeTypeToLegacy(NanSubscribeType type) { switch (type) { case NanSubscribeType::PASSIVE: return legacy_hal::NAN_SUBSCRIBE_TYPE_PASSIVE; @@ -1243,7 +1164,7 @@ legacy_hal::NanSRFType convertHidlNanSrfTypeToLegacy(NanSrfType type) { } legacy_hal::NanDataPathChannelCfg convertHidlNanDataPathChannelCfgToLegacy( - NanDataPathChannelCfg type) { + NanDataPathChannelCfg type) { switch (type) { case NanDataPathChannelCfg::CHANNEL_NOT_REQUESTED: return legacy_hal::NAN_DP_CHANNEL_NOT_REQUESTED; @@ -1287,39 +1208,36 @@ NanStatusType convertLegacyNanStatusTypeToHidl(legacy_hal::NanStatusType type) { CHECK(false); } -void convertToWifiNanStatus(legacy_hal::NanStatusType type, const char* str, - size_t max_len, WifiNanStatus* wifiNanStatus) { +void convertToWifiNanStatus(legacy_hal::NanStatusType type, const char* str, size_t max_len, + WifiNanStatus* wifiNanStatus) { wifiNanStatus->status = convertLegacyNanStatusTypeToHidl(type); wifiNanStatus->description = safeConvertChar(str, max_len); } -bool convertHidlNanEnableRequestToLegacy( - const V1_4::NanEnableRequest& hidl_request, - legacy_hal::NanEnableRequest* legacy_request) { +bool convertHidlNanEnableRequestToLegacy(const V1_4::NanEnableRequest& hidl_request, + legacy_hal::NanEnableRequest* legacy_request) { if (!legacy_request) { - LOG(ERROR) - << "convertHidlNanEnableRequestToLegacy: null legacy_request"; + LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: null legacy_request"; return false; } *legacy_request = {}; legacy_request->config_2dot4g_support = 1; legacy_request->support_2dot4g_val = - hidl_request.operateInBand[(size_t)NanBandIndex::NAN_BAND_24GHZ]; + hidl_request.operateInBand[(size_t)NanBandIndex::NAN_BAND_24GHZ]; legacy_request->config_support_5g = 1; legacy_request->support_5g_val = - hidl_request.operateInBand[(size_t)NanBandIndex::NAN_BAND_5GHZ]; + hidl_request.operateInBand[(size_t)NanBandIndex::NAN_BAND_5GHZ]; legacy_request->config_hop_count_limit = 1; legacy_request->hop_count_limit_val = hidl_request.hopCountMax; legacy_request->master_pref = hidl_request.configParams.masterPref; legacy_request->discovery_indication_cfg = 0; legacy_request->discovery_indication_cfg |= - hidl_request.configParams.disableDiscoveryAddressChangeIndication ? 0x1 - : 0x0; + hidl_request.configParams.disableDiscoveryAddressChangeIndication ? 0x1 : 0x0; legacy_request->discovery_indication_cfg |= - hidl_request.configParams.disableStartedClusterIndication ? 0x2 : 0x0; + hidl_request.configParams.disableStartedClusterIndication ? 0x2 : 0x0; legacy_request->discovery_indication_cfg |= - hidl_request.configParams.disableJoinedClusterIndication ? 0x4 : 0x0; + hidl_request.configParams.disableJoinedClusterIndication ? 0x4 : 0x0; legacy_request->config_sid_beacon = 1; if (hidl_request.configParams.numberOfPublishServiceIdsInBeacon > 127) { LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: " @@ -1327,9 +1245,8 @@ bool convertHidlNanEnableRequestToLegacy( return false; } legacy_request->sid_beacon_val = - (hidl_request.configParams.includePublishServiceIdsInBeacon ? 0x1 - : 0x0) | - (hidl_request.configParams.numberOfPublishServiceIdsInBeacon << 1); + (hidl_request.configParams.includePublishServiceIdsInBeacon ? 0x1 : 0x0) | + (hidl_request.configParams.numberOfPublishServiceIdsInBeacon << 1); legacy_request->config_subscribe_sid_beacon = 1; if (hidl_request.configParams.numberOfSubscribeServiceIdsInBeacon > 127) { LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: " @@ -1337,15 +1254,13 @@ bool convertHidlNanEnableRequestToLegacy( return false; } legacy_request->subscribe_sid_beacon_val = - (hidl_request.configParams.includeSubscribeServiceIdsInBeacon ? 0x1 - : 0x0) | - (hidl_request.configParams.numberOfSubscribeServiceIdsInBeacon << 1); + (hidl_request.configParams.includeSubscribeServiceIdsInBeacon ? 0x1 : 0x0) | + (hidl_request.configParams.numberOfSubscribeServiceIdsInBeacon << 1); legacy_request->config_rssi_window_size = 1; - legacy_request->rssi_window_size_val = - hidl_request.configParams.rssiWindowSize; + legacy_request->rssi_window_size_val = hidl_request.configParams.rssiWindowSize; legacy_request->config_disc_mac_addr_randomization = 1; legacy_request->disc_mac_addr_rand_interval_sec = - hidl_request.configParams.macAddressRandomizationIntervalSec; + hidl_request.configParams.macAddressRandomizationIntervalSec; legacy_request->config_2dot4g_rssi_close = 1; if (hidl_request.configParams.bandSpecificConfig.size() != 3) { LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: " @@ -1353,134 +1268,93 @@ bool convertHidlNanEnableRequestToLegacy( return false; } legacy_request->rssi_close_2dot4g_val = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] - .rssiClose; + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] + .rssiClose; legacy_request->config_2dot4g_rssi_middle = 1; legacy_request->rssi_middle_2dot4g_val = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] - .rssiMiddle; + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] + .rssiMiddle; legacy_request->config_2dot4g_rssi_proximity = 1; legacy_request->rssi_proximity_2dot4g_val = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] - .rssiCloseProximity; + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] + .rssiCloseProximity; legacy_request->config_scan_params = 1; - legacy_request->scan_params_val - .dwell_time[legacy_hal::NAN_CHANNEL_24G_BAND] = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] - .dwellTimeMs; - legacy_request->scan_params_val - .scan_period[legacy_hal::NAN_CHANNEL_24G_BAND] = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] - .scanPeriodSec; + legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_24G_BAND] = + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] + .dwellTimeMs; + legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_24G_BAND] = + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] + .scanPeriodSec; legacy_request->config_dw.config_2dot4g_dw_band = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] - .validDiscoveryWindowIntervalVal; + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] + .validDiscoveryWindowIntervalVal; legacy_request->config_dw.dw_2dot4g_interval_val = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] - .discoveryWindowIntervalVal; + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] + .discoveryWindowIntervalVal; legacy_request->config_5g_rssi_close = 1; legacy_request->rssi_close_5g_val = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .rssiClose; + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] + .rssiClose; legacy_request->config_5g_rssi_middle = 1; legacy_request->rssi_middle_5g_val = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .rssiMiddle; + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] + .rssiMiddle; legacy_request->config_5g_rssi_close_proximity = 1; legacy_request->rssi_close_proximity_5g_val = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .rssiCloseProximity; - legacy_request->scan_params_val - .dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .dwellTimeMs; - legacy_request->scan_params_val - .scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .scanPeriodSec; - legacy_request->scan_params_val - .dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .dwellTimeMs; - legacy_request->scan_params_val - .scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .scanPeriodSec; + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] + .rssiCloseProximity; + legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] = + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] + .dwellTimeMs; + legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] = + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] + .scanPeriodSec; + legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] = + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] + .dwellTimeMs; + legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] = + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] + .scanPeriodSec; legacy_request->config_dw.config_5g_dw_band = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .validDiscoveryWindowIntervalVal; + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] + .validDiscoveryWindowIntervalVal; legacy_request->config_dw.dw_5g_interval_val = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .discoveryWindowIntervalVal; + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] + .discoveryWindowIntervalVal; if (hidl_request.debugConfigs.validClusterIdVals) { - legacy_request->cluster_low = - hidl_request.debugConfigs.clusterIdBottomRangeVal; - legacy_request->cluster_high = - hidl_request.debugConfigs.clusterIdTopRangeVal; + legacy_request->cluster_low = hidl_request.debugConfigs.clusterIdBottomRangeVal; + legacy_request->cluster_high = hidl_request.debugConfigs.clusterIdTopRangeVal; } else { // need 'else' since not configurable in legacy HAL legacy_request->cluster_low = 0x0000; legacy_request->cluster_high = 0xFFFF; } - legacy_request->config_intf_addr = - hidl_request.debugConfigs.validIntfAddrVal; - memcpy(legacy_request->intf_addr_val, - hidl_request.debugConfigs.intfAddrVal.data(), 6); + legacy_request->config_intf_addr = hidl_request.debugConfigs.validIntfAddrVal; + memcpy(legacy_request->intf_addr_val, hidl_request.debugConfigs.intfAddrVal.data(), 6); legacy_request->config_oui = hidl_request.debugConfigs.validOuiVal; legacy_request->oui_val = hidl_request.debugConfigs.ouiVal; legacy_request->config_random_factor_force = - hidl_request.debugConfigs.validRandomFactorForceVal; - legacy_request->random_factor_force_val = - hidl_request.debugConfigs.randomFactorForceVal; - legacy_request->config_hop_count_force = - hidl_request.debugConfigs.validHopCountForceVal; - legacy_request->hop_count_force_val = - hidl_request.debugConfigs.hopCountForceVal; - legacy_request->config_24g_channel = - hidl_request.debugConfigs.validDiscoveryChannelVal; + hidl_request.debugConfigs.validRandomFactorForceVal; + legacy_request->random_factor_force_val = hidl_request.debugConfigs.randomFactorForceVal; + legacy_request->config_hop_count_force = hidl_request.debugConfigs.validHopCountForceVal; + legacy_request->hop_count_force_val = hidl_request.debugConfigs.hopCountForceVal; + legacy_request->config_24g_channel = hidl_request.debugConfigs.validDiscoveryChannelVal; legacy_request->channel_24g_val = - hidl_request.debugConfigs - .discoveryChannelMhzVal[(size_t)NanBandIndex::NAN_BAND_24GHZ]; - legacy_request->config_5g_channel = - hidl_request.debugConfigs.validDiscoveryChannelVal; + hidl_request.debugConfigs.discoveryChannelMhzVal[(size_t)NanBandIndex::NAN_BAND_24GHZ]; + legacy_request->config_5g_channel = hidl_request.debugConfigs.validDiscoveryChannelVal; legacy_request->channel_5g_val = - hidl_request.debugConfigs - .discoveryChannelMhzVal[(size_t)NanBandIndex::NAN_BAND_5GHZ]; - legacy_request->config_2dot4g_beacons = - hidl_request.debugConfigs.validUseBeaconsInBandVal; + hidl_request.debugConfigs.discoveryChannelMhzVal[(size_t)NanBandIndex::NAN_BAND_5GHZ]; + legacy_request->config_2dot4g_beacons = hidl_request.debugConfigs.validUseBeaconsInBandVal; legacy_request->beacon_2dot4g_val = - hidl_request.debugConfigs - .useBeaconsInBandVal[(size_t)NanBandIndex::NAN_BAND_24GHZ]; - legacy_request->config_5g_beacons = - hidl_request.debugConfigs.validUseBeaconsInBandVal; + hidl_request.debugConfigs.useBeaconsInBandVal[(size_t)NanBandIndex::NAN_BAND_24GHZ]; + legacy_request->config_5g_beacons = hidl_request.debugConfigs.validUseBeaconsInBandVal; legacy_request->beacon_5g_val = - hidl_request.debugConfigs - .useBeaconsInBandVal[(size_t)NanBandIndex::NAN_BAND_5GHZ]; - legacy_request->config_2dot4g_sdf = - hidl_request.debugConfigs.validUseSdfInBandVal; + hidl_request.debugConfigs.useBeaconsInBandVal[(size_t)NanBandIndex::NAN_BAND_5GHZ]; + legacy_request->config_2dot4g_sdf = hidl_request.debugConfigs.validUseSdfInBandVal; legacy_request->sdf_2dot4g_val = - hidl_request.debugConfigs - .useSdfInBandVal[(size_t)NanBandIndex::NAN_BAND_24GHZ]; - legacy_request->config_5g_sdf = - hidl_request.debugConfigs.validUseSdfInBandVal; + hidl_request.debugConfigs.useSdfInBandVal[(size_t)NanBandIndex::NAN_BAND_24GHZ]; + legacy_request->config_5g_sdf = hidl_request.debugConfigs.validUseSdfInBandVal; legacy_request->sdf_5g_val = - hidl_request.debugConfigs - .useSdfInBandVal[(size_t)NanBandIndex::NAN_BAND_5GHZ]; + hidl_request.debugConfigs.useSdfInBandVal[(size_t)NanBandIndex::NAN_BAND_5GHZ]; /* TODO: b/145609058 * Missing updates needed to legacy_hal::NanEnableRequest and conversion to @@ -1489,13 +1363,11 @@ bool convertHidlNanEnableRequestToLegacy( return true; } -bool convertHidlNanEnableRequest_1_4ToLegacy( - const V1_4::NanEnableRequest& hidl_request1, - const NanConfigRequestSupplemental& hidl_request2, - legacy_hal::NanEnableRequest* legacy_request) { +bool convertHidlNanEnableRequest_1_4ToLegacy(const V1_4::NanEnableRequest& hidl_request1, + const NanConfigRequestSupplemental& hidl_request2, + legacy_hal::NanEnableRequest* legacy_request) { if (!legacy_request) { - LOG(ERROR) - << "convertHidlNanEnableRequest_1_4ToLegacy: null legacy_request"; + LOG(ERROR) << "convertHidlNanEnableRequest_1_4ToLegacy: null legacy_request"; return false; } @@ -1505,71 +1377,60 @@ bool convertHidlNanEnableRequest_1_4ToLegacy( } legacy_request->config_discovery_beacon_int = 1; - legacy_request->discovery_beacon_interval = - hidl_request2.V1_2.discoveryBeaconIntervalMs; + legacy_request->discovery_beacon_interval = hidl_request2.V1_2.discoveryBeaconIntervalMs; legacy_request->config_nss = 1; legacy_request->nss = hidl_request2.V1_2.numberOfSpatialStreamsInDiscovery; legacy_request->config_dw_early_termination = 1; legacy_request->enable_dw_termination = - hidl_request2.V1_2.enableDiscoveryWindowEarlyTermination; + hidl_request2.V1_2.enableDiscoveryWindowEarlyTermination; legacy_request->config_enable_ranging = 1; legacy_request->enable_ranging = hidl_request2.V1_2.enableRanging; return true; } -bool convertHidlNanEnableRequest_1_5ToLegacy( - const V1_4::NanEnableRequest& hidl_request1, - const NanConfigRequestSupplemental& hidl_request2, - legacy_hal::NanEnableRequest* legacy_request) { +bool convertHidlNanEnableRequest_1_5ToLegacy(const V1_4::NanEnableRequest& hidl_request1, + const NanConfigRequestSupplemental& hidl_request2, + legacy_hal::NanEnableRequest* legacy_request) { if (!legacy_request) { - LOG(ERROR) - << "convertHidlNanEnableRequest_1_5ToLegacy: null legacy_request"; + LOG(ERROR) << "convertHidlNanEnableRequest_1_5ToLegacy: null legacy_request"; return false; } *legacy_request = {}; - if (!convertHidlNanEnableRequest_1_4ToLegacy(hidl_request1, hidl_request2, - legacy_request)) { + if (!convertHidlNanEnableRequest_1_4ToLegacy(hidl_request1, hidl_request2, legacy_request)) { return false; } legacy_request->config_enable_instant_mode = 1; - legacy_request->enable_instant_mode = - hidl_request2.enableInstantCommunicationMode; + legacy_request->enable_instant_mode = hidl_request2.enableInstantCommunicationMode; return true; } -bool convertHidlNanConfigRequest_1_5ToLegacy( - const V1_4::NanConfigRequest& hidl_request1, - const NanConfigRequestSupplemental& hidl_request2, - legacy_hal::NanConfigRequest* legacy_request) { +bool convertHidlNanConfigRequest_1_5ToLegacy(const V1_4::NanConfigRequest& hidl_request1, + const NanConfigRequestSupplemental& hidl_request2, + legacy_hal::NanConfigRequest* legacy_request) { if (!legacy_request) { - LOG(ERROR) - << "convertHidlNanConfigRequest_1_5ToLegacy: null legacy_request"; + LOG(ERROR) << "convertHidlNanConfigRequest_1_5ToLegacy: null legacy_request"; return false; } *legacy_request = {}; - if (!convertHidlNanConfigRequest_1_4ToLegacy(hidl_request1, hidl_request2, - legacy_request)) { + if (!convertHidlNanConfigRequest_1_4ToLegacy(hidl_request1, hidl_request2, legacy_request)) { return false; } legacy_request->config_enable_instant_mode = 1; - legacy_request->enable_instant_mode = - hidl_request2.enableInstantCommunicationMode; + legacy_request->enable_instant_mode = hidl_request2.enableInstantCommunicationMode; return true; } -bool convertHidlNanPublishRequestToLegacy( - const NanPublishRequest& hidl_request, - legacy_hal::NanPublishRequest* legacy_request) { +bool convertHidlNanPublishRequestToLegacy(const NanPublishRequest& hidl_request, + legacy_hal::NanPublishRequest* legacy_request) { if (!legacy_request) { - LOG(ERROR) - << "convertHidlNanPublishRequestToLegacy: null legacy_request"; + LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: null legacy_request"; return false; } *legacy_request = {}; @@ -1578,22 +1439,18 @@ bool convertHidlNanPublishRequestToLegacy( legacy_request->ttl = hidl_request.baseConfigs.ttlSec; legacy_request->period = hidl_request.baseConfigs.discoveryWindowPeriod; legacy_request->publish_count = hidl_request.baseConfigs.discoveryCount; - legacy_request->service_name_len = - hidl_request.baseConfigs.serviceName.size(); + legacy_request->service_name_len = hidl_request.baseConfigs.serviceName.size(); if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) { LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: service_name_len " "too large"; return false; } - memcpy(legacy_request->service_name, - hidl_request.baseConfigs.serviceName.data(), + memcpy(legacy_request->service_name, hidl_request.baseConfigs.serviceName.data(), legacy_request->service_name_len); - legacy_request->publish_match_indicator = convertHidlNanMatchAlgToLegacy( - hidl_request.baseConfigs.discoveryMatchIndicator); - legacy_request->service_specific_info_len = - hidl_request.baseConfigs.serviceSpecificInfo.size(); - if (legacy_request->service_specific_info_len > - NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) { + legacy_request->publish_match_indicator = + convertHidlNanMatchAlgToLegacy(hidl_request.baseConfigs.discoveryMatchIndicator); + legacy_request->service_specific_info_len = hidl_request.baseConfigs.serviceSpecificInfo.size(); + if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) { LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: " "service_specific_info_len too large"; return false; @@ -1602,9 +1459,8 @@ bool convertHidlNanPublishRequestToLegacy( hidl_request.baseConfigs.serviceSpecificInfo.data(), legacy_request->service_specific_info_len); legacy_request->sdea_service_specific_info_len = - hidl_request.baseConfigs.extendedServiceSpecificInfo.size(); - if (legacy_request->sdea_service_specific_info_len > - NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) { + hidl_request.baseConfigs.extendedServiceSpecificInfo.size(); + if (legacy_request->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) { LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: " "sdea_service_specific_info_len too large"; return false; @@ -1612,49 +1468,38 @@ bool convertHidlNanPublishRequestToLegacy( memcpy(legacy_request->sdea_service_specific_info, hidl_request.baseConfigs.extendedServiceSpecificInfo.data(), legacy_request->sdea_service_specific_info_len); - legacy_request->rx_match_filter_len = - hidl_request.baseConfigs.rxMatchFilter.size(); + legacy_request->rx_match_filter_len = hidl_request.baseConfigs.rxMatchFilter.size(); if (legacy_request->rx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) { LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: " "rx_match_filter_len too large"; return false; } - memcpy(legacy_request->rx_match_filter, - hidl_request.baseConfigs.rxMatchFilter.data(), + memcpy(legacy_request->rx_match_filter, hidl_request.baseConfigs.rxMatchFilter.data(), legacy_request->rx_match_filter_len); - legacy_request->tx_match_filter_len = - hidl_request.baseConfigs.txMatchFilter.size(); + legacy_request->tx_match_filter_len = hidl_request.baseConfigs.txMatchFilter.size(); if (legacy_request->tx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) { LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: " "tx_match_filter_len too large"; return false; } - memcpy(legacy_request->tx_match_filter, - hidl_request.baseConfigs.txMatchFilter.data(), + memcpy(legacy_request->tx_match_filter, hidl_request.baseConfigs.txMatchFilter.data(), legacy_request->tx_match_filter_len); - legacy_request->rssi_threshold_flag = - hidl_request.baseConfigs.useRssiThreshold; + legacy_request->rssi_threshold_flag = hidl_request.baseConfigs.useRssiThreshold; legacy_request->recv_indication_cfg = 0; legacy_request->recv_indication_cfg |= - hidl_request.baseConfigs.disableDiscoveryTerminationIndication ? 0x1 - : 0x0; + hidl_request.baseConfigs.disableDiscoveryTerminationIndication ? 0x1 : 0x0; legacy_request->recv_indication_cfg |= - hidl_request.baseConfigs.disableMatchExpirationIndication ? 0x2 : 0x0; + hidl_request.baseConfigs.disableMatchExpirationIndication ? 0x2 : 0x0; legacy_request->recv_indication_cfg |= - hidl_request.baseConfigs.disableFollowupReceivedIndication ? 0x4 : 0x0; + hidl_request.baseConfigs.disableFollowupReceivedIndication ? 0x4 : 0x0; legacy_request->recv_indication_cfg |= 0x8; - legacy_request->cipher_type = - (unsigned int)hidl_request.baseConfigs.securityConfig.cipherType; - if (hidl_request.baseConfigs.securityConfig.securityType == - NanDataPathSecurityType::PMK) { - legacy_request->key_info.key_type = - legacy_hal::NAN_SECURITY_KEY_INPUT_PMK; + legacy_request->cipher_type = (unsigned int)hidl_request.baseConfigs.securityConfig.cipherType; + if (hidl_request.baseConfigs.securityConfig.securityType == NanDataPathSecurityType::PMK) { + legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK; legacy_request->key_info.body.pmk_info.pmk_len = - hidl_request.baseConfigs.securityConfig.pmk.size(); - if (legacy_request->key_info.body.pmk_info.pmk_len != - NAN_PMK_INFO_LEN) { - LOG(ERROR) - << "convertHidlNanPublishRequestToLegacy: invalid pmk_len"; + hidl_request.baseConfigs.securityConfig.pmk.size(); + if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) { + LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: invalid pmk_len"; return false; } memcpy(legacy_request->key_info.body.pmk_info.pmk, @@ -1663,10 +1508,9 @@ bool convertHidlNanPublishRequestToLegacy( } if (hidl_request.baseConfigs.securityConfig.securityType == NanDataPathSecurityType::PASSPHRASE) { - legacy_request->key_info.key_type = - legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE; + legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE; legacy_request->key_info.body.passphrase_info.passphrase_len = - hidl_request.baseConfigs.securityConfig.passphrase.size(); + hidl_request.baseConfigs.securityConfig.passphrase.size(); if (legacy_request->key_info.body.passphrase_info.passphrase_len < NAN_SECURITY_MIN_PASSPHRASE_LEN) { LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: " @@ -1684,45 +1528,36 @@ bool convertHidlNanPublishRequestToLegacy( legacy_request->key_info.body.passphrase_info.passphrase_len); } legacy_request->sdea_params.security_cfg = - (hidl_request.baseConfigs.securityConfig.securityType != - NanDataPathSecurityType::OPEN) - ? legacy_hal::NAN_DP_CONFIG_SECURITY - : legacy_hal::NAN_DP_CONFIG_NO_SECURITY; - legacy_request->sdea_params.ranging_state = - hidl_request.baseConfigs.rangingRequired - ? legacy_hal::NAN_RANGING_ENABLE - : legacy_hal::NAN_RANGING_DISABLE; + (hidl_request.baseConfigs.securityConfig.securityType != NanDataPathSecurityType::OPEN) + ? legacy_hal::NAN_DP_CONFIG_SECURITY + : legacy_hal::NAN_DP_CONFIG_NO_SECURITY; + legacy_request->sdea_params.ranging_state = hidl_request.baseConfigs.rangingRequired + ? legacy_hal::NAN_RANGING_ENABLE + : legacy_hal::NAN_RANGING_DISABLE; legacy_request->ranging_cfg.ranging_interval_msec = - hidl_request.baseConfigs.rangingIntervalMsec; + hidl_request.baseConfigs.rangingIntervalMsec; legacy_request->ranging_cfg.config_ranging_indications = - hidl_request.baseConfigs.configRangingIndications; + hidl_request.baseConfigs.configRangingIndications; legacy_request->ranging_cfg.distance_ingress_mm = - hidl_request.baseConfigs.distanceIngressCm * 10; - legacy_request->ranging_cfg.distance_egress_mm = - hidl_request.baseConfigs.distanceEgressCm * 10; - legacy_request->ranging_auto_response = - hidl_request.baseConfigs.rangingRequired - ? legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE - : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE; - legacy_request->sdea_params.range_report = - legacy_hal::NAN_DISABLE_RANGE_REPORT; - legacy_request->publish_type = - convertHidlNanPublishTypeToLegacy(hidl_request.publishType); + hidl_request.baseConfigs.distanceIngressCm * 10; + legacy_request->ranging_cfg.distance_egress_mm = hidl_request.baseConfigs.distanceEgressCm * 10; + legacy_request->ranging_auto_response = hidl_request.baseConfigs.rangingRequired + ? legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE + : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE; + legacy_request->sdea_params.range_report = legacy_hal::NAN_DISABLE_RANGE_REPORT; + legacy_request->publish_type = convertHidlNanPublishTypeToLegacy(hidl_request.publishType); legacy_request->tx_type = convertHidlNanTxTypeToLegacy(hidl_request.txType); - legacy_request->service_responder_policy = - hidl_request.autoAcceptDataPathRequests - ? legacy_hal::NAN_SERVICE_ACCEPT_POLICY_ALL - : legacy_hal::NAN_SERVICE_ACCEPT_POLICY_NONE; + legacy_request->service_responder_policy = hidl_request.autoAcceptDataPathRequests + ? legacy_hal::NAN_SERVICE_ACCEPT_POLICY_ALL + : legacy_hal::NAN_SERVICE_ACCEPT_POLICY_NONE; return true; } -bool convertHidlNanSubscribeRequestToLegacy( - const NanSubscribeRequest& hidl_request, - legacy_hal::NanSubscribeRequest* legacy_request) { +bool convertHidlNanSubscribeRequestToLegacy(const NanSubscribeRequest& hidl_request, + legacy_hal::NanSubscribeRequest* legacy_request) { if (!legacy_request) { - LOG(ERROR) - << "convertHidlNanSubscribeRequestToLegacy: legacy_request is null"; + LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: legacy_request is null"; return false; } *legacy_request = {}; @@ -1731,22 +1566,18 @@ bool convertHidlNanSubscribeRequestToLegacy( legacy_request->ttl = hidl_request.baseConfigs.ttlSec; legacy_request->period = hidl_request.baseConfigs.discoveryWindowPeriod; legacy_request->subscribe_count = hidl_request.baseConfigs.discoveryCount; - legacy_request->service_name_len = - hidl_request.baseConfigs.serviceName.size(); + legacy_request->service_name_len = hidl_request.baseConfigs.serviceName.size(); if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) { LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: " "service_name_len too large"; return false; } - memcpy(legacy_request->service_name, - hidl_request.baseConfigs.serviceName.data(), + memcpy(legacy_request->service_name, hidl_request.baseConfigs.serviceName.data(), legacy_request->service_name_len); - legacy_request->subscribe_match_indicator = convertHidlNanMatchAlgToLegacy( - hidl_request.baseConfigs.discoveryMatchIndicator); - legacy_request->service_specific_info_len = - hidl_request.baseConfigs.serviceSpecificInfo.size(); - if (legacy_request->service_specific_info_len > - NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) { + legacy_request->subscribe_match_indicator = + convertHidlNanMatchAlgToLegacy(hidl_request.baseConfigs.discoveryMatchIndicator); + legacy_request->service_specific_info_len = hidl_request.baseConfigs.serviceSpecificInfo.size(); + if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) { LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: " "service_specific_info_len too large"; return false; @@ -1755,9 +1586,8 @@ bool convertHidlNanSubscribeRequestToLegacy( hidl_request.baseConfigs.serviceSpecificInfo.data(), legacy_request->service_specific_info_len); legacy_request->sdea_service_specific_info_len = - hidl_request.baseConfigs.extendedServiceSpecificInfo.size(); - if (legacy_request->sdea_service_specific_info_len > - NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) { + hidl_request.baseConfigs.extendedServiceSpecificInfo.size(); + if (legacy_request->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) { LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: " "sdea_service_specific_info_len too large"; return false; @@ -1765,48 +1595,37 @@ bool convertHidlNanSubscribeRequestToLegacy( memcpy(legacy_request->sdea_service_specific_info, hidl_request.baseConfigs.extendedServiceSpecificInfo.data(), legacy_request->sdea_service_specific_info_len); - legacy_request->rx_match_filter_len = - hidl_request.baseConfigs.rxMatchFilter.size(); + legacy_request->rx_match_filter_len = hidl_request.baseConfigs.rxMatchFilter.size(); if (legacy_request->rx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) { LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: " "rx_match_filter_len too large"; return false; } - memcpy(legacy_request->rx_match_filter, - hidl_request.baseConfigs.rxMatchFilter.data(), + memcpy(legacy_request->rx_match_filter, hidl_request.baseConfigs.rxMatchFilter.data(), legacy_request->rx_match_filter_len); - legacy_request->tx_match_filter_len = - hidl_request.baseConfigs.txMatchFilter.size(); + legacy_request->tx_match_filter_len = hidl_request.baseConfigs.txMatchFilter.size(); if (legacy_request->tx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) { LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: " "tx_match_filter_len too large"; return false; } - memcpy(legacy_request->tx_match_filter, - hidl_request.baseConfigs.txMatchFilter.data(), + memcpy(legacy_request->tx_match_filter, hidl_request.baseConfigs.txMatchFilter.data(), legacy_request->tx_match_filter_len); - legacy_request->rssi_threshold_flag = - hidl_request.baseConfigs.useRssiThreshold; + legacy_request->rssi_threshold_flag = hidl_request.baseConfigs.useRssiThreshold; legacy_request->recv_indication_cfg = 0; legacy_request->recv_indication_cfg |= - hidl_request.baseConfigs.disableDiscoveryTerminationIndication ? 0x1 - : 0x0; + hidl_request.baseConfigs.disableDiscoveryTerminationIndication ? 0x1 : 0x0; legacy_request->recv_indication_cfg |= - hidl_request.baseConfigs.disableMatchExpirationIndication ? 0x2 : 0x0; + hidl_request.baseConfigs.disableMatchExpirationIndication ? 0x2 : 0x0; legacy_request->recv_indication_cfg |= - hidl_request.baseConfigs.disableFollowupReceivedIndication ? 0x4 : 0x0; - legacy_request->cipher_type = - (unsigned int)hidl_request.baseConfigs.securityConfig.cipherType; - if (hidl_request.baseConfigs.securityConfig.securityType == - NanDataPathSecurityType::PMK) { - legacy_request->key_info.key_type = - legacy_hal::NAN_SECURITY_KEY_INPUT_PMK; + hidl_request.baseConfigs.disableFollowupReceivedIndication ? 0x4 : 0x0; + legacy_request->cipher_type = (unsigned int)hidl_request.baseConfigs.securityConfig.cipherType; + if (hidl_request.baseConfigs.securityConfig.securityType == NanDataPathSecurityType::PMK) { + legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK; legacy_request->key_info.body.pmk_info.pmk_len = - hidl_request.baseConfigs.securityConfig.pmk.size(); - if (legacy_request->key_info.body.pmk_info.pmk_len != - NAN_PMK_INFO_LEN) { - LOG(ERROR) - << "convertHidlNanSubscribeRequestToLegacy: invalid pmk_len"; + hidl_request.baseConfigs.securityConfig.pmk.size(); + if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) { + LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: invalid pmk_len"; return false; } memcpy(legacy_request->key_info.body.pmk_info.pmk, @@ -1815,10 +1634,9 @@ bool convertHidlNanSubscribeRequestToLegacy( } if (hidl_request.baseConfigs.securityConfig.securityType == NanDataPathSecurityType::PASSPHRASE) { - legacy_request->key_info.key_type = - legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE; + legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE; legacy_request->key_info.body.passphrase_info.passphrase_len = - hidl_request.baseConfigs.securityConfig.passphrase.size(); + hidl_request.baseConfigs.securityConfig.passphrase.size(); if (legacy_request->key_info.body.passphrase_info.passphrase_len < NAN_SECURITY_MIN_PASSPHRASE_LEN) { LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: " @@ -1836,43 +1654,34 @@ bool convertHidlNanSubscribeRequestToLegacy( legacy_request->key_info.body.passphrase_info.passphrase_len); } legacy_request->sdea_params.security_cfg = - (hidl_request.baseConfigs.securityConfig.securityType != - NanDataPathSecurityType::OPEN) - ? legacy_hal::NAN_DP_CONFIG_SECURITY - : legacy_hal::NAN_DP_CONFIG_NO_SECURITY; - legacy_request->sdea_params.ranging_state = - hidl_request.baseConfigs.rangingRequired - ? legacy_hal::NAN_RANGING_ENABLE - : legacy_hal::NAN_RANGING_DISABLE; + (hidl_request.baseConfigs.securityConfig.securityType != NanDataPathSecurityType::OPEN) + ? legacy_hal::NAN_DP_CONFIG_SECURITY + : legacy_hal::NAN_DP_CONFIG_NO_SECURITY; + legacy_request->sdea_params.ranging_state = hidl_request.baseConfigs.rangingRequired + ? legacy_hal::NAN_RANGING_ENABLE + : legacy_hal::NAN_RANGING_DISABLE; legacy_request->ranging_cfg.ranging_interval_msec = - hidl_request.baseConfigs.rangingIntervalMsec; + hidl_request.baseConfigs.rangingIntervalMsec; legacy_request->ranging_cfg.config_ranging_indications = - hidl_request.baseConfigs.configRangingIndications; + hidl_request.baseConfigs.configRangingIndications; legacy_request->ranging_cfg.distance_ingress_mm = - hidl_request.baseConfigs.distanceIngressCm * 10; - legacy_request->ranging_cfg.distance_egress_mm = - hidl_request.baseConfigs.distanceEgressCm * 10; - legacy_request->ranging_auto_response = - hidl_request.baseConfigs.rangingRequired - ? legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE - : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE; - legacy_request->sdea_params.range_report = - legacy_hal::NAN_DISABLE_RANGE_REPORT; + hidl_request.baseConfigs.distanceIngressCm * 10; + legacy_request->ranging_cfg.distance_egress_mm = hidl_request.baseConfigs.distanceEgressCm * 10; + legacy_request->ranging_auto_response = hidl_request.baseConfigs.rangingRequired + ? legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE + : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE; + legacy_request->sdea_params.range_report = legacy_hal::NAN_DISABLE_RANGE_REPORT; legacy_request->subscribe_type = - convertHidlNanSubscribeTypeToLegacy(hidl_request.subscribeType); - legacy_request->serviceResponseFilter = - convertHidlNanSrfTypeToLegacy(hidl_request.srfType); - legacy_request->serviceResponseInclude = - hidl_request.srfRespondIfInAddressSet - ? legacy_hal::NAN_SRF_INCLUDE_RESPOND - : legacy_hal::NAN_SRF_INCLUDE_DO_NOT_RESPOND; + convertHidlNanSubscribeTypeToLegacy(hidl_request.subscribeType); + legacy_request->serviceResponseFilter = convertHidlNanSrfTypeToLegacy(hidl_request.srfType); + legacy_request->serviceResponseInclude = hidl_request.srfRespondIfInAddressSet + ? legacy_hal::NAN_SRF_INCLUDE_RESPOND + : legacy_hal::NAN_SRF_INCLUDE_DO_NOT_RESPOND; legacy_request->useServiceResponseFilter = - hidl_request.shouldUseSrf ? legacy_hal::NAN_USE_SRF - : legacy_hal::NAN_DO_NOT_USE_SRF; + hidl_request.shouldUseSrf ? legacy_hal::NAN_USE_SRF : legacy_hal::NAN_DO_NOT_USE_SRF; legacy_request->ssiRequiredForMatchIndication = - hidl_request.isSsiRequiredForMatch - ? legacy_hal::NAN_SSI_REQUIRED_IN_MATCH_IND - : legacy_hal::NAN_SSI_NOT_REQUIRED_IN_MATCH_IND; + hidl_request.isSsiRequiredForMatch ? legacy_hal::NAN_SSI_REQUIRED_IN_MATCH_IND + : legacy_hal::NAN_SSI_NOT_REQUIRED_IN_MATCH_IND; legacy_request->num_intf_addr_present = hidl_request.intfAddr.size(); if (legacy_request->num_intf_addr_present > NAN_MAX_SUBSCRIBE_MAX_ADDRESS) { LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: " @@ -1880,16 +1689,15 @@ bool convertHidlNanSubscribeRequestToLegacy( return false; } for (int i = 0; i < legacy_request->num_intf_addr_present; i++) { - memcpy(legacy_request->intf_addr[i], hidl_request.intfAddr[i].data(), - 6); + memcpy(legacy_request->intf_addr[i], hidl_request.intfAddr[i].data(), 6); } return true; } bool convertHidlNanTransmitFollowupRequestToLegacy( - const NanTransmitFollowupRequest& hidl_request, - legacy_hal::NanTransmitFollowupRequest* legacy_request) { + const NanTransmitFollowupRequest& hidl_request, + legacy_hal::NanTransmitFollowupRequest* legacy_request) { if (!legacy_request) { LOG(ERROR) << "convertHidlNanTransmitFollowupRequestToLegacy: " "legacy_request is null"; @@ -1900,27 +1708,22 @@ bool convertHidlNanTransmitFollowupRequestToLegacy( legacy_request->publish_subscribe_id = hidl_request.discoverySessionId; legacy_request->requestor_instance_id = hidl_request.peerId; memcpy(legacy_request->addr, hidl_request.addr.data(), 6); - legacy_request->priority = hidl_request.isHighPriority - ? legacy_hal::NAN_TX_PRIORITY_HIGH - : legacy_hal::NAN_TX_PRIORITY_NORMAL; + legacy_request->priority = hidl_request.isHighPriority ? legacy_hal::NAN_TX_PRIORITY_HIGH + : legacy_hal::NAN_TX_PRIORITY_NORMAL; legacy_request->dw_or_faw = hidl_request.shouldUseDiscoveryWindow - ? legacy_hal::NAN_TRANSMIT_IN_DW - : legacy_hal::NAN_TRANSMIT_IN_FAW; - legacy_request->service_specific_info_len = - hidl_request.serviceSpecificInfo.size(); - if (legacy_request->service_specific_info_len > - NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) { + ? legacy_hal::NAN_TRANSMIT_IN_DW + : legacy_hal::NAN_TRANSMIT_IN_FAW; + legacy_request->service_specific_info_len = hidl_request.serviceSpecificInfo.size(); + if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) { LOG(ERROR) << "convertHidlNanTransmitFollowupRequestToLegacy: " "service_specific_info_len too large"; return false; } - memcpy(legacy_request->service_specific_info, - hidl_request.serviceSpecificInfo.data(), + memcpy(legacy_request->service_specific_info, hidl_request.serviceSpecificInfo.data(), legacy_request->service_specific_info_len); legacy_request->sdea_service_specific_info_len = - hidl_request.extendedServiceSpecificInfo.size(); - if (legacy_request->sdea_service_specific_info_len > - NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) { + hidl_request.extendedServiceSpecificInfo.size(); + if (legacy_request->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) { LOG(ERROR) << "convertHidlNanTransmitFollowupRequestToLegacy: " "sdea_service_specific_info_len too large"; return false; @@ -1928,18 +1731,15 @@ bool convertHidlNanTransmitFollowupRequestToLegacy( memcpy(legacy_request->sdea_service_specific_info, hidl_request.extendedServiceSpecificInfo.data(), legacy_request->sdea_service_specific_info_len); - legacy_request->recv_indication_cfg = - hidl_request.disableFollowupResultIndication ? 0x1 : 0x0; + legacy_request->recv_indication_cfg = hidl_request.disableFollowupResultIndication ? 0x1 : 0x0; return true; } -bool convertHidlNanConfigRequestToLegacy( - const V1_4::NanConfigRequest& hidl_request, - legacy_hal::NanConfigRequest* legacy_request) { +bool convertHidlNanConfigRequestToLegacy(const V1_4::NanConfigRequest& hidl_request, + legacy_hal::NanConfigRequest* legacy_request) { if (!legacy_request) { - LOG(ERROR) - << "convertHidlNanConfigRequestToLegacy: legacy_request is null"; + LOG(ERROR) << "convertHidlNanConfigRequestToLegacy: legacy_request is null"; return false; } *legacy_request = {}; @@ -1949,20 +1749,19 @@ bool convertHidlNanConfigRequestToLegacy( legacy_request->master_pref = hidl_request.masterPref; legacy_request->discovery_indication_cfg = 0; legacy_request->discovery_indication_cfg |= - hidl_request.disableDiscoveryAddressChangeIndication ? 0x1 : 0x0; + hidl_request.disableDiscoveryAddressChangeIndication ? 0x1 : 0x0; legacy_request->discovery_indication_cfg |= - hidl_request.disableStartedClusterIndication ? 0x2 : 0x0; + hidl_request.disableStartedClusterIndication ? 0x2 : 0x0; legacy_request->discovery_indication_cfg |= - hidl_request.disableJoinedClusterIndication ? 0x4 : 0x0; + hidl_request.disableJoinedClusterIndication ? 0x4 : 0x0; legacy_request->config_sid_beacon = 1; if (hidl_request.numberOfPublishServiceIdsInBeacon > 127) { LOG(ERROR) << "convertHidlNanConfigRequestToLegacy: " "numberOfPublishServiceIdsInBeacon > 127"; return false; } - legacy_request->sid_beacon = - (hidl_request.includePublishServiceIdsInBeacon ? 0x1 : 0x0) | - (hidl_request.numberOfPublishServiceIdsInBeacon << 1); + legacy_request->sid_beacon = (hidl_request.includePublishServiceIdsInBeacon ? 0x1 : 0x0) | + (hidl_request.numberOfPublishServiceIdsInBeacon << 1); legacy_request->config_subscribe_sid_beacon = 1; if (hidl_request.numberOfSubscribeServiceIdsInBeacon > 127) { LOG(ERROR) << "convertHidlNanConfigRequestToLegacy: " @@ -1970,13 +1769,13 @@ bool convertHidlNanConfigRequestToLegacy( return false; } legacy_request->subscribe_sid_beacon_val = - (hidl_request.includeSubscribeServiceIdsInBeacon ? 0x1 : 0x0) | - (hidl_request.numberOfSubscribeServiceIdsInBeacon << 1); + (hidl_request.includeSubscribeServiceIdsInBeacon ? 0x1 : 0x0) | + (hidl_request.numberOfSubscribeServiceIdsInBeacon << 1); legacy_request->config_rssi_window_size = 1; legacy_request->rssi_window_size_val = hidl_request.rssiWindowSize; legacy_request->config_disc_mac_addr_randomization = 1; legacy_request->disc_mac_addr_rand_interval_sec = - hidl_request.macAddressRandomizationIntervalSec; + hidl_request.macAddressRandomizationIntervalSec; /* TODO : missing legacy_request->config_2dot4g_rssi_close = 1; legacy_request->rssi_close_2dot4g_val = @@ -1992,20 +1791,16 @@ bool convertHidlNanConfigRequestToLegacy( (size_t) NanBandIndex::NAN_BAND_24GHZ].rssiCloseProximity; */ legacy_request->config_scan_params = 1; - legacy_request->scan_params_val - .dwell_time[legacy_hal::NAN_CHANNEL_24G_BAND] = - hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] - .dwellTimeMs; - legacy_request->scan_params_val - .scan_period[legacy_hal::NAN_CHANNEL_24G_BAND] = - hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] - .scanPeriodSec; + legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_24G_BAND] = + hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ].dwellTimeMs; + legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_24G_BAND] = + hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ].scanPeriodSec; legacy_request->config_dw.config_2dot4g_dw_band = - hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] - .validDiscoveryWindowIntervalVal; + hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] + .validDiscoveryWindowIntervalVal; legacy_request->config_dw.dw_2dot4g_interval_val = - hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] - .discoveryWindowIntervalVal; + hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] + .discoveryWindowIntervalVal; /* TODO: missing legacy_request->config_5g_rssi_close = 1; legacy_request->rssi_close_5g_val = @@ -2018,30 +1813,21 @@ bool convertHidlNanConfigRequestToLegacy( */ legacy_request->config_5g_rssi_close_proximity = 1; legacy_request->rssi_close_proximity_5g_val = - hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .rssiCloseProximity; - legacy_request->scan_params_val - .dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] = - hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .dwellTimeMs; - legacy_request->scan_params_val - .scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] = - hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .scanPeriodSec; - legacy_request->scan_params_val - .dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] = - hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .dwellTimeMs; - legacy_request->scan_params_val - .scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] = - hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .scanPeriodSec; + hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].rssiCloseProximity; + legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] = + hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].dwellTimeMs; + legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] = + hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].scanPeriodSec; + legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] = + hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].dwellTimeMs; + legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] = + hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].scanPeriodSec; legacy_request->config_dw.config_5g_dw_band = - hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .validDiscoveryWindowIntervalVal; + hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] + .validDiscoveryWindowIntervalVal; legacy_request->config_dw.dw_5g_interval_val = - hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .discoveryWindowIntervalVal; + hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] + .discoveryWindowIntervalVal; /* TODO: b/145609058 * Missing updates needed to legacy_hal::NanConfigRequest and conversion to * it for 6GHz band */ @@ -2049,10 +1835,9 @@ bool convertHidlNanConfigRequestToLegacy( return true; } -bool convertHidlNanConfigRequest_1_4ToLegacy( - const V1_4::NanConfigRequest& hidl_request1, - const NanConfigRequestSupplemental& hidl_request2, - legacy_hal::NanConfigRequest* legacy_request) { +bool convertHidlNanConfigRequest_1_4ToLegacy(const V1_4::NanConfigRequest& hidl_request1, + const NanConfigRequestSupplemental& hidl_request2, + legacy_hal::NanConfigRequest* legacy_request) { if (!legacy_request) { LOG(ERROR) << "convertHidlNanConfigRequest_1_4ToLegacy: legacy_request " "is null"; @@ -2065,13 +1850,12 @@ bool convertHidlNanConfigRequest_1_4ToLegacy( } legacy_request->config_discovery_beacon_int = 1; - legacy_request->discovery_beacon_interval = - hidl_request2.V1_2.discoveryBeaconIntervalMs; + legacy_request->discovery_beacon_interval = hidl_request2.V1_2.discoveryBeaconIntervalMs; legacy_request->config_nss = 1; legacy_request->nss = hidl_request2.V1_2.numberOfSpatialStreamsInDiscovery; legacy_request->config_dw_early_termination = 1; legacy_request->enable_dw_termination = - hidl_request2.V1_2.enableDiscoveryWindowEarlyTermination; + hidl_request2.V1_2.enableDiscoveryWindowEarlyTermination; legacy_request->config_enable_ranging = 1; legacy_request->enable_ranging = hidl_request2.V1_2.enableRanging; @@ -2079,8 +1863,8 @@ bool convertHidlNanConfigRequest_1_4ToLegacy( } bool convertHidlNanDataPathInitiatorRequestToLegacy( - const NanInitiateDataPathRequest& hidl_request, - legacy_hal::NanDataPathInitiatorRequest* legacy_request) { + const NanInitiateDataPathRequest& hidl_request, + legacy_hal::NanDataPathInitiatorRequest* legacy_request) { if (!legacy_request) { LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: " "legacy_request is null"; @@ -2089,24 +1873,20 @@ bool convertHidlNanDataPathInitiatorRequestToLegacy( *legacy_request = {}; legacy_request->requestor_instance_id = hidl_request.peerId; - memcpy(legacy_request->peer_disc_mac_addr, - hidl_request.peerDiscMacAddr.data(), 6); + memcpy(legacy_request->peer_disc_mac_addr, hidl_request.peerDiscMacAddr.data(), 6); legacy_request->channel_request_type = - convertHidlNanDataPathChannelCfgToLegacy( - hidl_request.channelRequestType); + convertHidlNanDataPathChannelCfgToLegacy(hidl_request.channelRequestType); legacy_request->channel = hidl_request.channel; if (strnlen(hidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) { LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: " "ifaceName too long"; return false; } - strncpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(), - IFNAMSIZ + 1); + strncpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(), IFNAMSIZ + 1); legacy_request->ndp_cfg.security_cfg = - (hidl_request.securityConfig.securityType != - NanDataPathSecurityType::OPEN) - ? legacy_hal::NAN_DP_CONFIG_SECURITY - : legacy_hal::NAN_DP_CONFIG_NO_SECURITY; + (hidl_request.securityConfig.securityType != NanDataPathSecurityType::OPEN) + ? legacy_hal::NAN_DP_CONFIG_SECURITY + : legacy_hal::NAN_DP_CONFIG_NO_SECURITY; legacy_request->app_info.ndp_app_info_len = hidl_request.appInfo.size(); if (legacy_request->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) { LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: " @@ -2115,30 +1895,22 @@ bool convertHidlNanDataPathInitiatorRequestToLegacy( } memcpy(legacy_request->app_info.ndp_app_info, hidl_request.appInfo.data(), legacy_request->app_info.ndp_app_info_len); - legacy_request->cipher_type = - (unsigned int)hidl_request.securityConfig.cipherType; - if (hidl_request.securityConfig.securityType == - NanDataPathSecurityType::PMK) { - legacy_request->key_info.key_type = - legacy_hal::NAN_SECURITY_KEY_INPUT_PMK; - legacy_request->key_info.body.pmk_info.pmk_len = - hidl_request.securityConfig.pmk.size(); - if (legacy_request->key_info.body.pmk_info.pmk_len != - NAN_PMK_INFO_LEN) { + legacy_request->cipher_type = (unsigned int)hidl_request.securityConfig.cipherType; + if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PMK) { + legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK; + legacy_request->key_info.body.pmk_info.pmk_len = hidl_request.securityConfig.pmk.size(); + if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) { LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: " "invalid pmk_len"; return false; } - memcpy(legacy_request->key_info.body.pmk_info.pmk, - hidl_request.securityConfig.pmk.data(), + memcpy(legacy_request->key_info.body.pmk_info.pmk, hidl_request.securityConfig.pmk.data(), legacy_request->key_info.body.pmk_info.pmk_len); } - if (hidl_request.securityConfig.securityType == - NanDataPathSecurityType::PASSPHRASE) { - legacy_request->key_info.key_type = - legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE; + if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PASSPHRASE) { + legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE; legacy_request->key_info.body.passphrase_info.passphrase_len = - hidl_request.securityConfig.passphrase.size(); + hidl_request.securityConfig.passphrase.size(); if (legacy_request->key_info.body.passphrase_info.passphrase_len < NAN_SECURITY_MIN_PASSPHRASE_LEN) { LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: " @@ -2161,16 +1933,15 @@ bool convertHidlNanDataPathInitiatorRequestToLegacy( "service_name_len too large"; return false; } - memcpy(legacy_request->service_name, - hidl_request.serviceNameOutOfBand.data(), + memcpy(legacy_request->service_name, hidl_request.serviceNameOutOfBand.data(), legacy_request->service_name_len); return true; } bool convertHidlNanDataPathIndicationResponseToLegacy( - const NanRespondToDataPathIndicationRequest& hidl_request, - legacy_hal::NanDataPathIndicationResponse* legacy_request) { + const NanRespondToDataPathIndicationRequest& hidl_request, + legacy_hal::NanDataPathIndicationResponse* legacy_request) { if (!legacy_request) { LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: " "legacy_request is null"; @@ -2178,22 +1949,19 @@ bool convertHidlNanDataPathIndicationResponseToLegacy( } *legacy_request = {}; - legacy_request->rsp_code = hidl_request.acceptRequest - ? legacy_hal::NAN_DP_REQUEST_ACCEPT - : legacy_hal::NAN_DP_REQUEST_REJECT; + legacy_request->rsp_code = hidl_request.acceptRequest ? legacy_hal::NAN_DP_REQUEST_ACCEPT + : legacy_hal::NAN_DP_REQUEST_REJECT; legacy_request->ndp_instance_id = hidl_request.ndpInstanceId; if (strnlen(hidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) { LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: " "ifaceName too long"; return false; } - strncpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(), - IFNAMSIZ + 1); + strncpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(), IFNAMSIZ + 1); legacy_request->ndp_cfg.security_cfg = - (hidl_request.securityConfig.securityType != - NanDataPathSecurityType::OPEN) - ? legacy_hal::NAN_DP_CONFIG_SECURITY - : legacy_hal::NAN_DP_CONFIG_NO_SECURITY; + (hidl_request.securityConfig.securityType != NanDataPathSecurityType::OPEN) + ? legacy_hal::NAN_DP_CONFIG_SECURITY + : legacy_hal::NAN_DP_CONFIG_NO_SECURITY; legacy_request->app_info.ndp_app_info_len = hidl_request.appInfo.size(); if (legacy_request->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) { LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: " @@ -2202,30 +1970,22 @@ bool convertHidlNanDataPathIndicationResponseToLegacy( } memcpy(legacy_request->app_info.ndp_app_info, hidl_request.appInfo.data(), legacy_request->app_info.ndp_app_info_len); - legacy_request->cipher_type = - (unsigned int)hidl_request.securityConfig.cipherType; - if (hidl_request.securityConfig.securityType == - NanDataPathSecurityType::PMK) { - legacy_request->key_info.key_type = - legacy_hal::NAN_SECURITY_KEY_INPUT_PMK; - legacy_request->key_info.body.pmk_info.pmk_len = - hidl_request.securityConfig.pmk.size(); - if (legacy_request->key_info.body.pmk_info.pmk_len != - NAN_PMK_INFO_LEN) { + legacy_request->cipher_type = (unsigned int)hidl_request.securityConfig.cipherType; + if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PMK) { + legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK; + legacy_request->key_info.body.pmk_info.pmk_len = hidl_request.securityConfig.pmk.size(); + if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) { LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: " "invalid pmk_len"; return false; } - memcpy(legacy_request->key_info.body.pmk_info.pmk, - hidl_request.securityConfig.pmk.data(), + memcpy(legacy_request->key_info.body.pmk_info.pmk, hidl_request.securityConfig.pmk.data(), legacy_request->key_info.body.pmk_info.pmk_len); } - if (hidl_request.securityConfig.securityType == - NanDataPathSecurityType::PASSPHRASE) { - legacy_request->key_info.key_type = - legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE; + if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PASSPHRASE) { + legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE; legacy_request->key_info.body.passphrase_info.passphrase_len = - hidl_request.securityConfig.passphrase.size(); + hidl_request.securityConfig.passphrase.size(); if (legacy_request->key_info.body.passphrase_info.passphrase_len < NAN_SECURITY_MIN_PASSPHRASE_LEN) { LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: " @@ -2248,19 +2008,16 @@ bool convertHidlNanDataPathIndicationResponseToLegacy( "service_name_len too large"; return false; } - memcpy(legacy_request->service_name, - hidl_request.serviceNameOutOfBand.data(), + memcpy(legacy_request->service_name, hidl_request.serviceNameOutOfBand.data(), legacy_request->service_name_len); return true; } -bool convertLegacyNanResponseHeaderToHidl( - const legacy_hal::NanResponseMsg& legacy_response, - WifiNanStatus* wifiNanStatus) { +bool convertLegacyNanResponseHeaderToHidl(const legacy_hal::NanResponseMsg& legacy_response, + WifiNanStatus* wifiNanStatus) { if (!wifiNanStatus) { - LOG(ERROR) - << "convertLegacyNanResponseHeaderToHidl: wifiNanStatus is null"; + LOG(ERROR) << "convertLegacyNanResponseHeaderToHidl: wifiNanStatus is null"; return false; } *wifiNanStatus = {}; @@ -2270,9 +2027,8 @@ bool convertLegacyNanResponseHeaderToHidl( return true; } -bool convertLegacyNanCapabilitiesResponseToHidl( - const legacy_hal::NanCapabilities& legacy_response, - NanCapabilities* hidl_response) { +bool convertLegacyNanCapabilitiesResponseToHidl(const legacy_hal::NanCapabilities& legacy_response, + V1_5::NanCapabilities* hidl_response) { if (!hidl_response) { LOG(ERROR) << "convertLegacyNanCapabilitiesResponseToHidl: " "hidl_response is null"; @@ -2280,31 +2036,23 @@ bool convertLegacyNanCapabilitiesResponseToHidl( } *hidl_response = {}; - hidl_response->V1_0.maxConcurrentClusters = - legacy_response.max_concurrent_nan_clusters; + hidl_response->V1_0.maxConcurrentClusters = legacy_response.max_concurrent_nan_clusters; hidl_response->V1_0.maxPublishes = legacy_response.max_publishes; hidl_response->V1_0.maxSubscribes = legacy_response.max_subscribes; - hidl_response->V1_0.maxServiceNameLen = - legacy_response.max_service_name_len; - hidl_response->V1_0.maxMatchFilterLen = - legacy_response.max_match_filter_len; - hidl_response->V1_0.maxTotalMatchFilterLen = - legacy_response.max_total_match_filter_len; - hidl_response->V1_0.maxServiceSpecificInfoLen = - legacy_response.max_service_specific_info_len; + hidl_response->V1_0.maxServiceNameLen = legacy_response.max_service_name_len; + hidl_response->V1_0.maxMatchFilterLen = legacy_response.max_match_filter_len; + hidl_response->V1_0.maxTotalMatchFilterLen = legacy_response.max_total_match_filter_len; + hidl_response->V1_0.maxServiceSpecificInfoLen = legacy_response.max_service_specific_info_len; hidl_response->V1_0.maxExtendedServiceSpecificInfoLen = - legacy_response.max_sdea_service_specific_info_len; + legacy_response.max_sdea_service_specific_info_len; hidl_response->V1_0.maxNdiInterfaces = legacy_response.max_ndi_interfaces; hidl_response->V1_0.maxNdpSessions = legacy_response.max_ndp_sessions; hidl_response->V1_0.maxAppInfoLen = legacy_response.max_app_info_len; hidl_response->V1_0.maxQueuedTransmitFollowupMsgs = - legacy_response.max_queued_transmit_followup_msgs; - hidl_response->V1_0.maxSubscribeInterfaceAddresses = - legacy_response.max_subscribe_address; - hidl_response->V1_0.supportedCipherSuites = - legacy_response.cipher_suites_supported; - hidl_response->instantCommunicationModeSupportFlag = - legacy_response.is_instant_mode_supported; + legacy_response.max_queued_transmit_followup_msgs; + hidl_response->V1_0.maxSubscribeInterfaceAddresses = legacy_response.max_subscribe_address; + hidl_response->V1_0.supportedCipherSuites = legacy_response.cipher_suites_supported; + hidl_response->instantCommunicationModeSupportFlag = legacy_response.is_instant_mode_supported; return true; } @@ -2320,36 +2068,31 @@ bool convertLegacyNanMatchIndToHidl(const legacy_hal::NanMatchInd& legacy_ind, hidl_ind->discoverySessionId = legacy_ind.publish_subscribe_id; hidl_ind->peerId = legacy_ind.requestor_instance_id; hidl_ind->addr = hidl_array<uint8_t, 6>(legacy_ind.addr); - hidl_ind->serviceSpecificInfo = - std::vector<uint8_t>(legacy_ind.service_specific_info, - legacy_ind.service_specific_info + - legacy_ind.service_specific_info_len); - hidl_ind->extendedServiceSpecificInfo = - std::vector<uint8_t>(legacy_ind.sdea_service_specific_info, - legacy_ind.sdea_service_specific_info + - legacy_ind.sdea_service_specific_info_len); - hidl_ind->matchFilter = std::vector<uint8_t>( - legacy_ind.sdf_match_filter, - legacy_ind.sdf_match_filter + legacy_ind.sdf_match_filter_len); + hidl_ind->serviceSpecificInfo = std::vector<uint8_t>( + legacy_ind.service_specific_info, + legacy_ind.service_specific_info + legacy_ind.service_specific_info_len); + hidl_ind->extendedServiceSpecificInfo = std::vector<uint8_t>( + legacy_ind.sdea_service_specific_info, + legacy_ind.sdea_service_specific_info + legacy_ind.sdea_service_specific_info_len); + hidl_ind->matchFilter = + std::vector<uint8_t>(legacy_ind.sdf_match_filter, + legacy_ind.sdf_match_filter + legacy_ind.sdf_match_filter_len); hidl_ind->matchOccuredInBeaconFlag = legacy_ind.match_occured_flag == 1; hidl_ind->outOfResourceFlag = legacy_ind.out_of_resource_flag == 1; hidl_ind->rssiValue = legacy_ind.rssi_value; hidl_ind->peerCipherType = (NanCipherSuiteType)legacy_ind.peer_cipher_type; hidl_ind->peerRequiresSecurityEnabledInNdp = - legacy_ind.peer_sdea_params.security_cfg == - legacy_hal::NAN_DP_CONFIG_SECURITY; - hidl_ind->peerRequiresRanging = legacy_ind.peer_sdea_params.ranging_state == - legacy_hal::NAN_RANGING_ENABLE; - hidl_ind->rangingMeasurementInCm = - legacy_ind.range_info.range_measurement_mm / 10; + legacy_ind.peer_sdea_params.security_cfg == legacy_hal::NAN_DP_CONFIG_SECURITY; + hidl_ind->peerRequiresRanging = + legacy_ind.peer_sdea_params.ranging_state == legacy_hal::NAN_RANGING_ENABLE; + hidl_ind->rangingMeasurementInCm = legacy_ind.range_info.range_measurement_mm / 10; hidl_ind->rangingIndicationType = legacy_ind.range_info.ranging_event_type; return true; } -bool convertLegacyNanFollowupIndToHidl( - const legacy_hal::NanFollowupInd& legacy_ind, - NanFollowupReceivedInd* hidl_ind) { +bool convertLegacyNanFollowupIndToHidl(const legacy_hal::NanFollowupInd& legacy_ind, + NanFollowupReceivedInd* hidl_ind) { if (!hidl_ind) { LOG(ERROR) << "convertLegacyNanFollowupIndToHidl: hidl_ind is null"; return false; @@ -2360,45 +2103,38 @@ bool convertLegacyNanFollowupIndToHidl( hidl_ind->peerId = legacy_ind.requestor_instance_id; hidl_ind->addr = hidl_array<uint8_t, 6>(legacy_ind.addr); hidl_ind->receivedInFaw = legacy_ind.dw_or_faw == 1; - hidl_ind->serviceSpecificInfo = - std::vector<uint8_t>(legacy_ind.service_specific_info, - legacy_ind.service_specific_info + - legacy_ind.service_specific_info_len); - hidl_ind->extendedServiceSpecificInfo = - std::vector<uint8_t>(legacy_ind.sdea_service_specific_info, - legacy_ind.sdea_service_specific_info + - legacy_ind.sdea_service_specific_info_len); + hidl_ind->serviceSpecificInfo = std::vector<uint8_t>( + legacy_ind.service_specific_info, + legacy_ind.service_specific_info + legacy_ind.service_specific_info_len); + hidl_ind->extendedServiceSpecificInfo = std::vector<uint8_t>( + legacy_ind.sdea_service_specific_info, + legacy_ind.sdea_service_specific_info + legacy_ind.sdea_service_specific_info_len); return true; } -bool convertLegacyNanDataPathRequestIndToHidl( - const legacy_hal::NanDataPathRequestInd& legacy_ind, - NanDataPathRequestInd* hidl_ind) { +bool convertLegacyNanDataPathRequestIndToHidl(const legacy_hal::NanDataPathRequestInd& legacy_ind, + NanDataPathRequestInd* hidl_ind) { if (!hidl_ind) { - LOG(ERROR) - << "convertLegacyNanDataPathRequestIndToHidl: hidl_ind is null"; + LOG(ERROR) << "convertLegacyNanDataPathRequestIndToHidl: hidl_ind is null"; return false; } *hidl_ind = {}; hidl_ind->discoverySessionId = legacy_ind.service_instance_id; - hidl_ind->peerDiscMacAddr = - hidl_array<uint8_t, 6>(legacy_ind.peer_disc_mac_addr); + hidl_ind->peerDiscMacAddr = hidl_array<uint8_t, 6>(legacy_ind.peer_disc_mac_addr); hidl_ind->ndpInstanceId = legacy_ind.ndp_instance_id; hidl_ind->securityRequired = - legacy_ind.ndp_cfg.security_cfg == legacy_hal::NAN_DP_CONFIG_SECURITY; - hidl_ind->appInfo = - std::vector<uint8_t>(legacy_ind.app_info.ndp_app_info, - legacy_ind.app_info.ndp_app_info + - legacy_ind.app_info.ndp_app_info_len); + legacy_ind.ndp_cfg.security_cfg == legacy_hal::NAN_DP_CONFIG_SECURITY; + hidl_ind->appInfo = std::vector<uint8_t>( + legacy_ind.app_info.ndp_app_info, + legacy_ind.app_info.ndp_app_info + legacy_ind.app_info.ndp_app_info_len); return true; } -bool convertLegacyNdpChannelInfoToHidl( - const legacy_hal::NanChannelInfo& legacy_struct, - V1_2::NanDataPathChannelInfo* hidl_struct) { +bool convertLegacyNdpChannelInfoToHidl(const legacy_hal::NanChannelInfo& legacy_struct, + V1_2::NanDataPathChannelInfo* hidl_struct) { if (!hidl_struct) { LOG(ERROR) << "convertLegacyNdpChannelInfoToHidl: hidl_struct is null"; return false; @@ -2407,40 +2143,33 @@ bool convertLegacyNdpChannelInfoToHidl( hidl_struct->channelFreq = legacy_struct.channel; hidl_struct->channelBandwidth = convertLegacyWifiChannelWidthToHidl( - (legacy_hal::wifi_channel_width)legacy_struct.bandwidth); + (legacy_hal::wifi_channel_width)legacy_struct.bandwidth); hidl_struct->numSpatialStreams = legacy_struct.nss; return true; } -bool convertLegacyNanDataPathConfirmIndToHidl( - const legacy_hal::NanDataPathConfirmInd& legacy_ind, - V1_2::NanDataPathConfirmInd* hidl_ind) { +bool convertLegacyNanDataPathConfirmIndToHidl(const legacy_hal::NanDataPathConfirmInd& legacy_ind, + V1_2::NanDataPathConfirmInd* hidl_ind) { if (!hidl_ind) { - LOG(ERROR) - << "convertLegacyNanDataPathConfirmIndToHidl: hidl_ind is null"; + LOG(ERROR) << "convertLegacyNanDataPathConfirmIndToHidl: hidl_ind is null"; return false; } *hidl_ind = {}; hidl_ind->V1_0.ndpInstanceId = legacy_ind.ndp_instance_id; - hidl_ind->V1_0.dataPathSetupSuccess = - legacy_ind.rsp_code == legacy_hal::NAN_DP_REQUEST_ACCEPT; - hidl_ind->V1_0.peerNdiMacAddr = - hidl_array<uint8_t, 6>(legacy_ind.peer_ndi_mac_addr); - hidl_ind->V1_0.appInfo = - std::vector<uint8_t>(legacy_ind.app_info.ndp_app_info, - legacy_ind.app_info.ndp_app_info + - legacy_ind.app_info.ndp_app_info_len); - hidl_ind->V1_0.status.status = - convertLegacyNanStatusTypeToHidl(legacy_ind.reason_code); + hidl_ind->V1_0.dataPathSetupSuccess = legacy_ind.rsp_code == legacy_hal::NAN_DP_REQUEST_ACCEPT; + hidl_ind->V1_0.peerNdiMacAddr = hidl_array<uint8_t, 6>(legacy_ind.peer_ndi_mac_addr); + hidl_ind->V1_0.appInfo = std::vector<uint8_t>( + legacy_ind.app_info.ndp_app_info, + legacy_ind.app_info.ndp_app_info + legacy_ind.app_info.ndp_app_info_len); + hidl_ind->V1_0.status.status = convertLegacyNanStatusTypeToHidl(legacy_ind.reason_code); hidl_ind->V1_0.status.description = ""; // TODO: b/34059183 std::vector<V1_2::NanDataPathChannelInfo> channelInfo; for (unsigned int i = 0; i < legacy_ind.num_channels; ++i) { V1_2::NanDataPathChannelInfo hidl_struct; - if (!convertLegacyNdpChannelInfoToHidl(legacy_ind.channel_info[i], - &hidl_struct)) { + if (!convertLegacyNdpChannelInfoToHidl(legacy_ind.channel_info[i], &hidl_struct)) { return false; } channelInfo.push_back(hidl_struct); @@ -2451,8 +2180,8 @@ bool convertLegacyNanDataPathConfirmIndToHidl( } bool convertLegacyNanDataPathScheduleUpdateIndToHidl( - const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind, - V1_2::NanDataPathScheduleUpdateInd* hidl_ind) { + const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind, + V1_2::NanDataPathScheduleUpdateInd* hidl_ind) { if (!hidl_ind) { LOG(ERROR) << "convertLegacyNanDataPathScheduleUpdateIndToHidl: " "hidl_ind is null"; @@ -2460,13 +2189,11 @@ bool convertLegacyNanDataPathScheduleUpdateIndToHidl( } *hidl_ind = {}; - hidl_ind->peerDiscoveryAddress = - hidl_array<uint8_t, 6>(legacy_ind.peer_mac_addr); + hidl_ind->peerDiscoveryAddress = hidl_array<uint8_t, 6>(legacy_ind.peer_mac_addr); std::vector<V1_2::NanDataPathChannelInfo> channelInfo; for (unsigned int i = 0; i < legacy_ind.num_channels; ++i) { V1_2::NanDataPathChannelInfo hidl_struct; - if (!convertLegacyNdpChannelInfoToHidl(legacy_ind.channel_info[i], - &hidl_struct)) { + if (!convertLegacyNdpChannelInfoToHidl(legacy_ind.channel_info[i], &hidl_struct)) { return false; } channelInfo.push_back(hidl_struct); @@ -2517,8 +2244,7 @@ legacy_hal::rtt_peer_type convertHidlRttPeerTypeToLegacy(RttPeerType type) { CHECK(false); } -legacy_hal::wifi_channel_width convertHidlWifiChannelWidthToLegacy( - WifiChannelWidthInMhz type) { +legacy_hal::wifi_channel_width convertHidlWifiChannelWidthToLegacy(WifiChannelWidthInMhz type) { switch (type) { case WifiChannelWidthInMhz::WIDTH_20: return legacy_hal::WIFI_CHAN_WIDTH_20; @@ -2540,8 +2266,7 @@ legacy_hal::wifi_channel_width convertHidlWifiChannelWidthToLegacy( CHECK(false); } -WifiChannelWidthInMhz convertLegacyWifiChannelWidthToHidl( - legacy_hal::wifi_channel_width type) { +WifiChannelWidthInMhz convertLegacyWifiChannelWidthToHidl(legacy_hal::wifi_channel_width type) { switch (type) { case legacy_hal::WIFI_CHAN_WIDTH_20: return WifiChannelWidthInMhz::WIDTH_20; @@ -2562,8 +2287,7 @@ WifiChannelWidthInMhz convertLegacyWifiChannelWidthToHidl( }; } -legacy_hal::wifi_rtt_preamble convertHidlRttPreambleToLegacy( - V1_4::RttPreamble type) { +legacy_hal::wifi_rtt_preamble convertHidlRttPreambleToLegacy(V1_4::RttPreamble type) { switch (type) { case V1_4::RttPreamble::LEGACY: return legacy_hal::WIFI_RTT_PREAMBLE_LEGACY; @@ -2577,8 +2301,7 @@ legacy_hal::wifi_rtt_preamble convertHidlRttPreambleToLegacy( CHECK(false); } -V1_4::RttPreamble convertLegacyRttPreambleToHidl( - legacy_hal::wifi_rtt_preamble type) { +V1_4::RttPreamble convertLegacyRttPreambleToHidl(legacy_hal::wifi_rtt_preamble type) { switch (type) { case legacy_hal::WIFI_RTT_PREAMBLE_LEGACY: return V1_4::RttPreamble::LEGACY; @@ -2628,8 +2351,7 @@ RttBw convertLegacyRttBwToHidl(legacy_hal::wifi_rtt_bw type) { CHECK(false) << "Unknown legacy type: " << type; } -legacy_hal::wifi_motion_pattern convertHidlRttMotionPatternToLegacy( - RttMotionPattern type) { +legacy_hal::wifi_motion_pattern convertHidlRttMotionPatternToLegacy(RttMotionPattern type) { switch (type) { case RttMotionPattern::NOT_EXPECTED: return legacy_hal::WIFI_MOTION_NOT_EXPECTED; @@ -2716,9 +2438,8 @@ RttStatus convertLegacyRttStatusToHidl(legacy_hal::wifi_rtt_status status) { CHECK(false) << "Unknown legacy status: " << status; } -bool convertHidlWifiChannelInfoToLegacy( - const WifiChannelInfo& hidl_info, - legacy_hal::wifi_channel_info* legacy_info) { +bool convertHidlWifiChannelInfoToLegacy(const WifiChannelInfo& hidl_info, + legacy_hal::wifi_channel_info* legacy_info) { if (!legacy_info) { return false; } @@ -2730,9 +2451,8 @@ bool convertHidlWifiChannelInfoToLegacy( return true; } -bool convertLegacyWifiChannelInfoToHidl( - const legacy_hal::wifi_channel_info& legacy_info, - WifiChannelInfo* hidl_info) { +bool convertLegacyWifiChannelInfoToHidl(const legacy_hal::wifi_channel_info& legacy_info, + WifiChannelInfo* hidl_info) { if (!hidl_info) { return false; } @@ -2751,32 +2471,28 @@ bool convertHidlRttConfigToLegacy(const V1_4::RttConfig& hidl_config, } *legacy_config = {}; CHECK(hidl_config.addr.size() == sizeof(legacy_config->addr)); - memcpy(legacy_config->addr, hidl_config.addr.data(), - hidl_config.addr.size()); + memcpy(legacy_config->addr, hidl_config.addr.data(), hidl_config.addr.size()); legacy_config->type = convertHidlRttTypeToLegacy(hidl_config.type); legacy_config->peer = convertHidlRttPeerTypeToLegacy(hidl_config.peer); - if (!convertHidlWifiChannelInfoToLegacy(hidl_config.channel, - &legacy_config->channel)) { + if (!convertHidlWifiChannelInfoToLegacy(hidl_config.channel, &legacy_config->channel)) { return false; } legacy_config->burst_period = hidl_config.burstPeriod; legacy_config->num_burst = hidl_config.numBurst; legacy_config->num_frames_per_burst = hidl_config.numFramesPerBurst; - legacy_config->num_retries_per_rtt_frame = - hidl_config.numRetriesPerRttFrame; + legacy_config->num_retries_per_rtt_frame = hidl_config.numRetriesPerRttFrame; legacy_config->num_retries_per_ftmr = hidl_config.numRetriesPerFtmr; legacy_config->LCI_request = hidl_config.mustRequestLci; legacy_config->LCR_request = hidl_config.mustRequestLcr; legacy_config->burst_duration = hidl_config.burstDuration; - legacy_config->preamble = - convertHidlRttPreambleToLegacy(hidl_config.preamble); + legacy_config->preamble = convertHidlRttPreambleToLegacy(hidl_config.preamble); legacy_config->bw = convertHidlRttBwToLegacy(hidl_config.bw); return true; } bool convertHidlVectorOfRttConfigToLegacy( - const std::vector<V1_4::RttConfig>& hidl_configs, - std::vector<legacy_hal::wifi_rtt_config>* legacy_configs) { + const std::vector<V1_4::RttConfig>& hidl_configs, + std::vector<legacy_hal::wifi_rtt_config>* legacy_configs) { if (!legacy_configs) { return false; } @@ -2791,9 +2507,8 @@ bool convertHidlVectorOfRttConfigToLegacy( return true; } -bool convertHidlRttLciInformationToLegacy( - const RttLciInformation& hidl_info, - legacy_hal::wifi_lci_information* legacy_info) { +bool convertHidlRttLciInformationToLegacy(const RttLciInformation& hidl_info, + legacy_hal::wifi_lci_information* legacy_info) { if (!legacy_info) { return false; } @@ -2804,99 +2519,83 @@ bool convertHidlRttLciInformationToLegacy( legacy_info->latitude_unc = hidl_info.latitudeUnc; legacy_info->longitude_unc = hidl_info.longitudeUnc; legacy_info->altitude_unc = hidl_info.altitudeUnc; - legacy_info->motion_pattern = - convertHidlRttMotionPatternToLegacy(hidl_info.motionPattern); + legacy_info->motion_pattern = convertHidlRttMotionPatternToLegacy(hidl_info.motionPattern); legacy_info->floor = hidl_info.floor; legacy_info->height_above_floor = hidl_info.heightAboveFloor; legacy_info->height_unc = hidl_info.heightUnc; return true; } -bool convertHidlRttLcrInformationToLegacy( - const RttLcrInformation& hidl_info, - legacy_hal::wifi_lcr_information* legacy_info) { +bool convertHidlRttLcrInformationToLegacy(const RttLcrInformation& hidl_info, + legacy_hal::wifi_lcr_information* legacy_info) { if (!legacy_info) { return false; } *legacy_info = {}; CHECK(hidl_info.countryCode.size() == sizeof(legacy_info->country_code)); - memcpy(legacy_info->country_code, hidl_info.countryCode.data(), - hidl_info.countryCode.size()); + memcpy(legacy_info->country_code, hidl_info.countryCode.data(), hidl_info.countryCode.size()); if (hidl_info.civicInfo.size() > sizeof(legacy_info->civic_info)) { return false; } legacy_info->length = hidl_info.civicInfo.size(); - memcpy(legacy_info->civic_info, hidl_info.civicInfo.c_str(), - hidl_info.civicInfo.size()); + memcpy(legacy_info->civic_info, hidl_info.civicInfo.c_str(), hidl_info.civicInfo.size()); return true; } -bool convertHidlRttResponderToLegacy( - const V1_4::RttResponder& hidl_responder, - legacy_hal::wifi_rtt_responder* legacy_responder) { +bool convertHidlRttResponderToLegacy(const V1_4::RttResponder& hidl_responder, + legacy_hal::wifi_rtt_responder* legacy_responder) { if (!legacy_responder) { return false; } *legacy_responder = {}; - if (!convertHidlWifiChannelInfoToLegacy(hidl_responder.channel, - &legacy_responder->channel)) { + if (!convertHidlWifiChannelInfoToLegacy(hidl_responder.channel, &legacy_responder->channel)) { return false; } - legacy_responder->preamble = - convertHidlRttPreambleToLegacy(hidl_responder.preamble); + legacy_responder->preamble = convertHidlRttPreambleToLegacy(hidl_responder.preamble); return true; } -bool convertLegacyRttResponderToHidl( - const legacy_hal::wifi_rtt_responder& legacy_responder, - V1_4::RttResponder* hidl_responder) { +bool convertLegacyRttResponderToHidl(const legacy_hal::wifi_rtt_responder& legacy_responder, + V1_4::RttResponder* hidl_responder) { if (!hidl_responder) { return false; } *hidl_responder = {}; - if (!convertLegacyWifiChannelInfoToHidl(legacy_responder.channel, - &hidl_responder->channel)) { + if (!convertLegacyWifiChannelInfoToHidl(legacy_responder.channel, &hidl_responder->channel)) { return false; } - hidl_responder->preamble = - convertLegacyRttPreambleToHidl(legacy_responder.preamble); + hidl_responder->preamble = convertLegacyRttPreambleToHidl(legacy_responder.preamble); return true; } bool convertLegacyRttCapabilitiesToHidl( - const legacy_hal::wifi_rtt_capabilities& legacy_capabilities, - V1_4::RttCapabilities* hidl_capabilities) { + const legacy_hal::wifi_rtt_capabilities& legacy_capabilities, + V1_4::RttCapabilities* hidl_capabilities) { if (!hidl_capabilities) { return false; } *hidl_capabilities = {}; - hidl_capabilities->rttOneSidedSupported = - legacy_capabilities.rtt_one_sided_supported; + hidl_capabilities->rttOneSidedSupported = legacy_capabilities.rtt_one_sided_supported; hidl_capabilities->rttFtmSupported = legacy_capabilities.rtt_ftm_supported; hidl_capabilities->lciSupported = legacy_capabilities.lci_support; hidl_capabilities->lcrSupported = legacy_capabilities.lcr_support; - hidl_capabilities->responderSupported = - legacy_capabilities.responder_supported; + hidl_capabilities->responderSupported = legacy_capabilities.responder_supported; hidl_capabilities->preambleSupport = 0; - for (const auto flag : - {legacy_hal::WIFI_RTT_PREAMBLE_LEGACY, - legacy_hal::WIFI_RTT_PREAMBLE_HT, legacy_hal::WIFI_RTT_PREAMBLE_VHT, - legacy_hal::WIFI_RTT_PREAMBLE_HE}) { + for (const auto flag : {legacy_hal::WIFI_RTT_PREAMBLE_LEGACY, legacy_hal::WIFI_RTT_PREAMBLE_HT, + legacy_hal::WIFI_RTT_PREAMBLE_VHT, legacy_hal::WIFI_RTT_PREAMBLE_HE}) { if (legacy_capabilities.preamble_support & flag) { hidl_capabilities->preambleSupport |= - static_cast<std::underlying_type<V1_4::RttPreamble>::type>( - convertLegacyRttPreambleToHidl(flag)); + static_cast<std::underlying_type<V1_4::RttPreamble>::type>( + convertLegacyRttPreambleToHidl(flag)); } } hidl_capabilities->bwSupport = 0; for (const auto flag : - {legacy_hal::WIFI_RTT_BW_5, legacy_hal::WIFI_RTT_BW_10, - legacy_hal::WIFI_RTT_BW_20, legacy_hal::WIFI_RTT_BW_40, - legacy_hal::WIFI_RTT_BW_80, legacy_hal::WIFI_RTT_BW_160}) { + {legacy_hal::WIFI_RTT_BW_5, legacy_hal::WIFI_RTT_BW_10, legacy_hal::WIFI_RTT_BW_20, + legacy_hal::WIFI_RTT_BW_40, legacy_hal::WIFI_RTT_BW_80, legacy_hal::WIFI_RTT_BW_160}) { if (legacy_capabilities.bw_support & flag) { hidl_capabilities->bwSupport |= - static_cast<std::underlying_type<RttBw>::type>( - convertLegacyRttBwToHidl(flag)); + static_cast<std::underlying_type<RttBw>::type>(convertLegacyRttBwToHidl(flag)); } } hidl_capabilities->mcVersion = legacy_capabilities.mc_version; @@ -2909,26 +2608,23 @@ bool convertLegacyWifiRateInfoToHidl(const legacy_hal::wifi_rate& legacy_rate, return false; } *hidl_rate = {}; - hidl_rate->preamble = - convertLegacyWifiRatePreambleToHidl(legacy_rate.preamble); + hidl_rate->preamble = convertLegacyWifiRatePreambleToHidl(legacy_rate.preamble); hidl_rate->nss = convertLegacyWifiRateNssToHidl(legacy_rate.nss); hidl_rate->bw = convertLegacyWifiChannelWidthToHidl( - static_cast<legacy_hal::wifi_channel_width>(legacy_rate.bw)); + static_cast<legacy_hal::wifi_channel_width>(legacy_rate.bw)); hidl_rate->rateMcsIdx = legacy_rate.rateMcsIdx; hidl_rate->bitRateInKbps = legacy_rate.bitrate; return true; } -bool convertLegacyRttResultToHidl( - const legacy_hal::wifi_rtt_result& legacy_result, - V1_4::RttResult* hidl_result) { +bool convertLegacyRttResultToHidl(const legacy_hal::wifi_rtt_result& legacy_result, + V1_4::RttResult* hidl_result) { if (!hidl_result) { return false; } *hidl_result = {}; CHECK(sizeof(legacy_result.addr) == hidl_result->addr.size()); - memcpy(hidl_result->addr.data(), legacy_result.addr, - sizeof(legacy_result.addr)); + memcpy(hidl_result->addr.data(), legacy_result.addr, sizeof(legacy_result.addr)); hidl_result->burstNum = legacy_result.burst_num; hidl_result->measurementNumber = legacy_result.measurement_number; hidl_result->successNumber = legacy_result.success_number; @@ -2938,12 +2634,10 @@ bool convertLegacyRttResultToHidl( hidl_result->type = convertLegacyRttTypeToHidl(legacy_result.type); hidl_result->rssi = legacy_result.rssi; hidl_result->rssiSpread = legacy_result.rssi_spread; - if (!convertLegacyWifiRateInfoToHidl(legacy_result.tx_rate, - &hidl_result->txRate)) { + if (!convertLegacyWifiRateInfoToHidl(legacy_result.tx_rate, &hidl_result->txRate)) { return false; } - if (!convertLegacyWifiRateInfoToHidl(legacy_result.rx_rate, - &hidl_result->rxRate)) { + if (!convertLegacyWifiRateInfoToHidl(legacy_result.rx_rate, &hidl_result->rxRate)) { return false; } hidl_result->rtt = legacy_result.rtt; @@ -2955,20 +2649,18 @@ bool convertLegacyRttResultToHidl( hidl_result->timeStampInUs = legacy_result.ts; hidl_result->burstDurationInMs = legacy_result.burst_duration; hidl_result->negotiatedBurstNum = legacy_result.negotiated_burst_num; - if (legacy_result.LCI && - !convertLegacyIeToHidl(*legacy_result.LCI, &hidl_result->lci)) { + if (legacy_result.LCI && !convertLegacyIeToHidl(*legacy_result.LCI, &hidl_result->lci)) { return false; } - if (legacy_result.LCR && - !convertLegacyIeToHidl(*legacy_result.LCR, &hidl_result->lcr)) { + if (legacy_result.LCR && !convertLegacyIeToHidl(*legacy_result.LCR, &hidl_result->lcr)) { return false; } return true; } bool convertLegacyVectorOfRttResultToHidl( - const std::vector<const legacy_hal::wifi_rtt_result*>& legacy_results, - std::vector<V1_4::RttResult>* hidl_results) { + const std::vector<const legacy_hal::wifi_rtt_result*>& legacy_results, + std::vector<V1_4::RttResult>* hidl_results) { if (!hidl_results) { return false; } @@ -2983,8 +2675,7 @@ bool convertLegacyVectorOfRttResultToHidl( return true; } -legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy( - IfaceType hidl_interface_type) { +legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy(IfaceType hidl_interface_type) { switch (hidl_interface_type) { case IfaceType::STA: return legacy_hal::WIFI_INTERFACE_TYPE_STA; @@ -2999,28 +2690,28 @@ legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy( } legacy_hal::wifi_multi_sta_use_case convertHidlMultiStaUseCaseToLegacy( - IWifiChip::MultiStaUseCase use_case) { + V1_5::IWifiChip::MultiStaUseCase use_case) { switch (use_case) { - case IWifiChip::MultiStaUseCase::DUAL_STA_TRANSIENT_PREFER_PRIMARY: + case V1_5::IWifiChip::MultiStaUseCase::DUAL_STA_TRANSIENT_PREFER_PRIMARY: return legacy_hal::WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY; - case IWifiChip::MultiStaUseCase::DUAL_STA_NON_TRANSIENT_UNBIASED: + case V1_5::IWifiChip::MultiStaUseCase::DUAL_STA_NON_TRANSIENT_UNBIASED: return legacy_hal::WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED; } CHECK(false); } bool convertHidlCoexUnsafeChannelToLegacy( - const IWifiChip::CoexUnsafeChannel& hidl_unsafe_channel, - legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel) { + const V1_5::IWifiChip::CoexUnsafeChannel& hidl_unsafe_channel, + legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel) { if (!legacy_unsafe_channel) { return false; } *legacy_unsafe_channel = {}; switch (hidl_unsafe_channel.band) { - case WifiBand::BAND_24GHZ: + case V1_5::WifiBand::BAND_24GHZ: legacy_unsafe_channel->band = legacy_hal::WLAN_MAC_2_4_BAND; break; - case WifiBand::BAND_5GHZ: + case V1_5::WifiBand::BAND_5GHZ: legacy_unsafe_channel->band = legacy_hal::WLAN_MAC_5_0_BAND; break; default: @@ -3032,16 +2723,16 @@ bool convertHidlCoexUnsafeChannelToLegacy( } bool convertHidlVectorOfCoexUnsafeChannelToLegacy( - const std::vector<IWifiChip::CoexUnsafeChannel>& hidl_unsafe_channels, - std::vector<legacy_hal::wifi_coex_unsafe_channel>* legacy_unsafe_channels) { + const std::vector<V1_5::IWifiChip::CoexUnsafeChannel>& hidl_unsafe_channels, + std::vector<legacy_hal::wifi_coex_unsafe_channel>* legacy_unsafe_channels) { if (!legacy_unsafe_channels) { return false; } *legacy_unsafe_channels = {}; for (const auto& hidl_unsafe_channel : hidl_unsafe_channels) { legacy_hal::wifi_coex_unsafe_channel legacy_unsafe_channel; - if (!hidl_struct_util::convertHidlCoexUnsafeChannelToLegacy( - hidl_unsafe_channel, &legacy_unsafe_channel)) { + if (!hidl_struct_util::convertHidlCoexUnsafeChannelToLegacy(hidl_unsafe_channel, + &legacy_unsafe_channel)) { return false; } legacy_unsafe_channels->push_back(legacy_unsafe_channel); @@ -3051,7 +2742,7 @@ bool convertHidlVectorOfCoexUnsafeChannelToLegacy( } // namespace hidl_struct_util } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.6/default/hidl_struct_util.h b/wifi/1.6/default/hidl_struct_util.h new file mode 100644 index 0000000000..15a3205847 --- /dev/null +++ b/wifi/1.6/default/hidl_struct_util.h @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HIDL_STRUCT_UTIL_H_ +#define HIDL_STRUCT_UTIL_H_ + +#include <vector> + +#include <android/hardware/wifi/1.0/IWifiChip.h> +#include <android/hardware/wifi/1.0/types.h> +#include <android/hardware/wifi/1.2/types.h> +#include <android/hardware/wifi/1.3/types.h> +#include <android/hardware/wifi/1.4/IWifiChipEventCallback.h> +#include <android/hardware/wifi/1.4/types.h> +#include <android/hardware/wifi/1.5/IWifiChip.h> +#include <android/hardware/wifi/1.5/types.h> + +#include "wifi_legacy_hal.h" + +/** + * This file contains a bunch of functions to convert structs from the legacy + * HAL to HIDL and vice versa. + * TODO(b/32093047): Add unit tests for these conversion methods in the VTS test + * suite. + */ +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace hidl_struct_util { +using namespace android::hardware::wifi::V1_0; + +// Chip conversion methods. +bool convertLegacyFeaturesToHidlChipCapabilities(uint64_t legacy_feature_set, + uint32_t legacy_logger_feature_set, + uint32_t* hidl_caps); +bool convertLegacyDebugRingBufferStatusToHidl( + const legacy_hal::wifi_ring_buffer_status& legacy_status, + WifiDebugRingBufferStatus* hidl_status); +bool convertLegacyVectorOfDebugRingBufferStatusToHidl( + const std::vector<legacy_hal::wifi_ring_buffer_status>& legacy_status_vec, + std::vector<WifiDebugRingBufferStatus>* hidl_status_vec); +bool convertLegacyWakeReasonStatsToHidl(const legacy_hal::WakeReasonStats& legacy_stats, + WifiDebugHostWakeReasonStats* hidl_stats); +legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy( + V1_1::IWifiChip::TxPowerScenario hidl_scenario); +legacy_hal::wifi_latency_mode convertHidlLatencyModeToLegacy( + V1_3::IWifiChip::LatencyMode hidl_latency_mode); +legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy_1_2( + V1_2::IWifiChip::TxPowerScenario hidl_scenario); +bool convertLegacyWifiMacInfosToHidl( + const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos, + std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo>* hidl_radio_mode_infos); +legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy(IfaceType hidl_interface_type); +legacy_hal::wifi_multi_sta_use_case convertHidlMultiStaUseCaseToLegacy( + V1_5::IWifiChip::MultiStaUseCase use_case); +bool convertHidlCoexUnsafeChannelToLegacy( + const V1_5::IWifiChip::CoexUnsafeChannel& hidl_unsafe_channel, + legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel); +bool convertHidlVectorOfCoexUnsafeChannelToLegacy( + const std::vector<V1_5::IWifiChip::CoexUnsafeChannel>& hidl_unsafe_channels, + std::vector<legacy_hal::wifi_coex_unsafe_channel>* legacy_unsafe_channels); + +// STA iface conversion methods. +bool convertLegacyFeaturesToHidlStaCapabilities(uint64_t legacy_feature_set, + uint32_t legacy_logger_feature_set, + uint32_t* hidl_caps); +bool convertLegacyApfCapabilitiesToHidl(const legacy_hal::PacketFilterCapabilities& legacy_caps, + StaApfPacketFilterCapabilities* hidl_caps); +bool convertLegacyGscanCapabilitiesToHidl(const legacy_hal::wifi_gscan_capabilities& legacy_caps, + StaBackgroundScanCapabilities* hidl_caps); +legacy_hal::wifi_band convertHidlWifiBandToLegacy(V1_0::WifiBand band); +bool convertHidlGscanParamsToLegacy(const StaBackgroundScanParameters& hidl_scan_params, + legacy_hal::wifi_scan_cmd_params* legacy_scan_params); +// |has_ie_data| indicates whether or not the wifi_scan_result includes 802.11 +// Information Elements (IEs) +bool convertLegacyGscanResultToHidl(const legacy_hal::wifi_scan_result& legacy_scan_result, + bool has_ie_data, StaScanResult* hidl_scan_result); +// |cached_results| is assumed to not include IEs. +bool convertLegacyVectorOfCachedGscanResultsToHidl( + const std::vector<legacy_hal::wifi_cached_scan_results>& legacy_cached_scan_results, + std::vector<StaScanData>* hidl_scan_datas); +bool convertLegacyLinkLayerStatsToHidl(const legacy_hal::LinkLayerStats& legacy_stats, + V1_5::StaLinkLayerStats* hidl_stats); +bool convertLegacyRoamingCapabilitiesToHidl( + const legacy_hal::wifi_roaming_capabilities& legacy_caps, + StaRoamingCapabilities* hidl_caps); +bool convertHidlRoamingConfigToLegacy(const StaRoamingConfig& hidl_config, + legacy_hal::wifi_roaming_config* legacy_config); +legacy_hal::fw_roaming_state_t convertHidlRoamingStateToLegacy(StaRoamingState state); +bool convertLegacyVectorOfDebugTxPacketFateToHidl( + const std::vector<legacy_hal::wifi_tx_report>& legacy_fates, + std::vector<WifiDebugTxPacketFateReport>* hidl_fates); +bool convertLegacyVectorOfDebugRxPacketFateToHidl( + const std::vector<legacy_hal::wifi_rx_report>& legacy_fates, + std::vector<WifiDebugRxPacketFateReport>* hidl_fates); + +// NAN iface conversion methods. +void convertToWifiNanStatus(legacy_hal::NanStatusType type, const char* str, size_t max_len, + WifiNanStatus* wifiNanStatus); +bool convertHidlNanEnableRequestToLegacy(const V1_4::NanEnableRequest& hidl_request, + legacy_hal::NanEnableRequest* legacy_request); +bool convertHidlNanConfigRequestToLegacy(const V1_4::NanConfigRequest& hidl_request, + legacy_hal::NanConfigRequest* legacy_request); +bool convertHidlNanEnableRequest_1_4ToLegacy( + const V1_4::NanEnableRequest& hidl_request1, + const V1_5::NanConfigRequestSupplemental& hidl_request2, + legacy_hal::NanEnableRequest* legacy_request); +bool convertHidlNanConfigRequest_1_4ToLegacy( + const V1_4::NanConfigRequest& hidl_request1, + const V1_5::NanConfigRequestSupplemental& hidl_request2, + legacy_hal::NanConfigRequest* legacy_request); +bool convertHidlNanEnableRequest_1_5ToLegacy( + const V1_4::NanEnableRequest& hidl_request1, + const V1_5::NanConfigRequestSupplemental& hidl_request2, + legacy_hal::NanEnableRequest* legacy_request); +bool convertHidlNanConfigRequest_1_5ToLegacy( + const V1_4::NanConfigRequest& hidl_request1, + const V1_5::NanConfigRequestSupplemental& hidl_request2, + legacy_hal::NanConfigRequest* legacy_request); +bool convertHidlNanPublishRequestToLegacy(const NanPublishRequest& hidl_request, + legacy_hal::NanPublishRequest* legacy_request); +bool convertHidlNanSubscribeRequestToLegacy(const NanSubscribeRequest& hidl_request, + legacy_hal::NanSubscribeRequest* legacy_request); +bool convertHidlNanTransmitFollowupRequestToLegacy( + const NanTransmitFollowupRequest& hidl_request, + legacy_hal::NanTransmitFollowupRequest* legacy_request); +bool convertHidlNanDataPathInitiatorRequestToLegacy( + const NanInitiateDataPathRequest& hidl_request, + legacy_hal::NanDataPathInitiatorRequest* legacy_request); +bool convertHidlNanDataPathIndicationResponseToLegacy( + const NanRespondToDataPathIndicationRequest& hidl_response, + legacy_hal::NanDataPathIndicationResponse* legacy_response); +bool convertLegacyNanResponseHeaderToHidl(const legacy_hal::NanResponseMsg& legacy_response, + WifiNanStatus* wifiNanStatus); +bool convertLegacyNanCapabilitiesResponseToHidl(const legacy_hal::NanCapabilities& legacy_response, + V1_5::NanCapabilities* hidl_response); +bool convertLegacyNanMatchIndToHidl(const legacy_hal::NanMatchInd& legacy_ind, + NanMatchInd* hidl_ind); +bool convertLegacyNanFollowupIndToHidl(const legacy_hal::NanFollowupInd& legacy_ind, + NanFollowupReceivedInd* hidl_ind); +bool convertLegacyNanDataPathRequestIndToHidl(const legacy_hal::NanDataPathRequestInd& legacy_ind, + NanDataPathRequestInd* hidl_ind); +bool convertLegacyNanDataPathConfirmIndToHidl(const legacy_hal::NanDataPathConfirmInd& legacy_ind, + V1_2::NanDataPathConfirmInd* hidl_ind); +bool convertLegacyNanDataPathScheduleUpdateIndToHidl( + const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind, + V1_2::NanDataPathScheduleUpdateInd* hidl_ind); + +// RTT controller conversion methods. +bool convertHidlVectorOfRttConfigToLegacy(const std::vector<V1_4::RttConfig>& hidl_configs, + std::vector<legacy_hal::wifi_rtt_config>* legacy_configs); +bool convertHidlRttLciInformationToLegacy(const RttLciInformation& hidl_info, + legacy_hal::wifi_lci_information* legacy_info); +bool convertHidlRttLcrInformationToLegacy(const RttLcrInformation& hidl_info, + legacy_hal::wifi_lcr_information* legacy_info); +bool convertHidlRttResponderToLegacy(const V1_4::RttResponder& hidl_responder, + legacy_hal::wifi_rtt_responder* legacy_responder); +bool convertHidlWifiChannelInfoToLegacy(const WifiChannelInfo& hidl_info, + legacy_hal::wifi_channel_info* legacy_info); +bool convertLegacyRttResponderToHidl(const legacy_hal::wifi_rtt_responder& legacy_responder, + V1_4::RttResponder* hidl_responder); +bool convertLegacyRttCapabilitiesToHidl( + const legacy_hal::wifi_rtt_capabilities& legacy_capabilities, + V1_4::RttCapabilities* hidl_capabilities); +bool convertLegacyVectorOfRttResultToHidl( + const std::vector<const legacy_hal::wifi_rtt_result*>& legacy_results, + std::vector<V1_4::RttResult>* hidl_results); +uint32_t convertHidlWifiBandToLegacyMacBand(V1_5::WifiBand band); +uint32_t convertHidlWifiIfaceModeToLegacy(uint32_t hidl_iface_mask); +uint32_t convertHidlUsableChannelFilterToLegacy(uint32_t hidl_filter_mask); +bool convertLegacyWifiUsableChannelsToHidl( + const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels, + std::vector<V1_5::WifiUsableChannel>* hidl_usable_channels); +bool convertLegacyPeerInfoStatsToHidl(const legacy_hal::WifiPeerInfo& legacy_peer_info_stats, + V1_5::StaPeerInfo* hidl_peer_info_stats); +bool convertLegacyWifiRateInfoToHidl(const legacy_hal::wifi_rate& legacy_rate, + V1_4::WifiRateInfo* hidl_rate); +} // namespace hidl_struct_util +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // HIDL_STRUCT_UTIL_H_ diff --git a/wifi/1.5/default/hidl_sync_util.cpp b/wifi/1.6/default/hidl_sync_util.cpp index 93eefe9560..358d95e668 100644 --- a/wifi/1.5/default/hidl_sync_util.cpp +++ b/wifi/1.6/default/hidl_sync_util.cpp @@ -23,7 +23,7 @@ std::recursive_mutex g_mutex; namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace hidl_sync_util { @@ -33,7 +33,7 @@ std::unique_lock<std::recursive_mutex> acquireGlobalLock() { } // namespace hidl_sync_util } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/hidl_sync_util.h b/wifi/1.6/default/hidl_sync_util.h index e706f4cd87..2c1c37b0ad 100644 --- a/wifi/1.5/default/hidl_sync_util.h +++ b/wifi/1.6/default/hidl_sync_util.h @@ -24,13 +24,13 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace hidl_sync_util { std::unique_lock<std::recursive_mutex> acquireGlobalLock(); } // namespace hidl_sync_util } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/ringbuffer.cpp b/wifi/1.6/default/ringbuffer.cpp index f554111e61..6d4ed843c3 100644 --- a/wifi/1.5/default/ringbuffer.cpp +++ b/wifi/1.6/default/ringbuffer.cpp @@ -21,7 +21,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { Ringbuffer::Ringbuffer(size_t maxSize) : size_(0), maxSize_(maxSize) {} @@ -31,8 +31,7 @@ void Ringbuffer::append(const std::vector<uint8_t>& input) { return; } if (input.size() > maxSize_) { - LOG(INFO) << "Oversized message of " << input.size() - << " bytes is dropped"; + LOG(INFO) << "Oversized message of " << input.size() << " bytes is dropped"; return; } data_.push_back(input); @@ -53,7 +52,7 @@ void Ringbuffer::clear() { } } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/ringbuffer.h b/wifi/1.6/default/ringbuffer.h index 03fb37a6a2..8571a9f3d4 100644 --- a/wifi/1.5/default/ringbuffer.h +++ b/wifi/1.6/default/ringbuffer.h @@ -23,14 +23,14 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { /** * Ringbuffer object used to store debug data. */ class Ringbuffer { - public: + public: explicit Ringbuffer(size_t maxSize); // Appends the data buffer and deletes from the front until buffer is @@ -39,14 +39,14 @@ class Ringbuffer { const std::list<std::vector<uint8_t>>& getData() const; void clear(); - private: + private: std::list<std::vector<uint8_t>> data_; size_t size_; size_t maxSize_; }; } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/service.cpp b/wifi/1.6/default/service.cpp index 4c089d86ea..c874d8b199 100644 --- a/wifi/1.5/default/service.cpp +++ b/wifi/1.6/default/service.cpp @@ -20,8 +20,6 @@ #include <signal.h> #include <utils/Looper.h> #include <utils/StrongPointer.h> -#include <hwbinder/ProcessState.h> -#include <cutils/properties.h> #include "wifi.h" #include "wifi_feature_flags.h" @@ -32,24 +30,10 @@ using android::hardware::configureRpcThreadpool; using android::hardware::joinRpcThreadpool; using android::hardware::LazyServiceRegistrar; -using android::hardware::wifi::V1_5::implementation::feature_flags:: - WifiFeatureFlags; -using android::hardware::wifi::V1_5::implementation::legacy_hal::WifiLegacyHal; -using android::hardware::wifi::V1_5::implementation::legacy_hal:: - WifiLegacyHalFactory; -using android::hardware::wifi::V1_5::implementation::mode_controller:: - WifiModeController; - -#ifdef ARCH_ARM_32 -#define DEFAULT_WIFIHAL_HW_BINDER_SIZE_KB 16 -size_t getHWBinderMmapSize() { - size_t value = 0; - value = property_get_int32("persist.vendor.wifi.wifihal.hw.binder.size", DEFAULT_WIFIHAL_HW_BINDER_SIZE_KB); - if (!value) value = DEFAULT_WIFIHAL_HW_BINDER_SIZE_KB; // deafult to 1 page of 4 Kb - - return 1024 * value; -} -#endif /* ARCH_ARM_32 */ +using android::hardware::wifi::V1_6::implementation::feature_flags::WifiFeatureFlags; +using android::hardware::wifi::V1_6::implementation::legacy_hal::WifiLegacyHal; +using android::hardware::wifi::V1_6::implementation::legacy_hal::WifiLegacyHalFactory; +using android::hardware::wifi::V1_6::implementation::mode_controller::WifiModeController; #ifdef LAZY_SERVICE const bool kLazyService = true; @@ -59,33 +43,25 @@ const bool kLazyService = false; int main(int /*argc*/, char** argv) { signal(SIGPIPE, SIG_IGN); -#ifdef ARCH_ARM_32 - android::hardware::ProcessState::initWithMmapSize(getHWBinderMmapSize()); -#endif /* ARCH_ARM_32 */ - android::base::InitLogging( - argv, android::base::LogdLogger(android::base::SYSTEM)); + android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM)); LOG(INFO) << "Wifi Hal is booting up..."; configureRpcThreadpool(1, true /* callerWillJoin */); - const auto iface_tool = - std::make_shared<android::wifi_system::InterfaceTool>(); - const auto legacy_hal_factory = - std::make_shared<WifiLegacyHalFactory>(iface_tool); + const auto iface_tool = std::make_shared<android::wifi_system::InterfaceTool>(); + const auto legacy_hal_factory = std::make_shared<WifiLegacyHalFactory>(iface_tool); // Setup hwbinder service - android::sp<android::hardware::wifi::V1_5::IWifi> service = - new android::hardware::wifi::V1_5::implementation::Wifi( - iface_tool, legacy_hal_factory, - std::make_shared<WifiModeController>(), - std::make_shared<WifiFeatureFlags>()); + android::sp<android::hardware::wifi::V1_6::IWifi> service = + new android::hardware::wifi::V1_6::implementation::Wifi( + iface_tool, legacy_hal_factory, std::make_shared<WifiModeController>(), + std::make_shared<WifiFeatureFlags>()); if (kLazyService) { auto registrar = LazyServiceRegistrar::getInstance(); CHECK_EQ(registrar.registerService(service), android::NO_ERROR) - << "Failed to register wifi HAL"; + << "Failed to register wifi HAL"; } else { - CHECK_EQ(service->registerAsService(), android::NO_ERROR) - << "Failed to register wifi HAL"; + CHECK_EQ(service->registerAsService(), android::NO_ERROR) << "Failed to register wifi HAL"; } joinRpcThreadpool(); diff --git a/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp b/wifi/1.6/default/tests/hidl_struct_util_unit_tests.cpp index 4b4ebd6138..1182a58dbd 100644 --- a/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp +++ b/wifi/1.6/default/tests/hidl_struct_util_unit_tests.cpp @@ -34,7 +34,7 @@ constexpr char kIfaceName2[] = "wlan1"; namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { using namespace android::hardware::wifi::V1_0; using ::android::hardware::wifi::V1_0::WifiChannelWidthInMhz; @@ -44,21 +44,17 @@ class HidlStructUtilTest : public Test {}; TEST_F(HidlStructUtilTest, CanConvertLegacyWifiMacInfosToHidlWithOneMac) { std::vector<legacy_hal::WifiMacInfo> legacy_mac_infos; legacy_hal::WifiMacInfo legacy_mac_info1 = { - .wlan_mac_id = kMacId1, - .mac_band = - legacy_hal::WLAN_MAC_5_0_BAND | legacy_hal::WLAN_MAC_2_4_BAND}; - legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1, - .channel = kIfaceChannel1}; - legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2, - .channel = kIfaceChannel2}; + .wlan_mac_id = kMacId1, + .mac_band = legacy_hal::WLAN_MAC_5_0_BAND | legacy_hal::WLAN_MAC_2_4_BAND}; + legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1, .channel = kIfaceChannel1}; + legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2, .channel = kIfaceChannel2}; legacy_mac_info1.iface_infos.push_back(legacy_iface_info1); legacy_mac_info1.iface_infos.push_back(legacy_iface_info2); legacy_mac_infos.push_back(legacy_mac_info1); - std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo> - hidl_radio_mode_infos; - ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl( - legacy_mac_infos, &hidl_radio_mode_infos)); + std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo> hidl_radio_mode_infos; + ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl(legacy_mac_infos, + &hidl_radio_mode_infos)); ASSERT_EQ(1u, hidl_radio_mode_infos.size()); auto hidl_radio_mode_info1 = hidl_radio_mode_infos[0]; @@ -67,65 +63,56 @@ TEST_F(HidlStructUtilTest, CanConvertLegacyWifiMacInfosToHidlWithOneMac) { ASSERT_EQ(2u, hidl_radio_mode_info1.ifaceInfos.size()); auto hidl_iface_info1 = hidl_radio_mode_info1.ifaceInfos[0]; EXPECT_EQ(legacy_iface_info1.name, hidl_iface_info1.name); - EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info1.channel), - hidl_iface_info1.channel); + EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info1.channel), hidl_iface_info1.channel); auto hidl_iface_info2 = hidl_radio_mode_info1.ifaceInfos[1]; EXPECT_EQ(legacy_iface_info2.name, hidl_iface_info2.name); - EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info2.channel), - hidl_iface_info2.channel); + EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info2.channel), hidl_iface_info2.channel); } TEST_F(HidlStructUtilTest, CanConvertLegacyWifiMacInfosToHidlWithTwoMac) { std::vector<legacy_hal::WifiMacInfo> legacy_mac_infos; - legacy_hal::WifiMacInfo legacy_mac_info1 = { - .wlan_mac_id = kMacId1, .mac_band = legacy_hal::WLAN_MAC_5_0_BAND}; - legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1, - .channel = kIfaceChannel1}; - legacy_hal::WifiMacInfo legacy_mac_info2 = { - .wlan_mac_id = kMacId2, .mac_band = legacy_hal::WLAN_MAC_2_4_BAND}; - legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2, - .channel = kIfaceChannel2}; + legacy_hal::WifiMacInfo legacy_mac_info1 = {.wlan_mac_id = kMacId1, + .mac_band = legacy_hal::WLAN_MAC_5_0_BAND}; + legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1, .channel = kIfaceChannel1}; + legacy_hal::WifiMacInfo legacy_mac_info2 = {.wlan_mac_id = kMacId2, + .mac_band = legacy_hal::WLAN_MAC_2_4_BAND}; + legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2, .channel = kIfaceChannel2}; legacy_mac_info1.iface_infos.push_back(legacy_iface_info1); legacy_mac_infos.push_back(legacy_mac_info1); legacy_mac_info2.iface_infos.push_back(legacy_iface_info2); legacy_mac_infos.push_back(legacy_mac_info2); - std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo> - hidl_radio_mode_infos; - ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl( - legacy_mac_infos, &hidl_radio_mode_infos)); + std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo> hidl_radio_mode_infos; + ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl(legacy_mac_infos, + &hidl_radio_mode_infos)); ASSERT_EQ(2u, hidl_radio_mode_infos.size()); // Find mac info 1. const auto hidl_radio_mode_info1 = - std::find_if(hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(), - [&legacy_mac_info1]( - const V1_4::IWifiChipEventCallback::RadioModeInfo& x) { - return x.radioId == legacy_mac_info1.wlan_mac_id; - }); + std::find_if(hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(), + [&legacy_mac_info1](const V1_4::IWifiChipEventCallback::RadioModeInfo& x) { + return x.radioId == legacy_mac_info1.wlan_mac_id; + }); ASSERT_NE(hidl_radio_mode_infos.end(), hidl_radio_mode_info1); EXPECT_EQ(V1_4::WifiBand::BAND_5GHZ, hidl_radio_mode_info1->bandInfo); ASSERT_EQ(1u, hidl_radio_mode_info1->ifaceInfos.size()); auto hidl_iface_info1 = hidl_radio_mode_info1->ifaceInfos[0]; EXPECT_EQ(legacy_iface_info1.name, hidl_iface_info1.name); - EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info1.channel), - hidl_iface_info1.channel); + EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info1.channel), hidl_iface_info1.channel); // Find mac info 2. const auto hidl_radio_mode_info2 = - std::find_if(hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(), - [&legacy_mac_info2]( - const V1_4::IWifiChipEventCallback::RadioModeInfo& x) { - return x.radioId == legacy_mac_info2.wlan_mac_id; - }); + std::find_if(hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(), + [&legacy_mac_info2](const V1_4::IWifiChipEventCallback::RadioModeInfo& x) { + return x.radioId == legacy_mac_info2.wlan_mac_id; + }); ASSERT_NE(hidl_radio_mode_infos.end(), hidl_radio_mode_info2); EXPECT_EQ(V1_4::WifiBand::BAND_24GHZ, hidl_radio_mode_info2->bandInfo); ASSERT_EQ(1u, hidl_radio_mode_info2->ifaceInfos.size()); auto hidl_iface_info2 = hidl_radio_mode_info2->ifaceInfos[0]; EXPECT_EQ(legacy_iface_info2.name, hidl_iface_info2.name); - EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info2.channel), - hidl_iface_info2.channel); + EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info2.channel), hidl_iface_info2.channel); } TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { @@ -143,8 +130,7 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples = - rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu = rand(); @@ -153,8 +139,7 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples = - rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu = rand(); @@ -163,8 +148,7 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples = - rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu = rand(); @@ -173,8 +157,7 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples = - rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples = rand(); legacy_stats.iface.info.time_slicing_duty_cycle_percent = rand(); legacy_stats.iface.num_peers = 1; @@ -195,14 +178,14 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { } legacy_hal::wifi_channel_stat channel_stat1 = { - .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 2437, 2437, 0}, - .on_time = 0x1111, - .cca_busy_time = 0x55, + .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 2437, 2437, 0}, + .on_time = 0x1111, + .cca_busy_time = 0x55, }; legacy_hal::wifi_channel_stat channel_stat2 = { - .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 5180, 5180, 0}, - .on_time = 0x2222, - .cca_busy_time = 0x66, + .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 5180, 5180, 0}, + .on_time = 0x2222, + .cca_busy_time = 0x66, }; radio.channel_stats.push_back(channel_stat1); radio.channel_stats.push_back(channel_stat2); @@ -212,30 +195,29 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { peer.peer_info.bssload.sta_count = rand(); peer.peer_info.bssload.chan_util = rand(); wifi_rate_stat rate_stat1 = { - .rate = {3, 1, 2, 5, 0, 0}, - .tx_mpdu = 0, - .rx_mpdu = 1, - .mpdu_lost = 2, - .retries = 3, - .retries_short = 4, - .retries_long = 5, + .rate = {3, 1, 2, 5, 0, 0}, + .tx_mpdu = 0, + .rx_mpdu = 1, + .mpdu_lost = 2, + .retries = 3, + .retries_short = 4, + .retries_long = 5, }; wifi_rate_stat rate_stat2 = { - .rate = {2, 2, 1, 6, 0, 1}, - .tx_mpdu = 6, - .rx_mpdu = 7, - .mpdu_lost = 8, - .retries = 9, - .retries_short = 10, - .retries_long = 11, + .rate = {2, 2, 1, 6, 0, 1}, + .tx_mpdu = 6, + .rx_mpdu = 7, + .mpdu_lost = 8, + .retries = 9, + .retries_short = 10, + .retries_long = 11, }; peer.rate_stats.push_back(rate_stat1); peer.rate_stats.push_back(rate_stat2); } V1_5::StaLinkLayerStats converted{}; - hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats, - &converted); + hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats, &converted); EXPECT_EQ(legacy_stats.iface.beacon_rx, converted.iface.V1_0.beaconRx); EXPECT_EQ(legacy_stats.iface.rssi_mgmt, converted.iface.V1_0.avgRssiMgmt); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu, @@ -252,9 +234,8 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { converted.iface.wmeBeContentionTimeStats.contentionTimeMaxInUsec); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg, converted.iface.wmeBeContentionTimeStats.contentionTimeAvgInUsec); - EXPECT_EQ( - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples, - converted.iface.wmeBeContentionTimeStats.contentionNumSamples); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples, + converted.iface.wmeBeContentionTimeStats.contentionNumSamples); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu, converted.iface.V1_0.wmeBkPktStats.rxMpdu); @@ -270,9 +251,8 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { converted.iface.wmeBkContentionTimeStats.contentionTimeMaxInUsec); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg, converted.iface.wmeBkContentionTimeStats.contentionTimeAvgInUsec); - EXPECT_EQ( - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples, - converted.iface.wmeBkContentionTimeStats.contentionNumSamples); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples, + converted.iface.wmeBkContentionTimeStats.contentionNumSamples); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu, converted.iface.V1_0.wmeViPktStats.rxMpdu); @@ -288,9 +268,8 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { converted.iface.wmeViContentionTimeStats.contentionTimeMaxInUsec); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg, converted.iface.wmeViContentionTimeStats.contentionTimeAvgInUsec); - EXPECT_EQ( - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples, - converted.iface.wmeViContentionTimeStats.contentionNumSamples); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples, + converted.iface.wmeViContentionTimeStats.contentionNumSamples); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu, converted.iface.V1_0.wmeVoPktStats.rxMpdu); @@ -306,29 +285,23 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { converted.iface.wmeVoContentionTimeStats.contentionTimeMaxInUsec); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg, converted.iface.wmeVoContentionTimeStats.contentionTimeAvgInUsec); - EXPECT_EQ( - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples, - converted.iface.wmeVoContentionTimeStats.contentionNumSamples); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples, + converted.iface.wmeVoContentionTimeStats.contentionNumSamples); EXPECT_EQ(legacy_stats.iface.info.time_slicing_duty_cycle_percent, converted.iface.timeSliceDutyCycleInPercent); EXPECT_EQ(legacy_stats.radios.size(), converted.radios.size()); for (size_t i = 0; i < legacy_stats.radios.size(); i++) { - EXPECT_EQ(legacy_stats.radios[i].stats.radio, - converted.radios[i].radioId); - EXPECT_EQ(legacy_stats.radios[i].stats.on_time, - converted.radios[i].V1_3.V1_0.onTimeInMs); - EXPECT_EQ(legacy_stats.radios[i].stats.tx_time, - converted.radios[i].V1_3.V1_0.txTimeInMs); - EXPECT_EQ(legacy_stats.radios[i].stats.rx_time, - converted.radios[i].V1_3.V1_0.rxTimeInMs); + EXPECT_EQ(legacy_stats.radios[i].stats.radio, converted.radios[i].radioId); + EXPECT_EQ(legacy_stats.radios[i].stats.on_time, converted.radios[i].V1_3.V1_0.onTimeInMs); + EXPECT_EQ(legacy_stats.radios[i].stats.tx_time, converted.radios[i].V1_3.V1_0.txTimeInMs); + EXPECT_EQ(legacy_stats.radios[i].stats.rx_time, converted.radios[i].V1_3.V1_0.rxTimeInMs); EXPECT_EQ(legacy_stats.radios[i].stats.on_time_scan, converted.radios[i].V1_3.V1_0.onTimeInMsForScan); EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels.size(), converted.radios[i].V1_3.V1_0.txTimeInMsPerLevel.size()); - for (size_t j = 0; j < legacy_stats.radios[i].tx_time_per_levels.size(); - j++) { + for (size_t j = 0; j < legacy_stats.radios[i].tx_time_per_levels.size(); j++) { EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels[j], converted.radios[i].V1_3.V1_0.txTimeInMsPerLevel[j]); } @@ -344,20 +317,16 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { converted.radios[i].V1_3.onTimeInMsForHs20Scan); EXPECT_EQ(legacy_stats.radios[i].channel_stats.size(), converted.radios[i].V1_3.channelStats.size()); - for (size_t k = 0; k < legacy_stats.radios[i].channel_stats.size(); - k++) { + for (size_t k = 0; k < legacy_stats.radios[i].channel_stats.size(); k++) { auto& legacy_channel_st = legacy_stats.radios[i].channel_stats[k]; EXPECT_EQ(WifiChannelWidthInMhz::WIDTH_20, converted.radios[i].V1_3.channelStats[k].channel.width); - EXPECT_EQ( - WifiChannelInMhz(legacy_channel_st.channel.center_freq), - converted.radios[i].V1_3.channelStats[k].channel.centerFreq); - EXPECT_EQ( - WifiChannelInMhz(legacy_channel_st.channel.center_freq0), - converted.radios[i].V1_3.channelStats[k].channel.centerFreq0); - EXPECT_EQ( - WifiChannelInMhz(legacy_channel_st.channel.center_freq1), - converted.radios[i].V1_3.channelStats[k].channel.centerFreq1); + EXPECT_EQ(WifiChannelInMhz(legacy_channel_st.channel.center_freq), + converted.radios[i].V1_3.channelStats[k].channel.centerFreq); + EXPECT_EQ(WifiChannelInMhz(legacy_channel_st.channel.center_freq0), + converted.radios[i].V1_3.channelStats[k].channel.centerFreq0); + EXPECT_EQ(WifiChannelInMhz(legacy_channel_st.channel.center_freq1), + converted.radios[i].V1_3.channelStats[k].channel.centerFreq1); EXPECT_EQ(legacy_channel_st.cca_busy_time, converted.radios[i].V1_3.channelStats[k].ccaBusyTimeInMs); EXPECT_EQ(legacy_channel_st.on_time, @@ -373,18 +342,13 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { converted.iface.peers[i].chanUtil); for (size_t j = 0; j < legacy_stats.peers[i].rate_stats.size(); j++) { EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.preamble, - (uint32_t)converted.iface.peers[i] - .rateStats[j] - .rateInfo.preamble); - EXPECT_EQ( - legacy_stats.peers[i].rate_stats[j].rate.nss, - (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.nss); - EXPECT_EQ( - legacy_stats.peers[i].rate_stats[j].rate.bw, - (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.bw); - EXPECT_EQ( - legacy_stats.peers[i].rate_stats[j].rate.rateMcsIdx, - converted.iface.peers[i].rateStats[j].rateInfo.rateMcsIdx); + (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.preamble); + EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.nss, + (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.nss); + EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.bw, + (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.bw); + EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.rateMcsIdx, + converted.iface.peers[i].rateStats[j].rateInfo.rateMcsIdx); EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].tx_mpdu, converted.iface.peers[i].rateStats[j].txMpdu); EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rx_mpdu, @@ -402,23 +366,20 @@ TEST_F(HidlStructUtilTest, CanConvertLegacyFeaturesToHidl) { uint32_t hidle_caps; - uint32_t legacy_feature_set = - WIFI_FEATURE_D2D_RTT | WIFI_FEATURE_SET_LATENCY_MODE; - uint32_t legacy_logger_feature_set = - legacy_hal::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED; + uint32_t legacy_feature_set = WIFI_FEATURE_D2D_RTT | WIFI_FEATURE_SET_LATENCY_MODE; + uint32_t legacy_logger_feature_set = legacy_hal::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED; ASSERT_TRUE(hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities( - legacy_feature_set, legacy_logger_feature_set, &hidle_caps)); + legacy_feature_set, legacy_logger_feature_set, &hidle_caps)); EXPECT_EQ(HidlChipCaps::DEBUG_RING_BUFFER_VENDOR_DATA | - HidlChipCaps::DEBUG_HOST_WAKE_REASON_STATS | - HidlChipCaps::DEBUG_ERROR_ALERTS | HidlChipCaps::D2D_RTT | - HidlChipCaps::SET_LATENCY_MODE | - HidlChipCaps::DEBUG_MEMORY_DRIVER_DUMP, + HidlChipCaps::DEBUG_HOST_WAKE_REASON_STATS | + HidlChipCaps::DEBUG_ERROR_ALERTS | HidlChipCaps::D2D_RTT | + HidlChipCaps::SET_LATENCY_MODE | HidlChipCaps::DEBUG_MEMORY_DRIVER_DUMP, hidle_caps); } } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/tests/main.cpp b/wifi/1.6/default/tests/main.cpp index 9aac837242..9aac837242 100644 --- a/wifi/1.5/default/tests/main.cpp +++ b/wifi/1.6/default/tests/main.cpp diff --git a/wifi/1.5/default/tests/mock_interface_tool.cpp b/wifi/1.6/default/tests/mock_interface_tool.cpp index b99a16446c..b99a16446c 100644 --- a/wifi/1.5/default/tests/mock_interface_tool.cpp +++ b/wifi/1.6/default/tests/mock_interface_tool.cpp diff --git a/wifi/1.5/default/tests/mock_interface_tool.h b/wifi/1.6/default/tests/mock_interface_tool.h index 0f17551f96..7ce3992c7e 100644 --- a/wifi/1.5/default/tests/mock_interface_tool.h +++ b/wifi/1.6/default/tests/mock_interface_tool.h @@ -24,17 +24,15 @@ namespace android { namespace wifi_system { class MockInterfaceTool : public InterfaceTool { - public: + public: MockInterfaceTool(); MOCK_METHOD1(GetUpState, bool(const char* if_name)); MOCK_METHOD2(SetUpState, bool(const char* if_name, bool request_up)); MOCK_METHOD1(SetWifiUpState, bool(bool request_up)); MOCK_METHOD2(SetMacAddress, - bool(const char* if_name, - const std::array<uint8_t, ETH_ALEN>& address)); - MOCK_METHOD1(GetFactoryMacAddress, - std::array<uint8_t, ETH_ALEN>(const char* if_name)); + bool(const char* if_name, const std::array<uint8_t, ETH_ALEN>& address)); + MOCK_METHOD1(GetFactoryMacAddress, std::array<uint8_t, ETH_ALEN>(const char* if_name)); }; // class MockInterfaceTool diff --git a/wifi/1.5/default/tests/mock_wifi_feature_flags.cpp b/wifi/1.6/default/tests/mock_wifi_feature_flags.cpp index 2f66ba121b..d10b74c3a0 100644 --- a/wifi/1.5/default/tests/mock_wifi_feature_flags.cpp +++ b/wifi/1.6/default/tests/mock_wifi_feature_flags.cpp @@ -21,7 +21,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace feature_flags { @@ -29,7 +29,7 @@ MockWifiFeatureFlags::MockWifiFeatureFlags() {} } // namespace feature_flags } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/tests/mock_wifi_feature_flags.h b/wifi/1.6/default/tests/mock_wifi_feature_flags.h index c3877edd60..fa3600a4b1 100644 --- a/wifi/1.5/default/tests/mock_wifi_feature_flags.h +++ b/wifi/1.6/default/tests/mock_wifi_feature_flags.h @@ -25,22 +25,21 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace feature_flags { class MockWifiFeatureFlags : public WifiFeatureFlags { - public: + public: MockWifiFeatureFlags(); - MOCK_METHOD1(getChipModes, - std::vector<V1_0::IWifiChip::ChipMode>(bool is_primary)); + MOCK_METHOD1(getChipModes, std::vector<V1_0::IWifiChip::ChipMode>(bool is_primary)); MOCK_METHOD0(isApMacRandomizationDisabled, bool()); }; } // namespace feature_flags } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/tests/mock_wifi_iface_util.cpp b/wifi/1.6/default/tests/mock_wifi_iface_util.cpp index b101c4ac34..24b16cb469 100644 --- a/wifi/1.5/default/tests/mock_wifi_iface_util.cpp +++ b/wifi/1.6/default/tests/mock_wifi_iface_util.cpp @@ -24,17 +24,16 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace iface_util { -MockWifiIfaceUtil::MockWifiIfaceUtil( - const std::weak_ptr<wifi_system::InterfaceTool> iface_tool, - const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal) +MockWifiIfaceUtil::MockWifiIfaceUtil(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool, + const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal) : WifiIfaceUtil(iface_tool, legacy_hal) {} } // namespace iface_util } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/tests/mock_wifi_iface_util.h b/wifi/1.6/default/tests/mock_wifi_iface_util.h index 6d5f59ce53..2701c36d76 100644 --- a/wifi/1.5/default/tests/mock_wifi_iface_util.h +++ b/wifi/1.6/default/tests/mock_wifi_iface_util.h @@ -24,29 +24,25 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace iface_util { class MockWifiIfaceUtil : public WifiIfaceUtil { - public: - MockWifiIfaceUtil( - const std::weak_ptr<wifi_system::InterfaceTool> iface_tool, - const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal); - MOCK_METHOD1(getFactoryMacAddress, - std::array<uint8_t, 6>(const std::string&)); - MOCK_METHOD2(setMacAddress, - bool(const std::string&, const std::array<uint8_t, 6>&)); + public: + MockWifiIfaceUtil(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool, + const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal); + MOCK_METHOD1(getFactoryMacAddress, std::array<uint8_t, 6>(const std::string&)); + MOCK_METHOD2(setMacAddress, bool(const std::string&, const std::array<uint8_t, 6>&)); MOCK_METHOD0(getOrCreateRandomMacAddress, std::array<uint8_t, 6>()); - MOCK_METHOD2(registerIfaceEventHandlers, - void(const std::string&, IfaceEventHandlers)); + MOCK_METHOD2(registerIfaceEventHandlers, void(const std::string&, IfaceEventHandlers)); MOCK_METHOD1(unregisterIfaceEventHandlers, void(const std::string&)); MOCK_METHOD2(setUpState, bool(const std::string&, bool)); MOCK_METHOD1(ifNameToIndex, unsigned(const std::string&)); }; } // namespace iface_util } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/tests/mock_wifi_legacy_hal.cpp b/wifi/1.6/default/tests/mock_wifi_legacy_hal.cpp index d13c5568b3..2c558612e3 100644 --- a/wifi/1.5/default/tests/mock_wifi_legacy_hal.cpp +++ b/wifi/1.6/default/tests/mock_wifi_legacy_hal.cpp @@ -24,17 +24,16 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace legacy_hal { -MockWifiLegacyHal::MockWifiLegacyHal( - const std::weak_ptr<wifi_system::InterfaceTool> iface_tool, - const wifi_hal_fn& fn, bool is_primary) +MockWifiLegacyHal::MockWifiLegacyHal(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool, + const wifi_hal_fn& fn, bool is_primary) : WifiLegacyHal(iface_tool, fn, is_primary) {} } // namespace legacy_hal } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/tests/mock_wifi_legacy_hal.h b/wifi/1.6/default/tests/mock_wifi_legacy_hal.h index 826b35f8dd..b1f53273ba 100644 --- a/wifi/1.5/default/tests/mock_wifi_legacy_hal.h +++ b/wifi/1.6/default/tests/mock_wifi_legacy_hal.h @@ -24,49 +24,42 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace legacy_hal { class MockWifiLegacyHal : public WifiLegacyHal { - public: - MockWifiLegacyHal( - const std::weak_ptr<wifi_system::InterfaceTool> iface_tool, - const wifi_hal_fn& fn, bool is_primary); + public: + MockWifiLegacyHal(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool, + const wifi_hal_fn& fn, bool is_primary); MOCK_METHOD0(initialize, wifi_error()); MOCK_METHOD0(start, wifi_error()); - MOCK_METHOD2(stop, wifi_error(std::unique_lock<std::recursive_mutex>*, - const std::function<void()>&)); + MOCK_METHOD2(stop, + wifi_error(std::unique_lock<std::recursive_mutex>*, const std::function<void()>&)); MOCK_METHOD2(setDfsFlag, wifi_error(const std::string&, bool)); MOCK_METHOD2(registerRadioModeChangeCallbackHandler, - wifi_error(const std::string&, - const on_radio_mode_change_callback&)); - MOCK_METHOD1(getFirmwareVersion, std::pair<wifi_error, std::string>( - const std::string& iface_name)); - MOCK_METHOD1(getDriverVersion, std::pair<wifi_error, std::string>( - const std::string& iface_name)); + wifi_error(const std::string&, const on_radio_mode_change_callback&)); + MOCK_METHOD1(getFirmwareVersion, + std::pair<wifi_error, std::string>(const std::string& iface_name)); + MOCK_METHOD1(getDriverVersion, + std::pair<wifi_error, std::string>(const std::string& iface_name)); MOCK_METHOD2(selectTxPowerScenario, - wifi_error(const std::string& iface_name, - wifi_power_scenario scenario)); - MOCK_METHOD1(resetTxPowerScenario, - wifi_error(const std::string& iface_name)); + wifi_error(const std::string& iface_name, wifi_power_scenario scenario)); + MOCK_METHOD1(resetTxPowerScenario, wifi_error(const std::string& iface_name)); MOCK_METHOD2(nanRegisterCallbackHandlers, wifi_error(const std::string&, const NanCallbackHandlers&)); - MOCK_METHOD2(nanDisableRequest, - wifi_error(const std::string&, transaction_id)); + MOCK_METHOD2(nanDisableRequest, wifi_error(const std::string&, transaction_id)); MOCK_METHOD3(nanDataInterfaceDelete, - wifi_error(const std::string&, transaction_id, - const std::string&)); + wifi_error(const std::string&, transaction_id, const std::string&)); MOCK_METHOD2(createVirtualInterface, - wifi_error(const std::string& ifname, - wifi_interface_type iftype)); + wifi_error(const std::string& ifname, wifi_interface_type iftype)); MOCK_METHOD1(deleteVirtualInterface, wifi_error(const std::string& ifname)); MOCK_METHOD0(waitForDriverReady, wifi_error()); }; } // namespace legacy_hal } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/tests/mock_wifi_mode_controller.cpp b/wifi/1.6/default/tests/mock_wifi_mode_controller.cpp index e7ab22a01b..446f8296f8 100644 --- a/wifi/1.5/default/tests/mock_wifi_mode_controller.cpp +++ b/wifi/1.6/default/tests/mock_wifi_mode_controller.cpp @@ -24,14 +24,14 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace mode_controller { MockWifiModeController::MockWifiModeController() : WifiModeController() {} } // namespace mode_controller } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/tests/mock_wifi_mode_controller.h b/wifi/1.6/default/tests/mock_wifi_mode_controller.h index b9151f18b4..addcc81591 100644 --- a/wifi/1.5/default/tests/mock_wifi_mode_controller.h +++ b/wifi/1.6/default/tests/mock_wifi_mode_controller.h @@ -24,12 +24,12 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace mode_controller { class MockWifiModeController : public WifiModeController { - public: + public: MockWifiModeController(); MOCK_METHOD0(initialize, bool()); MOCK_METHOD1(changeFirmwareMode, bool(IfaceType)); @@ -38,7 +38,7 @@ class MockWifiModeController : public WifiModeController { }; } // namespace mode_controller } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/tests/ringbuffer_unit_tests.cpp b/wifi/1.6/default/tests/ringbuffer_unit_tests.cpp index 6fd34ee29c..eb86194ff0 100644 --- a/wifi/1.5/default/tests/ringbuffer_unit_tests.cpp +++ b/wifi/1.6/default/tests/ringbuffer_unit_tests.cpp @@ -24,11 +24,11 @@ using testing::Test; namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { class RingbufferTest : public Test { - public: + public: const uint32_t maxBufferSize_ = 10; Ringbuffer buffer_{maxBufferSize_}; }; @@ -91,7 +91,7 @@ TEST_F(RingbufferTest, OversizedAppendDoesNotDropExistingData) { EXPECT_EQ(input, buffer_.getData().front()); } } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/tests/runtests.sh b/wifi/1.6/default/tests/runtests.sh index 6bce3ef8c4..6bce3ef8c4 100755 --- a/wifi/1.5/default/tests/runtests.sh +++ b/wifi/1.6/default/tests/runtests.sh diff --git a/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.6/default/tests/wifi_chip_unit_tests.cpp index 0ad6f3e821..53904116cf 100644 --- a/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp +++ b/wifi/1.6/default/tests/wifi_chip_unit_tests.cpp @@ -41,11 +41,11 @@ constexpr ChipId kFakeChipId = 5; namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { class WifiChipTest : public Test { - protected: + protected: void setupV1IfaceCombination() { // clang-format off const hidl_vec<V1_0::IWifiChip::ChipIfaceCombination> combinationsSta = { @@ -59,8 +59,7 @@ class WifiChipTest : public Test { {feature_flags::chip_mode_ids::kV1Ap, combinationsAp} }; // clang-format on - EXPECT_CALL(*feature_flags_, getChipModes(true)) - .WillRepeatedly(testing::Return(modes)); + EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes)); } void setupV1_AwareIfaceCombination() { @@ -76,8 +75,7 @@ class WifiChipTest : public Test { {feature_flags::chip_mode_ids::kV1Ap, combinationsAp} }; // clang-format on - EXPECT_CALL(*feature_flags_, getChipModes(true)) - .WillRepeatedly(testing::Return(modes)); + EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes)); } void setupV1_AwareDisabledApIfaceCombination() { @@ -89,8 +87,7 @@ class WifiChipTest : public Test { {feature_flags::chip_mode_ids::kV1Sta, combinationsSta} }; // clang-format on - EXPECT_CALL(*feature_flags_, getChipModes(true)) - .WillRepeatedly(testing::Return(modes)); + EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes)); } void setupV2_AwareIfaceCombination() { @@ -103,8 +100,7 @@ class WifiChipTest : public Test { {feature_flags::chip_mode_ids::kV3, combinations} }; // clang-format on - EXPECT_CALL(*feature_flags_, getChipModes(true)) - .WillRepeatedly(testing::Return(modes)); + EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes)); } void setupV2_AwareDisabledApIfaceCombination() { @@ -116,8 +112,7 @@ class WifiChipTest : public Test { {feature_flags::chip_mode_ids::kV3, combinations} }; // clang-format on - EXPECT_CALL(*feature_flags_, getChipModes(true)) - .WillRepeatedly(testing::Return(modes)); + EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes)); } void setup_MultiIfaceCombination() { @@ -129,39 +124,35 @@ class WifiChipTest : public Test { {feature_flags::chip_mode_ids::kV3, combinations} }; // clang-format on - EXPECT_CALL(*feature_flags_, getChipModes(true)) - .WillRepeatedly(testing::Return(modes)); + EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes)); } void assertNumberOfModes(uint32_t num_modes) { - chip_->getAvailableModes( - [num_modes](const WifiStatus& status, - const std::vector<WifiChip::ChipMode>& modes) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - // V2_Aware has 1 mode of operation. - ASSERT_EQ(num_modes, modes.size()); - }); + chip_->getAvailableModes([num_modes](const WifiStatus& status, + const std::vector<WifiChip::ChipMode>& modes) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + // V2_Aware has 1 mode of operation. + ASSERT_EQ(num_modes, modes.size()); + }); } void findModeAndConfigureForIfaceType(const IfaceType& type) { // This should be aligned with kInvalidModeId in wifi_chip.cpp. ChipModeId mode_id = UINT32_MAX; - chip_->getAvailableModes( - [&mode_id, &type](const WifiStatus& status, - const std::vector<WifiChip::ChipMode>& modes) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - for (const auto& mode : modes) { - for (const auto& combination : mode.availableCombinations) { - for (const auto& limit : combination.limits) { - if (limit.types.end() != - std::find(limit.types.begin(), - limit.types.end(), type)) { - mode_id = mode.id; - } + chip_->getAvailableModes([&mode_id, &type](const WifiStatus& status, + const std::vector<WifiChip::ChipMode>& modes) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + for (const auto& mode : modes) { + for (const auto& combination : mode.availableCombinations) { + for (const auto& limit : combination.limits) { + if (limit.types.end() != + std::find(limit.types.begin(), limit.types.end(), type)) { + mode_id = mode.id; } } } - }); + } + }); ASSERT_NE(UINT32_MAX, mode_id); chip_->configureChip(mode_id, [](const WifiStatus& status) { @@ -174,58 +165,53 @@ class WifiChipTest : public Test { std::string iface_name; if (type == IfaceType::AP) { chip_->createApIface( - [&iface_name](const WifiStatus& status, - const sp<V1_0::IWifiApIface>& iface) { - if (WifiStatusCode::SUCCESS == status.code) { - ASSERT_NE(iface.get(), nullptr); - iface->getName([&iface_name](const WifiStatus& status, - const hidl_string& name) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - iface_name = name.c_str(); - }); - } - }); + [&iface_name](const WifiStatus& status, const sp<V1_0::IWifiApIface>& iface) { + if (WifiStatusCode::SUCCESS == status.code) { + ASSERT_NE(iface.get(), nullptr); + iface->getName([&iface_name](const WifiStatus& status, + const hidl_string& name) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + iface_name = name.c_str(); + }); + } + }); } else if (type == IfaceType::NAN) { chip_->createNanIface( - [&iface_name]( - const WifiStatus& status, - const sp<android::hardware::wifi::V1_0::IWifiNanIface>& - iface) { - if (WifiStatusCode::SUCCESS == status.code) { - ASSERT_NE(iface.get(), nullptr); - iface->getName([&iface_name](const WifiStatus& status, - const hidl_string& name) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - iface_name = name.c_str(); - }); - } - }); + [&iface_name](const WifiStatus& status, + const sp<android::hardware::wifi::V1_0::IWifiNanIface>& iface) { + if (WifiStatusCode::SUCCESS == status.code) { + ASSERT_NE(iface.get(), nullptr); + iface->getName([&iface_name](const WifiStatus& status, + const hidl_string& name) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + iface_name = name.c_str(); + }); + } + }); } else if (type == IfaceType::P2P) { chip_->createP2pIface( - [&iface_name](const WifiStatus& status, - const sp<IWifiP2pIface>& iface) { - if (WifiStatusCode::SUCCESS == status.code) { - ASSERT_NE(iface.get(), nullptr); - iface->getName([&iface_name](const WifiStatus& status, - const hidl_string& name) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - iface_name = name.c_str(); - }); - } - }); + [&iface_name](const WifiStatus& status, const sp<IWifiP2pIface>& iface) { + if (WifiStatusCode::SUCCESS == status.code) { + ASSERT_NE(iface.get(), nullptr); + iface->getName([&iface_name](const WifiStatus& status, + const hidl_string& name) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + iface_name = name.c_str(); + }); + } + }); } else if (type == IfaceType::STA) { chip_->createStaIface( - [&iface_name](const WifiStatus& status, - const sp<V1_0::IWifiStaIface>& iface) { - if (WifiStatusCode::SUCCESS == status.code) { - ASSERT_NE(iface.get(), nullptr); - iface->getName([&iface_name](const WifiStatus& status, - const hidl_string& name) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - iface_name = name.c_str(); - }); - } - }); + [&iface_name](const WifiStatus& status, const sp<V1_0::IWifiStaIface>& iface) { + if (WifiStatusCode::SUCCESS == status.code) { + ASSERT_NE(iface.get(), nullptr); + iface->getName([&iface_name](const WifiStatus& status, + const hidl_string& name) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + iface_name = name.c_str(); + }); + } + }); } return iface_name; } @@ -253,13 +239,12 @@ class WifiChipTest : public Test { bool createRttController() { bool success = false; chip_->createRttController_1_4( - NULL, [&success](const WifiStatus& status, - const sp<IWifiRttController>& rtt) { - if (WifiStatusCode::SUCCESS == status.code) { - ASSERT_NE(rtt.get(), nullptr); - success = true; - } - }); + NULL, [&success](const WifiStatus& status, const sp<IWifiRttController>& rtt) { + if (WifiStatusCode::SUCCESS == status.code) { + ASSERT_NE(rtt.get(), nullptr); + success = true; + } + }); return success; } @@ -269,27 +254,25 @@ class WifiChipTest : public Test { ChipId chip_id_ = kFakeChipId; legacy_hal::wifi_hal_fn fake_func_table_; std::shared_ptr<NiceMock<wifi_system::MockInterfaceTool>> iface_tool_{ - new NiceMock<wifi_system::MockInterfaceTool>}; + new NiceMock<wifi_system::MockInterfaceTool>}; std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{ - new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_, - fake_func_table_, true)}; - std::shared_ptr<NiceMock<mode_controller::MockWifiModeController>> - mode_controller_{new NiceMock<mode_controller::MockWifiModeController>}; + new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_, fake_func_table_, true)}; + std::shared_ptr<NiceMock<mode_controller::MockWifiModeController>> mode_controller_{ + new NiceMock<mode_controller::MockWifiModeController>}; std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{ - new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_, legacy_hal_)}; - std::shared_ptr<NiceMock<feature_flags::MockWifiFeatureFlags>> - feature_flags_{new NiceMock<feature_flags::MockWifiFeatureFlags>}; + new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_, legacy_hal_)}; + std::shared_ptr<NiceMock<feature_flags::MockWifiFeatureFlags>> feature_flags_{ + new NiceMock<feature_flags::MockWifiFeatureFlags>}; - public: + public: void SetUp() override { - chip_ = - new WifiChip(chip_id_, true, legacy_hal_, mode_controller_, - iface_util_, feature_flags_, subsystemRestartHandler); + chip_ = new WifiChip(chip_id_, true, legacy_hal_, mode_controller_, iface_util_, + feature_flags_, subsystemRestartHandler); EXPECT_CALL(*mode_controller_, changeFirmwareMode(testing::_)) - .WillRepeatedly(testing::Return(true)); + .WillRepeatedly(testing::Return(true)); EXPECT_CALL(*legacy_hal_, start()) - .WillRepeatedly(testing::Return(legacy_hal::WIFI_SUCCESS)); + .WillRepeatedly(testing::Return(legacy_hal::WIFI_SUCCESS)); } void TearDown() override { @@ -305,7 +288,7 @@ class WifiChipTest : public Test { // Mode 1 - STA + P2P // Mode 2 - AP class WifiChipV1IfaceCombinationTest : public WifiChipTest { - public: + public: void SetUp() override { setupV1IfaceCombination(); WifiChipTest::SetUp(); @@ -364,7 +347,7 @@ TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateNan_ShouldFail) { // Mode 1 - STA + P2P/NAN // Mode 2 - AP class WifiChipV1_AwareIfaceCombinationTest : public WifiChipTest { - public: + public: void SetUp() override { setupV1_AwareIfaceCombination(); WifiChipTest::SetUp(); @@ -393,30 +376,26 @@ TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateAp_ShouldFail) { ASSERT_TRUE(createIface(IfaceType::AP).empty()); } -TEST_F(WifiChipV1_AwareIfaceCombinationTest, - StaMode_CreateStaP2p_ShouldSucceed) { +TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaP2p_ShouldSucceed) { findModeAndConfigureForIfaceType(IfaceType::STA); ASSERT_FALSE(createIface(IfaceType::STA).empty()); ASSERT_FALSE(createIface(IfaceType::P2P).empty()); } -TEST_F(WifiChipV1_AwareIfaceCombinationTest, - StaMode_CreateStaNan_ShouldSucceed) { +TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaNan_ShouldSucceed) { findModeAndConfigureForIfaceType(IfaceType::STA); ASSERT_FALSE(createIface(IfaceType::STA).empty()); ASSERT_FALSE(createIface(IfaceType::NAN).empty()); } -TEST_F(WifiChipV1_AwareIfaceCombinationTest, - StaMode_CreateStaP2PNan_ShouldFail) { +TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaP2PNan_ShouldFail) { findModeAndConfigureForIfaceType(IfaceType::STA); ASSERT_FALSE(createIface(IfaceType::STA).empty()); ASSERT_FALSE(createIface(IfaceType::P2P).empty()); ASSERT_TRUE(createIface(IfaceType::NAN).empty()); } -TEST_F(WifiChipV1_AwareIfaceCombinationTest, - StaMode_CreateStaNan_AfterP2pRemove_ShouldSucceed) { +TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaNan_AfterP2pRemove_ShouldSucceed) { findModeAndConfigureForIfaceType(IfaceType::STA); ASSERT_FALSE(createIface(IfaceType::STA).empty()); const auto p2p_iface_name = createIface(IfaceType::P2P); @@ -428,8 +407,7 @@ TEST_F(WifiChipV1_AwareIfaceCombinationTest, ASSERT_FALSE(createIface(IfaceType::NAN).empty()); } -TEST_F(WifiChipV1_AwareIfaceCombinationTest, - StaMode_CreateStaP2p_AfterNanRemove_ShouldSucceed) { +TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaP2p_AfterNanRemove_ShouldSucceed) { findModeAndConfigureForIfaceType(IfaceType::STA); ASSERT_FALSE(createIface(IfaceType::STA).empty()); const auto nan_iface_name = createIface(IfaceType::NAN); @@ -488,31 +466,27 @@ TEST_F(WifiChipV1_AwareIfaceCombinationTest, SelectTxScenarioWithOnlySta) { findModeAndConfigureForIfaceType(IfaceType::STA); ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_)) - .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); + .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); chip_->selectTxPowerScenario_1_2( - V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF, - [](const WifiStatus& status) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - }); + V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF, + [](const WifiStatus& status) { ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); }); } TEST_F(WifiChipV1_AwareIfaceCombinationTest, SelectTxScenarioWithOnlyAp) { findModeAndConfigureForIfaceType(IfaceType::AP); ASSERT_EQ(createIface(IfaceType::AP), "wlan0"); EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_)) - .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); + .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); chip_->selectTxPowerScenario_1_2( - V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF, - [](const WifiStatus& status) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - }); + V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF, + [](const WifiStatus& status) { ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); }); } ////////// V2 + Aware Iface Combinations //////////// // Mode 1 - STA + STA/AP // - STA + P2P/NAN class WifiChipV2_AwareIfaceCombinationTest : public WifiChipTest { - public: + public: void SetUp() override { setupV2_AwareIfaceCombination(); WifiChipTest::SetUp(); @@ -559,8 +533,7 @@ TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApSta_ShouldSucceed) { ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); } -TEST_F(WifiChipV2_AwareIfaceCombinationTest, - CreateSta_AfterStaApRemove_ShouldSucceed) { +TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateSta_AfterStaApRemove_ShouldSucceed) { findModeAndConfigureForIfaceType(IfaceType::STA); const auto sta_iface_name = createIface(IfaceType::STA); ASSERT_FALSE(sta_iface_name.empty()); @@ -594,8 +567,7 @@ TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaP2PNan_ShouldFail) { ASSERT_TRUE(createIface(IfaceType::NAN).empty()); } -TEST_F(WifiChipV2_AwareIfaceCombinationTest, - CreateStaNan_AfterP2pRemove_ShouldSucceed) { +TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaNan_AfterP2pRemove_ShouldSucceed) { findModeAndConfigureForIfaceType(IfaceType::STA); ASSERT_FALSE(createIface(IfaceType::STA).empty()); const auto p2p_iface_name = createIface(IfaceType::P2P); @@ -607,8 +579,7 @@ TEST_F(WifiChipV2_AwareIfaceCombinationTest, ASSERT_FALSE(createIface(IfaceType::NAN).empty()); } -TEST_F(WifiChipV2_AwareIfaceCombinationTest, - CreateStaP2p_AfterNanRemove_ShouldSucceed) { +TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaP2p_AfterNanRemove_ShouldSucceed) { findModeAndConfigureForIfaceType(IfaceType::STA); ASSERT_FALSE(createIface(IfaceType::STA).empty()); const auto nan_iface_name = createIface(IfaceType::NAN); @@ -632,8 +603,7 @@ TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApP2p_ShouldFail) { ASSERT_TRUE(createIface(IfaceType::P2P).empty()); } -TEST_F(WifiChipV2_AwareIfaceCombinationTest, - StaMode_CreateStaNan_AfterP2pRemove_ShouldSucceed) { +TEST_F(WifiChipV2_AwareIfaceCombinationTest, StaMode_CreateStaNan_AfterP2pRemove_ShouldSucceed) { findModeAndConfigureForIfaceType(IfaceType::STA); ASSERT_FALSE(createIface(IfaceType::STA).empty()); const auto p2p_iface_name = createIface(IfaceType::P2P); @@ -645,8 +615,7 @@ TEST_F(WifiChipV2_AwareIfaceCombinationTest, ASSERT_FALSE(createIface(IfaceType::NAN).empty()); } -TEST_F(WifiChipV2_AwareIfaceCombinationTest, - StaMode_CreateStaP2p_AfterNanRemove_ShouldSucceed) { +TEST_F(WifiChipV2_AwareIfaceCombinationTest, StaMode_CreateStaP2p_AfterNanRemove_ShouldSucceed) { findModeAndConfigureForIfaceType(IfaceType::STA); ASSERT_FALSE(createIface(IfaceType::STA).empty()); const auto nan_iface_name = createIface(IfaceType::NAN); @@ -658,8 +627,7 @@ TEST_F(WifiChipV2_AwareIfaceCombinationTest, ASSERT_FALSE(createIface(IfaceType::P2P).empty()); } -TEST_F(WifiChipV2_AwareIfaceCombinationTest, - CreateStaAp_EnsureDifferentIfaceNames) { +TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaAp_EnsureDifferentIfaceNames) { findModeAndConfigureForIfaceType(IfaceType::AP); const auto sta_iface_name = createIface(IfaceType::STA); const auto ap_iface_name = createIface(IfaceType::AP); @@ -690,28 +658,23 @@ TEST_F(WifiChipV2_AwareIfaceCombinationTest, SelectTxScenarioWithOnlySta) { findModeAndConfigureForIfaceType(IfaceType::STA); ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_)) - .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); + .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); chip_->selectTxPowerScenario_1_2( - V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF, - [](const WifiStatus& status) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - }); + V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF, + [](const WifiStatus& status) { ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); }); } TEST_F(WifiChipV2_AwareIfaceCombinationTest, SelectTxScenarioWithOnlyAp) { findModeAndConfigureForIfaceType(IfaceType::AP); ASSERT_EQ(createIface(IfaceType::AP), "wlan1"); EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan1", testing::_)) - .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); + .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); chip_->selectTxPowerScenario_1_2( - V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF, - [](const WifiStatus& status) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - }); + V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF, + [](const WifiStatus& status) { ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); }); } -TEST_F(WifiChipV2_AwareIfaceCombinationTest, - InvalidateAndRemoveNanOnStaRemove) { +TEST_F(WifiChipV2_AwareIfaceCombinationTest, InvalidateAndRemoveNanOnStaRemove) { findModeAndConfigureForIfaceType(IfaceType::STA); ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); @@ -719,64 +682,55 @@ TEST_F(WifiChipV2_AwareIfaceCombinationTest, ASSERT_EQ(createIface(IfaceType::NAN), "wlan0"); // We should have 1 nan iface. - chip_->getNanIfaceNames( - [](const WifiStatus& status, const hidl_vec<hidl_string>& iface_names) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - ASSERT_EQ(iface_names.size(), 1u); - ASSERT_EQ(iface_names[0], "wlan0"); - }); + chip_->getNanIfaceNames([](const WifiStatus& status, const hidl_vec<hidl_string>& iface_names) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + ASSERT_EQ(iface_names.size(), 1u); + ASSERT_EQ(iface_names[0], "wlan0"); + }); // Retrieve the exact iface object. sp<android::hardware::wifi::V1_0::IWifiNanIface> nan_iface; - chip_->getNanIface( - "wlan0", - [&nan_iface]( - const WifiStatus& status, - const sp<android::hardware::wifi::V1_0::IWifiNanIface>& iface) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - ASSERT_NE(iface.get(), nullptr); - nan_iface = iface; - }); + chip_->getNanIface("wlan0", + [&nan_iface](const WifiStatus& status, + const sp<android::hardware::wifi::V1_0::IWifiNanIface>& iface) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + ASSERT_NE(iface.get(), nullptr); + nan_iface = iface; + }); // Remove the STA iface. removeIface(IfaceType::STA, "wlan0"); // We should have 0 nan iface now. - chip_->getNanIfaceNames( - [](const WifiStatus& status, const hidl_vec<hidl_string>& iface_names) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - ASSERT_EQ(iface_names.size(), 0u); - }); + chip_->getNanIfaceNames([](const WifiStatus& status, const hidl_vec<hidl_string>& iface_names) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + ASSERT_EQ(iface_names.size(), 0u); + }); // Any operation on the nan iface object should return error now. - nan_iface->getName( - [](const WifiStatus& status, const std::string& /* iface_name */) { - ASSERT_EQ(WifiStatusCode::ERROR_WIFI_IFACE_INVALID, status.code); - }); + nan_iface->getName([](const WifiStatus& status, const std::string& /* iface_name */) { + ASSERT_EQ(WifiStatusCode::ERROR_WIFI_IFACE_INVALID, status.code); + }); } -TEST_F(WifiChipV2_AwareIfaceCombinationTest, - InvalidateAndRemoveRttControllerOnStaRemove) { +TEST_F(WifiChipV2_AwareIfaceCombinationTest, InvalidateAndRemoveRttControllerOnStaRemove) { findModeAndConfigureForIfaceType(IfaceType::STA); ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); // Create RTT controller sp<IWifiRttController> rtt_controller; chip_->createRttController_1_4( - NULL, [&rtt_controller](const WifiStatus& status, - const sp<IWifiRttController>& rtt) { - if (WifiStatusCode::SUCCESS == status.code) { - ASSERT_NE(rtt.get(), nullptr); - rtt_controller = rtt; - } - }); + NULL, [&rtt_controller](const WifiStatus& status, const sp<IWifiRttController>& rtt) { + if (WifiStatusCode::SUCCESS == status.code) { + ASSERT_NE(rtt.get(), nullptr); + rtt_controller = rtt; + } + }); // Remove the STA iface. removeIface(IfaceType::STA, "wlan0"); // Any operation on the rtt controller object should return error now. - rtt_controller->getBoundIface( - [](const WifiStatus& status, const sp<IWifiIface>& /* iface */) { - ASSERT_EQ(WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - status.code); - }); + rtt_controller->getBoundIface([](const WifiStatus& status, const sp<IWifiIface>& /* iface */) { + ASSERT_EQ(WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, status.code); + }); } TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNanWithSharedNanIface) { @@ -792,28 +746,24 @@ TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNanWithDedicatedNanIface) { property_set("wifi.aware.interface", "aware0"); findModeAndConfigureForIfaceType(IfaceType::STA); ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); - EXPECT_CALL(*iface_util_, ifNameToIndex("aware0")) - .WillOnce(testing::Return(4)); - EXPECT_CALL(*iface_util_, setUpState("aware0", true)) - .WillOnce(testing::Return(true)); + EXPECT_CALL(*iface_util_, ifNameToIndex("aware0")).WillOnce(testing::Return(4)); + EXPECT_CALL(*iface_util_, setUpState("aware0", true)).WillOnce(testing::Return(true)); ASSERT_EQ(createIface(IfaceType::NAN), "aware0"); - EXPECT_CALL(*iface_util_, setUpState("aware0", false)) - .WillOnce(testing::Return(true)); + EXPECT_CALL(*iface_util_, setUpState("aware0", false)).WillOnce(testing::Return(true)); removeIface(IfaceType::NAN, "aware0"); } ////////// V1 Iface Combinations when AP creation is disabled ////////// class WifiChipV1_AwareDisabledApIfaceCombinationTest : public WifiChipTest { - public: + public: void SetUp() override { setupV1_AwareDisabledApIfaceCombination(); WifiChipTest::SetUp(); } }; -TEST_F(WifiChipV1_AwareDisabledApIfaceCombinationTest, - StaMode_CreateSta_ShouldSucceed) { +TEST_F(WifiChipV1_AwareDisabledApIfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) { findModeAndConfigureForIfaceType(IfaceType::STA); ASSERT_FALSE(createIface(IfaceType::STA).empty()); ASSERT_TRUE(createIface(IfaceType::AP).empty()); @@ -821,15 +771,14 @@ TEST_F(WifiChipV1_AwareDisabledApIfaceCombinationTest, ////////// V2 Iface Combinations when AP creation is disabled ////////// class WifiChipV2_AwareDisabledApIfaceCombinationTest : public WifiChipTest { - public: + public: void SetUp() override { setupV2_AwareDisabledApIfaceCombination(); WifiChipTest::SetUp(); } }; -TEST_F(WifiChipV2_AwareDisabledApIfaceCombinationTest, - CreateSta_ShouldSucceed) { +TEST_F(WifiChipV2_AwareDisabledApIfaceCombinationTest, CreateSta_ShouldSucceed) { findModeAndConfigureForIfaceType(IfaceType::STA); ASSERT_FALSE(createIface(IfaceType::STA).empty()); ASSERT_TRUE(createIface(IfaceType::AP).empty()); @@ -837,7 +786,7 @@ TEST_F(WifiChipV2_AwareDisabledApIfaceCombinationTest, ////////// Hypothetical Iface Combination with multiple ifaces ////////// class WifiChip_MultiIfaceTest : public WifiChipTest { - public: + public: void SetUp() override { setup_MultiIfaceCombination(); WifiChipTest::SetUp(); @@ -899,7 +848,7 @@ TEST_F(WifiChip_MultiIfaceTest, CreateApStartsWithIdx1) { ASSERT_EQ(createIface(IfaceType::STA), "wlan3"); } } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp b/wifi/1.6/default/tests/wifi_iface_util_unit_tests.cpp index 8b67bb80c8..cc9a3340a5 100644 --- a/wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp +++ b/wifi/1.6/default/tests/wifi_iface_util_unit_tests.cpp @@ -32,8 +32,7 @@ constexpr uint8_t kValidUnicastLocallyAssignedMacAddressMask = 0x02; constexpr uint8_t kMacAddress[] = {0x02, 0x12, 0x45, 0x56, 0xab, 0xcc}; constexpr char kIfaceName[] = "test-wlan0"; -bool isValidUnicastLocallyAssignedMacAddress( - const std::array<uint8_t, 6>& mac_address) { +bool isValidUnicastLocallyAssignedMacAddress(const std::array<uint8_t, 6>& mac_address) { uint8_t first_byte = mac_address[0]; return (first_byte & 0x3) == kValidUnicastLocallyAssignedMacAddressMask; } @@ -42,17 +41,16 @@ bool isValidUnicastLocallyAssignedMacAddress( namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace iface_util { class WifiIfaceUtilTest : public Test { - protected: + protected: std::shared_ptr<NiceMock<wifi_system::MockInterfaceTool>> iface_tool_{ - new NiceMock<wifi_system::MockInterfaceTool>}; + new NiceMock<wifi_system::MockInterfaceTool>}; legacy_hal::wifi_hal_fn fake_func_table_; std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{ - new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_, - fake_func_table_, true)}; + new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_, fake_func_table_, true)}; WifiIfaceUtil* iface_util_ = new WifiIfaceUtil(iface_tool_, legacy_hal_); }; @@ -67,20 +65,17 @@ TEST_F(WifiIfaceUtilTest, GetOrCreateRandomMacAddress) { TEST_F(WifiIfaceUtilTest, IfaceEventHandlers_SetMacAddress) { std::array<uint8_t, 6> mac_address = {}; - std::copy(std::begin(kMacAddress), std::end(kMacAddress), - std::begin(mac_address)); + std::copy(std::begin(kMacAddress), std::end(kMacAddress), std::begin(mac_address)); EXPECT_CALL(*iface_tool_, SetMacAddress(testing::_, testing::_)) - .WillRepeatedly(testing::Return(true)); + .WillRepeatedly(testing::Return(true)); EXPECT_CALL(*iface_tool_, SetUpState(testing::_, testing::_)) - .WillRepeatedly(testing::Return(true)); + .WillRepeatedly(testing::Return(true)); // Register for iface state toggle events. bool callback_invoked = false; iface_util::IfaceEventHandlers event_handlers = {}; event_handlers.on_state_toggle_off_on = - [&callback_invoked](const std::string& /* iface_name */) { - callback_invoked = true; - }; + [&callback_invoked](const std::string& /* iface_name */) { callback_invoked = true; }; iface_util_->registerIfaceEventHandlers(kIfaceName, event_handlers); // Invoke setMacAddress and ensure that the cb is invoked. ASSERT_TRUE(iface_util_->setMacAddress(kIfaceName, mac_address)); @@ -95,7 +90,7 @@ TEST_F(WifiIfaceUtilTest, IfaceEventHandlers_SetMacAddress) { } } // namespace iface_util } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.6/default/tests/wifi_nan_iface_unit_tests.cpp b/wifi/1.6/default/tests/wifi_nan_iface_unit_tests.cpp new file mode 100644 index 0000000000..c7c566bec1 --- /dev/null +++ b/wifi/1.6/default/tests/wifi_nan_iface_unit_tests.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <android-base/logging.h> +#include <android-base/macros.h> +#include <cutils/properties.h> +#include <gmock/gmock.h> + +#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38 +#include "wifi_nan_iface.h" + +#include "mock_interface_tool.h" +#include "mock_wifi_feature_flags.h" +#include "mock_wifi_iface_util.h" +#include "mock_wifi_legacy_hal.h" + +using testing::NiceMock; +using testing::Return; +using testing::Test; + +namespace { +constexpr char kIfaceName[] = "mockWlan0"; +} // namespace + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { + +using android::hardware::wifi::V1_2::NanDataPathConfirmInd; + +bool CaptureIfaceEventHandlers(const std::string& /* iface_name*/, + iface_util::IfaceEventHandlers in_iface_event_handlers, + iface_util::IfaceEventHandlers* out_iface_event_handlers) { + *out_iface_event_handlers = in_iface_event_handlers; + return true; +} + +class MockNanIfaceEventCallback : public V1_5::IWifiNanIfaceEventCallback { + public: + MockNanIfaceEventCallback() = default; + + MOCK_METHOD3(notifyCapabilitiesResponse, + Return<void>(uint16_t, const WifiNanStatus&, + const android::hardware::wifi::V1_0::NanCapabilities&)); + MOCK_METHOD2(notifyEnableResponse, Return<void>(uint16_t, const WifiNanStatus&)); + MOCK_METHOD2(notifyConfigResponse, Return<void>(uint16_t, const WifiNanStatus&)); + MOCK_METHOD2(notifyDisableResponse, Return<void>(uint16_t, const WifiNanStatus&)); + MOCK_METHOD3(notifyStartPublishResponse, Return<void>(uint16_t, const WifiNanStatus&, uint8_t)); + MOCK_METHOD2(notifyStopPublishResponse, Return<void>(uint16_t, const WifiNanStatus&)); + MOCK_METHOD3(notifyStartSubscribeResponse, + Return<void>(uint16_t, const WifiNanStatus&, uint8_t)); + MOCK_METHOD2(notifyStopSubscribeResponse, Return<void>(uint16_t, const WifiNanStatus&)); + MOCK_METHOD2(notifyTransmitFollowupResponse, Return<void>(uint16_t, const WifiNanStatus&)); + MOCK_METHOD2(notifyCreateDataInterfaceResponse, Return<void>(uint16_t, const WifiNanStatus&)); + MOCK_METHOD2(notifyDeleteDataInterfaceResponse, Return<void>(uint16_t, const WifiNanStatus&)); + MOCK_METHOD3(notifyInitiateDataPathResponse, + Return<void>(uint16_t, const WifiNanStatus&, uint32_t)); + MOCK_METHOD2(notifyRespondToDataPathIndicationResponse, + Return<void>(uint16_t, const WifiNanStatus&)); + MOCK_METHOD2(notifyTerminateDataPathResponse, Return<void>(uint16_t, const WifiNanStatus&)); + MOCK_METHOD1(eventClusterEvent, Return<void>(const NanClusterEventInd&)); + MOCK_METHOD1(eventDisabled, Return<void>(const WifiNanStatus&)); + MOCK_METHOD2(eventPublishTerminated, Return<void>(uint8_t, const WifiNanStatus&)); + MOCK_METHOD2(eventSubscribeTerminated, Return<void>(uint8_t, const WifiNanStatus&)); + MOCK_METHOD1(eventMatch, Return<void>(const NanMatchInd&)); + MOCK_METHOD2(eventMatchExpired, Return<void>(uint8_t, uint32_t)); + MOCK_METHOD1(eventFollowupReceived, Return<void>(const NanFollowupReceivedInd&)); + MOCK_METHOD2(eventTransmitFollowup, Return<void>(uint16_t, const WifiNanStatus&)); + MOCK_METHOD1(eventDataPathRequest, Return<void>(const NanDataPathRequestInd&)); + MOCK_METHOD1(eventDataPathConfirm, + Return<void>(const android::hardware::wifi::V1_0::NanDataPathConfirmInd&)); + MOCK_METHOD1(eventDataPathTerminated, Return<void>(uint32_t)); + MOCK_METHOD1(eventDataPathConfirm_1_2, Return<void>(const NanDataPathConfirmInd&)); + MOCK_METHOD1(eventDataPathScheduleUpdate, Return<void>(const NanDataPathScheduleUpdateInd&)); + MOCK_METHOD3(notifyCapabilitiesResponse_1_5, + Return<void>(uint16_t, const WifiNanStatus&, const V1_5::NanCapabilities&)); +}; + +class WifiNanIfaceTest : public Test { + protected: + legacy_hal::wifi_hal_fn fake_func_table_; + std::shared_ptr<NiceMock<wifi_system::MockInterfaceTool>> iface_tool_{ + new NiceMock<wifi_system::MockInterfaceTool>}; + std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{ + new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_, fake_func_table_, true)}; + std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{ + new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_, legacy_hal_)}; +}; + +TEST_F(WifiNanIfaceTest, IfacEventHandlers_OnStateToggleOffOn) { + iface_util::IfaceEventHandlers captured_iface_event_handlers = {}; + EXPECT_CALL(*legacy_hal_, nanRegisterCallbackHandlers(testing::_, testing::_)) + .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); + EXPECT_CALL(*iface_util_, registerIfaceEventHandlers(testing::_, testing::_)) + .WillOnce(testing::Invoke(bind(CaptureIfaceEventHandlers, std::placeholders::_1, + std::placeholders::_2, &captured_iface_event_handlers))); + sp<WifiNanIface> nan_iface = new WifiNanIface(kIfaceName, false, legacy_hal_, iface_util_); + + // Register a mock nan event callback. + sp<NiceMock<MockNanIfaceEventCallback>> mock_event_callback{ + new NiceMock<MockNanIfaceEventCallback>}; + nan_iface->registerEventCallback(mock_event_callback, [](const WifiStatus& status) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + }); + // Ensure that the eventDisabled() function in mock callback will be + // invoked. + WifiNanStatus expected_nan_status = {NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""}; + EXPECT_CALL(*mock_event_callback, eventDisabled(expected_nan_status)).Times(1); + + // Trigger the iface state toggle callback. + captured_iface_event_handlers.on_state_toggle_off_on(kIfaceName); +} +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.5/default/wifi.cpp b/wifi/1.6/default/wifi.cpp index a85b242a8a..c302ce2434 100644 --- a/wifi/1.5/default/wifi.cpp +++ b/wifi/1.6/default/wifi.cpp @@ -28,16 +28,15 @@ static constexpr android::hardware::wifi::V1_0::ChipId kPrimaryChipId = 0; namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { using hidl_return_util::validateAndCall; using hidl_return_util::validateAndCallWithLock; -Wifi::Wifi( - const std::shared_ptr<wifi_system::InterfaceTool> iface_tool, - const std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory, - const std::shared_ptr<mode_controller::WifiModeController> mode_controller, - const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags) +Wifi::Wifi(const std::shared_ptr<wifi_system::InterfaceTool> iface_tool, + const std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory, + const std::shared_ptr<mode_controller::WifiModeController> mode_controller, + const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags) : iface_tool_(iface_tool), legacy_hal_factory_(legacy_hal_factory), mode_controller_(mode_controller), @@ -49,46 +48,44 @@ bool Wifi::isValid() { return true; } -Return<void> Wifi::registerEventCallback( - const sp<V1_0::IWifiEventCallback>& event_callback, - registerEventCallback_cb hidl_status_cb) { +Return<void> Wifi::registerEventCallback(const sp<V1_0::IWifiEventCallback>& event_callback, + registerEventCallback_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, - &Wifi::registerEventCallbackInternal, hidl_status_cb, - event_callback); + &Wifi::registerEventCallbackInternal, hidl_status_cb, event_callback); } -Return<void> Wifi::registerEventCallback_1_5( - const sp<V1_5::IWifiEventCallback>& event_callback, - registerEventCallback_1_5_cb hidl_status_cb) { +Return<void> Wifi::registerEventCallback_1_5(const sp<V1_5::IWifiEventCallback>& event_callback, + registerEventCallback_1_5_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, - &Wifi::registerEventCallbackInternal_1_5, - hidl_status_cb, event_callback); + &Wifi::registerEventCallbackInternal_1_5, hidl_status_cb, + event_callback); } -Return<bool> Wifi::isStarted() { return run_state_ != RunState::STOPPED; } +Return<bool> Wifi::isStarted() { + return run_state_ != RunState::STOPPED; +} Return<void> Wifi::start(start_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, - &Wifi::startInternal, hidl_status_cb); + return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::startInternal, + hidl_status_cb); } Return<void> Wifi::stop(stop_cb hidl_status_cb) { - return validateAndCallWithLock(this, WifiStatusCode::ERROR_UNKNOWN, - &Wifi::stopInternal, hidl_status_cb); + return validateAndCallWithLock(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::stopInternal, + hidl_status_cb); } Return<void> Wifi::getChipIds(getChipIds_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, - &Wifi::getChipIdsInternal, hidl_status_cb); + return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::getChipIdsInternal, + hidl_status_cb); } Return<void> Wifi::getChip(ChipId chip_id, getChip_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, - &Wifi::getChipInternal, hidl_status_cb, chip_id); + return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::getChipInternal, + hidl_status_cb, chip_id); } -Return<void> Wifi::debug(const hidl_handle& handle, - const hidl_vec<hidl_string>&) { +Return<void> Wifi::debug(const hidl_handle& handle, const hidl_vec<hidl_string>&) { LOG(INFO) << "-----------Debug is called----------------"; if (chips_.size() == 0) { return Void(); @@ -103,13 +100,13 @@ Return<void> Wifi::debug(const hidl_handle& handle, } WifiStatus Wifi::registerEventCallbackInternal( - const sp<V1_0::IWifiEventCallback>& event_callback __unused) { + const sp<V1_0::IWifiEventCallback>& event_callback __unused) { // Deprecated support for this callback. return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); } WifiStatus Wifi::registerEventCallbackInternal_1_5( - const sp<V1_5::IWifiEventCallback>& event_callback) { + const sp<V1_5::IWifiEventCallback>& event_callback) { if (!event_cb_handler_.addCallback(event_callback)) { return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); } @@ -120,36 +117,32 @@ WifiStatus Wifi::startInternal() { if (run_state_ == RunState::STARTED) { return createWifiStatus(WifiStatusCode::SUCCESS); } else if (run_state_ == RunState::STOPPING) { - return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, - "HAL is stopping"); + return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, "HAL is stopping"); } WifiStatus wifi_status = initializeModeControllerAndLegacyHal(); if (wifi_status.code == WifiStatusCode::SUCCESS) { // Register the callback for subsystem restart - const auto& on_subsystem_restart_callback = - [this](const std::string& error) { - WifiStatus wifi_status = - createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, error); - for (const auto& callback : event_cb_handler_.getCallbacks()) { - LOG(INFO) << "Attempting to invoke onSubsystemRestart " + const auto& on_subsystem_restart_callback = [this](const std::string& error) { + WifiStatus wifi_status = createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, error); + for (const auto& callback : event_cb_handler_.getCallbacks()) { + LOG(INFO) << "Attempting to invoke onSubsystemRestart " + "callback"; + if (!callback->onSubsystemRestart(wifi_status).isOk()) { + LOG(ERROR) << "Failed to invoke onSubsystemRestart callback"; + } else { + LOG(INFO) << "Succeeded to invoke onSubsystemRestart " "callback"; - if (!callback->onSubsystemRestart(wifi_status).isOk()) { - LOG(ERROR) - << "Failed to invoke onSubsystemRestart callback"; - } else { - LOG(INFO) << "Succeeded to invoke onSubsystemRestart " - "callback"; - } } - }; + } + }; // Create the chip instance once the HAL is started. android::hardware::wifi::V1_0::ChipId chipId = kPrimaryChipId; for (auto& hal : legacy_hals_) { - chips_.push_back(new WifiChip( - chipId, chipId == kPrimaryChipId, hal, mode_controller_, - std::make_shared<iface_util::WifiIfaceUtil>(iface_tool_, hal), - feature_flags_, on_subsystem_restart_callback)); + chips_.push_back( + new WifiChip(chipId, chipId == kPrimaryChipId, hal, mode_controller_, + std::make_shared<iface_util::WifiIfaceUtil>(iface_tool_, hal), + feature_flags_, on_subsystem_restart_callback)); chipId++; } run_state_ = RunState::STARTED; @@ -173,12 +166,11 @@ WifiStatus Wifi::startInternal() { } WifiStatus Wifi::stopInternal( - /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) { + /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) { if (run_state_ == RunState::STOPPED) { return createWifiStatus(WifiStatusCode::SUCCESS); } else if (run_state_ == RunState::STOPPING) { - return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, - "HAL is stopping"); + return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, "HAL is stopping"); } // Clear the chip object and its child objects since the HAL is now // stopped. @@ -220,8 +212,7 @@ std::pair<WifiStatus, std::vector<ChipId>> Wifi::getChipIdsInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), std::move(chip_ids)}; } -std::pair<WifiStatus, sp<V1_4::IWifiChip>> Wifi::getChipInternal( - ChipId chip_id) { +std::pair<WifiStatus, sp<V1_4::IWifiChip>> Wifi::getChipInternal(ChipId chip_id) { for (auto& chip : chips_) { ChipId cand_id = getChipIdFromWifiChip(chip); if ((cand_id != UINT32_MAX) && (cand_id == chip_id)) @@ -238,8 +229,7 @@ WifiStatus Wifi::initializeModeControllerAndLegacyHal() { } legacy_hals_ = legacy_hal_factory_->getHals(); - if (legacy_hals_.empty()) - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + if (legacy_hals_.empty()) return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); int index = 0; // for failure log for (auto& hal : legacy_hals_) { legacy_hal::wifi_error legacy_status = hal->initialize(); @@ -258,7 +248,7 @@ WifiStatus Wifi::initializeModeControllerAndLegacyHal() { } WifiStatus Wifi::stopLegacyHalAndDeinitializeModeController( - /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) { + /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) { legacy_hal::wifi_error legacy_status = legacy_hal::WIFI_SUCCESS; int index = 0; @@ -298,7 +288,7 @@ ChipId Wifi::getChipIdFromWifiChip(sp<WifiChip>& chip) { return chip_id; } } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/wifi.h b/wifi/1.6/default/wifi.h index c94ef3f4cf..435358e797 100644 --- a/wifi/1.5/default/wifi.h +++ b/wifi/1.6/default/wifi.h @@ -21,7 +21,7 @@ // headers. This wifi HAL uses an enum called NAN, which does not compile when // the macro is defined. Undefine NAN to work around it. #undef NAN -#include <android/hardware/wifi/1.5/IWifi.h> +#include <android/hardware/wifi/1.6/IWifi.h> #include <android-base/macros.h> #include <utils/Looper.h> @@ -37,46 +37,41 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { /** * Root HIDL interface object used to control the Wifi HAL. */ -class Wifi : public V1_5::IWifi { - public: +class Wifi : public V1_6::IWifi { + public: Wifi(const std::shared_ptr<wifi_system::InterfaceTool> iface_tool, - const std::shared_ptr<legacy_hal::WifiLegacyHalFactory> - legacy_hal_factory, - const std::shared_ptr<mode_controller::WifiModeController> - mode_controller, + const std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory, + const std::shared_ptr<mode_controller::WifiModeController> mode_controller, const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags); bool isValid(); // HIDL methods exposed. - Return<void> registerEventCallback( - const sp<V1_0::IWifiEventCallback>& event_callback, - registerEventCallback_cb hidl_status_cb) override; - Return<void> registerEventCallback_1_5( - const sp<V1_5::IWifiEventCallback>& event_callback, - registerEventCallback_1_5_cb hidl_status_cb) override; + Return<void> registerEventCallback(const sp<V1_0::IWifiEventCallback>& event_callback, + registerEventCallback_cb hidl_status_cb) override; + Return<void> registerEventCallback_1_5(const sp<V1_5::IWifiEventCallback>& event_callback, + registerEventCallback_1_5_cb hidl_status_cb) override; Return<bool> isStarted() override; Return<void> start(start_cb hidl_status_cb) override; Return<void> stop(stop_cb hidl_status_cb) override; Return<void> getChipIds(getChipIds_cb hidl_status_cb) override; Return<void> getChip(ChipId chip_id, getChip_cb hidl_status_cb) override; - Return<void> debug(const hidl_handle& handle, - const hidl_vec<hidl_string>& options) override; + Return<void> debug(const hidl_handle& handle, const hidl_vec<hidl_string>& options) override; - private: + private: enum class RunState { STOPPED, STARTED, STOPPING }; // Corresponding worker functions for the HIDL methods. WifiStatus registerEventCallbackInternal( - const sp<V1_0::IWifiEventCallback>& event_callback __unused); + const sp<V1_0::IWifiEventCallback>& event_callback __unused); WifiStatus registerEventCallbackInternal_1_5( - const sp<V1_5::IWifiEventCallback>& event_callback); + const sp<V1_5::IWifiEventCallback>& event_callback); WifiStatus startInternal(); WifiStatus stopInternal(std::unique_lock<std::recursive_mutex>* lock); std::pair<WifiStatus, std::vector<ChipId>> getChipIdsInternal(); @@ -84,7 +79,7 @@ class Wifi : public V1_5::IWifi { WifiStatus initializeModeControllerAndLegacyHal(); WifiStatus stopLegacyHalAndDeinitializeModeController( - std::unique_lock<std::recursive_mutex>* lock); + std::unique_lock<std::recursive_mutex>* lock); ChipId getChipIdFromWifiChip(sp<WifiChip>& chip); // Instance is created in this root level |IWifi| HIDL interface object @@ -96,14 +91,13 @@ class Wifi : public V1_5::IWifi { std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags_; RunState run_state_; std::vector<sp<WifiChip>> chips_; - hidl_callback_util::HidlCallbackHandler<V1_5::IWifiEventCallback> - event_cb_handler_; + hidl_callback_util::HidlCallbackHandler<V1_5::IWifiEventCallback> event_cb_handler_; DISALLOW_COPY_AND_ASSIGN(Wifi); }; } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/wifi_ap_iface.cpp b/wifi/1.6/default/wifi_ap_iface.cpp index 1ae7905f74..b2957db13f 100644 --- a/wifi/1.5/default/wifi_ap_iface.cpp +++ b/wifi/1.6/default/wifi_ap_iface.cpp @@ -24,14 +24,13 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { using hidl_return_util::validateAndCall; -WifiApIface::WifiApIface( - const std::string& ifname, const std::vector<std::string>& instances, - const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal, - const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util) +WifiApIface::WifiApIface(const std::string& ifname, const std::vector<std::string>& instances, + const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal, + const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util) : ifname_(ifname), instances_(instances), legacy_hal_(legacy_hal), @@ -43,14 +42,16 @@ void WifiApIface::invalidate() { is_valid_ = false; } -bool WifiApIface::isValid() { return is_valid_; } +bool WifiApIface::isValid() { + return is_valid_; +} -std::string WifiApIface::getName() { return ifname_; } +std::string WifiApIface::getName() { + return ifname_; +} void WifiApIface::removeInstance(std::string instance) { - instances_.erase( - std::remove(instances_.begin(), instances_.end(), instance), - instances_.end()); + instances_.erase(std::remove(instances_.begin(), instances_.end(), instance), instances_.end()); } Return<void> WifiApIface::getName(getName_cb hidl_status_cb) { @@ -66,44 +67,35 @@ Return<void> WifiApIface::getType(getType_cb hidl_status_cb) { Return<void> WifiApIface::setCountryCode(const hidl_array<int8_t, 2>& code, setCountryCode_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiApIface::setCountryCodeInternal, hidl_status_cb, - code); + &WifiApIface::setCountryCodeInternal, hidl_status_cb, code); } -Return<void> WifiApIface::getValidFrequenciesForBand( - V1_0::WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) { +Return<void> WifiApIface::getValidFrequenciesForBand(V1_0::WifiBand band, + getValidFrequenciesForBand_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiApIface::getValidFrequenciesForBandInternal, - hidl_status_cb, band); + &WifiApIface::getValidFrequenciesForBandInternal, hidl_status_cb, band); } Return<void> WifiApIface::setMacAddress(const hidl_array<uint8_t, 6>& mac, setMacAddress_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiApIface::setMacAddressInternal, hidl_status_cb, - mac); + &WifiApIface::setMacAddressInternal, hidl_status_cb, mac); } -Return<void> WifiApIface::getFactoryMacAddress( - getFactoryMacAddress_cb hidl_status_cb) { +Return<void> WifiApIface::getFactoryMacAddress(getFactoryMacAddress_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiApIface::getFactoryMacAddressInternal, - hidl_status_cb, + &WifiApIface::getFactoryMacAddressInternal, hidl_status_cb, instances_.size() > 0 ? instances_[0] : ifname_); } -Return<void> WifiApIface::resetToFactoryMacAddress( - resetToFactoryMacAddress_cb hidl_status_cb) { +Return<void> WifiApIface::resetToFactoryMacAddress(resetToFactoryMacAddress_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiApIface::resetToFactoryMacAddressInternal, - hidl_status_cb); + &WifiApIface::resetToFactoryMacAddressInternal, hidl_status_cb); } -Return<void> WifiApIface::getBridgedInstances( - getBridgedInstances_cb hidl_status_cb) { +Return<void> WifiApIface::getBridgedInstances(getBridgedInstances_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiApIface::getBridgedInstancesInternal, - hidl_status_cb); + &WifiApIface::getBridgedInstancesInternal, hidl_status_cb); } std::pair<WifiStatus, std::string> WifiApIface::getNameInternal() { @@ -114,28 +106,24 @@ std::pair<WifiStatus, IfaceType> WifiApIface::getTypeInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::AP}; } -WifiStatus WifiApIface::setCountryCodeInternal( - const std::array<int8_t, 2>& code) { +WifiStatus WifiApIface::setCountryCodeInternal(const std::array<int8_t, 2>& code) { legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setCountryCode( - instances_.size() > 0 ? instances_[0] : ifname_, code); + instances_.size() > 0 ? instances_[0] : ifname_, code); return createWifiStatusFromLegacyError(legacy_status); } std::pair<WifiStatus, std::vector<WifiChannelInMhz>> WifiApIface::getValidFrequenciesForBandInternal(V1_0::WifiBand band) { - static_assert(sizeof(WifiChannelInMhz) == sizeof(uint32_t), - "Size mismatch"); + static_assert(sizeof(WifiChannelInMhz) == sizeof(uint32_t), "Size mismatch"); legacy_hal::wifi_error legacy_status; std::vector<uint32_t> valid_frequencies; - std::tie(legacy_status, valid_frequencies) = - legacy_hal_.lock()->getValidFrequenciesForBand( + std::tie(legacy_status, valid_frequencies) = legacy_hal_.lock()->getValidFrequenciesForBand( instances_.size() > 0 ? instances_[0] : ifname_, hidl_struct_util::convertHidlWifiBandToLegacy(band)); return {createWifiStatusFromLegacyError(legacy_status), valid_frequencies}; } -WifiStatus WifiApIface::setMacAddressInternal( - const std::array<uint8_t, 6>& mac) { +WifiStatus WifiApIface::setMacAddressInternal(const std::array<uint8_t, 6>& mac) { // Support random MAC up to 2 interfaces if (instances_.size() == 2) { int rbyte = 1; @@ -160,12 +148,10 @@ WifiStatus WifiApIface::setMacAddressInternal( return createWifiStatus(WifiStatusCode::SUCCESS); } -std::pair<WifiStatus, std::array<uint8_t, 6>> -WifiApIface::getFactoryMacAddressInternal(const std::string& ifaceName) { - std::array<uint8_t, 6> mac = - iface_util_.lock()->getFactoryMacAddress(ifaceName); - if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 && - mac[4] == 0 && mac[5] == 0) { +std::pair<WifiStatus, std::array<uint8_t, 6>> WifiApIface::getFactoryMacAddressInternal( + const std::string& ifaceName) { + std::array<uint8_t, 6> mac = iface_util_.lock()->getFactoryMacAddress(ifaceName); + if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 && mac[4] == 0 && mac[5] == 0) { return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), mac}; } return {createWifiStatus(WifiStatusCode::SUCCESS), mac}; @@ -188,10 +174,9 @@ WifiStatus WifiApIface::resetToFactoryMacAddressInternal() { // bridged interface even if we got the request to reset the Factory // MAC. Since the bridged interface is an internal interface for the // operation of bpf and others networking operation. - if (!iface_util_.lock()->setMacAddress( - ifname_, iface_util_.lock()->createRandomMacAddress())) { - LOG(ERROR) << "Fail to config MAC for bridged interface " - << ifname_; + if (!iface_util_.lock()->setMacAddress(ifname_, + iface_util_.lock()->createRandomMacAddress())) { + LOG(ERROR) << "Fail to config MAC for bridged interface " << ifname_; return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); } } else { @@ -205,8 +190,7 @@ WifiStatus WifiApIface::resetToFactoryMacAddressInternal() { return createWifiStatus(WifiStatusCode::SUCCESS); } -std::pair<WifiStatus, std::vector<hidl_string>> -WifiApIface::getBridgedInstancesInternal() { +std::pair<WifiStatus, std::vector<hidl_string>> WifiApIface::getBridgedInstancesInternal() { std::vector<hidl_string> instances; for (const auto& instance_name : instances_) { instances.push_back(instance_name); @@ -214,7 +198,7 @@ WifiApIface::getBridgedInstancesInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), instances}; } } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/wifi_ap_iface.h b/wifi/1.6/default/wifi_ap_iface.h index 8f8387deae..d1c06424df 100644 --- a/wifi/1.5/default/wifi_ap_iface.h +++ b/wifi/1.6/default/wifi_ap_iface.h @@ -26,7 +26,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { using namespace android::hardware::wifi::V1_0; @@ -34,9 +34,8 @@ using namespace android::hardware::wifi::V1_0; * HIDL interface object used to control a AP Iface instance. */ class WifiApIface : public V1_5::IWifiApIface { - public: - WifiApIface(const std::string& ifname, - const std::vector<std::string>& instances, + public: + WifiApIface(const std::string& ifname, const std::vector<std::string>& instances, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal, const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util); // Refer to |WifiChip::invalidate()|. @@ -50,32 +49,27 @@ class WifiApIface : public V1_5::IWifiApIface { Return<void> getType(getType_cb hidl_status_cb) override; Return<void> setCountryCode(const hidl_array<int8_t, 2>& code, setCountryCode_cb hidl_status_cb) override; - Return<void> getValidFrequenciesForBand( - V1_0::WifiBand band, - getValidFrequenciesForBand_cb hidl_status_cb) override; + Return<void> getValidFrequenciesForBand(V1_0::WifiBand band, + getValidFrequenciesForBand_cb hidl_status_cb) override; Return<void> setMacAddress(const hidl_array<uint8_t, 6>& mac, setMacAddress_cb hidl_status_cb) override; - Return<void> getFactoryMacAddress( - getFactoryMacAddress_cb hidl_status_cb) override; - Return<void> resetToFactoryMacAddress( - resetToFactoryMacAddress_cb hidl_status_cb) override; + Return<void> getFactoryMacAddress(getFactoryMacAddress_cb hidl_status_cb) override; + Return<void> resetToFactoryMacAddress(resetToFactoryMacAddress_cb hidl_status_cb) override; - Return<void> getBridgedInstances( - getBridgedInstances_cb hidl_status_cb) override; + Return<void> getBridgedInstances(getBridgedInstances_cb hidl_status_cb) override; - private: + private: // Corresponding worker functions for the HIDL methods. std::pair<WifiStatus, std::string> getNameInternal(); std::pair<WifiStatus, IfaceType> getTypeInternal(); WifiStatus setCountryCodeInternal(const std::array<int8_t, 2>& code); - std::pair<WifiStatus, std::vector<WifiChannelInMhz>> - getValidFrequenciesForBandInternal(V1_0::WifiBand band); + std::pair<WifiStatus, std::vector<WifiChannelInMhz>> getValidFrequenciesForBandInternal( + V1_0::WifiBand band); WifiStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac); std::pair<WifiStatus, std::array<uint8_t, 6>> getFactoryMacAddressInternal( - const std::string& ifaceName); + const std::string& ifaceName); WifiStatus resetToFactoryMacAddressInternal(); - std::pair<WifiStatus, std::vector<hidl_string>> - getBridgedInstancesInternal(); + std::pair<WifiStatus, std::vector<hidl_string>> getBridgedInstancesInternal(); std::string ifname_; std::vector<std::string> instances_; @@ -87,7 +81,7 @@ class WifiApIface : public V1_5::IWifiApIface { }; } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.6/default/wifi_chip.cpp index def8bb8226..c1ce766a4f 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.6/default/wifi_chip.cpp @@ -22,7 +22,6 @@ #include <net/if.h> #include <sys/stat.h> #include <sys/sysmacros.h> -#include <net/if.h> #include "hidl_return_util.h" #include "hidl_struct_util.h" @@ -53,8 +52,7 @@ constexpr char kApBridgeIfacePrefix[] = "ap_br_"; template <typename Iface> void invalidateAndClear(std::vector<sp<Iface>>& ifaces, sp<Iface> iface) { iface->invalidate(); - ifaces.erase(std::remove(ifaces.begin(), ifaces.end(), iface), - ifaces.end()); + ifaces.erase(std::remove(ifaces.begin(), ifaces.end(), iface), ifaces.end()); } template <typename Iface> @@ -75,8 +73,7 @@ std::vector<hidl_string> getNames(std::vector<sp<Iface>>& ifaces) { } template <typename Iface> -sp<Iface> findUsingName(std::vector<sp<Iface>>& ifaces, - const std::string& name) { +sp<Iface> findUsingName(std::vector<sp<Iface>>& ifaces, const std::string& name) { std::vector<hidl_string> names; for (const auto& iface : ifaces) { if (name == iface->getName()) { @@ -94,8 +91,7 @@ std::string getWlanIfaceName(unsigned idx) { std::array<char, PROPERTY_VALUE_MAX> buffer; if (idx == 0 || idx == 1) { - const char* altPropName = - (idx == 0) ? "wifi.interface" : "wifi.concurrent.interface"; + const char* altPropName = (idx == 0) ? "wifi.interface" : "wifi.concurrent.interface"; auto res = property_get(altPropName, buffer.data(), nullptr); if (res > 0) return buffer.data(); } @@ -112,15 +108,13 @@ std::vector<std::string> getPredefinedApIfaceNames(bool is_bridged) { std::vector<std::string> ifnames; std::array<char, PROPERTY_VALUE_MAX> buffer; buffer.fill(0); - if (property_get("ro.vendor.wifi.sap.interface", buffer.data(), nullptr) == - 0) { + if (property_get("ro.vendor.wifi.sap.interface", buffer.data(), nullptr) == 0) { return ifnames; } ifnames.push_back(buffer.data()); if (is_bridged) { buffer.fill(0); - if (property_get("ro.vendor.wifi.sap.concurrent.iface", buffer.data(), - nullptr) == 0) { + if (property_get("ro.vendor.wifi.sap.concurrent.iface", buffer.data(), nullptr) == 0) { return ifnames; } ifnames.push_back(buffer.data()); @@ -134,29 +128,25 @@ std::string getPredefinedP2pIfaceName() { std::string p2pDevIfName = ""; std::array<char, PROPERTY_VALUE_MAX> buffer; property_get("wifi.direct.interface", buffer.data(), "p2p0"); - if (strncmp(buffer.data(), P2P_MGMT_DEVICE_PREFIX, - strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) { + if (strncmp(buffer.data(), P2P_MGMT_DEVICE_PREFIX, strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) { /* Get the p2p parent interface name from p2p device interface name set * in property */ strncpy(p2pParentIfname, buffer.data() + strlen(P2P_MGMT_DEVICE_PREFIX), strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX)); - if (property_get(kActiveWlanIfaceNameProperty, primaryIfaceName.data(), - nullptr) == 0) { + if (property_get(kActiveWlanIfaceNameProperty, primaryIfaceName.data(), nullptr) == 0) { return buffer.data(); } /* Check if the parent interface derived from p2p device interface name * is active */ if (strncmp(p2pParentIfname, primaryIfaceName.data(), - strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX)) != - 0) { + strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX)) != 0) { /* * Update the predefined p2p device interface parent interface name * with current active wlan interface */ p2pDevIfName += P2P_MGMT_DEVICE_PREFIX; p2pDevIfName += primaryIfaceName.data(); - LOG(INFO) << "update the p2p device interface name to " - << p2pDevIfName.c_str(); + LOG(INFO) << "update the p2p device interface name to " << p2pDevIfName.c_str(); return p2pDevIfName; } } @@ -185,8 +175,7 @@ void setActiveWlanIfaceNameProperty(const std::string& ifname) { bool removeOldFilesInternal() { time_t now = time(0); const time_t delete_files_before = now - kMaxRingBufferFileAgeSeconds; - std::unique_ptr<DIR, decltype(&closedir)> dir_dump( - opendir(kTombstoneFolderPath), closedir); + std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(kTombstoneFolderPath), closedir); if (!dir_dump) { PLOG(ERROR) << "Failed to open directory"; return false; @@ -207,15 +196,13 @@ bool removeOldFilesInternal() { continue; } const time_t cur_file_time = cur_file_stat.st_mtime; - valid_files.push_back( - std::pair<const time_t, std::string>(cur_file_time, cur_file_path)); + valid_files.push_back(std::pair<const time_t, std::string>(cur_file_time, cur_file_path)); } valid_files.sort(); // sort the list of files by last modified time from // small to big. uint32_t cur_file_count = valid_files.size(); for (auto cur_file : valid_files) { - if (cur_file_count > kMaxRingBufferFileNum || - cur_file.first < delete_files_before) { + if (cur_file_count > kMaxRingBufferFileNum || cur_file.first < delete_files_before) { if (unlink(cur_file.second.c_str()) != 0) { PLOG(ERROR) << "Error deleting file"; success = false; @@ -229,17 +216,14 @@ bool removeOldFilesInternal() { } // Helper function for |cpioArchiveFilesInDir| -bool cpioWriteHeader(int out_fd, struct stat& st, const char* file_name, - size_t file_name_len) { +bool cpioWriteHeader(int out_fd, struct stat& st, const char* file_name, size_t file_name_len) { std::array<char, 32 * 1024> read_buf; ssize_t llen = - sprintf(read_buf.data(), - "%s%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X", - kCpioMagic, static_cast<int>(st.st_ino), st.st_mode, st.st_uid, - st.st_gid, static_cast<int>(st.st_nlink), - static_cast<int>(st.st_mtime), static_cast<int>(st.st_size), - major(st.st_dev), minor(st.st_dev), major(st.st_rdev), - minor(st.st_rdev), static_cast<uint32_t>(file_name_len), 0); + sprintf(read_buf.data(), "%s%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X", + kCpioMagic, static_cast<int>(st.st_ino), st.st_mode, st.st_uid, st.st_gid, + static_cast<int>(st.st_nlink), static_cast<int>(st.st_mtime), + static_cast<int>(st.st_size), major(st.st_dev), minor(st.st_dev), + major(st.st_rdev), minor(st.st_rdev), static_cast<uint32_t>(file_name_len), 0); if (write(out_fd, read_buf.data(), llen) == -1) { PLOG(ERROR) << "Error writing cpio header to file " << file_name; return false; @@ -301,9 +285,7 @@ bool cpioWriteFileTrailer(int out_fd) { std::array<char, 4096> read_buf; read_buf.fill(0); if (write(out_fd, read_buf.data(), - sprintf(read_buf.data(), "070701%040X%056X%08XTRAILER!!!", 1, - 0x0b, 0) + - 4) == -1) { + sprintf(read_buf.data(), "070701%040X%056X%08XTRAILER!!!", 1, 0x0b, 0) + 4) == -1) { PLOG(ERROR) << "Error writing trailing bytes"; return false; } @@ -316,8 +298,7 @@ bool cpioWriteFileTrailer(int out_fd) { size_t cpioArchiveFilesInDir(int out_fd, const char* input_dir) { struct dirent* dp; size_t n_error = 0; - std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(input_dir), - closedir); + std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(input_dir), closedir); if (!dir_dump) { PLOG(ERROR) << "Failed to open directory"; return ++n_error; @@ -341,14 +322,12 @@ size_t cpioArchiveFilesInDir(int out_fd, const char* input_dir) { continue; } std::string file_name_with_last_modified_time = - cur_file_name + "-" + std::to_string(st.st_mtime); + cur_file_name + "-" + std::to_string(st.st_mtime); // string.size() does not include the null terminator. The cpio FreeBSD // file header expects the null character to be included in the length. - const size_t file_name_len = - file_name_with_last_modified_time.size() + 1; + const size_t file_name_len = file_name_with_last_modified_time.size() + 1; unique_fd file_auto_closer(fd_read); - if (!cpioWriteHeader(out_fd, st, - file_name_with_last_modified_time.c_str(), + if (!cpioWriteHeader(out_fd, st, file_name_with_last_modified_time.c_str(), file_name_len)) { return ++n_error; } @@ -376,18 +355,17 @@ std::vector<char> makeCharVec(const std::string& str) { namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { using hidl_return_util::validateAndCall; using hidl_return_util::validateAndCallWithLock; -WifiChip::WifiChip( - ChipId chip_id, bool is_primary, - const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal, - const std::weak_ptr<mode_controller::WifiModeController> mode_controller, - const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util, - const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags, - const std::function<void(const std::string&)>& handler) +WifiChip::WifiChip(ChipId chip_id, bool is_primary, + const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal, + const std::weak_ptr<mode_controller::WifiModeController> mode_controller, + const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util, + const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags, + const std::function<void(const std::string&)>& handler) : chip_id_(chip_id), legacy_hal_(legacy_hal), mode_controller_(mode_controller), @@ -411,24 +389,25 @@ void WifiChip::invalidate() { is_valid_ = false; } -bool WifiChip::isValid() { return is_valid_; } +bool WifiChip::isValid() { + return is_valid_; +} std::set<sp<V1_4::IWifiChipEventCallback>> WifiChip::getEventCallbacks() { return event_cb_handler_.getCallbacks(); } Return<void> WifiChip::getId(getId_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getIdInternal, hidl_status_cb); + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::getIdInternal, + hidl_status_cb); } // Deprecated support for this callback -Return<void> WifiChip::registerEventCallback( - const sp<V1_0::IWifiChipEventCallback>& event_callback, - registerEventCallback_cb hidl_status_cb) { +Return<void> WifiChip::registerEventCallback(const sp<V1_0::IWifiChipEventCallback>& event_callback, + registerEventCallback_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::registerEventCallbackInternal, - hidl_status_cb, event_callback); + &WifiChip::registerEventCallbackInternal, hidl_status_cb, + event_callback); } Return<void> WifiChip::getCapabilities(getCapabilities_cb hidl_status_cb) { @@ -438,15 +417,12 @@ Return<void> WifiChip::getCapabilities(getCapabilities_cb hidl_status_cb) { Return<void> WifiChip::getAvailableModes(getAvailableModes_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getAvailableModesInternal, - hidl_status_cb); + &WifiChip::getAvailableModesInternal, hidl_status_cb); } -Return<void> WifiChip::configureChip(ChipModeId mode_id, - configureChip_cb hidl_status_cb) { - return validateAndCallWithLock( - this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::configureChipInternal, hidl_status_cb, mode_id); +Return<void> WifiChip::configureChip(ChipModeId mode_id, configureChip_cb hidl_status_cb) { + return validateAndCallWithLock(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::configureChipInternal, hidl_status_cb, mode_id); } Return<void> WifiChip::getMode(getMode_cb hidl_status_cb) { @@ -454,25 +430,19 @@ Return<void> WifiChip::getMode(getMode_cb hidl_status_cb) { &WifiChip::getModeInternal, hidl_status_cb); } -Return<void> WifiChip::requestChipDebugInfo( - requestChipDebugInfo_cb hidl_status_cb) { +Return<void> WifiChip::requestChipDebugInfo(requestChipDebugInfo_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::requestChipDebugInfoInternal, - hidl_status_cb); + &WifiChip::requestChipDebugInfoInternal, hidl_status_cb); } -Return<void> WifiChip::requestDriverDebugDump( - requestDriverDebugDump_cb hidl_status_cb) { +Return<void> WifiChip::requestDriverDebugDump(requestDriverDebugDump_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::requestDriverDebugDumpInternal, - hidl_status_cb); + &WifiChip::requestDriverDebugDumpInternal, hidl_status_cb); } -Return<void> WifiChip::requestFirmwareDebugDump( - requestFirmwareDebugDump_cb hidl_status_cb) { +Return<void> WifiChip::requestFirmwareDebugDump(requestFirmwareDebugDump_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::requestFirmwareDebugDumpInternal, - hidl_status_cb); + &WifiChip::requestFirmwareDebugDumpInternal, hidl_status_cb); } Return<void> WifiChip::createApIface(createApIface_cb hidl_status_cb) { @@ -480,11 +450,9 @@ Return<void> WifiChip::createApIface(createApIface_cb hidl_status_cb) { &WifiChip::createApIfaceInternal, hidl_status_cb); } -Return<void> WifiChip::createBridgedApIface( - createBridgedApIface_cb hidl_status_cb) { +Return<void> WifiChip::createBridgedApIface(createBridgedApIface_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::createBridgedApIfaceInternal, - hidl_status_cb); + &WifiChip::createBridgedApIfaceInternal, hidl_status_cb); } Return<void> WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) { @@ -492,27 +460,22 @@ Return<void> WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) { &WifiChip::getApIfaceNamesInternal, hidl_status_cb); } -Return<void> WifiChip::getApIface(const hidl_string& ifname, - getApIface_cb hidl_status_cb) { +Return<void> WifiChip::getApIface(const hidl_string& ifname, getApIface_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getApIfaceInternal, hidl_status_cb, - ifname); + &WifiChip::getApIfaceInternal, hidl_status_cb, ifname); } -Return<void> WifiChip::removeApIface(const hidl_string& ifname, - removeApIface_cb hidl_status_cb) { +Return<void> WifiChip::removeApIface(const hidl_string& ifname, removeApIface_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::removeApIfaceInternal, hidl_status_cb, - ifname); + &WifiChip::removeApIfaceInternal, hidl_status_cb, ifname); } Return<void> WifiChip::removeIfaceInstanceFromBridgedApIface( - const hidl_string& ifname, const hidl_string& ifInstanceName, - removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal, - hidl_status_cb, ifname, ifInstanceName); + const hidl_string& ifname, const hidl_string& ifInstanceName, + removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal, hidl_status_cb, + ifname, ifInstanceName); } Return<void> WifiChip::createNanIface(createNanIface_cb hidl_status_cb) { @@ -525,18 +488,14 @@ Return<void> WifiChip::getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) { &WifiChip::getNanIfaceNamesInternal, hidl_status_cb); } -Return<void> WifiChip::getNanIface(const hidl_string& ifname, - getNanIface_cb hidl_status_cb) { +Return<void> WifiChip::getNanIface(const hidl_string& ifname, getNanIface_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getNanIfaceInternal, hidl_status_cb, - ifname); + &WifiChip::getNanIfaceInternal, hidl_status_cb, ifname); } -Return<void> WifiChip::removeNanIface(const hidl_string& ifname, - removeNanIface_cb hidl_status_cb) { +Return<void> WifiChip::removeNanIface(const hidl_string& ifname, removeNanIface_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::removeNanIfaceInternal, hidl_status_cb, - ifname); + &WifiChip::removeNanIfaceInternal, hidl_status_cb, ifname); } Return<void> WifiChip::createP2pIface(createP2pIface_cb hidl_status_cb) { @@ -549,18 +508,14 @@ Return<void> WifiChip::getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) { &WifiChip::getP2pIfaceNamesInternal, hidl_status_cb); } -Return<void> WifiChip::getP2pIface(const hidl_string& ifname, - getP2pIface_cb hidl_status_cb) { +Return<void> WifiChip::getP2pIface(const hidl_string& ifname, getP2pIface_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getP2pIfaceInternal, hidl_status_cb, - ifname); + &WifiChip::getP2pIfaceInternal, hidl_status_cb, ifname); } -Return<void> WifiChip::removeP2pIface(const hidl_string& ifname, - removeP2pIface_cb hidl_status_cb) { +Return<void> WifiChip::removeP2pIface(const hidl_string& ifname, removeP2pIface_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::removeP2pIfaceInternal, hidl_status_cb, - ifname); + &WifiChip::removeP2pIfaceInternal, hidl_status_cb, ifname); } Return<void> WifiChip::createStaIface(createStaIface_cb hidl_status_cb) { @@ -573,132 +528,106 @@ Return<void> WifiChip::getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) { &WifiChip::getStaIfaceNamesInternal, hidl_status_cb); } -Return<void> WifiChip::getStaIface(const hidl_string& ifname, - getStaIface_cb hidl_status_cb) { +Return<void> WifiChip::getStaIface(const hidl_string& ifname, getStaIface_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getStaIfaceInternal, hidl_status_cb, - ifname); + &WifiChip::getStaIfaceInternal, hidl_status_cb, ifname); } -Return<void> WifiChip::removeStaIface(const hidl_string& ifname, - removeStaIface_cb hidl_status_cb) { +Return<void> WifiChip::removeStaIface(const hidl_string& ifname, removeStaIface_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::removeStaIfaceInternal, hidl_status_cb, - ifname); + &WifiChip::removeStaIfaceInternal, hidl_status_cb, ifname); } -Return<void> WifiChip::createRttController( - const sp<IWifiIface>& bound_iface, createRttController_cb hidl_status_cb) { +Return<void> WifiChip::createRttController(const sp<IWifiIface>& bound_iface, + createRttController_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::createRttControllerInternal, - hidl_status_cb, bound_iface); + &WifiChip::createRttControllerInternal, hidl_status_cb, bound_iface); } -Return<void> WifiChip::getDebugRingBuffersStatus( - getDebugRingBuffersStatus_cb hidl_status_cb) { +Return<void> WifiChip::getDebugRingBuffersStatus(getDebugRingBuffersStatus_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getDebugRingBuffersStatusInternal, - hidl_status_cb); + &WifiChip::getDebugRingBuffersStatusInternal, hidl_status_cb); } Return<void> WifiChip::startLoggingToDebugRingBuffer( - const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level, - uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes, - startLoggingToDebugRingBuffer_cb hidl_status_cb) { + const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level, + uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes, + startLoggingToDebugRingBuffer_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::startLoggingToDebugRingBufferInternal, - hidl_status_cb, ring_name, verbose_level, - max_interval_in_sec, min_data_size_in_bytes); + &WifiChip::startLoggingToDebugRingBufferInternal, hidl_status_cb, + ring_name, verbose_level, max_interval_in_sec, min_data_size_in_bytes); } -Return<void> WifiChip::forceDumpToDebugRingBuffer( - const hidl_string& ring_name, - forceDumpToDebugRingBuffer_cb hidl_status_cb) { +Return<void> WifiChip::forceDumpToDebugRingBuffer(const hidl_string& ring_name, + forceDumpToDebugRingBuffer_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::forceDumpToDebugRingBufferInternal, - hidl_status_cb, ring_name); + &WifiChip::forceDumpToDebugRingBufferInternal, hidl_status_cb, + ring_name); } -Return<void> WifiChip::flushRingBufferToFile( - flushRingBufferToFile_cb hidl_status_cb) { +Return<void> WifiChip::flushRingBufferToFile(flushRingBufferToFile_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::flushRingBufferToFileInternal, - hidl_status_cb); + &WifiChip::flushRingBufferToFileInternal, hidl_status_cb); } Return<void> WifiChip::stopLoggingToDebugRingBuffer( - stopLoggingToDebugRingBuffer_cb hidl_status_cb) { + stopLoggingToDebugRingBuffer_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::stopLoggingToDebugRingBufferInternal, - hidl_status_cb); + &WifiChip::stopLoggingToDebugRingBufferInternal, hidl_status_cb); } -Return<void> WifiChip::getDebugHostWakeReasonStats( - getDebugHostWakeReasonStats_cb hidl_status_cb) { +Return<void> WifiChip::getDebugHostWakeReasonStats(getDebugHostWakeReasonStats_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getDebugHostWakeReasonStatsInternal, - hidl_status_cb); + &WifiChip::getDebugHostWakeReasonStatsInternal, hidl_status_cb); } -Return<void> WifiChip::enableDebugErrorAlerts( - bool enable, enableDebugErrorAlerts_cb hidl_status_cb) { +Return<void> WifiChip::enableDebugErrorAlerts(bool enable, + enableDebugErrorAlerts_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::enableDebugErrorAlertsInternal, - hidl_status_cb, enable); + &WifiChip::enableDebugErrorAlertsInternal, hidl_status_cb, enable); } -Return<void> WifiChip::selectTxPowerScenario( - V1_1::IWifiChip::TxPowerScenario scenario, - selectTxPowerScenario_cb hidl_status_cb) { +Return<void> WifiChip::selectTxPowerScenario(V1_1::IWifiChip::TxPowerScenario scenario, + selectTxPowerScenario_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::selectTxPowerScenarioInternal, - hidl_status_cb, scenario); + &WifiChip::selectTxPowerScenarioInternal, hidl_status_cb, scenario); } -Return<void> WifiChip::resetTxPowerScenario( - resetTxPowerScenario_cb hidl_status_cb) { +Return<void> WifiChip::resetTxPowerScenario(resetTxPowerScenario_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::resetTxPowerScenarioInternal, - hidl_status_cb); + &WifiChip::resetTxPowerScenarioInternal, hidl_status_cb); } -Return<void> WifiChip::setLatencyMode(LatencyMode mode, - setLatencyMode_cb hidl_status_cb) { +Return<void> WifiChip::setLatencyMode(LatencyMode mode, setLatencyMode_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::setLatencyModeInternal, hidl_status_cb, - mode); + &WifiChip::setLatencyModeInternal, hidl_status_cb, mode); } Return<void> WifiChip::registerEventCallback_1_2( - const sp<V1_2::IWifiChipEventCallback>& event_callback, - registerEventCallback_cb hidl_status_cb) { + const sp<V1_2::IWifiChipEventCallback>& event_callback, + registerEventCallback_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::registerEventCallbackInternal_1_2, - hidl_status_cb, event_callback); + &WifiChip::registerEventCallbackInternal_1_2, hidl_status_cb, + event_callback); } -Return<void> WifiChip::selectTxPowerScenario_1_2( - TxPowerScenario scenario, selectTxPowerScenario_cb hidl_status_cb) { +Return<void> WifiChip::selectTxPowerScenario_1_2(TxPowerScenario scenario, + selectTxPowerScenario_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::selectTxPowerScenarioInternal_1_2, - hidl_status_cb, scenario); + &WifiChip::selectTxPowerScenarioInternal_1_2, hidl_status_cb, scenario); } Return<void> WifiChip::getCapabilities_1_3(getCapabilities_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getCapabilitiesInternal_1_3, - hidl_status_cb); + &WifiChip::getCapabilitiesInternal_1_3, hidl_status_cb); } -Return<void> WifiChip::getCapabilities_1_5( - getCapabilities_1_5_cb hidl_status_cb) { +Return<void> WifiChip::getCapabilities_1_5(getCapabilities_1_5_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getCapabilitiesInternal_1_5, - hidl_status_cb); + &WifiChip::getCapabilitiesInternal_1_5, hidl_status_cb); } -Return<void> WifiChip::debug(const hidl_handle& handle, - const hidl_vec<hidl_string>&) { +Return<void> WifiChip::debug(const hidl_handle& handle, const hidl_vec<hidl_string>&) { if (handle != nullptr && handle->numFds >= 1) { { std::unique_lock<std::mutex> lk(lock_t); @@ -724,98 +653,61 @@ Return<void> WifiChip::debug(const hidl_handle& handle, return Void(); } -Return<void> WifiChip::createRttController_1_4( - const sp<IWifiIface>& bound_iface, - createRttController_1_4_cb hidl_status_cb) { +Return<void> WifiChip::createRttController_1_4(const sp<IWifiIface>& bound_iface, + createRttController_1_4_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::createRttControllerInternal_1_4, - hidl_status_cb, bound_iface); + &WifiChip::createRttControllerInternal_1_4, hidl_status_cb, bound_iface); } Return<void> WifiChip::registerEventCallback_1_4( - const sp<V1_4::IWifiChipEventCallback>& event_callback, - registerEventCallback_cb hidl_status_cb) { + const sp<V1_4::IWifiChipEventCallback>& event_callback, + registerEventCallback_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::registerEventCallbackInternal_1_4, - hidl_status_cb, event_callback); + &WifiChip::registerEventCallbackInternal_1_4, hidl_status_cb, + event_callback); } Return<void> WifiChip::setMultiStaPrimaryConnection( - const hidl_string& ifname, setMultiStaPrimaryConnection_cb hidl_status_cb) { + const hidl_string& ifname, setMultiStaPrimaryConnection_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::setMultiStaPrimaryConnectionInternal, - hidl_status_cb, ifname); + &WifiChip::setMultiStaPrimaryConnectionInternal, hidl_status_cb, ifname); } -Return<void> WifiChip::setMultiStaUseCase( - MultiStaUseCase use_case, setMultiStaUseCase_cb hidl_status_cb) { +Return<void> WifiChip::setMultiStaUseCase(MultiStaUseCase use_case, + setMultiStaUseCase_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::setMultiStaUseCaseInternal, - hidl_status_cb, use_case); + &WifiChip::setMultiStaUseCaseInternal, hidl_status_cb, use_case); } -Return<void> WifiChip::setCoexUnsafeChannels( - const hidl_vec<CoexUnsafeChannel>& unsafeChannels, - hidl_bitfield<CoexRestriction> restrictions, - setCoexUnsafeChannels_cb hidl_status_cb) { +Return<void> WifiChip::setCoexUnsafeChannels(const hidl_vec<CoexUnsafeChannel>& unsafeChannels, + hidl_bitfield<CoexRestriction> restrictions, + setCoexUnsafeChannels_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::setCoexUnsafeChannelsInternal, - hidl_status_cb, unsafeChannels, restrictions); + &WifiChip::setCoexUnsafeChannelsInternal, hidl_status_cb, unsafeChannels, + restrictions); } Return<void> WifiChip::setCountryCode(const hidl_array<int8_t, 2>& code, setCountryCode_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiChip::setCountryCodeInternal, hidl_status_cb, - code); + &WifiChip::setCountryCodeInternal, hidl_status_cb, code); } Return<void> WifiChip::getUsableChannels( - WifiBand band, hidl_bitfield<WifiIfaceMode> ifaceModeMask, - hidl_bitfield<UsableChannelFilter> filterMask, - getUsableChannels_cb _hidl_cb) { + WifiBand band, hidl_bitfield<V1_5::WifiIfaceMode> ifaceModeMask, + hidl_bitfield<V1_5::IWifiChip::UsableChannelFilter> filterMask, + getUsableChannels_cb _hidl_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getUsableChannelsInternal, _hidl_cb, band, - ifaceModeMask, filterMask); + &WifiChip::getUsableChannelsInternal, _hidl_cb, band, ifaceModeMask, + filterMask); } -Return<void> WifiChip::triggerSubsystemRestart( - triggerSubsystemRestart_cb hidl_status_cb) { +Return<void> WifiChip::triggerSubsystemRestart(triggerSubsystemRestart_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::triggerSubsystemRestartInternal, - hidl_status_cb); -} - -void WifiChip::QcRemoveAndClearDynamicIfaces() { - for (const auto& iface : created_ap_ifaces_) { - std::string ifname = iface->getName(); - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->deleteVirtualInterface(ifname); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to remove interface: " << ifname << " " - << legacyErrorToString(legacy_status); - } - } - - for (const auto& iface : created_sta_ifaces_) { - std::string ifname = iface->getName(); - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->deleteVirtualInterface(ifname); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to remove interface: " << ifname << " " - << legacyErrorToString(legacy_status); - } - } - - // created_ap/sta_ifaces are also part of sta/ap_ifaces. - // Do no invalidate here. - - created_ap_ifaces_.clear(); - created_sta_ifaces_.clear(); + &WifiChip::triggerSubsystemRestartInternal, hidl_status_cb); } void WifiChip::invalidateAndRemoveAllIfaces() { - QcRemoveAndClearDynamicIfaces(); invalidateAndClearBridgedApAll(); invalidateAndClearAll(ap_ifaces_); invalidateAndClearAll(nan_ifaces_); @@ -829,16 +721,13 @@ void WifiChip::invalidateAndRemoveAllIfaces() { rtt_controllers_.clear(); } -void WifiChip::invalidateAndRemoveDependencies( - const std::string& removed_iface_name) { +void WifiChip::invalidateAndRemoveDependencies(const std::string& removed_iface_name) { for (auto it = nan_ifaces_.begin(); it != nan_ifaces_.end();) { auto nan_iface = *it; if (nan_iface->getName() == removed_iface_name) { nan_iface->invalidate(); for (const auto& callback : event_cb_handler_.getCallbacks()) { - if (!callback - ->onIfaceRemoved(IfaceType::NAN, removed_iface_name) - .isOk()) { + if (!callback->onIfaceRemoved(IfaceType::NAN, removed_iface_name).isOk()) { LOG(ERROR) << "Failed to invoke onIfaceRemoved callback"; } } @@ -864,7 +753,7 @@ std::pair<WifiStatus, ChipId> WifiChip::getIdInternal() { } WifiStatus WifiChip::registerEventCallbackInternal( - const sp<V1_0::IWifiChipEventCallback>& /* event_callback */) { + const sp<V1_0::IWifiChipEventCallback>& /* event_callback */) { // Deprecated support for this callback. return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); } @@ -880,8 +769,7 @@ WifiChip::getAvailableModesInternal() { } WifiStatus WifiChip::configureChipInternal( - /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, - ChipModeId mode_id) { + /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id) { if (!isValidModeId(mode_id)) { return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); } @@ -893,8 +781,7 @@ WifiStatus WifiChip::configureChipInternal( if (status.code != WifiStatusCode::SUCCESS) { for (const auto& callback : event_cb_handler_.getCallbacks()) { if (!callback->onChipReconfigureFailure(status).isOk()) { - LOG(ERROR) - << "Failed to invoke onChipReconfigureFailure callback"; + LOG(ERROR) << "Failed to invoke onChipReconfigureFailure callback"; } } return status; @@ -908,45 +795,38 @@ WifiStatus WifiChip::configureChipInternal( LOG(INFO) << "Configured chip in mode " << mode_id; setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName()); - legacy_hal_.lock()->registerSubsystemRestartCallbackHandler( - subsystemCallbackHandler_); + legacy_hal_.lock()->registerSubsystemRestartCallbackHandler(subsystemCallbackHandler_); return status; } std::pair<WifiStatus, uint32_t> WifiChip::getModeInternal() { if (!isValidModeId(current_mode_id_)) { - return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), - current_mode_id_}; + return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), current_mode_id_}; } return {createWifiStatus(WifiStatusCode::SUCCESS), current_mode_id_}; } -std::pair<WifiStatus, V1_4::IWifiChip::ChipDebugInfo> -WifiChip::requestChipDebugInfoInternal() { +std::pair<WifiStatus, V1_4::IWifiChip::ChipDebugInfo> WifiChip::requestChipDebugInfoInternal() { V1_4::IWifiChip::ChipDebugInfo result; legacy_hal::wifi_error legacy_status; std::string driver_desc; const auto ifname = getFirstActiveWlanIfaceName(); - std::tie(legacy_status, driver_desc) = - legacy_hal_.lock()->getDriverVersion(ifname); + std::tie(legacy_status, driver_desc) = legacy_hal_.lock()->getDriverVersion(ifname); if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to get driver version: " - << legacyErrorToString(legacy_status); - WifiStatus status = createWifiStatusFromLegacyError( - legacy_status, "failed to get driver version"); + LOG(ERROR) << "Failed to get driver version: " << legacyErrorToString(legacy_status); + WifiStatus status = + createWifiStatusFromLegacyError(legacy_status, "failed to get driver version"); return {status, result}; } result.driverDescription = driver_desc.c_str(); std::string firmware_desc; - std::tie(legacy_status, firmware_desc) = - legacy_hal_.lock()->getFirmwareVersion(ifname); + std::tie(legacy_status, firmware_desc) = legacy_hal_.lock()->getFirmwareVersion(ifname); if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to get firmware version: " - << legacyErrorToString(legacy_status); - WifiStatus status = createWifiStatusFromLegacyError( - legacy_status, "failed to get firmware version"); + LOG(ERROR) << "Failed to get firmware version: " << legacyErrorToString(legacy_status); + WifiStatus status = + createWifiStatusFromLegacyError(legacy_status, "failed to get firmware version"); return {status, result}; } result.firmwareDescription = firmware_desc.c_str(); @@ -954,32 +834,25 @@ WifiChip::requestChipDebugInfoInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), result}; } -std::pair<WifiStatus, std::vector<uint8_t>> -WifiChip::requestDriverDebugDumpInternal() { +std::pair<WifiStatus, std::vector<uint8_t>> WifiChip::requestDriverDebugDumpInternal() { legacy_hal::wifi_error legacy_status; std::vector<uint8_t> driver_dump; std::tie(legacy_status, driver_dump) = - legacy_hal_.lock()->requestDriverMemoryDump( - getFirstActiveWlanIfaceName()); + legacy_hal_.lock()->requestDriverMemoryDump(getFirstActiveWlanIfaceName()); if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to get driver debug dump: " - << legacyErrorToString(legacy_status); - return {createWifiStatusFromLegacyError(legacy_status), - std::vector<uint8_t>()}; + LOG(ERROR) << "Failed to get driver debug dump: " << legacyErrorToString(legacy_status); + return {createWifiStatusFromLegacyError(legacy_status), std::vector<uint8_t>()}; } return {createWifiStatus(WifiStatusCode::SUCCESS), driver_dump}; } -std::pair<WifiStatus, std::vector<uint8_t>> -WifiChip::requestFirmwareDebugDumpInternal() { +std::pair<WifiStatus, std::vector<uint8_t>> WifiChip::requestFirmwareDebugDumpInternal() { legacy_hal::wifi_error legacy_status; std::vector<uint8_t> firmware_dump; std::tie(legacy_status, firmware_dump) = - legacy_hal_.lock()->requestFirmwareMemoryDump( - getFirstActiveWlanIfaceName()); + legacy_hal_.lock()->requestFirmwareMemoryDump(getFirstActiveWlanIfaceName()); if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to get firmware debug dump: " - << legacyErrorToString(legacy_status); + LOG(ERROR) << "Failed to get firmware debug dump: " << legacyErrorToString(legacy_status); return {createWifiStatusFromLegacyError(legacy_status), {}}; } return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump}; @@ -988,8 +861,7 @@ WifiChip::requestFirmwareDebugDumpInternal() { WifiStatus WifiChip::createVirtualApInterface(const std::string& apVirtIf) { legacy_hal::wifi_error legacy_status; legacy_status = legacy_hal_.lock()->createVirtualInterface( - apVirtIf, - hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::AP)); + apVirtIf, hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::AP)); if (legacy_status != legacy_hal::WIFI_SUCCESS) { LOG(ERROR) << "Failed to add interface: " << apVirtIf << " " << legacyErrorToString(legacy_status); @@ -1005,9 +877,7 @@ sp<WifiApIface> WifiChip::newWifiApIface(std::string& ifname) { ap_instances = it.second; } } - iface_util_->setRandomMacAddressIndex(ap_ifaces_.size()); - sp<WifiApIface> iface = - new WifiApIface(ifname, ap_instances, legacy_hal_, iface_util_); + sp<WifiApIface> iface = new WifiApIface(ifname, ap_instances, legacy_hal_, iface_util_); ap_ifaces_.push_back(iface); for (const auto& callback : event_cb_handler_.getCallbacks()) { if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) { @@ -1018,27 +888,20 @@ sp<WifiApIface> WifiChip::newWifiApIface(std::string& ifname) { return iface; } -std::pair<WifiStatus, sp<V1_5::IWifiApIface>> -WifiChip::createApIfaceInternal() { +std::pair<WifiStatus, sp<V1_5::IWifiApIface>> WifiChip::createApIfaceInternal() { if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) { return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } - bool iface_created = false; std::string ifname = allocateApIfaceName(); - if (!if_nametoindex(ifname.c_str())) { - WifiStatus status = createVirtualApInterface(ifname); - if (status.code != WifiStatusCode::SUCCESS) { - return {status, {}}; - } - iface_created = true; + WifiStatus status = createVirtualApInterface(ifname); + if (status.code != WifiStatusCode::SUCCESS) { + return {status, {}}; } sp<WifiApIface> iface = newWifiApIface(ifname); - if (iface_created) created_ap_ifaces_.push_back(iface); return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; } -std::pair<WifiStatus, sp<V1_5::IWifiApIface>> -WifiChip::createBridgedApIfaceInternal() { +std::pair<WifiStatus, sp<V1_5::IWifiApIface>> WifiChip::createBridgedApIfaceInternal() { if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) { return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } @@ -1054,7 +917,7 @@ WifiChip::createBridgedApIfaceInternal() { if (i != 0) { // The failure happened when creating second virtual // iface. legacy_hal_.lock()->deleteVirtualInterface( - ap_instances.front()); // Remove the first virtual iface. + ap_instances.front()); // Remove the first virtual iface. } return {status, {}}; } @@ -1068,8 +931,7 @@ WifiChip::createBridgedApIfaceInternal() { for (auto const& instance : ap_instances) { // Bind ap instance interface to AP bridge if (!iface_util_->addIfaceToBridge(br_ifname, instance)) { - LOG(ERROR) << "Failed add if to Bridge - if_name=" - << instance.c_str(); + LOG(ERROR) << "Failed add if to Bridge - if_name=" << instance.c_str(); invalidateAndClearBridgedAp(br_ifname); return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } @@ -1078,8 +940,7 @@ WifiChip::createBridgedApIfaceInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; } -std::pair<WifiStatus, std::vector<hidl_string>> -WifiChip::getApIfaceNamesInternal() { +std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getApIfaceNamesInternal() { if (ap_ifaces_.empty()) { return {createWifiStatus(WifiStatusCode::SUCCESS), {}}; } @@ -1087,7 +948,7 @@ WifiChip::getApIfaceNamesInternal() { } std::pair<WifiStatus, sp<V1_5::IWifiApIface>> WifiChip::getApIfaceInternal( - const std::string& ifname) { + const std::string& ifname) { const auto iface = findUsingName(ap_ifaces_, ifname); if (!iface.get()) { return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr}; @@ -1105,9 +966,6 @@ WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) { // nan/rtt objects over AP iface. But, there is no harm to do it // here and not make that assumption all over the place. invalidateAndRemoveDependencies(ifname); - if (findUsingName(created_ap_ifaces_, ifname) != nullptr) { - invalidateAndClear(created_ap_ifaces_, iface); - } // Clear the bridge interface and the iface instance. invalidateAndClearBridgedAp(ifname); invalidateAndClear(ap_ifaces_, iface); @@ -1121,7 +979,7 @@ WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) { } WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal( - const std::string& ifname, const std::string& ifInstanceName) { + const std::string& ifname, const std::string& ifInstanceName) { const auto iface = findUsingName(ap_ifaces_, ifname); if (!iface.get() || ifInstanceName.empty()) { return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); @@ -1133,23 +991,20 @@ WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal( for (auto const& iface : ap_instances) { if (iface == ifInstanceName) { if (!iface_util_->removeIfaceFromBridge(it.first, iface)) { - LOG(ERROR) - << "Failed to remove interface: " << ifInstanceName - << " from " << ifname; - return createWifiStatus( - WifiStatusCode::ERROR_NOT_AVAILABLE); + LOG(ERROR) << "Failed to remove interface: " << ifInstanceName << " from " + << ifname; + return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE); } legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->deleteVirtualInterface(iface); + legacy_hal_.lock()->deleteVirtualInterface(iface); if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to del interface: " << iface - << " " << legacyErrorToString(legacy_status); + LOG(ERROR) << "Failed to del interface: " << iface << " " + << legacyErrorToString(legacy_status); return createWifiStatusFromLegacyError(legacy_status); } ap_instances.erase( - std::remove(ap_instances.begin(), ap_instances.end(), - ifInstanceName), - ap_instances.end()); + std::remove(ap_instances.begin(), ap_instances.end(), ifInstanceName), + ap_instances.end()); br_ifaces_ap_instances_[ifname] = ap_instances; break; } @@ -1163,8 +1018,7 @@ WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal( return createWifiStatus(WifiStatusCode::SUCCESS); } -std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> -WifiChip::createNanIfaceInternal() { +std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> WifiChip::createNanIfaceInternal() { if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::NAN)) { return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } @@ -1176,8 +1030,7 @@ WifiChip::createNanIfaceInternal() { ifname = getFirstActiveWlanIfaceName(); is_dedicated_iface = false; } - sp<WifiNanIface> iface = - new WifiNanIface(ifname, is_dedicated_iface, legacy_hal_, iface_util_); + sp<WifiNanIface> iface = new WifiNanIface(ifname, is_dedicated_iface, legacy_hal_, iface_util_); nan_ifaces_.push_back(iface); for (const auto& callback : event_cb_handler_.getCallbacks()) { if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) { @@ -1187,8 +1040,7 @@ WifiChip::createNanIfaceInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; } -std::pair<WifiStatus, std::vector<hidl_string>> -WifiChip::getNanIfaceNamesInternal() { +std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getNanIfaceNamesInternal() { if (nan_ifaces_.empty()) { return {createWifiStatus(WifiStatusCode::SUCCESS), {}}; } @@ -1196,7 +1048,7 @@ WifiChip::getNanIfaceNamesInternal() { } std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> WifiChip::getNanIfaceInternal( - const std::string& ifname) { + const std::string& ifname) { const auto iface = findUsingName(nan_ifaces_, ifname); if (!iface.get()) { return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr}; @@ -1233,16 +1085,14 @@ std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::createP2pIfaceInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; } -std::pair<WifiStatus, std::vector<hidl_string>> -WifiChip::getP2pIfaceNamesInternal() { +std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getP2pIfaceNamesInternal() { if (p2p_ifaces_.empty()) { return {createWifiStatus(WifiStatusCode::SUCCESS), {}}; } return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(p2p_ifaces_)}; } -std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::getP2pIfaceInternal( - const std::string& ifname) { +std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::getP2pIfaceInternal(const std::string& ifname) { const auto iface = findUsingName(p2p_ifaces_, ifname); if (!iface.get()) { return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr}; @@ -1264,28 +1114,20 @@ WifiStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) { return createWifiStatus(WifiStatusCode::SUCCESS); } -std::pair<WifiStatus, sp<V1_5::IWifiStaIface>> -WifiChip::createStaIfaceInternal() { +std::pair<WifiStatus, sp<V1_5::IWifiStaIface>> WifiChip::createStaIfaceInternal() { if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::STA)) { return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } - bool iface_created = false; std::string ifname = allocateStaIfaceName(); - if (!if_nametoindex(ifname.c_str())) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->createVirtualInterface( - ifname, - hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::STA)); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to add interface: " << ifname << " " - << legacyErrorToString(legacy_status); - return {createWifiStatusFromLegacyError(legacy_status), {}}; - } - iface_created = true; + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->createVirtualInterface( + ifname, hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::STA)); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + LOG(ERROR) << "Failed to add interface: " << ifname << " " + << legacyErrorToString(legacy_status); + return {createWifiStatusFromLegacyError(legacy_status), {}}; } sp<WifiStaIface> iface = new WifiStaIface(ifname, legacy_hal_, iface_util_); sta_ifaces_.push_back(iface); - if (iface_created) created_sta_ifaces_.push_back(iface); for (const auto& callback : event_cb_handler_.getCallbacks()) { if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) { LOG(ERROR) << "Failed to invoke onIfaceAdded callback"; @@ -1295,8 +1137,7 @@ WifiChip::createStaIfaceInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; } -std::pair<WifiStatus, std::vector<hidl_string>> -WifiChip::getStaIfaceNamesInternal() { +std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getStaIfaceNamesInternal() { if (sta_ifaces_.empty()) { return {createWifiStatus(WifiStatusCode::SUCCESS), {}}; } @@ -1304,7 +1145,7 @@ WifiChip::getStaIfaceNamesInternal() { } std::pair<WifiStatus, sp<V1_5::IWifiStaIface>> WifiChip::getStaIfaceInternal( - const std::string& ifname) { + const std::string& ifname) { const auto iface = findUsingName(sta_ifaces_, ifname); if (!iface.get()) { return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr}; @@ -1319,14 +1160,10 @@ WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) { } // Invalidate & remove any dependent objects first. invalidateAndRemoveDependencies(ifname); - if (findUsingName(created_sta_ifaces_, ifname) != nullptr) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->deleteVirtualInterface(ifname); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to remove interface: " << ifname << " " - << legacyErrorToString(legacy_status); - } - invalidateAndClear(created_sta_ifaces_, iface); + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->deleteVirtualInterface(ifname); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + LOG(ERROR) << "Failed to remove interface: " << ifname << " " + << legacyErrorToString(legacy_status); } invalidateAndClear(sta_ifaces_, iface); for (const auto& callback : event_cb_handler_.getCallbacks()) { @@ -1338,8 +1175,8 @@ WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) { return createWifiStatus(WifiStatusCode::SUCCESS); } -std::pair<WifiStatus, sp<V1_0::IWifiRttController>> -WifiChip::createRttControllerInternal(const sp<IWifiIface>& /*bound_iface*/) { +std::pair<WifiStatus, sp<V1_0::IWifiRttController>> WifiChip::createRttControllerInternal( + const sp<IWifiIface>& /*bound_iface*/) { LOG(ERROR) << "createRttController is not supported on this HAL"; return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}}; } @@ -1347,38 +1184,33 @@ WifiChip::createRttControllerInternal(const sp<IWifiIface>& /*bound_iface*/) { std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>> WifiChip::getDebugRingBuffersStatusInternal() { legacy_hal::wifi_error legacy_status; - std::vector<legacy_hal::wifi_ring_buffer_status> - legacy_ring_buffer_status_vec; + std::vector<legacy_hal::wifi_ring_buffer_status> legacy_ring_buffer_status_vec; std::tie(legacy_status, legacy_ring_buffer_status_vec) = - legacy_hal_.lock()->getRingBuffersStatus(getFirstActiveWlanIfaceName()); + legacy_hal_.lock()->getRingBuffersStatus(getFirstActiveWlanIfaceName()); if (legacy_status != legacy_hal::WIFI_SUCCESS) { return {createWifiStatusFromLegacyError(legacy_status), {}}; } std::vector<WifiDebugRingBufferStatus> hidl_ring_buffer_status_vec; if (!hidl_struct_util::convertLegacyVectorOfDebugRingBufferStatusToHidl( - legacy_ring_buffer_status_vec, &hidl_ring_buffer_status_vec)) { + legacy_ring_buffer_status_vec, &hidl_ring_buffer_status_vec)) { return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; } - return {createWifiStatus(WifiStatusCode::SUCCESS), - hidl_ring_buffer_status_vec}; + return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_ring_buffer_status_vec}; } WifiStatus WifiChip::startLoggingToDebugRingBufferInternal( - const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level, - uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes) { + const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level, + uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes) { WifiStatus status = registerDebugRingBufferCallback(); if (status.code != WifiStatusCode::SUCCESS) { return status; } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->startRingBufferLogging( + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRingBufferLogging( getFirstActiveWlanIfaceName(), ring_name, - static_cast< - std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>( - verbose_level), + static_cast<std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(verbose_level), max_interval_in_sec, min_data_size_in_bytes); - ringbuffer_map_.insert(std::pair<std::string, Ringbuffer>( - ring_name, Ringbuffer(kMaxBufferSizeBytes))); + ringbuffer_map_.insert( + std::pair<std::string, Ringbuffer>(ring_name, Ringbuffer(kMaxBufferSizeBytes))); // if verbose logging enabled, turn up HAL daemon logging as well. if (verbose_level < WifiDebugRingBufferVerboseLevel::VERBOSE) { android::base::SetMinimumLogSeverity(android::base::DEBUG); @@ -1388,15 +1220,13 @@ WifiStatus WifiChip::startLoggingToDebugRingBufferInternal( return createWifiStatusFromLegacyError(legacy_status); } -WifiStatus WifiChip::forceDumpToDebugRingBufferInternal( - const hidl_string& ring_name) { +WifiStatus WifiChip::forceDumpToDebugRingBufferInternal(const hidl_string& ring_name) { WifiStatus status = registerDebugRingBufferCallback(); if (status.code != WifiStatusCode::SUCCESS) { return status; } legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->getRingBufferData(getFirstActiveWlanIfaceName(), - ring_name); + legacy_hal_.lock()->getRingBufferData(getFirstActiveWlanIfaceName(), ring_name); return createWifiStatusFromLegacyError(legacy_status); } @@ -1411,8 +1241,7 @@ WifiStatus WifiChip::flushRingBufferToFileInternal() { WifiStatus WifiChip::stopLoggingToDebugRingBufferInternal() { legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->deregisterRingBufferCallbackHandler( - getFirstActiveWlanIfaceName()); + legacy_hal_.lock()->deregisterRingBufferCallbackHandler(getFirstActiveWlanIfaceName()); if (legacy_status == legacy_hal::WIFI_SUCCESS) { debug_ring_buffer_cb_registered_ = false; } @@ -1424,13 +1253,12 @@ WifiChip::getDebugHostWakeReasonStatsInternal() { legacy_hal::wifi_error legacy_status; legacy_hal::WakeReasonStats legacy_stats; std::tie(legacy_status, legacy_stats) = - legacy_hal_.lock()->getWakeReasonStats(getFirstActiveWlanIfaceName()); + legacy_hal_.lock()->getWakeReasonStats(getFirstActiveWlanIfaceName()); if (legacy_status != legacy_hal::WIFI_SUCCESS) { return {createWifiStatusFromLegacyError(legacy_status), {}}; } WifiDebugHostWakeReasonStats hidl_stats; - if (!hidl_struct_util::convertLegacyWakeReasonStatsToHidl(legacy_stats, - &hidl_stats)) { + if (!hidl_struct_util::convertLegacyWakeReasonStatsToHidl(legacy_stats, &hidl_stats)) { return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; } return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats}; @@ -1440,62 +1268,56 @@ WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) { legacy_hal::wifi_error legacy_status; if (enable) { android::wp<WifiChip> weak_ptr_this(this); - const auto& on_alert_callback = [weak_ptr_this]( - int32_t error_code, - std::vector<uint8_t> debug_data) { + const auto& on_alert_callback = [weak_ptr_this](int32_t error_code, + std::vector<uint8_t> debug_data) { const auto shared_ptr_this = weak_ptr_this.promote(); if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { LOG(ERROR) << "Callback invoked on an invalid object"; return; } for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->onDebugErrorAlert(error_code, debug_data) - .isOk()) { + if (!callback->onDebugErrorAlert(error_code, debug_data).isOk()) { LOG(ERROR) << "Failed to invoke onDebugErrorAlert callback"; } } }; legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler( - getFirstActiveWlanIfaceName(), on_alert_callback); + getFirstActiveWlanIfaceName(), on_alert_callback); } else { legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler( - getFirstActiveWlanIfaceName()); + getFirstActiveWlanIfaceName()); } return createWifiStatusFromLegacyError(legacy_status); } -WifiStatus WifiChip::selectTxPowerScenarioInternal( - V1_1::IWifiChip::TxPowerScenario scenario) { +WifiStatus WifiChip::selectTxPowerScenarioInternal(V1_1::IWifiChip::TxPowerScenario scenario) { auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario( - getFirstActiveWlanIfaceName(), - hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario)); + getFirstActiveWlanIfaceName(), + hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario)); return createWifiStatusFromLegacyError(legacy_status); } WifiStatus WifiChip::resetTxPowerScenarioInternal() { - auto legacy_status = - legacy_hal_.lock()->resetTxPowerScenario(getFirstActiveWlanIfaceName()); + auto legacy_status = legacy_hal_.lock()->resetTxPowerScenario(getFirstActiveWlanIfaceName()); return createWifiStatusFromLegacyError(legacy_status); } WifiStatus WifiChip::setLatencyModeInternal(LatencyMode mode) { auto legacy_status = legacy_hal_.lock()->setLatencyMode( - getFirstActiveWlanIfaceName(), - hidl_struct_util::convertHidlLatencyModeToLegacy(mode)); + getFirstActiveWlanIfaceName(), hidl_struct_util::convertHidlLatencyModeToLegacy(mode)); return createWifiStatusFromLegacyError(legacy_status); } WifiStatus WifiChip::registerEventCallbackInternal_1_2( - const sp<V1_2::IWifiChipEventCallback>& /* event_callback */) { + const sp<V1_2::IWifiChipEventCallback>& /* event_callback */) { // Deprecated support for this callback. return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); } -WifiStatus WifiChip::selectTxPowerScenarioInternal_1_2( - TxPowerScenario scenario) { +WifiStatus WifiChip::selectTxPowerScenarioInternal_1_2(TxPowerScenario scenario) { auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario( - getFirstActiveWlanIfaceName(), - hidl_struct_util::convertHidlTxPowerScenarioToLegacy_1_2(scenario)); + getFirstActiveWlanIfaceName(), + hidl_struct_util::convertHidlTxPowerScenarioToLegacy_1_2(scenario)); return createWifiStatusFromLegacyError(legacy_status); } @@ -1510,65 +1332,61 @@ std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal_1_5() { uint32_t legacy_logger_feature_set; const auto ifname = getFirstActiveWlanIfaceName(); std::tie(legacy_status, legacy_feature_set) = - legacy_hal_.lock()->getSupportedFeatureSet(ifname); + legacy_hal_.lock()->getSupportedFeatureSet(ifname); if (legacy_status != legacy_hal::WIFI_SUCCESS) { return {createWifiStatusFromLegacyError(legacy_status), 0}; } std::tie(legacy_status, legacy_logger_feature_set) = - legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname); + legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname); if (legacy_status != legacy_hal::WIFI_SUCCESS) { // some devices don't support querying logger feature set legacy_logger_feature_set = 0; } uint32_t hidl_caps; if (!hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities( - legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) { + legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) { return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0}; } return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps}; } -std::pair<WifiStatus, sp<V1_4::IWifiRttController>> -WifiChip::createRttControllerInternal_1_4(const sp<IWifiIface>& bound_iface) { - if (sta_ifaces_.size() == 0 && - !canCurrentModeSupportIfaceOfType(IfaceType::STA)) { - LOG(ERROR) - << "createRttControllerInternal_1_4: Chip cannot support STAs " - "(and RTT by extension)"; +std::pair<WifiStatus, sp<V1_4::IWifiRttController>> WifiChip::createRttControllerInternal_1_4( + const sp<IWifiIface>& bound_iface) { + if (sta_ifaces_.size() == 0 && !canCurrentModeSupportIfaceOfType(IfaceType::STA)) { + LOG(ERROR) << "createRttControllerInternal_1_4: Chip cannot support STAs " + "(and RTT by extension)"; return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } - sp<WifiRttController> rtt = new WifiRttController( - getFirstActiveWlanIfaceName(), bound_iface, legacy_hal_); + sp<WifiRttController> rtt = + new WifiRttController(getFirstActiveWlanIfaceName(), bound_iface, legacy_hal_); rtt_controllers_.emplace_back(rtt); return {createWifiStatus(WifiStatusCode::SUCCESS), rtt}; } WifiStatus WifiChip::registerEventCallbackInternal_1_4( - const sp<V1_4::IWifiChipEventCallback>& event_callback) { + const sp<V1_4::IWifiChipEventCallback>& event_callback) { if (!event_cb_handler_.addCallback(event_callback)) { return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); } return createWifiStatus(WifiStatusCode::SUCCESS); } -WifiStatus WifiChip::setMultiStaPrimaryConnectionInternal( - const std::string& ifname) { - auto legacy_status = - legacy_hal_.lock()->multiStaSetPrimaryConnection(ifname); +WifiStatus WifiChip::setMultiStaPrimaryConnectionInternal(const std::string& ifname) { + auto legacy_status = legacy_hal_.lock()->multiStaSetPrimaryConnection(ifname); return createWifiStatusFromLegacyError(legacy_status); } WifiStatus WifiChip::setMultiStaUseCaseInternal(MultiStaUseCase use_case) { auto legacy_status = legacy_hal_.lock()->multiStaSetUseCase( - hidl_struct_util::convertHidlMultiStaUseCaseToLegacy(use_case)); + hidl_struct_util::convertHidlMultiStaUseCaseToLegacy(use_case)); return createWifiStatusFromLegacyError(legacy_status); } -WifiStatus WifiChip::setCoexUnsafeChannelsInternal( - std::vector<CoexUnsafeChannel> unsafe_channels, uint32_t restrictions) { +WifiStatus WifiChip::setCoexUnsafeChannelsInternal(std::vector<CoexUnsafeChannel> unsafe_channels, + uint32_t restrictions) { std::vector<legacy_hal::wifi_coex_unsafe_channel> legacy_unsafe_channels; - if (!hidl_struct_util::convertHidlVectorOfCoexUnsafeChannelToLegacy( - unsafe_channels, &legacy_unsafe_channels)) { + if (!hidl_struct_util::convertHidlVectorOfCoexUnsafeChannelToLegacy(unsafe_channels, + &legacy_unsafe_channels)) { return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); } uint32_t legacy_restrictions = 0; @@ -1581,35 +1399,31 @@ WifiStatus WifiChip::setCoexUnsafeChannelsInternal( if (restrictions & CoexRestriction::WIFI_AWARE) { legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_AWARE; } - auto legacy_status = legacy_hal_.lock()->setCoexUnsafeChannels( - legacy_unsafe_channels, legacy_restrictions); + auto legacy_status = + legacy_hal_.lock()->setCoexUnsafeChannels(legacy_unsafe_channels, legacy_restrictions); return createWifiStatusFromLegacyError(legacy_status); } WifiStatus WifiChip::setCountryCodeInternal(const std::array<int8_t, 2>& code) { - auto legacy_status = - legacy_hal_.lock()->setCountryCode(getFirstActiveWlanIfaceName(), code); + auto legacy_status = legacy_hal_.lock()->setCountryCode(getFirstActiveWlanIfaceName(), code); return createWifiStatusFromLegacyError(legacy_status); } -std::pair<WifiStatus, std::vector<WifiUsableChannel>> -WifiChip::getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask, - uint32_t filterMask) { +std::pair<WifiStatus, std::vector<WifiUsableChannel>> WifiChip::getUsableChannelsInternal( + WifiBand band, uint32_t ifaceModeMask, uint32_t filterMask) { legacy_hal::wifi_error legacy_status; std::vector<legacy_hal::wifi_usable_channel> legacy_usable_channels; - std::tie(legacy_status, legacy_usable_channels) = - legacy_hal_.lock()->getUsableChannels( + std::tie(legacy_status, legacy_usable_channels) = legacy_hal_.lock()->getUsableChannels( hidl_struct_util::convertHidlWifiBandToLegacyMacBand(band), hidl_struct_util::convertHidlWifiIfaceModeToLegacy(ifaceModeMask), - hidl_struct_util::convertHidlUsableChannelFilterToLegacy( - filterMask)); + hidl_struct_util::convertHidlUsableChannelFilterToLegacy(filterMask)); if (legacy_status != legacy_hal::WIFI_SUCCESS) { return {createWifiStatusFromLegacyError(legacy_status), {}}; } std::vector<WifiUsableChannel> hidl_usable_channels; - if (!hidl_struct_util::convertLegacyWifiUsableChannelsToHidl( - legacy_usable_channels, &hidl_usable_channels)) { + if (!hidl_struct_util::convertLegacyWifiUsableChannelsToHidl(legacy_usable_channels, + &hidl_usable_channels)) { return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; } return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_usable_channels}; @@ -1621,19 +1435,15 @@ WifiStatus WifiChip::triggerSubsystemRestartInternal() { } WifiStatus WifiChip::handleChipConfiguration( - /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, - ChipModeId mode_id) { + /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id) { // If the chip is already configured in a different mode, stop // the legacy HAL and then start it after firmware mode change. if (isValidModeId(current_mode_id_)) { - LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_ - << " to mode " << mode_id; + LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_ << " to mode " << mode_id; invalidateAndRemoveAllIfaces(); - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->stop(lock, []() {}); + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stop(lock, []() {}); if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to stop legacy HAL: " - << legacyErrorToString(legacy_status); + LOG(ERROR) << "Failed to stop legacy HAL: " << legacyErrorToString(legacy_status); return createWifiStatusFromLegacyError(legacy_status); } } @@ -1649,8 +1459,7 @@ WifiStatus WifiChip::handleChipConfiguration( } legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start(); if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to start legacy HAL: " - << legacyErrorToString(legacy_status); + LOG(ERROR) << "Failed to start legacy HAL: " << legacyErrorToString(legacy_status); return createWifiStatusFromLegacyError(legacy_status); } // Every time the HAL is restarted, we need to register the @@ -1666,8 +1475,7 @@ WifiStatus WifiChip::handleChipConfiguration( if (WifiStatusCode::SUCCESS == version_info.first.code) { property_set("vendor.wlan.firmware.version", version_info.second.firmwareDescription.c_str()); - property_set("vendor.wlan.driver.version", - version_info.second.driverDescription.c_str()); + property_set("vendor.wlan.driver.version", version_info.second.driverDescription.c_str()); } return createWifiStatus(WifiStatusCode::SUCCESS); @@ -1680,36 +1488,33 @@ WifiStatus WifiChip::registerDebugRingBufferCallback() { android::wp<WifiChip> weak_ptr_this(this); const auto& on_ring_buffer_data_callback = - [weak_ptr_this](const std::string& name, - const std::vector<uint8_t>& data, - const legacy_hal::wifi_ring_buffer_status& status) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - WifiDebugRingBufferStatus hidl_status; - if (!hidl_struct_util::convertLegacyDebugRingBufferStatusToHidl( - status, &hidl_status)) { - LOG(ERROR) << "Error converting ring buffer status"; - return; - } - { - std::unique_lock<std::mutex> lk(shared_ptr_this->lock_t); - const auto& target = - shared_ptr_this->ringbuffer_map_.find(name); - if (target != shared_ptr_this->ringbuffer_map_.end()) { - Ringbuffer& cur_buffer = target->second; - cur_buffer.append(data); - } else { - LOG(ERROR) << "Ringname " << name << " not found"; + [weak_ptr_this](const std::string& name, const std::vector<uint8_t>& data, + const legacy_hal::wifi_ring_buffer_status& status) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; return; } - // unique_lock unlocked here - } - }; - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->registerRingBufferCallbackHandler( + WifiDebugRingBufferStatus hidl_status; + if (!hidl_struct_util::convertLegacyDebugRingBufferStatusToHidl(status, + &hidl_status)) { + LOG(ERROR) << "Error converting ring buffer status"; + return; + } + { + std::unique_lock<std::mutex> lk(shared_ptr_this->lock_t); + const auto& target = shared_ptr_this->ringbuffer_map_.find(name); + if (target != shared_ptr_this->ringbuffer_map_.end()) { + Ringbuffer& cur_buffer = target->second; + cur_buffer.append(data); + } else { + LOG(ERROR) << "Ringname " << name << " not found"; + return; + } + // unique_lock unlocked here + } + }; + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->registerRingBufferCallbackHandler( getFirstActiveWlanIfaceName(), on_ring_buffer_data_callback); if (legacy_status == legacy_hal::WIFI_SUCCESS) { @@ -1721,35 +1526,32 @@ WifiStatus WifiChip::registerDebugRingBufferCallback() { WifiStatus WifiChip::registerRadioModeChangeCallback() { android::wp<WifiChip> weak_ptr_this(this); const auto& on_radio_mode_change_callback = - [weak_ptr_this](const std::vector<legacy_hal::WifiMacInfo>& mac_infos) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo> - hidl_radio_mode_infos; - if (!hidl_struct_util::convertLegacyWifiMacInfosToHidl( - mac_infos, &hidl_radio_mode_infos)) { - LOG(ERROR) << "Error converting wifi mac info"; - return; - } - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->onRadioModeChange_1_4(hidl_radio_mode_infos) - .isOk()) { - LOG(ERROR) << "Failed to invoke onRadioModeChange_1_4" - << " callback on: " << toString(callback); + [weak_ptr_this](const std::vector<legacy_hal::WifiMacInfo>& mac_infos) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; } - } - }; + std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo> hidl_radio_mode_infos; + if (!hidl_struct_util::convertLegacyWifiMacInfosToHidl(mac_infos, + &hidl_radio_mode_infos)) { + LOG(ERROR) << "Error converting wifi mac info"; + return; + } + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->onRadioModeChange_1_4(hidl_radio_mode_infos).isOk()) { + LOG(ERROR) << "Failed to invoke onRadioModeChange_1_4" + << " callback on: " << toString(callback); + } + } + }; legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->registerRadioModeChangeCallbackHandler( - getFirstActiveWlanIfaceName(), on_radio_mode_change_callback); + legacy_hal_.lock()->registerRadioModeChangeCallbackHandler( + getFirstActiveWlanIfaceName(), on_radio_mode_change_callback); return createWifiStatusFromLegacyError(legacy_status); } -std::vector<V1_4::IWifiChip::ChipIfaceCombination> -WifiChip::getCurrentModeIfaceCombinations() { +std::vector<V1_4::IWifiChip::ChipIfaceCombination> WifiChip::getCurrentModeIfaceCombinations() { if (!isValidModeId(current_mode_id_)) { LOG(ERROR) << "Chip not configured in a mode yet"; return {}; @@ -1779,7 +1581,7 @@ std::map<IfaceType, size_t> WifiChip::getCurrentIfaceCombination() { // of ifaces of each type in the combination. // This method is a port of HalDeviceManager.expandIfaceCombos() from framework. std::vector<std::map<IfaceType, size_t>> WifiChip::expandIfaceCombinations( - const V1_4::IWifiChip::ChipIfaceCombination& combination) { + const V1_4::IWifiChip::ChipIfaceCombination& combination) { uint32_t num_expanded_combos = 1; for (const auto& limit : combination.limits) { for (uint32_t i = 0; i < limit.maxIfaces; i++) { @@ -1792,8 +1594,7 @@ std::vector<std::map<IfaceType, size_t>> WifiChip::expandIfaceCombinations( std::vector<std::map<IfaceType, size_t>> expanded_combos; expanded_combos.resize(num_expanded_combos); for (auto& expanded_combo : expanded_combos) { - for (const auto type : - {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) { + for (const auto type : {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) { expanded_combo[type] = 0; } } @@ -1802,8 +1603,7 @@ std::vector<std::map<IfaceType, size_t>> WifiChip::expandIfaceCombinations( for (uint32_t i = 0; i < limit.maxIfaces; i++) { span /= limit.types.size(); for (uint32_t k = 0; k < num_expanded_combos; ++k) { - const auto iface_type = - limit.types[(k / span) % limit.types.size()]; + const auto iface_type = limit.types[(k / span) % limit.types.size()]; expanded_combos[k][iface_type]++; } } @@ -1812,13 +1612,11 @@ std::vector<std::map<IfaceType, size_t>> WifiChip::expandIfaceCombinations( } bool WifiChip::canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces( - const std::map<IfaceType, size_t>& expanded_combo, - IfaceType requested_type) { + const std::map<IfaceType, size_t>& expanded_combo, IfaceType requested_type) { const auto current_combo = getCurrentIfaceCombination(); // Check if we have space for 1 more iface of |type| in this combo - for (const auto type : - {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) { + for (const auto type : {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) { size_t num_ifaces_needed = current_combo.at(type); if (type == requested_type) { num_ifaces_needed++; @@ -1836,8 +1634,7 @@ bool WifiChip::canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces( // ChipIfaceCombination. // b) Check if the requested iface type can be added to the current mode // with the iface combination that is already active. -bool WifiChip::canCurrentModeSupportIfaceOfTypeWithCurrentIfaces( - IfaceType requested_type) { +bool WifiChip::canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType requested_type) { if (!isValidModeId(current_mode_id_)) { LOG(ERROR) << "Chip not configured in a mode yet"; return false; @@ -1846,8 +1643,8 @@ bool WifiChip::canCurrentModeSupportIfaceOfTypeWithCurrentIfaces( for (const auto& combination : combinations) { const auto expanded_combos = expandIfaceCombinations(combination); for (const auto& expanded_combo : expanded_combos) { - if (canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces( - expanded_combo, requested_type)) { + if (canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces(expanded_combo, + requested_type)) { return true; } } @@ -1858,11 +1655,10 @@ bool WifiChip::canCurrentModeSupportIfaceOfTypeWithCurrentIfaces( // Note: This does not consider ifaces already active. It only checks if the // provided expanded iface combination can support the requested combo. bool WifiChip::canExpandedIfaceComboSupportIfaceCombo( - const std::map<IfaceType, size_t>& expanded_combo, - const std::map<IfaceType, size_t>& req_combo) { + const std::map<IfaceType, size_t>& expanded_combo, + const std::map<IfaceType, size_t>& req_combo) { // Check if we have space for 1 more iface of |type| in this combo - for (const auto type : - {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) { + for (const auto type : {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) { if (req_combo.count(type) == 0) { // Iface of "type" not in the req_combo. continue; @@ -1881,8 +1677,7 @@ bool WifiChip::canExpandedIfaceComboSupportIfaceCombo( // b) Check if the requested iface combo can be added to the current mode. // Note: This does not consider ifaces already active. It only checks if the // current mode can support the requested combo. -bool WifiChip::canCurrentModeSupportIfaceCombo( - const std::map<IfaceType, size_t>& req_combo) { +bool WifiChip::canCurrentModeSupportIfaceCombo(const std::map<IfaceType, size_t>& req_combo) { if (!isValidModeId(current_mode_id_)) { LOG(ERROR) << "Chip not configured in a mode yet"; return false; @@ -1891,8 +1686,7 @@ bool WifiChip::canCurrentModeSupportIfaceCombo( for (const auto& combination : combinations) { const auto expanded_combos = expandIfaceCombinations(combination); for (const auto& expanded_combo : expanded_combos) { - if (canExpandedIfaceComboSupportIfaceCombo(expanded_combo, - req_combo)) { + if (canExpandedIfaceComboSupportIfaceCombo(expanded_combo, req_combo)) { return true; } } @@ -1956,8 +1750,7 @@ std::string WifiChip::getFirstActiveWlanIfaceName() { // Return the first wlan (wlan0, wlan1 etc.) starting from |start_idx| // not already in use. // Note: This doesn't check the actual presence of these interfaces. -std::string WifiChip::allocateApOrStaIfaceName(IfaceType type, - uint32_t start_idx) { +std::string WifiChip::allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx) { for (unsigned idx = start_idx; idx < kMaxWlanIfaces; idx++) { const auto ifname = getWlanIfaceNameWithType(type, idx); if (findUsingNameFromBridgedApInstances(ifname)) continue; @@ -1984,7 +1777,7 @@ uint32_t WifiChip::startIdxOfApIface() { } // AP iface names start with idx 1 for modes supporting -// concurrent STA, else start with idx 0. +// concurrent STA and not dual AP, else start with idx 0. std::string WifiChip::allocateApIfaceName() { // Check if we have a dedicated iface for AP. std::vector<std::string> ifnames = getPredefinedApIfaceNames(false); @@ -2002,8 +1795,8 @@ std::vector<std::string> WifiChip::allocateBridgedApInstanceNames() { } else { int num_ifaces_need_to_allocate = 2 - instances.size(); for (int i = 0; i < num_ifaces_need_to_allocate; i++) { - std::string instance_name = allocateApOrStaIfaceName( - IfaceType::AP, startIdxOfApIface() + i); + std::string instance_name = + allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface() + i); if (!instance_name.empty()) { instances.push_back(instance_name); } @@ -2031,8 +1824,7 @@ bool WifiChip::writeRingbufferFilesInternal() { if (cur_buffer.getData().empty()) { continue; } - const std::string file_path_raw = - kTombstoneFolderPath + item.first + "XXXXXXXXXX"; + const std::string file_path_raw = kTombstoneFolderPath + item.first + "XXXXXXXXXX"; const int dump_fd = mkstemp(makeCharVec(file_path_raw).data()); if (dump_fd == -1) { PLOG(ERROR) << "create file failed"; @@ -2040,8 +1832,8 @@ bool WifiChip::writeRingbufferFilesInternal() { } unique_fd file_auto_closer(dump_fd); for (const auto& cur_block : cur_buffer.getData()) { - if (write(dump_fd, cur_block.data(), - sizeof(cur_block[0]) * cur_block.size()) == -1) { + if (write(dump_fd, cur_block.data(), sizeof(cur_block[0]) * cur_block.size()) == + -1) { PLOG(ERROR) << "Error writing to file"; } } @@ -2056,8 +1848,7 @@ std::string WifiChip::getWlanIfaceNameWithType(IfaceType type, unsigned idx) { std::string ifname; // let the legacy hal override the interface name - legacy_hal::wifi_error err = - legacy_hal_.lock()->getSupportedIfaceName((uint32_t)type, ifname); + legacy_hal::wifi_error err = legacy_hal_.lock()->getSupportedIfaceName((uint32_t)type, ifname); if (err == legacy_hal::WIFI_SUCCESS) return ifname; return getWlanIfaceName(idx); @@ -2106,7 +1897,7 @@ bool WifiChip::findUsingNameFromBridgedApInstances(const std::string& name) { } } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.6/default/wifi_chip.h index 51ade5d810..8a068985d1 100644 --- a/wifi/1.5/default/wifi_chip.h +++ b/wifi/1.6/default/wifi_chip.h @@ -39,9 +39,11 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { using namespace android::hardware::wifi::V1_0; +using V1_5::WifiBand; +using V1_5::WifiUsableChannel; /** * HIDL interface object used to control a Wifi HAL chip instance. @@ -49,15 +51,13 @@ using namespace android::hardware::wifi::V1_0; * identifying handle information stored here. */ class WifiChip : public V1_5::IWifiChip { - public: + public: WifiChip(ChipId chip_id, bool is_primary, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal, - const std::weak_ptr<mode_controller::WifiModeController> - mode_controller, + const std::weak_ptr<mode_controller::WifiModeController> mode_controller, const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util, const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags, - const std::function<void(const std::string&)>& - subsystemCallbackHandler); + const std::function<void(const std::string&)>& subsystemCallbackHandler); // HIDL does not provide a built-in mechanism to let the server invalidate // a HIDL interface object after creation. If any client process holds onto // a reference to the object in their context, any method calls on that @@ -78,116 +78,84 @@ class WifiChip : public V1_5::IWifiChip { // HIDL methods exposed. Return<void> getId(getId_cb hidl_status_cb) override; // Deprecated support for this callback - Return<void> registerEventCallback( - const sp<V1_0::IWifiChipEventCallback>& event_callback, - registerEventCallback_cb hidl_status_cb) override; + Return<void> registerEventCallback(const sp<V1_0::IWifiChipEventCallback>& event_callback, + registerEventCallback_cb hidl_status_cb) override; Return<void> getCapabilities(getCapabilities_cb hidl_status_cb) override; - Return<void> getAvailableModes( - getAvailableModes_cb hidl_status_cb) override; - Return<void> configureChip(ChipModeId mode_id, - configureChip_cb hidl_status_cb) override; + Return<void> getAvailableModes(getAvailableModes_cb hidl_status_cb) override; + Return<void> configureChip(ChipModeId mode_id, configureChip_cb hidl_status_cb) override; Return<void> getMode(getMode_cb hidl_status_cb) override; - Return<void> requestChipDebugInfo( - requestChipDebugInfo_cb hidl_status_cb) override; - Return<void> requestDriverDebugDump( - requestDriverDebugDump_cb hidl_status_cb) override; - Return<void> requestFirmwareDebugDump( - requestFirmwareDebugDump_cb hidl_status_cb) override; + Return<void> requestChipDebugInfo(requestChipDebugInfo_cb hidl_status_cb) override; + Return<void> requestDriverDebugDump(requestDriverDebugDump_cb hidl_status_cb) override; + Return<void> requestFirmwareDebugDump(requestFirmwareDebugDump_cb hidl_status_cb) override; Return<void> createApIface(createApIface_cb hidl_status_cb) override; - Return<void> createBridgedApIface( - createBridgedApIface_cb hidl_status_cb) override; + Return<void> createBridgedApIface(createBridgedApIface_cb hidl_status_cb) override; Return<void> getApIfaceNames(getApIfaceNames_cb hidl_status_cb) override; - Return<void> getApIface(const hidl_string& ifname, - getApIface_cb hidl_status_cb) override; - Return<void> removeApIface(const hidl_string& ifname, - removeApIface_cb hidl_status_cb) override; + Return<void> getApIface(const hidl_string& ifname, getApIface_cb hidl_status_cb) override; + Return<void> removeApIface(const hidl_string& ifname, removeApIface_cb hidl_status_cb) override; Return<void> removeIfaceInstanceFromBridgedApIface( - const hidl_string& brIfaceName, const hidl_string& ifaceInstanceName, - removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) override; + const hidl_string& brIfaceName, const hidl_string& ifaceInstanceName, + removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) override; Return<void> createNanIface(createNanIface_cb hidl_status_cb) override; Return<void> getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) override; - Return<void> getNanIface(const hidl_string& ifname, - getNanIface_cb hidl_status_cb) override; + Return<void> getNanIface(const hidl_string& ifname, getNanIface_cb hidl_status_cb) override; Return<void> removeNanIface(const hidl_string& ifname, removeNanIface_cb hidl_status_cb) override; Return<void> createP2pIface(createP2pIface_cb hidl_status_cb) override; Return<void> getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) override; - Return<void> getP2pIface(const hidl_string& ifname, - getP2pIface_cb hidl_status_cb) override; + Return<void> getP2pIface(const hidl_string& ifname, getP2pIface_cb hidl_status_cb) override; Return<void> removeP2pIface(const hidl_string& ifname, removeP2pIface_cb hidl_status_cb) override; Return<void> createStaIface(createStaIface_cb hidl_status_cb) override; Return<void> getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) override; - Return<void> getStaIface(const hidl_string& ifname, - getStaIface_cb hidl_status_cb) override; + Return<void> getStaIface(const hidl_string& ifname, getStaIface_cb hidl_status_cb) override; Return<void> removeStaIface(const hidl_string& ifname, removeStaIface_cb hidl_status_cb) override; - Return<void> createRttController( - const sp<IWifiIface>& bound_iface, - createRttController_cb hidl_status_cb) override; - Return<void> getDebugRingBuffersStatus( - getDebugRingBuffersStatus_cb hidl_status_cb) override; + Return<void> createRttController(const sp<IWifiIface>& bound_iface, + createRttController_cb hidl_status_cb) override; + Return<void> getDebugRingBuffersStatus(getDebugRingBuffersStatus_cb hidl_status_cb) override; Return<void> startLoggingToDebugRingBuffer( - const hidl_string& ring_name, - WifiDebugRingBufferVerboseLevel verbose_level, - uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes, - startLoggingToDebugRingBuffer_cb hidl_status_cb) override; - Return<void> forceDumpToDebugRingBuffer( - const hidl_string& ring_name, - forceDumpToDebugRingBuffer_cb hidl_status_cb) override; - Return<void> flushRingBufferToFile( - flushRingBufferToFile_cb hidl_status_cb) override; + const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level, + uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes, + startLoggingToDebugRingBuffer_cb hidl_status_cb) override; + Return<void> forceDumpToDebugRingBuffer(const hidl_string& ring_name, + forceDumpToDebugRingBuffer_cb hidl_status_cb) override; + Return<void> flushRingBufferToFile(flushRingBufferToFile_cb hidl_status_cb) override; Return<void> stopLoggingToDebugRingBuffer( - stopLoggingToDebugRingBuffer_cb hidl_status_cb) override; + stopLoggingToDebugRingBuffer_cb hidl_status_cb) override; Return<void> getDebugHostWakeReasonStats( - getDebugHostWakeReasonStats_cb hidl_status_cb) override; - Return<void> enableDebugErrorAlerts( - bool enable, enableDebugErrorAlerts_cb hidl_status_cb) override; - Return<void> selectTxPowerScenario( - V1_1::IWifiChip::TxPowerScenario scenario, - selectTxPowerScenario_cb hidl_status_cb) override; - Return<void> resetTxPowerScenario( - resetTxPowerScenario_cb hidl_status_cb) override; - Return<void> setLatencyMode(LatencyMode mode, - setLatencyMode_cb hidl_status_cb) override; - Return<void> registerEventCallback_1_2( - const sp<V1_2::IWifiChipEventCallback>& event_callback, - registerEventCallback_1_2_cb hidl_status_cb) override; - Return<void> selectTxPowerScenario_1_2( - TxPowerScenario scenario, - selectTxPowerScenario_cb hidl_status_cb) override; - Return<void> getCapabilities_1_3( - getCapabilities_cb hidl_status_cb) override; - Return<void> getCapabilities_1_5( - getCapabilities_1_5_cb hidl_status_cb) override; - Return<void> debug(const hidl_handle& handle, - const hidl_vec<hidl_string>& options) override; - Return<void> createRttController_1_4( - const sp<IWifiIface>& bound_iface, - createRttController_1_4_cb hidl_status_cb) override; - Return<void> registerEventCallback_1_4( - const sp<V1_4::IWifiChipEventCallback>& event_callback, - registerEventCallback_1_4_cb hidl_status_cb) override; + getDebugHostWakeReasonStats_cb hidl_status_cb) override; + Return<void> enableDebugErrorAlerts(bool enable, + enableDebugErrorAlerts_cb hidl_status_cb) override; + Return<void> selectTxPowerScenario(V1_1::IWifiChip::TxPowerScenario scenario, + selectTxPowerScenario_cb hidl_status_cb) override; + Return<void> resetTxPowerScenario(resetTxPowerScenario_cb hidl_status_cb) override; + Return<void> setLatencyMode(LatencyMode mode, setLatencyMode_cb hidl_status_cb) override; + Return<void> registerEventCallback_1_2(const sp<V1_2::IWifiChipEventCallback>& event_callback, + registerEventCallback_1_2_cb hidl_status_cb) override; + Return<void> selectTxPowerScenario_1_2(TxPowerScenario scenario, + selectTxPowerScenario_cb hidl_status_cb) override; + Return<void> getCapabilities_1_3(getCapabilities_cb hidl_status_cb) override; + Return<void> getCapabilities_1_5(getCapabilities_1_5_cb hidl_status_cb) override; + Return<void> debug(const hidl_handle& handle, const hidl_vec<hidl_string>& options) override; + Return<void> createRttController_1_4(const sp<IWifiIface>& bound_iface, + createRttController_1_4_cb hidl_status_cb) override; + Return<void> registerEventCallback_1_4(const sp<V1_4::IWifiChipEventCallback>& event_callback, + registerEventCallback_1_4_cb hidl_status_cb) override; Return<void> setMultiStaPrimaryConnection( - const hidl_string& ifname, - setMultiStaPrimaryConnection_cb hidl_status_cb) override; - Return<void> setMultiStaUseCase( - MultiStaUseCase use_case, - setMultiStaUseCase_cb hidl_status_cb) override; - Return<void> setCoexUnsafeChannels( - const hidl_vec<CoexUnsafeChannel>& unsafe_channels, - hidl_bitfield<IfaceType> restrictions, - setCoexUnsafeChannels_cb hidl_status_cb) override; + const hidl_string& ifname, setMultiStaPrimaryConnection_cb hidl_status_cb) override; + Return<void> setMultiStaUseCase(MultiStaUseCase use_case, + setMultiStaUseCase_cb hidl_status_cb) override; + Return<void> setCoexUnsafeChannels(const hidl_vec<CoexUnsafeChannel>& unsafe_channels, + hidl_bitfield<IfaceType> restrictions, + setCoexUnsafeChannels_cb hidl_status_cb) override; Return<void> setCountryCode(const hidl_array<int8_t, 2>& code, setCountryCode_cb _hidl_cb) override; - Return<void> getUsableChannels( - WifiBand band, hidl_bitfield<WifiIfaceMode> ifaceModeMask, - hidl_bitfield<UsableChannelFilter> filterMask, - getUsableChannels_cb _hidl_cb) override; - Return<void> triggerSubsystemRestart( - triggerSubsystemRestart_cb hidl_status_cb) override; + Return<void> getUsableChannels(WifiBand band, hidl_bitfield<V1_5::WifiIfaceMode> ifaceModeMask, + hidl_bitfield<UsableChannelFilter> filterMask, + getUsableChannels_cb _hidl_cb) override; + Return<void> triggerSubsystemRestart(triggerSubsystemRestart_cb hidl_status_cb) override; - private: + private: void invalidateAndRemoveAllIfaces(); // When a STA iface is removed any dependent NAN-ifaces/RTT-controllers are // invalidated & removed. @@ -197,99 +165,83 @@ class WifiChip : public V1_5::IWifiChip { std::pair<WifiStatus, ChipId> getIdInternal(); // Deprecated support for this callback WifiStatus registerEventCallbackInternal( - const sp<V1_0::IWifiChipEventCallback>& event_callback); + const sp<V1_0::IWifiChipEventCallback>& event_callback); std::pair<WifiStatus, uint32_t> getCapabilitiesInternal(); std::pair<WifiStatus, std::vector<ChipMode>> getAvailableModesInternal(); - WifiStatus configureChipInternal( - std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id); + WifiStatus configureChipInternal(std::unique_lock<std::recursive_mutex>* lock, + ChipModeId mode_id); std::pair<WifiStatus, uint32_t> getModeInternal(); - std::pair<WifiStatus, IWifiChip::ChipDebugInfo> - requestChipDebugInfoInternal(); - std::pair<WifiStatus, std::vector<uint8_t>> - requestDriverDebugDumpInternal(); - std::pair<WifiStatus, std::vector<uint8_t>> - requestFirmwareDebugDumpInternal(); + std::pair<WifiStatus, IWifiChip::ChipDebugInfo> requestChipDebugInfoInternal(); + std::pair<WifiStatus, std::vector<uint8_t>> requestDriverDebugDumpInternal(); + std::pair<WifiStatus, std::vector<uint8_t>> requestFirmwareDebugDumpInternal(); sp<WifiApIface> newWifiApIface(std::string& ifname); WifiStatus createVirtualApInterface(const std::string& apVirtIf); std::pair<WifiStatus, sp<V1_5::IWifiApIface>> createApIfaceInternal(); - std::pair<WifiStatus, sp<V1_5::IWifiApIface>> - createBridgedApIfaceInternal(); + std::pair<WifiStatus, sp<V1_5::IWifiApIface>> createBridgedApIfaceInternal(); std::pair<WifiStatus, std::vector<hidl_string>> getApIfaceNamesInternal(); - std::pair<WifiStatus, sp<V1_5::IWifiApIface>> getApIfaceInternal( - const std::string& ifname); + std::pair<WifiStatus, sp<V1_5::IWifiApIface>> getApIfaceInternal(const std::string& ifname); WifiStatus removeApIfaceInternal(const std::string& ifname); - WifiStatus removeIfaceInstanceFromBridgedApIfaceInternal( - const std::string& brIfaceName, const std::string& ifInstanceName); + WifiStatus removeIfaceInstanceFromBridgedApIfaceInternal(const std::string& brIfaceName, + const std::string& ifInstanceName); std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> createNanIfaceInternal(); std::pair<WifiStatus, std::vector<hidl_string>> getNanIfaceNamesInternal(); - std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> getNanIfaceInternal( - const std::string& ifname); + std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> getNanIfaceInternal(const std::string& ifname); WifiStatus removeNanIfaceInternal(const std::string& ifname); std::pair<WifiStatus, sp<IWifiP2pIface>> createP2pIfaceInternal(); std::pair<WifiStatus, std::vector<hidl_string>> getP2pIfaceNamesInternal(); - std::pair<WifiStatus, sp<IWifiP2pIface>> getP2pIfaceInternal( - const std::string& ifname); + std::pair<WifiStatus, sp<IWifiP2pIface>> getP2pIfaceInternal(const std::string& ifname); WifiStatus removeP2pIfaceInternal(const std::string& ifname); std::pair<WifiStatus, sp<V1_5::IWifiStaIface>> createStaIfaceInternal(); std::pair<WifiStatus, std::vector<hidl_string>> getStaIfaceNamesInternal(); - std::pair<WifiStatus, sp<V1_5::IWifiStaIface>> getStaIfaceInternal( - const std::string& ifname); + std::pair<WifiStatus, sp<V1_5::IWifiStaIface>> getStaIfaceInternal(const std::string& ifname); WifiStatus removeStaIfaceInternal(const std::string& ifname); - std::pair<WifiStatus, sp<V1_0::IWifiRttController>> - createRttControllerInternal(const sp<IWifiIface>& bound_iface); + std::pair<WifiStatus, sp<V1_0::IWifiRttController>> createRttControllerInternal( + const sp<IWifiIface>& bound_iface); std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>> getDebugRingBuffersStatusInternal(); - WifiStatus startLoggingToDebugRingBufferInternal( - const hidl_string& ring_name, - WifiDebugRingBufferVerboseLevel verbose_level, - uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes); + WifiStatus startLoggingToDebugRingBufferInternal(const hidl_string& ring_name, + WifiDebugRingBufferVerboseLevel verbose_level, + uint32_t max_interval_in_sec, + uint32_t min_data_size_in_bytes); WifiStatus forceDumpToDebugRingBufferInternal(const hidl_string& ring_name); WifiStatus flushRingBufferToFileInternal(); WifiStatus stopLoggingToDebugRingBufferInternal(); - std::pair<WifiStatus, WifiDebugHostWakeReasonStats> - getDebugHostWakeReasonStatsInternal(); + std::pair<WifiStatus, WifiDebugHostWakeReasonStats> getDebugHostWakeReasonStatsInternal(); WifiStatus enableDebugErrorAlertsInternal(bool enable); - WifiStatus selectTxPowerScenarioInternal( - V1_1::IWifiChip::TxPowerScenario scenario); + WifiStatus selectTxPowerScenarioInternal(V1_1::IWifiChip::TxPowerScenario scenario); WifiStatus resetTxPowerScenarioInternal(); WifiStatus setLatencyModeInternal(LatencyMode mode); WifiStatus registerEventCallbackInternal_1_2( - const sp<V1_2::IWifiChipEventCallback>& event_callback); + const sp<V1_2::IWifiChipEventCallback>& event_callback); WifiStatus selectTxPowerScenarioInternal_1_2(TxPowerScenario scenario); std::pair<WifiStatus, uint32_t> getCapabilitiesInternal_1_3(); std::pair<WifiStatus, uint32_t> getCapabilitiesInternal_1_5(); - std::pair<WifiStatus, sp<V1_4::IWifiRttController>> - createRttControllerInternal_1_4(const sp<IWifiIface>& bound_iface); + std::pair<WifiStatus, sp<V1_4::IWifiRttController>> createRttControllerInternal_1_4( + const sp<IWifiIface>& bound_iface); WifiStatus registerEventCallbackInternal_1_4( - const sp<V1_4::IWifiChipEventCallback>& event_callback); + const sp<V1_4::IWifiChipEventCallback>& event_callback); WifiStatus setMultiStaPrimaryConnectionInternal(const std::string& ifname); WifiStatus setMultiStaUseCaseInternal(MultiStaUseCase use_case); - WifiStatus setCoexUnsafeChannelsInternal( - std::vector<CoexUnsafeChannel> unsafe_channels, uint32_t restrictions); + WifiStatus setCoexUnsafeChannelsInternal(std::vector<CoexUnsafeChannel> unsafe_channels, + uint32_t restrictions); WifiStatus setCountryCodeInternal(const std::array<int8_t, 2>& code); - std::pair<WifiStatus, std::vector<WifiUsableChannel>> - getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask, - uint32_t filterMask); - WifiStatus handleChipConfiguration( - std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id); + std::pair<WifiStatus, std::vector<WifiUsableChannel>> getUsableChannelsInternal( + WifiBand band, uint32_t ifaceModeMask, uint32_t filterMask); + WifiStatus handleChipConfiguration(std::unique_lock<std::recursive_mutex>* lock, + ChipModeId mode_id); WifiStatus registerDebugRingBufferCallback(); WifiStatus registerRadioModeChangeCallback(); - std::vector<V1_4::IWifiChip::ChipIfaceCombination> - getCurrentModeIfaceCombinations(); + std::vector<V1_4::IWifiChip::ChipIfaceCombination> getCurrentModeIfaceCombinations(); std::map<IfaceType, size_t> getCurrentIfaceCombination(); std::vector<std::map<IfaceType, size_t>> expandIfaceCombinations( - const V1_4::IWifiChip::ChipIfaceCombination& combination); + const V1_4::IWifiChip::ChipIfaceCombination& combination); bool canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces( - const std::map<IfaceType, size_t>& expanded_combo, - IfaceType requested_type); - bool canCurrentModeSupportIfaceOfTypeWithCurrentIfaces( - IfaceType requested_type); - bool canExpandedIfaceComboSupportIfaceCombo( - const std::map<IfaceType, size_t>& expanded_combo, - const std::map<IfaceType, size_t>& req_combo); - bool canCurrentModeSupportIfaceCombo( - const std::map<IfaceType, size_t>& req_combo); + const std::map<IfaceType, size_t>& expanded_combo, IfaceType requested_type); + bool canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType requested_type); + bool canExpandedIfaceComboSupportIfaceCombo(const std::map<IfaceType, size_t>& expanded_combo, + const std::map<IfaceType, size_t>& req_combo); + bool canCurrentModeSupportIfaceCombo(const std::map<IfaceType, size_t>& req_combo); bool canCurrentModeSupportIfaceOfType(IfaceType requested_type); bool isValidModeId(ChipModeId mode_id); bool isStaApConcurrencyAllowedInCurrentMode(); @@ -306,7 +258,6 @@ class WifiChip : public V1_5::IWifiChip { void invalidateAndClearBridgedAp(const std::string& br_name); bool findUsingNameFromBridgedApInstances(const std::string& name); WifiStatus triggerSubsystemRestartInternal(); - void QcRemoveAndClearDynamicIfaces(); ChipId chip_id_; std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_; @@ -327,20 +278,15 @@ class WifiChip : public V1_5::IWifiChip { // registration mechanism. Use this to check if we have already // registered a callback. bool debug_ring_buffer_cb_registered_; - hidl_callback_util::HidlCallbackHandler<V1_4::IWifiChipEventCallback> - event_cb_handler_; + hidl_callback_util::HidlCallbackHandler<V1_4::IWifiChipEventCallback> event_cb_handler_; const std::function<void(const std::string&)> subsystemCallbackHandler_; std::map<std::string, std::vector<std::string>> br_ifaces_ap_instances_; - - std::vector<sp<WifiApIface>> created_ap_ifaces_; - std::vector<sp<WifiStaIface>> created_sta_ifaces_; - DISALLOW_COPY_AND_ASSIGN(WifiChip); }; } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/wifi_feature_flags.cpp b/wifi/1.6/default/wifi_feature_flags.cpp index 293563e3ac..71319e1e90 100644 --- a/wifi/1.5/default/wifi_feature_flags.cpp +++ b/wifi/1.6/default/wifi_feature_flags.cpp @@ -24,7 +24,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace feature_flags { @@ -84,54 +84,14 @@ constexpr ChipModeId kMainModeId = chip_mode_ids::kV3; # define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P}, 1}} # endif # else -# if defined(QC_WIFI_HIDL_FEATURE_DUAL_AP) && defined(QC_WIFI_HIDL_FEATURE_DUAL_STA) -# ifdef WIFI_HIDL_FEATURE_AWARE -// (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN)) or (2 AP) or (2 STA) -# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\ - {{{STA}, 1}, {{P2P, NAN}, 1}},\ - {{{AP}, 2}},\ - {{{STA}, 2}} -# else -// (1 STA + 1 AP) or (1 STA + 1 P2P) or (2 AP) or (2 STA) -# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\ - {{{STA}, 1}, {{P2P}, 1}},\ - {{{AP}, 2}},\ - {{{STA}, 2}} -# endif -# elif defined(QC_WIFI_HIDL_FEATURE_DUAL_AP) -# ifdef WIFI_HIDL_FEATURE_AWARE -// (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN)) or (2 AP) -# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\ - {{{STA}, 1}, {{P2P, NAN}, 1}},\ - {{{AP}, 2}} -# else -// (1 STA + 1 AP) or (1 STA + 1 P2P) or (2 AP) -# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\ - {{{STA}, 1}, {{P2P}, 1}},\ - {{{AP}, 2}} -# endif -# elif defined(QC_WIFI_HIDL_FEATURE_DUAL_STA) -# ifdef WIFI_HIDL_FEATURE_AWARE -// (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN)) or (2 STA) -# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\ - {{{STA}, 1}, {{P2P, NAN}, 1}},\ - {{{STA}, 2}} -# else -// (1 STA + 1 AP) or (1 STA + 1 P2P) or (2 STA) -# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\ - {{{STA}, 1}, {{P2P}, 1}},\ - {{{STA}, 2}} -# endif +# ifdef WIFI_HIDL_FEATURE_AWARE +// (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN)) +# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\ + {{{STA}, 1}, {{P2P, NAN}, 1}} # else -# ifdef WIFI_HIDL_FEATURE_AWARE -// (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN)) -# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\ - {{{STA}, 1}, {{P2P, NAN}, 1}} -# else -// (1 STA + 1 AP) or (1 STA + 1 P2P) -# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\ - {{{STA}, 1}, {{P2P}, 1}} -# endif +// (1 STA + 1 AP) or (1 STA + 1 P2P) +# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\ + {{{STA}, 1}, {{P2P}, 1}} # endif # endif #else @@ -157,18 +117,16 @@ constexpr ChipModeId kMainModeId = chip_mode_ids::kV1Sta; * The main point here is to simplify the syntax required by * WIFI_HAL_INTERFACE_COMBINATIONS. */ -struct ChipIfaceCombination - : public hidl_vec<IWifiChip::ChipIfaceCombinationLimit> { - ChipIfaceCombination( - const std::initializer_list<IWifiChip::ChipIfaceCombinationLimit> list) +struct ChipIfaceCombination : public hidl_vec<IWifiChip::ChipIfaceCombinationLimit> { + ChipIfaceCombination(const std::initializer_list<IWifiChip::ChipIfaceCombinationLimit> list) : hidl_vec(list) {} operator IWifiChip::ChipIfaceCombination() const { return {*this}; } static hidl_vec<IWifiChip::ChipIfaceCombination> make_vec( - const std::initializer_list<ChipIfaceCombination> list) { + const std::initializer_list<ChipIfaceCombination> list) { return hidl_vec<IWifiChip::ChipIfaceCombination>( // - std::begin(list), std::end(list)); + std::begin(list), std::end(list)); } }; @@ -177,23 +135,22 @@ struct ChipIfaceCombination #define P2P IfaceType::P2P #define NAN IfaceType::NAN static const std::vector<IWifiChip::ChipMode> kChipModesPrimary{ - {kMainModeId, - ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS})}, + {kMainModeId, ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS})}, #ifdef WIFI_HAL_INTERFACE_COMBINATIONS_AP - {chip_mode_ids::kV1Ap, - ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS_AP})}, + {chip_mode_ids::kV1Ap, + ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS_AP})}, #endif }; static const std::vector<IWifiChip::ChipMode> kChipModesSecondary{ #ifdef WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP - {chip_mode_ids::kV3, ChipIfaceCombination::make_vec( - {WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP})}, + {chip_mode_ids::kV3, + ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP})}, #endif }; constexpr char kDebugPresetInterfaceCombinationIdxProperty[] = - "persist.vendor.debug.wifi.hal.preset_interface_combination_idx"; + "persist.vendor.debug.wifi.hal.preset_interface_combination_idx"; // List of pre-defined interface combinations that can be enabled at runtime via // setting the property: "kDebugPresetInterfaceCombinationIdxProperty" to the // corresponding index value. @@ -240,19 +197,18 @@ static const std::vector<std::pair<std::string, std::vector<IWifiChip::ChipMode> #undef NAN #ifdef WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION -#pragma message \ - "WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION is deprecated; override " \ - "'config_wifi_ap_randomization_supported' in " \ - "frameworks/base/core/res/res/values/config.xml in the device overlay " \ - "instead" +#pragma message \ + "WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION is deprecated; override " \ + "'config_wifi_ap_randomization_supported' in " \ + "frameworks/base/core/res/res/values/config.xml in the device overlay " \ + "instead" #endif // WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION WifiFeatureFlags::WifiFeatureFlags() {} std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModesForPrimary() { std::array<char, PROPERTY_VALUE_MAX> buffer; - auto res = property_get(kDebugPresetInterfaceCombinationIdxProperty, - buffer.data(), nullptr); + auto res = property_get(kDebugPresetInterfaceCombinationIdxProperty, buffer.data(), nullptr); // Debug propety not set, use the device preset interface combination. if (res <= 0) return kChipModesPrimary; @@ -266,19 +222,18 @@ std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModesForPrimary() { std::string name; std::vector<IWifiChip::ChipMode> chip_modes; std::tie(name, chip_modes) = kDebugChipModes[idx]; - LOG(INFO) << "Using debug chip mode: <" << name << "> set via property: " - << kDebugPresetInterfaceCombinationIdxProperty; + LOG(INFO) << "Using debug chip mode: <" << name + << "> set via property: " << kDebugPresetInterfaceCombinationIdxProperty; return chip_modes; } -std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModes( - bool is_primary) { +std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModes(bool is_primary) { return (is_primary) ? getChipModesForPrimary() : kChipModesSecondary; } } // namespace feature_flags } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/wifi_feature_flags.h b/wifi/1.6/default/wifi_feature_flags.h index 7d561fc949..d5844d99b3 100644 --- a/wifi/1.5/default/wifi_feature_flags.h +++ b/wifi/1.6/default/wifi_feature_flags.h @@ -22,7 +22,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace feature_flags { @@ -38,20 +38,19 @@ constexpr V1_0::ChipModeId kV3 = 3; } // namespace chip_mode_ids class WifiFeatureFlags { - public: + public: WifiFeatureFlags(); virtual ~WifiFeatureFlags() = default; - virtual std::vector<V1_0::IWifiChip::ChipMode> getChipModes( - bool is_primary); + virtual std::vector<V1_0::IWifiChip::ChipMode> getChipModes(bool is_primary); - private: + private: std::vector<V1_0::IWifiChip::ChipMode> getChipModesForPrimary(); }; } // namespace feature_flags } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/wifi_iface_util.cpp b/wifi/1.6/default/wifi_iface_util.cpp index f1c182fc7d..d55e4f8251 100644 --- a/wifi/1.5/default/wifi_iface_util.cpp +++ b/wifi/1.6/default/wifi_iface_util.cpp @@ -36,23 +36,18 @@ constexpr uint8_t kMacAddressLocallyAssignedMask = 0x02; namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace iface_util { -WifiIfaceUtil::WifiIfaceUtil( - const std::weak_ptr<wifi_system::InterfaceTool> iface_tool, - const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal) +WifiIfaceUtil::WifiIfaceUtil(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool, + const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal) : iface_tool_(iface_tool), legacy_hal_(legacy_hal), - random_mac_address_index_(0), - event_handlers_map_() { - for (int i=0; i < MAX_RANDOM_MAC_ADDR_INDEX; i++) - random_mac_address_[i] = nullptr; -} + random_mac_address_(nullptr), + event_handlers_map_() {} -std::array<uint8_t, 6> WifiIfaceUtil::getFactoryMacAddress( - const std::string& iface_name) { +std::array<uint8_t, 6> WifiIfaceUtil::getFactoryMacAddress(const std::string& iface_name) { return iface_tool_.lock()->GetFactoryMacAddress(iface_name.c_str()); } @@ -62,7 +57,7 @@ bool WifiIfaceUtil::setMacAddress(const std::string& iface_name, legacy_hal::wifi_error legacy_status; uint64_t legacy_feature_set; std::tie(legacy_status, legacy_feature_set) = - legacy_hal_.lock()->getSupportedFeatureSet(iface_name); + legacy_hal_.lock()->getSupportedFeatureSet(iface_name); if (!(legacy_feature_set & WIFI_FEATURE_DYNAMIC_SET_MAC) && !iface_tool_.lock()->SetUpState(iface_name.c_str(), false)) { @@ -76,8 +71,7 @@ bool WifiIfaceUtil::setMacAddress(const std::string& iface_name, !iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) { LOG(ERROR) << "SetUpState(true) failed. Wait for driver ready."; // Wait for driver ready and try to set iface UP again - if (legacy_hal_.lock()->waitForDriverReady() != - legacy_hal::WIFI_SUCCESS) { + if (legacy_hal_.lock()->waitForDriverReady() != legacy_hal::WIFI_SUCCESS) { LOG(ERROR) << "SetUpState(true) wait for driver ready failed."; return false; } @@ -103,22 +97,12 @@ bool WifiIfaceUtil::setMacAddress(const std::string& iface_name, return success; } -void WifiIfaceUtil::setRandomMacAddressIndex(int idx) { - if (idx >= MAX_RANDOM_MAC_ADDR_INDEX) { - LOG(ERROR) << "Requested random mac address index crossed max limit!!"; - return; - } - - random_mac_address_index_ = idx; -} - std::array<uint8_t, 6> WifiIfaceUtil::getOrCreateRandomMacAddress() { - if (random_mac_address_[random_mac_address_index_]) { - return *random_mac_address_[random_mac_address_index_].get(); + if (random_mac_address_) { + return *random_mac_address_.get(); } - random_mac_address_[random_mac_address_index_] = - std::make_unique<std::array<uint8_t, 6>>(createRandomMacAddress()); - return *random_mac_address_[random_mac_address_index_].get(); + random_mac_address_ = std::make_unique<std::array<uint8_t, 6>>(createRandomMacAddress()); + return *random_mac_address_.get(); } void WifiIfaceUtil::registerIfaceEventHandlers(const std::string& iface_name, @@ -126,8 +110,7 @@ void WifiIfaceUtil::registerIfaceEventHandlers(const std::string& iface_name, event_handlers_map_[iface_name] = handlers; } -void WifiIfaceUtil::unregisterIfaceEventHandlers( - const std::string& iface_name) { +void WifiIfaceUtil::unregisterIfaceEventHandlers(const std::string& iface_name) { event_handlers_map_.erase(iface_name); } @@ -135,9 +118,8 @@ std::array<uint8_t, 6> WifiIfaceUtil::createRandomMacAddress() { std::array<uint8_t, 6> address = {}; std::random_device rd; std::default_random_engine engine(rd()); - std::uniform_int_distribution<uint8_t> dist( - std::numeric_limits<uint8_t>::min(), - std::numeric_limits<uint8_t>::max()); + std::uniform_int_distribution<uint8_t> dist(std::numeric_limits<uint8_t>::min(), + std::numeric_limits<uint8_t>::max()); for (size_t i = 0; i < address.size(); i++) { address[i] = dist(engine); } @@ -178,19 +160,17 @@ bool WifiIfaceUtil::deleteBridge(const std::string& br_name) { return iface_tool_.lock()->deleteBridge(br_name); } -bool WifiIfaceUtil::addIfaceToBridge(const std::string& br_name, - const std::string& if_name) { +bool WifiIfaceUtil::addIfaceToBridge(const std::string& br_name, const std::string& if_name) { return iface_tool_.lock()->addIfaceToBridge(br_name, if_name); } -bool WifiIfaceUtil::removeIfaceFromBridge(const std::string& br_name, - const std::string& if_name) { +bool WifiIfaceUtil::removeIfaceFromBridge(const std::string& br_name, const std::string& if_name) { return iface_tool_.lock()->removeIfaceFromBridge(br_name, if_name); } } // namespace iface_util } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/wifi_iface_util.h b/wifi/1.6/default/wifi_iface_util.h index cb30ca8f9e..c5db5deed1 100644 --- a/wifi/1.5/default/wifi_iface_util.h +++ b/wifi/1.6/default/wifi_iface_util.h @@ -17,8 +17,6 @@ #ifndef WIFI_IFACE_UTIL_H_ #define WIFI_IFACE_UTIL_H_ -#define MAX_RANDOM_MAC_ADDR_INDEX 5 - #include <wifi_system/interface_tool.h> #include <android/hardware/wifi/1.0/IWifi.h> @@ -28,7 +26,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace iface_util { @@ -43,21 +41,18 @@ struct IfaceEventHandlers { * Util class for common iface operations. */ class WifiIfaceUtil { - public: + public: WifiIfaceUtil(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal); virtual ~WifiIfaceUtil() = default; - virtual std::array<uint8_t, 6> getFactoryMacAddress( - const std::string& iface_name); - virtual bool setMacAddress(const std::string& iface_name, - const std::array<uint8_t, 6>& mac); + virtual std::array<uint8_t, 6> getFactoryMacAddress(const std::string& iface_name); + virtual bool setMacAddress(const std::string& iface_name, const std::array<uint8_t, 6>& mac); // Get or create a random MAC address. The MAC address returned from // this method will remain the same throughout the lifetime of the HAL // daemon. (So, changes on every reboot) virtual std::array<uint8_t, 6> getOrCreateRandomMacAddress(); - virtual void setRandomMacAddressIndex(int idx); // Register for any iface event callbacks for the provided interface. virtual void registerIfaceEventHandlers(const std::string& iface_name, IfaceEventHandlers handlers); @@ -69,26 +64,22 @@ class WifiIfaceUtil { virtual bool deleteBridge(const std::string& br_name); - virtual bool addIfaceToBridge(const std::string& br_name, - const std::string& if_name); + virtual bool addIfaceToBridge(const std::string& br_name, const std::string& if_name); - virtual bool removeIfaceFromBridge(const std::string& br_name, - const std::string& if_name); + virtual bool removeIfaceFromBridge(const std::string& br_name, const std::string& if_name); // Get a random MAC address. virtual std::array<uint8_t, 6> createRandomMacAddress(); - private: + private: std::weak_ptr<wifi_system::InterfaceTool> iface_tool_; std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_; - std::unique_ptr<std::array<uint8_t, 6>> random_mac_address_[MAX_RANDOM_MAC_ADDR_INDEX]; - - int random_mac_address_index_; + std::unique_ptr<std::array<uint8_t, 6>> random_mac_address_; std::map<std::string, IfaceEventHandlers> event_handlers_map_; }; } // namespace iface_util } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.6/default/wifi_legacy_hal.cpp index 5074252d3d..e6e8141603 100644 --- a/wifi/1.5/default/wifi_legacy_hal.cpp +++ b/wifi/1.6/default/wifi_legacy_hal.cpp @@ -53,7 +53,7 @@ std::vector<char> makeCharVec(const std::string& str) { namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace legacy_hal { @@ -89,8 +89,7 @@ void onSyncFirmwareMemoryDump(char* buffer, int buffer_size) { } // Callback to be invoked for Gscan events. -std::function<void(wifi_request_id, wifi_scan_event)> - on_gscan_event_internal_callback; +std::function<void(wifi_request_id, wifi_scan_event)> on_gscan_event_internal_callback; void onAsyncGscanEvent(wifi_request_id id, wifi_scan_event event) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (on_gscan_event_internal_callback) { @@ -100,7 +99,7 @@ void onAsyncGscanEvent(wifi_request_id id, wifi_scan_event event) { // Callback to be invoked for Gscan full results. std::function<void(wifi_request_id, wifi_scan_result*, uint32_t)> - on_gscan_full_result_internal_callback; + on_gscan_full_result_internal_callback; void onAsyncGscanFullResult(wifi_request_id id, wifi_scan_result* result, uint32_t buckets_scanned) { const auto lock = hidl_sync_util::acquireGlobalLock(); @@ -111,20 +110,18 @@ void onAsyncGscanFullResult(wifi_request_id id, wifi_scan_result* result, // Callback to be invoked for link layer stats results. std::function<void((wifi_request_id, wifi_iface_stat*, int, wifi_radio_stat*))> - on_link_layer_stats_result_internal_callback; -void onSyncLinkLayerStatsResult(wifi_request_id id, wifi_iface_stat* iface_stat, - int num_radios, wifi_radio_stat* radio_stat) { + on_link_layer_stats_result_internal_callback; +void onSyncLinkLayerStatsResult(wifi_request_id id, wifi_iface_stat* iface_stat, int num_radios, + wifi_radio_stat* radio_stat) { if (on_link_layer_stats_result_internal_callback) { - on_link_layer_stats_result_internal_callback(id, iface_stat, num_radios, - radio_stat); + on_link_layer_stats_result_internal_callback(id, iface_stat, num_radios, radio_stat); } } // Callback to be invoked for rssi threshold breach. std::function<void((wifi_request_id, uint8_t*, int8_t))> - on_rssi_threshold_breached_internal_callback; -void onAsyncRssiThresholdBreached(wifi_request_id id, uint8_t* bssid, - int8_t rssi) { + on_rssi_threshold_breached_internal_callback; +void onAsyncRssiThresholdBreached(wifi_request_id id, uint8_t* bssid, int8_t rssi) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (on_rssi_threshold_breached_internal_callback) { on_rssi_threshold_breached_internal_callback(id, bssid, rssi); @@ -133,21 +130,18 @@ void onAsyncRssiThresholdBreached(wifi_request_id id, uint8_t* bssid, // Callback to be invoked for ring buffer data indication. std::function<void(char*, char*, int, wifi_ring_buffer_status*)> - on_ring_buffer_data_internal_callback; + on_ring_buffer_data_internal_callback; void onAsyncRingBufferData(char* ring_name, char* buffer, int buffer_size, wifi_ring_buffer_status* status) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (on_ring_buffer_data_internal_callback) { - on_ring_buffer_data_internal_callback(ring_name, buffer, buffer_size, - status); + on_ring_buffer_data_internal_callback(ring_name, buffer, buffer_size, status); } } // Callback to be invoked for error alert indication. -std::function<void(wifi_request_id, char*, int, int)> - on_error_alert_internal_callback; -void onAsyncErrorAlert(wifi_request_id id, char* buffer, int buffer_size, - int err_code) { +std::function<void(wifi_request_id, char*, int, int)> on_error_alert_internal_callback; +void onAsyncErrorAlert(wifi_request_id id, char* buffer, int buffer_size, int err_code) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (on_error_alert_internal_callback) { on_error_alert_internal_callback(id, buffer, buffer_size, err_code); @@ -156,9 +150,8 @@ void onAsyncErrorAlert(wifi_request_id id, char* buffer, int buffer_size, // Callback to be invoked for radio mode change indication. std::function<void(wifi_request_id, uint32_t, wifi_mac_info*)> - on_radio_mode_change_internal_callback; -void onAsyncRadioModeChange(wifi_request_id id, uint32_t num_macs, - wifi_mac_info* mac_infos) { + on_radio_mode_change_internal_callback; +void onAsyncRadioModeChange(wifi_request_id id, uint32_t num_macs, wifi_mac_info* mac_infos) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (on_radio_mode_change_internal_callback) { on_radio_mode_change_internal_callback(id, num_macs, mac_infos); @@ -175,11 +168,9 @@ void onAsyncSubsystemRestart(const char* error) { } // Callback to be invoked for rtt results results. -std::function<void(wifi_request_id, unsigned num_results, - wifi_rtt_result* rtt_results[])> - on_rtt_results_internal_callback; -void onAsyncRttResults(wifi_request_id id, unsigned num_results, - wifi_rtt_result* rtt_results[]) { +std::function<void(wifi_request_id, unsigned num_results, wifi_rtt_result* rtt_results[])> + on_rtt_results_internal_callback; +void onAsyncRttResults(wifi_request_id id, unsigned num_results, wifi_rtt_result* rtt_results[]) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (on_rtt_results_internal_callback) { on_rtt_results_internal_callback(id, num_results, rtt_results); @@ -191,8 +182,7 @@ void onAsyncRttResults(wifi_request_id id, unsigned num_results, // NOTE: These have very little conversions to perform before invoking the user // callbacks. // So, handle all of them here directly to avoid adding an unnecessary layer. -std::function<void(transaction_id, const NanResponseMsg&)> - on_nan_notify_response_user_callback; +std::function<void(transaction_id, const NanResponseMsg&)> on_nan_notify_response_user_callback; void onAysncNanNotifyResponse(transaction_id id, NanResponseMsg* msg) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (on_nan_notify_response_user_callback && msg) { @@ -200,14 +190,12 @@ void onAysncNanNotifyResponse(transaction_id id, NanResponseMsg* msg) { } } -std::function<void(const NanPublishRepliedInd&)> - on_nan_event_publish_replied_user_callback; +std::function<void(const NanPublishRepliedInd&)> on_nan_event_publish_replied_user_callback; void onAysncNanEventPublishReplied(NanPublishRepliedInd* /* event */) { LOG(ERROR) << "onAysncNanEventPublishReplied triggered"; } -std::function<void(const NanPublishTerminatedInd&)> - on_nan_event_publish_terminated_user_callback; +std::function<void(const NanPublishTerminatedInd&)> on_nan_event_publish_terminated_user_callback; void onAysncNanEventPublishTerminated(NanPublishTerminatedInd* event) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (on_nan_event_publish_terminated_user_callback && event) { @@ -223,8 +211,7 @@ void onAysncNanEventMatch(NanMatchInd* event) { } } -std::function<void(const NanMatchExpiredInd&)> - on_nan_event_match_expired_user_callback; +std::function<void(const NanMatchExpiredInd&)> on_nan_event_match_expired_user_callback; void onAysncNanEventMatchExpired(NanMatchExpiredInd* event) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (on_nan_event_match_expired_user_callback && event) { @@ -233,7 +220,7 @@ void onAysncNanEventMatchExpired(NanMatchExpiredInd* event) { } std::function<void(const NanSubscribeTerminatedInd&)> - on_nan_event_subscribe_terminated_user_callback; + on_nan_event_subscribe_terminated_user_callback; void onAysncNanEventSubscribeTerminated(NanSubscribeTerminatedInd* event) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (on_nan_event_subscribe_terminated_user_callback && event) { @@ -249,8 +236,7 @@ void onAysncNanEventFollowup(NanFollowupInd* event) { } } -std::function<void(const NanDiscEngEventInd&)> - on_nan_event_disc_eng_event_user_callback; +std::function<void(const NanDiscEngEventInd&)> on_nan_event_disc_eng_event_user_callback; void onAysncNanEventDiscEngEvent(NanDiscEngEventInd* event) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (on_nan_event_disc_eng_event_user_callback && event) { @@ -274,8 +260,7 @@ void onAysncNanEventTca(NanTCAInd* event) { } } -std::function<void(const NanBeaconSdfPayloadInd&)> - on_nan_event_beacon_sdf_payload_user_callback; +std::function<void(const NanBeaconSdfPayloadInd&)> on_nan_event_beacon_sdf_payload_user_callback; void onAysncNanEventBeaconSdfPayload(NanBeaconSdfPayloadInd* event) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (on_nan_event_beacon_sdf_payload_user_callback && event) { @@ -283,16 +268,14 @@ void onAysncNanEventBeaconSdfPayload(NanBeaconSdfPayloadInd* event) { } } -std::function<void(const NanDataPathRequestInd&)> - on_nan_event_data_path_request_user_callback; +std::function<void(const NanDataPathRequestInd&)> on_nan_event_data_path_request_user_callback; void onAysncNanEventDataPathRequest(NanDataPathRequestInd* event) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (on_nan_event_data_path_request_user_callback && event) { on_nan_event_data_path_request_user_callback(*event); } } -std::function<void(const NanDataPathConfirmInd&)> - on_nan_event_data_path_confirm_user_callback; +std::function<void(const NanDataPathConfirmInd&)> on_nan_event_data_path_confirm_user_callback; void onAysncNanEventDataPathConfirm(NanDataPathConfirmInd* event) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (on_nan_event_data_path_confirm_user_callback && event) { @@ -300,8 +283,7 @@ void onAysncNanEventDataPathConfirm(NanDataPathConfirmInd* event) { } } -std::function<void(const NanDataPathEndInd&)> - on_nan_event_data_path_end_user_callback; +std::function<void(const NanDataPathEndInd&)> on_nan_event_data_path_end_user_callback; void onAysncNanEventDataPathEnd(NanDataPathEndInd* event) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (on_nan_event_data_path_end_user_callback && event) { @@ -309,8 +291,7 @@ void onAysncNanEventDataPathEnd(NanDataPathEndInd* event) { } } -std::function<void(const NanTransmitFollowupInd&)> - on_nan_event_transmit_follow_up_user_callback; +std::function<void(const NanTransmitFollowupInd&)> on_nan_event_transmit_follow_up_user_callback; void onAysncNanEventTransmitFollowUp(NanTransmitFollowupInd* event) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (on_nan_event_transmit_follow_up_user_callback && event) { @@ -318,8 +299,7 @@ void onAysncNanEventTransmitFollowUp(NanTransmitFollowupInd* event) { } } -std::function<void(const NanRangeRequestInd&)> - on_nan_event_range_request_user_callback; +std::function<void(const NanRangeRequestInd&)> on_nan_event_range_request_user_callback; void onAysncNanEventRangeRequest(NanRangeRequestInd* event) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (on_nan_event_range_request_user_callback && event) { @@ -327,8 +307,7 @@ void onAysncNanEventRangeRequest(NanRangeRequestInd* event) { } } -std::function<void(const NanRangeReportInd&)> - on_nan_event_range_report_user_callback; +std::function<void(const NanRangeReportInd&)> on_nan_event_range_report_user_callback; void onAysncNanEventRangeReport(NanRangeReportInd* event) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (on_nan_event_range_report_user_callback && event) { @@ -336,8 +315,7 @@ void onAysncNanEventRangeReport(NanRangeReportInd* event) { } } -std::function<void(const NanDataPathScheduleUpdateInd&)> - on_nan_event_schedule_update_user_callback; +std::function<void(const NanDataPathScheduleUpdateInd&)> on_nan_event_schedule_update_user_callback; void onAsyncNanEventScheduleUpdate(NanDataPathScheduleUpdateInd* event) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (on_nan_event_schedule_update_user_callback && event) { @@ -346,8 +324,7 @@ void onAsyncNanEventScheduleUpdate(NanDataPathScheduleUpdateInd* event) { } // Callbacks for the various TWT operations. -std::function<void(const TwtSetupResponse&)> - on_twt_event_setup_response_callback; +std::function<void(const TwtSetupResponse&)> on_twt_event_setup_response_callback; void onAsyncTwtEventSetupResponse(TwtSetupResponse* event) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (on_twt_event_setup_response_callback && event) { @@ -355,8 +332,7 @@ void onAsyncTwtEventSetupResponse(TwtSetupResponse* event) { } } -std::function<void(const TwtTeardownCompletion&)> - on_twt_event_teardown_completion_callback; +std::function<void(const TwtTeardownCompletion&)> on_twt_event_teardown_completion_callback; void onAsyncTwtEventTeardownCompletion(TwtTeardownCompletion* event) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (on_twt_event_teardown_completion_callback && event) { @@ -364,8 +340,7 @@ void onAsyncTwtEventTeardownCompletion(TwtTeardownCompletion* event) { } } -std::function<void(const TwtInfoFrameReceived&)> - on_twt_event_info_frame_received_callback; +std::function<void(const TwtInfoFrameReceived&)> on_twt_event_info_frame_received_callback; void onAsyncTwtEventInfoFrameReceived(TwtInfoFrameReceived* event) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (on_twt_event_info_frame_received_callback && event) { @@ -383,9 +358,8 @@ void onAsyncTwtEventDeviceNotify(TwtDeviceNotify* event) { // End of the free-standing "C" style callbacks. -WifiLegacyHal::WifiLegacyHal( - const std::weak_ptr<wifi_system::InterfaceTool> iface_tool, - const wifi_hal_fn& fn, bool is_primary) +WifiLegacyHal::WifiLegacyHal(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool, + const wifi_hal_fn& fn, bool is_primary) : global_func_table_(fn), global_handle_(nullptr), awaiting_event_loop_termination_(false), @@ -402,8 +376,8 @@ wifi_error WifiLegacyHal::initialize() { wifi_error WifiLegacyHal::start() { // Ensure that we're starting in a good state. - CHECK(global_func_table_.wifi_initialize && !global_handle_ && - iface_name_to_handle_.empty() && !awaiting_event_loop_termination_); + CHECK(global_func_table_.wifi_initialize && !global_handle_ && iface_name_to_handle_.empty() && + !awaiting_event_loop_termination_); if (is_started_) { LOG(DEBUG) << "Legacy HAL already started"; return WIFI_SUCCESS; @@ -442,8 +416,8 @@ wifi_error WifiLegacyHal::start() { } wifi_error WifiLegacyHal::stop( - /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, - const std::function<void()>& on_stop_complete_user_callback) { + /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, + const std::function<void()>& on_stop_complete_user_callback) { if (!is_started_) { LOG(DEBUG) << "Legacy HAL already stopped"; on_stop_complete_user_callback(); @@ -463,9 +437,9 @@ wifi_error WifiLegacyHal::stop( }; awaiting_event_loop_termination_ = true; global_func_table_.wifi_cleanup(global_handle_, onAsyncStopComplete); - const auto status = stop_wait_cv_.wait_for( - *lock, std::chrono::milliseconds(kMaxStopCompleteWaitMs), - [this] { return !awaiting_event_loop_termination_; }); + const auto status = + stop_wait_cv_.wait_for(*lock, std::chrono::milliseconds(kMaxStopCompleteWaitMs), + [this] { return !awaiting_event_loop_termination_; }); if (!status) { LOG(ERROR) << "Legacy HAL stop failed or timed out"; return WIFI_ERROR_UNKNOWN; @@ -474,62 +448,59 @@ wifi_error WifiLegacyHal::stop( return WIFI_SUCCESS; } -bool WifiLegacyHal::isStarted() { return is_started_; } +bool WifiLegacyHal::isStarted() { + return is_started_; +} wifi_error WifiLegacyHal::waitForDriverReady() { return global_func_table_.wifi_wait_for_driver_ready(); } -std::pair<wifi_error, std::string> WifiLegacyHal::getDriverVersion( - const std::string& iface_name) { +std::pair<wifi_error, std::string> WifiLegacyHal::getDriverVersion(const std::string& iface_name) { std::array<char, kMaxVersionStringLength> buffer; buffer.fill(0); - wifi_error status = global_func_table_.wifi_get_driver_version( - getIfaceHandle(iface_name), buffer.data(), buffer.size()); + wifi_error status = global_func_table_.wifi_get_driver_version(getIfaceHandle(iface_name), + buffer.data(), buffer.size()); return {status, buffer.data()}; } std::pair<wifi_error, std::string> WifiLegacyHal::getFirmwareVersion( - const std::string& iface_name) { + const std::string& iface_name) { std::array<char, kMaxVersionStringLength> buffer; buffer.fill(0); - wifi_error status = global_func_table_.wifi_get_firmware_version( - getIfaceHandle(iface_name), buffer.data(), buffer.size()); + wifi_error status = global_func_table_.wifi_get_firmware_version(getIfaceHandle(iface_name), + buffer.data(), buffer.size()); return {status, buffer.data()}; } -std::pair<wifi_error, std::vector<uint8_t>> -WifiLegacyHal::requestDriverMemoryDump(const std::string& iface_name) { +std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::requestDriverMemoryDump( + const std::string& iface_name) { std::vector<uint8_t> driver_dump; - on_driver_memory_dump_internal_callback = [&driver_dump](char* buffer, - int buffer_size) { - driver_dump.insert(driver_dump.end(), - reinterpret_cast<uint8_t*>(buffer), + on_driver_memory_dump_internal_callback = [&driver_dump](char* buffer, int buffer_size) { + driver_dump.insert(driver_dump.end(), reinterpret_cast<uint8_t*>(buffer), reinterpret_cast<uint8_t*>(buffer) + buffer_size); }; - wifi_error status = global_func_table_.wifi_get_driver_memory_dump( - getIfaceHandle(iface_name), {onSyncDriverMemoryDump}); + wifi_error status = global_func_table_.wifi_get_driver_memory_dump(getIfaceHandle(iface_name), + {onSyncDriverMemoryDump}); on_driver_memory_dump_internal_callback = nullptr; return {status, std::move(driver_dump)}; } -std::pair<wifi_error, std::vector<uint8_t>> -WifiLegacyHal::requestFirmwareMemoryDump(const std::string& iface_name) { +std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::requestFirmwareMemoryDump( + const std::string& iface_name) { std::vector<uint8_t> firmware_dump; - on_firmware_memory_dump_internal_callback = - [&firmware_dump](char* buffer, int buffer_size) { - firmware_dump.insert( - firmware_dump.end(), reinterpret_cast<uint8_t*>(buffer), - reinterpret_cast<uint8_t*>(buffer) + buffer_size); - }; + on_firmware_memory_dump_internal_callback = [&firmware_dump](char* buffer, int buffer_size) { + firmware_dump.insert(firmware_dump.end(), reinterpret_cast<uint8_t*>(buffer), + reinterpret_cast<uint8_t*>(buffer) + buffer_size); + }; wifi_error status = global_func_table_.wifi_get_firmware_memory_dump( - getIfaceHandle(iface_name), {onSyncFirmwareMemoryDump}); + getIfaceHandle(iface_name), {onSyncFirmwareMemoryDump}); on_firmware_memory_dump_internal_callback = nullptr; return {status, std::move(firmware_dump)}; } std::pair<wifi_error, uint64_t> WifiLegacyHal::getSupportedFeatureSet( - const std::string& iface_name) { + const std::string& iface_name) { feature_set set = 0, chip_set = 0; wifi_error status = WIFI_SUCCESS; @@ -538,34 +509,33 @@ std::pair<wifi_error, uint64_t> WifiLegacyHal::getSupportedFeatureSet( wifi_interface_handle iface_handle = getIfaceHandle(iface_name); global_func_table_.wifi_get_chip_feature_set( - global_handle_, &chip_set); /* ignore error, chip_set will stay 0 */ + global_handle_, &chip_set); /* ignore error, chip_set will stay 0 */ if (iface_handle) { - status = global_func_table_.wifi_get_supported_feature_set(iface_handle, - &set); + status = global_func_table_.wifi_get_supported_feature_set(iface_handle, &set); } return {status, static_cast<uint64_t>(set | chip_set)}; } -std::pair<wifi_error, PacketFilterCapabilities> -WifiLegacyHal::getPacketFilterCapabilities(const std::string& iface_name) { +std::pair<wifi_error, PacketFilterCapabilities> WifiLegacyHal::getPacketFilterCapabilities( + const std::string& iface_name) { PacketFilterCapabilities caps; wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities( - getIfaceHandle(iface_name), &caps.version, &caps.max_len); + getIfaceHandle(iface_name), &caps.version, &caps.max_len); return {status, caps}; } wifi_error WifiLegacyHal::setPacketFilter(const std::string& iface_name, const std::vector<uint8_t>& program) { - return global_func_table_.wifi_set_packet_filter( - getIfaceHandle(iface_name), program.data(), program.size()); + return global_func_table_.wifi_set_packet_filter(getIfaceHandle(iface_name), program.data(), + program.size()); } -std::pair<wifi_error, std::vector<uint8_t>> -WifiLegacyHal::readApfPacketFilterData(const std::string& iface_name) { +std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::readApfPacketFilterData( + const std::string& iface_name) { PacketFilterCapabilities caps; wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities( - getIfaceHandle(iface_name), &caps.version, &caps.max_len); + getIfaceHandle(iface_name), &caps.version, &caps.max_len); if (status != WIFI_SUCCESS) { return {status, {}}; } @@ -574,74 +544,68 @@ WifiLegacyHal::readApfPacketFilterData(const std::string& iface_name) { std::vector<uint8_t> buffer(caps.max_len); status = global_func_table_.wifi_read_packet_filter( - getIfaceHandle(iface_name), /*src_offset=*/0, buffer.data(), - buffer.size()); + getIfaceHandle(iface_name), /*src_offset=*/0, buffer.data(), buffer.size()); return {status, move(buffer)}; } -std::pair<wifi_error, wifi_gscan_capabilities> -WifiLegacyHal::getGscanCapabilities(const std::string& iface_name) { +std::pair<wifi_error, wifi_gscan_capabilities> WifiLegacyHal::getGscanCapabilities( + const std::string& iface_name) { wifi_gscan_capabilities caps; - wifi_error status = global_func_table_.wifi_get_gscan_capabilities( - getIfaceHandle(iface_name), &caps); + wifi_error status = + global_func_table_.wifi_get_gscan_capabilities(getIfaceHandle(iface_name), &caps); return {status, caps}; } wifi_error WifiLegacyHal::startGscan( - const std::string& iface_name, wifi_request_id id, - const wifi_scan_cmd_params& params, - const std::function<void(wifi_request_id)>& on_failure_user_callback, - const on_gscan_results_callback& on_results_user_callback, - const on_gscan_full_result_callback& on_full_result_user_callback) { + const std::string& iface_name, wifi_request_id id, const wifi_scan_cmd_params& params, + const std::function<void(wifi_request_id)>& on_failure_user_callback, + const on_gscan_results_callback& on_results_user_callback, + const on_gscan_full_result_callback& on_full_result_user_callback) { // If there is already an ongoing background scan, reject new scan requests. - if (on_gscan_event_internal_callback || - on_gscan_full_result_internal_callback) { + if (on_gscan_event_internal_callback || on_gscan_full_result_internal_callback) { return WIFI_ERROR_NOT_AVAILABLE; } // This callback will be used to either trigger |on_results_user_callback| // or |on_failure_user_callback|. - on_gscan_event_internal_callback = - [iface_name, on_failure_user_callback, on_results_user_callback, this]( - wifi_request_id id, wifi_scan_event event) { - switch (event) { - case WIFI_SCAN_RESULTS_AVAILABLE: - case WIFI_SCAN_THRESHOLD_NUM_SCANS: - case WIFI_SCAN_THRESHOLD_PERCENT: { - wifi_error status; - std::vector<wifi_cached_scan_results> cached_scan_results; - std::tie(status, cached_scan_results) = - getGscanCachedResults(iface_name); - if (status == WIFI_SUCCESS) { - on_results_user_callback(id, cached_scan_results); - return; - } - FALLTHROUGH_INTENDED; - } - // Fall through if failed. Failure to retrieve cached scan - // results should trigger a background scan failure. - case WIFI_SCAN_FAILED: - on_failure_user_callback(id); - on_gscan_event_internal_callback = nullptr; - on_gscan_full_result_internal_callback = nullptr; + on_gscan_event_internal_callback = [iface_name, on_failure_user_callback, + on_results_user_callback, + this](wifi_request_id id, wifi_scan_event event) { + switch (event) { + case WIFI_SCAN_RESULTS_AVAILABLE: + case WIFI_SCAN_THRESHOLD_NUM_SCANS: + case WIFI_SCAN_THRESHOLD_PERCENT: { + wifi_error status; + std::vector<wifi_cached_scan_results> cached_scan_results; + std::tie(status, cached_scan_results) = getGscanCachedResults(iface_name); + if (status == WIFI_SUCCESS) { + on_results_user_callback(id, cached_scan_results); return; + } + FALLTHROUGH_INTENDED; } - LOG(FATAL) << "Unexpected gscan event received: " << event; - }; + // Fall through if failed. Failure to retrieve cached scan + // results should trigger a background scan failure. + case WIFI_SCAN_FAILED: + on_failure_user_callback(id); + on_gscan_event_internal_callback = nullptr; + on_gscan_full_result_internal_callback = nullptr; + return; + } + LOG(FATAL) << "Unexpected gscan event received: " << event; + }; on_gscan_full_result_internal_callback = [on_full_result_user_callback]( - wifi_request_id id, - wifi_scan_result* result, - uint32_t buckets_scanned) { + wifi_request_id id, wifi_scan_result* result, + uint32_t buckets_scanned) { if (result) { on_full_result_user_callback(id, result, buckets_scanned); } }; - wifi_scan_result_handler handler = {onAsyncGscanFullResult, - onAsyncGscanEvent}; - wifi_error status = global_func_table_.wifi_start_gscan( - id, getIfaceHandle(iface_name), params, handler); + wifi_scan_result_handler handler = {onAsyncGscanFullResult, onAsyncGscanEvent}; + wifi_error status = + global_func_table_.wifi_start_gscan(id, getIfaceHandle(iface_name), params, handler); if (status != WIFI_SUCCESS) { on_gscan_event_internal_callback = nullptr; on_gscan_full_result_internal_callback = nullptr; @@ -649,17 +613,14 @@ wifi_error WifiLegacyHal::startGscan( return status; } -wifi_error WifiLegacyHal::stopGscan(const std::string& iface_name, - wifi_request_id id) { +wifi_error WifiLegacyHal::stopGscan(const std::string& iface_name, wifi_request_id id) { // If there is no an ongoing background scan, reject stop requests. // TODO(b/32337212): This needs to be handled by the HIDL object because we // need to return the NOT_STARTED error code. - if (!on_gscan_event_internal_callback && - !on_gscan_full_result_internal_callback) { + if (!on_gscan_event_internal_callback && !on_gscan_full_result_internal_callback) { return WIFI_ERROR_NOT_AVAILABLE; } - wifi_error status = - global_func_table_.wifi_stop_gscan(id, getIfaceHandle(iface_name)); + wifi_error status = global_func_table_.wifi_stop_gscan(id, getIfaceHandle(iface_name)); // If the request Id is wrong, don't stop the ongoing background scan. Any // other error should be treated as the end of background scan. if (status != WIFI_ERROR_INVALID_REQUEST_ID) { @@ -669,161 +630,147 @@ wifi_error WifiLegacyHal::stopGscan(const std::string& iface_name, return status; } -std::pair<wifi_error, std::vector<uint32_t>> -WifiLegacyHal::getValidFrequenciesForBand(const std::string& iface_name, - wifi_band band) { +std::pair<wifi_error, std::vector<uint32_t>> WifiLegacyHal::getValidFrequenciesForBand( + const std::string& iface_name, wifi_band band) { static_assert(sizeof(uint32_t) >= sizeof(wifi_channel), "Wifi Channel cannot be represented in output"); std::vector<uint32_t> freqs; freqs.resize(kMaxGscanFrequenciesForBand); int32_t num_freqs = 0; wifi_error status = global_func_table_.wifi_get_valid_channels( - getIfaceHandle(iface_name), band, freqs.size(), - reinterpret_cast<wifi_channel*>(freqs.data()), &num_freqs); - CHECK(num_freqs >= 0 && - static_cast<uint32_t>(num_freqs) <= kMaxGscanFrequenciesForBand); + getIfaceHandle(iface_name), band, freqs.size(), + reinterpret_cast<wifi_channel*>(freqs.data()), &num_freqs); + CHECK(num_freqs >= 0 && static_cast<uint32_t>(num_freqs) <= kMaxGscanFrequenciesForBand); freqs.resize(num_freqs); return {status, std::move(freqs)}; } -wifi_error WifiLegacyHal::setDfsFlag(const std::string& iface_name, - bool dfs_on) { - return global_func_table_.wifi_set_nodfs_flag(getIfaceHandle(iface_name), - dfs_on ? 0 : 1); +wifi_error WifiLegacyHal::setDfsFlag(const std::string& iface_name, bool dfs_on) { + return global_func_table_.wifi_set_nodfs_flag(getIfaceHandle(iface_name), dfs_on ? 0 : 1); } -wifi_error WifiLegacyHal::enableLinkLayerStats(const std::string& iface_name, - bool debug) { +wifi_error WifiLegacyHal::enableLinkLayerStats(const std::string& iface_name, bool debug) { wifi_link_layer_params params; params.mpdu_size_threshold = kLinkLayerStatsDataMpduSizeThreshold; params.aggressive_statistics_gathering = debug; - return global_func_table_.wifi_set_link_stats(getIfaceHandle(iface_name), - params); + return global_func_table_.wifi_set_link_stats(getIfaceHandle(iface_name), params); } wifi_error WifiLegacyHal::disableLinkLayerStats(const std::string& iface_name) { // TODO: Do we care about these responses? uint32_t clear_mask_rsp; uint8_t stop_rsp; - return global_func_table_.wifi_clear_link_stats( - getIfaceHandle(iface_name), 0xFFFFFFFF, &clear_mask_rsp, 1, &stop_rsp); + return global_func_table_.wifi_clear_link_stats(getIfaceHandle(iface_name), 0xFFFFFFFF, + &clear_mask_rsp, 1, &stop_rsp); } std::pair<wifi_error, LinkLayerStats> WifiLegacyHal::getLinkLayerStats( - const std::string& iface_name) { + const std::string& iface_name) { LinkLayerStats link_stats{}; LinkLayerStats* link_stats_ptr = &link_stats; - on_link_layer_stats_result_internal_callback = - [&link_stats_ptr](wifi_request_id /* id */, - wifi_iface_stat* iface_stats_ptr, int num_radios, - wifi_radio_stat* radio_stats_ptr) { - wifi_radio_stat* l_radio_stats_ptr; - wifi_peer_info* l_peer_info_stats_ptr; - - if (iface_stats_ptr != nullptr) { - link_stats_ptr->iface = *iface_stats_ptr; - l_peer_info_stats_ptr = iface_stats_ptr->peer_info; - for (uint32_t i = 0; i < iface_stats_ptr->num_peers; i++) { - WifiPeerInfo peer; - peer.peer_info = *l_peer_info_stats_ptr; - if (l_peer_info_stats_ptr->num_rate > 0) { - /* Copy the rate stats */ - peer.rate_stats.assign( + on_link_layer_stats_result_internal_callback = [&link_stats_ptr]( + wifi_request_id /* id */, + wifi_iface_stat* iface_stats_ptr, + int num_radios, + wifi_radio_stat* radio_stats_ptr) { + wifi_radio_stat* l_radio_stats_ptr; + wifi_peer_info* l_peer_info_stats_ptr; + + if (iface_stats_ptr != nullptr) { + link_stats_ptr->iface = *iface_stats_ptr; + l_peer_info_stats_ptr = iface_stats_ptr->peer_info; + for (uint32_t i = 0; i < iface_stats_ptr->num_peers; i++) { + WifiPeerInfo peer; + peer.peer_info = *l_peer_info_stats_ptr; + if (l_peer_info_stats_ptr->num_rate > 0) { + /* Copy the rate stats */ + peer.rate_stats.assign( l_peer_info_stats_ptr->rate_stats, - l_peer_info_stats_ptr->rate_stats + - l_peer_info_stats_ptr->num_rate); - } - peer.peer_info.num_rate = 0; - link_stats_ptr->peers.push_back(peer); - l_peer_info_stats_ptr = - (wifi_peer_info*)((u8*)l_peer_info_stats_ptr + - sizeof(wifi_peer_info) + + l_peer_info_stats_ptr->rate_stats + l_peer_info_stats_ptr->num_rate); + } + peer.peer_info.num_rate = 0; + link_stats_ptr->peers.push_back(peer); + l_peer_info_stats_ptr = + (wifi_peer_info*)((u8*)l_peer_info_stats_ptr + sizeof(wifi_peer_info) + (sizeof(wifi_rate_stat) * l_peer_info_stats_ptr->num_rate)); - } - link_stats_ptr->iface.num_peers = 0; - } else { - LOG(ERROR) << "Invalid iface stats in link layer stats"; - } - if (num_radios <= 0 || radio_stats_ptr == nullptr) { - LOG(ERROR) << "Invalid radio stats in link layer stats"; - return; } - l_radio_stats_ptr = radio_stats_ptr; - for (int i = 0; i < num_radios; i++) { - LinkLayerRadioStats radio; - - radio.stats = *l_radio_stats_ptr; - // Copy over the tx level array to the separate vector. - if (l_radio_stats_ptr->num_tx_levels > 0 && - l_radio_stats_ptr->tx_time_per_levels != nullptr) { - radio.tx_time_per_levels.assign( + link_stats_ptr->iface.num_peers = 0; + } else { + LOG(ERROR) << "Invalid iface stats in link layer stats"; + } + if (num_radios <= 0 || radio_stats_ptr == nullptr) { + LOG(ERROR) << "Invalid radio stats in link layer stats"; + return; + } + l_radio_stats_ptr = radio_stats_ptr; + for (int i = 0; i < num_radios; i++) { + LinkLayerRadioStats radio; + + radio.stats = *l_radio_stats_ptr; + // Copy over the tx level array to the separate vector. + if (l_radio_stats_ptr->num_tx_levels > 0 && + l_radio_stats_ptr->tx_time_per_levels != nullptr) { + radio.tx_time_per_levels.assign( l_radio_stats_ptr->tx_time_per_levels, - l_radio_stats_ptr->tx_time_per_levels + - l_radio_stats_ptr->num_tx_levels); - } - radio.stats.num_tx_levels = 0; - radio.stats.tx_time_per_levels = nullptr; - /* Copy over the channel stat to separate vector */ - if (l_radio_stats_ptr->num_channels > 0) { - /* Copy the channel stats */ - radio.channel_stats.assign( + l_radio_stats_ptr->tx_time_per_levels + l_radio_stats_ptr->num_tx_levels); + } + radio.stats.num_tx_levels = 0; + radio.stats.tx_time_per_levels = nullptr; + /* Copy over the channel stat to separate vector */ + if (l_radio_stats_ptr->num_channels > 0) { + /* Copy the channel stats */ + radio.channel_stats.assign( l_radio_stats_ptr->channels, - l_radio_stats_ptr->channels + - l_radio_stats_ptr->num_channels); - } - link_stats_ptr->radios.push_back(radio); - l_radio_stats_ptr = - (wifi_radio_stat*)((u8*)l_radio_stats_ptr + - sizeof(wifi_radio_stat) + + l_radio_stats_ptr->channels + l_radio_stats_ptr->num_channels); + } + link_stats_ptr->radios.push_back(radio); + l_radio_stats_ptr = + (wifi_radio_stat*)((u8*)l_radio_stats_ptr + sizeof(wifi_radio_stat) + (sizeof(wifi_channel_stat) * l_radio_stats_ptr->num_channels)); - } - }; + } + }; - wifi_error status = global_func_table_.wifi_get_link_stats( - 0, getIfaceHandle(iface_name), {onSyncLinkLayerStatsResult}); + wifi_error status = global_func_table_.wifi_get_link_stats(0, getIfaceHandle(iface_name), + {onSyncLinkLayerStatsResult}); on_link_layer_stats_result_internal_callback = nullptr; return {status, link_stats}; } wifi_error WifiLegacyHal::startRssiMonitoring( - const std::string& iface_name, wifi_request_id id, int8_t max_rssi, - int8_t min_rssi, - const on_rssi_threshold_breached_callback& - on_threshold_breached_user_callback) { + const std::string& iface_name, wifi_request_id id, int8_t max_rssi, int8_t min_rssi, + const on_rssi_threshold_breached_callback& on_threshold_breached_user_callback) { if (on_rssi_threshold_breached_internal_callback) { return WIFI_ERROR_NOT_AVAILABLE; } - on_rssi_threshold_breached_internal_callback = - [on_threshold_breached_user_callback](wifi_request_id id, - uint8_t* bssid_ptr, int8_t rssi) { - if (!bssid_ptr) { - return; - } - std::array<uint8_t, 6> bssid_arr; - // |bssid_ptr| pointer is assumed to have 6 bytes for the mac - // address. - std::copy(bssid_ptr, bssid_ptr + 6, std::begin(bssid_arr)); - on_threshold_breached_user_callback(id, bssid_arr, rssi); - }; + on_rssi_threshold_breached_internal_callback = [on_threshold_breached_user_callback]( + wifi_request_id id, uint8_t* bssid_ptr, + int8_t rssi) { + if (!bssid_ptr) { + return; + } + std::array<uint8_t, 6> bssid_arr; + // |bssid_ptr| pointer is assumed to have 6 bytes for the mac + // address. + std::copy(bssid_ptr, bssid_ptr + 6, std::begin(bssid_arr)); + on_threshold_breached_user_callback(id, bssid_arr, rssi); + }; wifi_error status = global_func_table_.wifi_start_rssi_monitoring( - id, getIfaceHandle(iface_name), max_rssi, min_rssi, - {onAsyncRssiThresholdBreached}); + id, getIfaceHandle(iface_name), max_rssi, min_rssi, {onAsyncRssiThresholdBreached}); if (status != WIFI_SUCCESS) { on_rssi_threshold_breached_internal_callback = nullptr; } return status; } -wifi_error WifiLegacyHal::stopRssiMonitoring(const std::string& iface_name, - wifi_request_id id) { +wifi_error WifiLegacyHal::stopRssiMonitoring(const std::string& iface_name, wifi_request_id id) { if (!on_rssi_threshold_breached_internal_callback) { return WIFI_ERROR_NOT_AVAILABLE; } - wifi_error status = global_func_table_.wifi_stop_rssi_monitoring( - id, getIfaceHandle(iface_name)); + wifi_error status = + global_func_table_.wifi_stop_rssi_monitoring(id, getIfaceHandle(iface_name)); // If the request Id is wrong, don't stop the ongoing rssi monitoring. Any // other error should be treated as the end of background scan. if (status != WIFI_ERROR_INVALID_REQUEST_ID) { @@ -832,82 +779,75 @@ wifi_error WifiLegacyHal::stopRssiMonitoring(const std::string& iface_name, return status; } -std::pair<wifi_error, wifi_roaming_capabilities> -WifiLegacyHal::getRoamingCapabilities(const std::string& iface_name) { +std::pair<wifi_error, wifi_roaming_capabilities> WifiLegacyHal::getRoamingCapabilities( + const std::string& iface_name) { wifi_roaming_capabilities caps; - wifi_error status = global_func_table_.wifi_get_roaming_capabilities( - getIfaceHandle(iface_name), &caps); + wifi_error status = + global_func_table_.wifi_get_roaming_capabilities(getIfaceHandle(iface_name), &caps); return {status, caps}; } wifi_error WifiLegacyHal::configureRoaming(const std::string& iface_name, const wifi_roaming_config& config) { wifi_roaming_config config_internal = config; - return global_func_table_.wifi_configure_roaming(getIfaceHandle(iface_name), - &config_internal); + return global_func_table_.wifi_configure_roaming(getIfaceHandle(iface_name), &config_internal); } wifi_error WifiLegacyHal::enableFirmwareRoaming(const std::string& iface_name, fw_roaming_state_t state) { - return global_func_table_.wifi_enable_firmware_roaming( - getIfaceHandle(iface_name), state); + return global_func_table_.wifi_enable_firmware_roaming(getIfaceHandle(iface_name), state); } -wifi_error WifiLegacyHal::configureNdOffload(const std::string& iface_name, - bool enable) { - return global_func_table_.wifi_configure_nd_offload( - getIfaceHandle(iface_name), enable); +wifi_error WifiLegacyHal::configureNdOffload(const std::string& iface_name, bool enable) { + return global_func_table_.wifi_configure_nd_offload(getIfaceHandle(iface_name), enable); } -wifi_error WifiLegacyHal::startSendingOffloadedPacket( - const std::string& iface_name, uint32_t cmd_id, uint16_t ether_type, - const std::vector<uint8_t>& ip_packet_data, - const std::array<uint8_t, 6>& src_address, - const std::array<uint8_t, 6>& dst_address, uint32_t period_in_ms) { +wifi_error WifiLegacyHal::startSendingOffloadedPacket(const std::string& iface_name, + uint32_t cmd_id, uint16_t ether_type, + const std::vector<uint8_t>& ip_packet_data, + const std::array<uint8_t, 6>& src_address, + const std::array<uint8_t, 6>& dst_address, + uint32_t period_in_ms) { std::vector<uint8_t> ip_packet_data_internal(ip_packet_data); - std::vector<uint8_t> src_address_internal( - src_address.data(), src_address.data() + src_address.size()); - std::vector<uint8_t> dst_address_internal( - dst_address.data(), dst_address.data() + dst_address.size()); + std::vector<uint8_t> src_address_internal(src_address.data(), + src_address.data() + src_address.size()); + std::vector<uint8_t> dst_address_internal(dst_address.data(), + dst_address.data() + dst_address.size()); return global_func_table_.wifi_start_sending_offloaded_packet( - cmd_id, getIfaceHandle(iface_name), ether_type, - ip_packet_data_internal.data(), ip_packet_data_internal.size(), - src_address_internal.data(), dst_address_internal.data(), period_in_ms); + cmd_id, getIfaceHandle(iface_name), ether_type, ip_packet_data_internal.data(), + ip_packet_data_internal.size(), src_address_internal.data(), + dst_address_internal.data(), period_in_ms); } -wifi_error WifiLegacyHal::stopSendingOffloadedPacket( - const std::string& iface_name, uint32_t cmd_id) { - return global_func_table_.wifi_stop_sending_offloaded_packet( - cmd_id, getIfaceHandle(iface_name)); +wifi_error WifiLegacyHal::stopSendingOffloadedPacket(const std::string& iface_name, + uint32_t cmd_id) { + return global_func_table_.wifi_stop_sending_offloaded_packet(cmd_id, + getIfaceHandle(iface_name)); } wifi_error WifiLegacyHal::selectTxPowerScenario(const std::string& iface_name, wifi_power_scenario scenario) { - return global_func_table_.wifi_select_tx_power_scenario( - getIfaceHandle(iface_name), scenario); + return global_func_table_.wifi_select_tx_power_scenario(getIfaceHandle(iface_name), scenario); } wifi_error WifiLegacyHal::resetTxPowerScenario(const std::string& iface_name) { - return global_func_table_.wifi_reset_tx_power_scenario( - getIfaceHandle(iface_name)); + return global_func_table_.wifi_reset_tx_power_scenario(getIfaceHandle(iface_name)); } -wifi_error WifiLegacyHal::setLatencyMode(const std::string& iface_name, - wifi_latency_mode mode) { - return global_func_table_.wifi_set_latency_mode(getIfaceHandle(iface_name), - mode); +wifi_error WifiLegacyHal::setLatencyMode(const std::string& iface_name, wifi_latency_mode mode) { + return global_func_table_.wifi_set_latency_mode(getIfaceHandle(iface_name), mode); } wifi_error WifiLegacyHal::setThermalMitigationMode(wifi_thermal_mode mode, uint32_t completion_window) { - return global_func_table_.wifi_set_thermal_mitigation_mode( - global_handle_, mode, completion_window); + return global_func_table_.wifi_set_thermal_mitigation_mode(global_handle_, mode, + completion_window); } -wifi_error WifiLegacyHal::setDscpToAccessCategoryMapping( - uint32_t start, uint32_t end, uint32_t access_category) { - return global_func_table_.wifi_map_dscp_access_category( - global_handle_, start, end, access_category); +wifi_error WifiLegacyHal::setDscpToAccessCategoryMapping(uint32_t start, uint32_t end, + uint32_t access_category) { + return global_func_table_.wifi_map_dscp_access_category(global_handle_, start, end, + access_category); } wifi_error WifiLegacyHal::resetDscpToAccessCategoryMapping() { @@ -915,53 +855,49 @@ wifi_error WifiLegacyHal::resetDscpToAccessCategoryMapping() { } std::pair<wifi_error, uint32_t> WifiLegacyHal::getLoggerSupportedFeatureSet( - const std::string& iface_name) { + const std::string& iface_name) { uint32_t supported_feature_flags = 0; wifi_error status = WIFI_SUCCESS; wifi_interface_handle iface_handle = getIfaceHandle(iface_name); if (iface_handle) { - status = global_func_table_.wifi_get_logger_supported_feature_set( - iface_handle, &supported_feature_flags); + status = global_func_table_.wifi_get_logger_supported_feature_set(iface_handle, + &supported_feature_flags); } return {status, supported_feature_flags}; } -wifi_error WifiLegacyHal::startPktFateMonitoring( - const std::string& iface_name) { - return global_func_table_.wifi_start_pkt_fate_monitoring( - getIfaceHandle(iface_name)); +wifi_error WifiLegacyHal::startPktFateMonitoring(const std::string& iface_name) { + return global_func_table_.wifi_start_pkt_fate_monitoring(getIfaceHandle(iface_name)); } std::pair<wifi_error, std::vector<wifi_tx_report>> WifiLegacyHal::getTxPktFates( - const std::string& iface_name) { + const std::string& iface_name) { std::vector<wifi_tx_report> tx_pkt_fates; tx_pkt_fates.resize(MAX_FATE_LOG_LEN); size_t num_fates = 0; wifi_error status = global_func_table_.wifi_get_tx_pkt_fates( - getIfaceHandle(iface_name), tx_pkt_fates.data(), tx_pkt_fates.size(), - &num_fates); + getIfaceHandle(iface_name), tx_pkt_fates.data(), tx_pkt_fates.size(), &num_fates); CHECK(num_fates <= MAX_FATE_LOG_LEN); tx_pkt_fates.resize(num_fates); return {status, std::move(tx_pkt_fates)}; } std::pair<wifi_error, std::vector<wifi_rx_report>> WifiLegacyHal::getRxPktFates( - const std::string& iface_name) { + const std::string& iface_name) { std::vector<wifi_rx_report> rx_pkt_fates; rx_pkt_fates.resize(MAX_FATE_LOG_LEN); size_t num_fates = 0; wifi_error status = global_func_table_.wifi_get_rx_pkt_fates( - getIfaceHandle(iface_name), rx_pkt_fates.data(), rx_pkt_fates.size(), - &num_fates); + getIfaceHandle(iface_name), rx_pkt_fates.data(), rx_pkt_fates.size(), &num_fates); CHECK(num_fates <= MAX_FATE_LOG_LEN); rx_pkt_fates.resize(num_fates); return {status, std::move(rx_pkt_fates)}; } std::pair<wifi_error, WakeReasonStats> WifiLegacyHal::getWakeReasonStats( - const std::string& iface_name) { + const std::string& iface_name) { WakeReasonStats stats; stats.cmd_event_wake_cnt.resize(kMaxWakeReasonStatsArraySize); stats.driver_fw_local_wake_cnt.resize(kMaxWakeReasonStatsArraySize); @@ -969,79 +905,69 @@ std::pair<wifi_error, WakeReasonStats> WifiLegacyHal::getWakeReasonStats( // This legacy struct needs separate memory to store the variable sized wake // reason types. stats.wake_reason_cnt.cmd_event_wake_cnt = - reinterpret_cast<int32_t*>(stats.cmd_event_wake_cnt.data()); - stats.wake_reason_cnt.cmd_event_wake_cnt_sz = - stats.cmd_event_wake_cnt.size(); + reinterpret_cast<int32_t*>(stats.cmd_event_wake_cnt.data()); + stats.wake_reason_cnt.cmd_event_wake_cnt_sz = stats.cmd_event_wake_cnt.size(); stats.wake_reason_cnt.cmd_event_wake_cnt_used = 0; stats.wake_reason_cnt.driver_fw_local_wake_cnt = - reinterpret_cast<int32_t*>(stats.driver_fw_local_wake_cnt.data()); - stats.wake_reason_cnt.driver_fw_local_wake_cnt_sz = - stats.driver_fw_local_wake_cnt.size(); + reinterpret_cast<int32_t*>(stats.driver_fw_local_wake_cnt.data()); + stats.wake_reason_cnt.driver_fw_local_wake_cnt_sz = stats.driver_fw_local_wake_cnt.size(); stats.wake_reason_cnt.driver_fw_local_wake_cnt_used = 0; - wifi_error status = global_func_table_.wifi_get_wake_reason_stats( - getIfaceHandle(iface_name), &stats.wake_reason_cnt); + wifi_error status = global_func_table_.wifi_get_wake_reason_stats(getIfaceHandle(iface_name), + &stats.wake_reason_cnt); - CHECK( - stats.wake_reason_cnt.cmd_event_wake_cnt_used >= 0 && - static_cast<uint32_t>(stats.wake_reason_cnt.cmd_event_wake_cnt_used) <= - kMaxWakeReasonStatsArraySize); - stats.cmd_event_wake_cnt.resize( - stats.wake_reason_cnt.cmd_event_wake_cnt_used); + CHECK(stats.wake_reason_cnt.cmd_event_wake_cnt_used >= 0 && + static_cast<uint32_t>(stats.wake_reason_cnt.cmd_event_wake_cnt_used) <= + kMaxWakeReasonStatsArraySize); + stats.cmd_event_wake_cnt.resize(stats.wake_reason_cnt.cmd_event_wake_cnt_used); stats.wake_reason_cnt.cmd_event_wake_cnt = nullptr; CHECK(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used >= 0 && - static_cast<uint32_t>( - stats.wake_reason_cnt.driver_fw_local_wake_cnt_used) <= - kMaxWakeReasonStatsArraySize); - stats.driver_fw_local_wake_cnt.resize( - stats.wake_reason_cnt.driver_fw_local_wake_cnt_used); + static_cast<uint32_t>(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used) <= + kMaxWakeReasonStatsArraySize); + stats.driver_fw_local_wake_cnt.resize(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used); stats.wake_reason_cnt.driver_fw_local_wake_cnt = nullptr; return {status, stats}; } wifi_error WifiLegacyHal::registerRingBufferCallbackHandler( - const std::string& iface_name, - const on_ring_buffer_data_callback& on_user_data_callback) { + const std::string& iface_name, const on_ring_buffer_data_callback& on_user_data_callback) { if (on_ring_buffer_data_internal_callback) { return WIFI_ERROR_NOT_AVAILABLE; } - on_ring_buffer_data_internal_callback = - [on_user_data_callback](char* ring_name, char* buffer, int buffer_size, - wifi_ring_buffer_status* status) { - if (status && buffer) { - std::vector<uint8_t> buffer_vector( - reinterpret_cast<uint8_t*>(buffer), - reinterpret_cast<uint8_t*>(buffer) + buffer_size); - on_user_data_callback(ring_name, buffer_vector, *status); - } - }; - wifi_error status = global_func_table_.wifi_set_log_handler( - 0, getIfaceHandle(iface_name), {onAsyncRingBufferData}); + on_ring_buffer_data_internal_callback = [on_user_data_callback]( + char* ring_name, char* buffer, int buffer_size, + wifi_ring_buffer_status* status) { + if (status && buffer) { + std::vector<uint8_t> buffer_vector(reinterpret_cast<uint8_t*>(buffer), + reinterpret_cast<uint8_t*>(buffer) + buffer_size); + on_user_data_callback(ring_name, buffer_vector, *status); + } + }; + wifi_error status = global_func_table_.wifi_set_log_handler(0, getIfaceHandle(iface_name), + {onAsyncRingBufferData}); if (status != WIFI_SUCCESS) { on_ring_buffer_data_internal_callback = nullptr; } return status; } -wifi_error WifiLegacyHal::deregisterRingBufferCallbackHandler( - const std::string& iface_name) { +wifi_error WifiLegacyHal::deregisterRingBufferCallbackHandler(const std::string& iface_name) { if (!on_ring_buffer_data_internal_callback) { return WIFI_ERROR_NOT_AVAILABLE; } on_ring_buffer_data_internal_callback = nullptr; - return global_func_table_.wifi_reset_log_handler( - 0, getIfaceHandle(iface_name)); + return global_func_table_.wifi_reset_log_handler(0, getIfaceHandle(iface_name)); } -std::pair<wifi_error, std::vector<wifi_ring_buffer_status>> -WifiLegacyHal::getRingBuffersStatus(const std::string& iface_name) { +std::pair<wifi_error, std::vector<wifi_ring_buffer_status>> WifiLegacyHal::getRingBuffersStatus( + const std::string& iface_name) { std::vector<wifi_ring_buffer_status> ring_buffers_status; ring_buffers_status.resize(kMaxRingBuffers); uint32_t num_rings = kMaxRingBuffers; wifi_error status = global_func_table_.wifi_get_ring_buffers_status( - getIfaceHandle(iface_name), &num_rings, ring_buffers_status.data()); + getIfaceHandle(iface_name), &num_rings, ring_buffers_status.data()); CHECK(num_rings <= kMaxRingBuffers); ring_buffers_status.resize(num_rings); return {status, std::move(ring_buffers_status)}; @@ -1049,12 +975,11 @@ WifiLegacyHal::getRingBuffersStatus(const std::string& iface_name) { wifi_error WifiLegacyHal::startRingBufferLogging(const std::string& iface_name, const std::string& ring_name, - uint32_t verbose_level, - uint32_t max_interval_sec, + uint32_t verbose_level, uint32_t max_interval_sec, uint32_t min_data_size) { - return global_func_table_.wifi_start_logging( - getIfaceHandle(iface_name), verbose_level, 0, max_interval_sec, - min_data_size, makeCharVec(ring_name).data()); + return global_func_table_.wifi_start_logging(getIfaceHandle(iface_name), verbose_level, 0, + max_interval_sec, min_data_size, + makeCharVec(ring_name).data()); } wifi_error WifiLegacyHal::getRingBufferData(const std::string& iface_name, @@ -1064,51 +989,45 @@ wifi_error WifiLegacyHal::getRingBufferData(const std::string& iface_name, } wifi_error WifiLegacyHal::registerErrorAlertCallbackHandler( - const std::string& iface_name, - const on_error_alert_callback& on_user_alert_callback) { + const std::string& iface_name, const on_error_alert_callback& on_user_alert_callback) { if (on_error_alert_internal_callback) { return WIFI_ERROR_NOT_AVAILABLE; } - on_error_alert_internal_callback = [on_user_alert_callback]( - wifi_request_id id, char* buffer, - int buffer_size, int err_code) { + on_error_alert_internal_callback = [on_user_alert_callback](wifi_request_id id, char* buffer, + int buffer_size, int err_code) { if (buffer) { CHECK(id == 0); on_user_alert_callback( - err_code, - std::vector<uint8_t>( - reinterpret_cast<uint8_t*>(buffer), - reinterpret_cast<uint8_t*>(buffer) + buffer_size)); + err_code, + std::vector<uint8_t>(reinterpret_cast<uint8_t*>(buffer), + reinterpret_cast<uint8_t*>(buffer) + buffer_size)); } }; - wifi_error status = global_func_table_.wifi_set_alert_handler( - 0, getIfaceHandle(iface_name), {onAsyncErrorAlert}); + wifi_error status = global_func_table_.wifi_set_alert_handler(0, getIfaceHandle(iface_name), + {onAsyncErrorAlert}); if (status != WIFI_SUCCESS) { on_error_alert_internal_callback = nullptr; } return status; } -wifi_error WifiLegacyHal::deregisterErrorAlertCallbackHandler( - const std::string& iface_name) { +wifi_error WifiLegacyHal::deregisterErrorAlertCallbackHandler(const std::string& iface_name) { if (!on_error_alert_internal_callback) { return WIFI_ERROR_NOT_AVAILABLE; } on_error_alert_internal_callback = nullptr; - return global_func_table_.wifi_reset_alert_handler( - 0, getIfaceHandle(iface_name)); + return global_func_table_.wifi_reset_alert_handler(0, getIfaceHandle(iface_name)); } wifi_error WifiLegacyHal::registerRadioModeChangeCallbackHandler( - const std::string& iface_name, - const on_radio_mode_change_callback& on_user_change_callback) { + const std::string& iface_name, + const on_radio_mode_change_callback& on_user_change_callback) { if (on_radio_mode_change_internal_callback) { return WIFI_ERROR_NOT_AVAILABLE; } on_radio_mode_change_internal_callback = [on_user_change_callback]( - wifi_request_id /* id */, - uint32_t num_macs, - wifi_mac_info* mac_infos_arr) { + wifi_request_id /* id */, uint32_t num_macs, + wifi_mac_info* mac_infos_arr) { if (num_macs > 0 && mac_infos_arr) { std::vector<WifiMacInfo> mac_infos_vec; for (uint32_t i = 0; i < num_macs; i++) { @@ -1127,7 +1046,7 @@ wifi_error WifiLegacyHal::registerRadioModeChangeCallbackHandler( } }; wifi_error status = global_func_table_.wifi_set_radio_mode_change_handler( - 0, getIfaceHandle(iface_name), {onAsyncRadioModeChange}); + 0, getIfaceHandle(iface_name), {onAsyncRadioModeChange}); if (status != WIFI_SUCCESS) { on_radio_mode_change_internal_callback = nullptr; } @@ -1135,16 +1054,15 @@ wifi_error WifiLegacyHal::registerRadioModeChangeCallbackHandler( } wifi_error WifiLegacyHal::registerSubsystemRestartCallbackHandler( - const on_subsystem_restart_callback& on_restart_callback) { + const on_subsystem_restart_callback& on_restart_callback) { if (on_subsystem_restart_internal_callback) { return WIFI_ERROR_NOT_AVAILABLE; } - on_subsystem_restart_internal_callback = - [on_restart_callback](const char* error) { - on_restart_callback(error); - }; + on_subsystem_restart_internal_callback = [on_restart_callback](const char* error) { + on_restart_callback(error); + }; wifi_error status = global_func_table_.wifi_set_subsystem_restart_handler( - global_handle_, {onAsyncSubsystemRestart}); + global_handle_, {onAsyncSubsystemRestart}); if (status != WIFI_SUCCESS) { on_subsystem_restart_internal_callback = nullptr; } @@ -1152,33 +1070,30 @@ wifi_error WifiLegacyHal::registerSubsystemRestartCallbackHandler( } wifi_error WifiLegacyHal::startRttRangeRequest( - const std::string& iface_name, wifi_request_id id, - const std::vector<wifi_rtt_config>& rtt_configs, - const on_rtt_results_callback& on_results_user_callback) { + const std::string& iface_name, wifi_request_id id, + const std::vector<wifi_rtt_config>& rtt_configs, + const on_rtt_results_callback& on_results_user_callback) { if (on_rtt_results_internal_callback) { return WIFI_ERROR_NOT_AVAILABLE; } - on_rtt_results_internal_callback = - [on_results_user_callback](wifi_request_id id, unsigned num_results, - wifi_rtt_result* rtt_results[]) { - if (num_results > 0 && !rtt_results) { - LOG(ERROR) << "Unexpected nullptr in RTT results"; - return; - } - std::vector<const wifi_rtt_result*> rtt_results_vec; - std::copy_if(rtt_results, rtt_results + num_results, - back_inserter(rtt_results_vec), - [](wifi_rtt_result* rtt_result) { - return rtt_result != nullptr; - }); - on_results_user_callback(id, rtt_results_vec); - }; + on_rtt_results_internal_callback = [on_results_user_callback](wifi_request_id id, + unsigned num_results, + wifi_rtt_result* rtt_results[]) { + if (num_results > 0 && !rtt_results) { + LOG(ERROR) << "Unexpected nullptr in RTT results"; + return; + } + std::vector<const wifi_rtt_result*> rtt_results_vec; + std::copy_if(rtt_results, rtt_results + num_results, back_inserter(rtt_results_vec), + [](wifi_rtt_result* rtt_result) { return rtt_result != nullptr; }); + on_results_user_callback(id, rtt_results_vec); + }; std::vector<wifi_rtt_config> rtt_configs_internal(rtt_configs); wifi_error status = global_func_table_.wifi_rtt_range_request( - id, getIfaceHandle(iface_name), rtt_configs.size(), - rtt_configs_internal.data(), {onAsyncRttResults}); + id, getIfaceHandle(iface_name), rtt_configs.size(), rtt_configs_internal.data(), + {onAsyncRttResults}); if (status != WIFI_SUCCESS) { on_rtt_results_internal_callback = nullptr; } @@ -1186,19 +1101,18 @@ wifi_error WifiLegacyHal::startRttRangeRequest( } wifi_error WifiLegacyHal::cancelRttRangeRequest( - const std::string& iface_name, wifi_request_id id, - const std::vector<std::array<uint8_t, 6>>& mac_addrs) { + const std::string& iface_name, wifi_request_id id, + const std::vector<std::array<uint8_t, 6>>& mac_addrs) { if (!on_rtt_results_internal_callback) { return WIFI_ERROR_NOT_AVAILABLE; } - static_assert(sizeof(mac_addr) == sizeof(std::array<uint8_t, 6>), - "MAC address size mismatch"); + static_assert(sizeof(mac_addr) == sizeof(std::array<uint8_t, 6>), "MAC address size mismatch"); // TODO: How do we handle partial cancels (i.e only a subset of enabled mac // addressed are cancelled). std::vector<std::array<uint8_t, 6>> mac_addrs_internal(mac_addrs); wifi_error status = global_func_table_.wifi_rtt_range_cancel( - id, getIfaceHandle(iface_name), mac_addrs.size(), - reinterpret_cast<mac_addr*>(mac_addrs_internal.data())); + id, getIfaceHandle(iface_name), mac_addrs.size(), + reinterpret_cast<mac_addr*>(mac_addrs_internal.data())); // If the request Id is wrong, don't stop the ongoing range request. Any // other error should be treated as the end of rtt ranging. if (status != WIFI_ERROR_INVALID_REQUEST_ID) { @@ -1208,225 +1122,188 @@ wifi_error WifiLegacyHal::cancelRttRangeRequest( } std::pair<wifi_error, wifi_rtt_capabilities> WifiLegacyHal::getRttCapabilities( - const std::string& iface_name) { + const std::string& iface_name) { wifi_rtt_capabilities rtt_caps; - wifi_error status = global_func_table_.wifi_get_rtt_capabilities( - getIfaceHandle(iface_name), &rtt_caps); + wifi_error status = + global_func_table_.wifi_get_rtt_capabilities(getIfaceHandle(iface_name), &rtt_caps); return {status, rtt_caps}; } std::pair<wifi_error, wifi_rtt_responder> WifiLegacyHal::getRttResponderInfo( - const std::string& iface_name) { + const std::string& iface_name) { wifi_rtt_responder rtt_responder; - wifi_error status = global_func_table_.wifi_rtt_get_responder_info( - getIfaceHandle(iface_name), &rtt_responder); + wifi_error status = global_func_table_.wifi_rtt_get_responder_info(getIfaceHandle(iface_name), + &rtt_responder); return {status, rtt_responder}; } -wifi_error WifiLegacyHal::enableRttResponder( - const std::string& iface_name, wifi_request_id id, - const wifi_channel_info& channel_hint, uint32_t max_duration_secs, - const wifi_rtt_responder& info) { +wifi_error WifiLegacyHal::enableRttResponder(const std::string& iface_name, wifi_request_id id, + const wifi_channel_info& channel_hint, + uint32_t max_duration_secs, + const wifi_rtt_responder& info) { wifi_rtt_responder info_internal(info); - return global_func_table_.wifi_enable_responder( - id, getIfaceHandle(iface_name), channel_hint, max_duration_secs, - &info_internal); + return global_func_table_.wifi_enable_responder(id, getIfaceHandle(iface_name), channel_hint, + max_duration_secs, &info_internal); } -wifi_error WifiLegacyHal::disableRttResponder(const std::string& iface_name, - wifi_request_id id) { - return global_func_table_.wifi_disable_responder( - id, getIfaceHandle(iface_name)); +wifi_error WifiLegacyHal::disableRttResponder(const std::string& iface_name, wifi_request_id id) { + return global_func_table_.wifi_disable_responder(id, getIfaceHandle(iface_name)); } -wifi_error WifiLegacyHal::setRttLci(const std::string& iface_name, - wifi_request_id id, +wifi_error WifiLegacyHal::setRttLci(const std::string& iface_name, wifi_request_id id, const wifi_lci_information& info) { wifi_lci_information info_internal(info); - return global_func_table_.wifi_set_lci(id, getIfaceHandle(iface_name), - &info_internal); + return global_func_table_.wifi_set_lci(id, getIfaceHandle(iface_name), &info_internal); } -wifi_error WifiLegacyHal::setRttLcr(const std::string& iface_name, - wifi_request_id id, +wifi_error WifiLegacyHal::setRttLcr(const std::string& iface_name, wifi_request_id id, const wifi_lcr_information& info) { wifi_lcr_information info_internal(info); - return global_func_table_.wifi_set_lcr(id, getIfaceHandle(iface_name), - &info_internal); + return global_func_table_.wifi_set_lcr(id, getIfaceHandle(iface_name), &info_internal); } -wifi_error WifiLegacyHal::nanRegisterCallbackHandlers( - const std::string& iface_name, const NanCallbackHandlers& user_callbacks) { +wifi_error WifiLegacyHal::nanRegisterCallbackHandlers(const std::string& iface_name, + const NanCallbackHandlers& user_callbacks) { on_nan_notify_response_user_callback = user_callbacks.on_notify_response; - on_nan_event_publish_terminated_user_callback = - user_callbacks.on_event_publish_terminated; + on_nan_event_publish_terminated_user_callback = user_callbacks.on_event_publish_terminated; on_nan_event_match_user_callback = user_callbacks.on_event_match; - on_nan_event_match_expired_user_callback = - user_callbacks.on_event_match_expired; - on_nan_event_subscribe_terminated_user_callback = - user_callbacks.on_event_subscribe_terminated; + on_nan_event_match_expired_user_callback = user_callbacks.on_event_match_expired; + on_nan_event_subscribe_terminated_user_callback = user_callbacks.on_event_subscribe_terminated; on_nan_event_followup_user_callback = user_callbacks.on_event_followup; - on_nan_event_disc_eng_event_user_callback = - user_callbacks.on_event_disc_eng_event; + on_nan_event_disc_eng_event_user_callback = user_callbacks.on_event_disc_eng_event; on_nan_event_disabled_user_callback = user_callbacks.on_event_disabled; on_nan_event_tca_user_callback = user_callbacks.on_event_tca; - on_nan_event_beacon_sdf_payload_user_callback = - user_callbacks.on_event_beacon_sdf_payload; - on_nan_event_data_path_request_user_callback = - user_callbacks.on_event_data_path_request; - on_nan_event_data_path_confirm_user_callback = - user_callbacks.on_event_data_path_confirm; - on_nan_event_data_path_end_user_callback = - user_callbacks.on_event_data_path_end; - on_nan_event_transmit_follow_up_user_callback = - user_callbacks.on_event_transmit_follow_up; - on_nan_event_range_request_user_callback = - user_callbacks.on_event_range_request; - on_nan_event_range_report_user_callback = - user_callbacks.on_event_range_report; - on_nan_event_schedule_update_user_callback = - user_callbacks.on_event_schedule_update; + on_nan_event_beacon_sdf_payload_user_callback = user_callbacks.on_event_beacon_sdf_payload; + on_nan_event_data_path_request_user_callback = user_callbacks.on_event_data_path_request; + on_nan_event_data_path_confirm_user_callback = user_callbacks.on_event_data_path_confirm; + on_nan_event_data_path_end_user_callback = user_callbacks.on_event_data_path_end; + on_nan_event_transmit_follow_up_user_callback = user_callbacks.on_event_transmit_follow_up; + on_nan_event_range_request_user_callback = user_callbacks.on_event_range_request; + on_nan_event_range_report_user_callback = user_callbacks.on_event_range_report; + on_nan_event_schedule_update_user_callback = user_callbacks.on_event_schedule_update; return global_func_table_.wifi_nan_register_handler( - getIfaceHandle(iface_name), - {onAysncNanNotifyResponse, onAysncNanEventPublishReplied, - onAysncNanEventPublishTerminated, onAysncNanEventMatch, - onAysncNanEventMatchExpired, onAysncNanEventSubscribeTerminated, - onAysncNanEventFollowup, onAysncNanEventDiscEngEvent, - onAysncNanEventDisabled, onAysncNanEventTca, - onAysncNanEventBeaconSdfPayload, onAysncNanEventDataPathRequest, - onAysncNanEventDataPathConfirm, onAysncNanEventDataPathEnd, - onAysncNanEventTransmitFollowUp, onAysncNanEventRangeRequest, - onAysncNanEventRangeReport, onAsyncNanEventScheduleUpdate}); -} - -wifi_error WifiLegacyHal::nanEnableRequest(const std::string& iface_name, - transaction_id id, + getIfaceHandle(iface_name), + {onAysncNanNotifyResponse, onAysncNanEventPublishReplied, + onAysncNanEventPublishTerminated, onAysncNanEventMatch, onAysncNanEventMatchExpired, + onAysncNanEventSubscribeTerminated, onAysncNanEventFollowup, + onAysncNanEventDiscEngEvent, onAysncNanEventDisabled, onAysncNanEventTca, + onAysncNanEventBeaconSdfPayload, onAysncNanEventDataPathRequest, + onAysncNanEventDataPathConfirm, onAysncNanEventDataPathEnd, + onAysncNanEventTransmitFollowUp, onAysncNanEventRangeRequest, + onAysncNanEventRangeReport, onAsyncNanEventScheduleUpdate}); +} + +wifi_error WifiLegacyHal::nanEnableRequest(const std::string& iface_name, transaction_id id, const NanEnableRequest& msg) { NanEnableRequest msg_internal(msg); - return global_func_table_.wifi_nan_enable_request( - id, getIfaceHandle(iface_name), &msg_internal); + return global_func_table_.wifi_nan_enable_request(id, getIfaceHandle(iface_name), + &msg_internal); } -wifi_error WifiLegacyHal::nanDisableRequest(const std::string& iface_name, - transaction_id id) { - return global_func_table_.wifi_nan_disable_request( - id, getIfaceHandle(iface_name)); +wifi_error WifiLegacyHal::nanDisableRequest(const std::string& iface_name, transaction_id id) { + return global_func_table_.wifi_nan_disable_request(id, getIfaceHandle(iface_name)); } -wifi_error WifiLegacyHal::nanPublishRequest(const std::string& iface_name, - transaction_id id, +wifi_error WifiLegacyHal::nanPublishRequest(const std::string& iface_name, transaction_id id, const NanPublishRequest& msg) { NanPublishRequest msg_internal(msg); - return global_func_table_.wifi_nan_publish_request( - id, getIfaceHandle(iface_name), &msg_internal); + return global_func_table_.wifi_nan_publish_request(id, getIfaceHandle(iface_name), + &msg_internal); } -wifi_error WifiLegacyHal::nanPublishCancelRequest( - const std::string& iface_name, transaction_id id, - const NanPublishCancelRequest& msg) { +wifi_error WifiLegacyHal::nanPublishCancelRequest(const std::string& iface_name, transaction_id id, + const NanPublishCancelRequest& msg) { NanPublishCancelRequest msg_internal(msg); - return global_func_table_.wifi_nan_publish_cancel_request( - id, getIfaceHandle(iface_name), &msg_internal); + return global_func_table_.wifi_nan_publish_cancel_request(id, getIfaceHandle(iface_name), + &msg_internal); } -wifi_error WifiLegacyHal::nanSubscribeRequest(const std::string& iface_name, - transaction_id id, +wifi_error WifiLegacyHal::nanSubscribeRequest(const std::string& iface_name, transaction_id id, const NanSubscribeRequest& msg) { NanSubscribeRequest msg_internal(msg); - return global_func_table_.wifi_nan_subscribe_request( - id, getIfaceHandle(iface_name), &msg_internal); + return global_func_table_.wifi_nan_subscribe_request(id, getIfaceHandle(iface_name), + &msg_internal); } -wifi_error WifiLegacyHal::nanSubscribeCancelRequest( - const std::string& iface_name, transaction_id id, - const NanSubscribeCancelRequest& msg) { +wifi_error WifiLegacyHal::nanSubscribeCancelRequest(const std::string& iface_name, + transaction_id id, + const NanSubscribeCancelRequest& msg) { NanSubscribeCancelRequest msg_internal(msg); - return global_func_table_.wifi_nan_subscribe_cancel_request( - id, getIfaceHandle(iface_name), &msg_internal); + return global_func_table_.wifi_nan_subscribe_cancel_request(id, getIfaceHandle(iface_name), + &msg_internal); } -wifi_error WifiLegacyHal::nanTransmitFollowupRequest( - const std::string& iface_name, transaction_id id, - const NanTransmitFollowupRequest& msg) { +wifi_error WifiLegacyHal::nanTransmitFollowupRequest(const std::string& iface_name, + transaction_id id, + const NanTransmitFollowupRequest& msg) { NanTransmitFollowupRequest msg_internal(msg); - return global_func_table_.wifi_nan_transmit_followup_request( - id, getIfaceHandle(iface_name), &msg_internal); + return global_func_table_.wifi_nan_transmit_followup_request(id, getIfaceHandle(iface_name), + &msg_internal); } -wifi_error WifiLegacyHal::nanStatsRequest(const std::string& iface_name, - transaction_id id, +wifi_error WifiLegacyHal::nanStatsRequest(const std::string& iface_name, transaction_id id, const NanStatsRequest& msg) { NanStatsRequest msg_internal(msg); - return global_func_table_.wifi_nan_stats_request( - id, getIfaceHandle(iface_name), &msg_internal); + return global_func_table_.wifi_nan_stats_request(id, getIfaceHandle(iface_name), &msg_internal); } -wifi_error WifiLegacyHal::nanConfigRequest(const std::string& iface_name, - transaction_id id, +wifi_error WifiLegacyHal::nanConfigRequest(const std::string& iface_name, transaction_id id, const NanConfigRequest& msg) { NanConfigRequest msg_internal(msg); - return global_func_table_.wifi_nan_config_request( - id, getIfaceHandle(iface_name), &msg_internal); + return global_func_table_.wifi_nan_config_request(id, getIfaceHandle(iface_name), + &msg_internal); } -wifi_error WifiLegacyHal::nanTcaRequest(const std::string& iface_name, - transaction_id id, +wifi_error WifiLegacyHal::nanTcaRequest(const std::string& iface_name, transaction_id id, const NanTCARequest& msg) { NanTCARequest msg_internal(msg); - return global_func_table_.wifi_nan_tca_request( - id, getIfaceHandle(iface_name), &msg_internal); + return global_func_table_.wifi_nan_tca_request(id, getIfaceHandle(iface_name), &msg_internal); } -wifi_error WifiLegacyHal::nanBeaconSdfPayloadRequest( - const std::string& iface_name, transaction_id id, - const NanBeaconSdfPayloadRequest& msg) { +wifi_error WifiLegacyHal::nanBeaconSdfPayloadRequest(const std::string& iface_name, + transaction_id id, + const NanBeaconSdfPayloadRequest& msg) { NanBeaconSdfPayloadRequest msg_internal(msg); - return global_func_table_.wifi_nan_beacon_sdf_payload_request( - id, getIfaceHandle(iface_name), &msg_internal); + return global_func_table_.wifi_nan_beacon_sdf_payload_request(id, getIfaceHandle(iface_name), + &msg_internal); } std::pair<wifi_error, NanVersion> WifiLegacyHal::nanGetVersion() { NanVersion version; - wifi_error status = - global_func_table_.wifi_nan_get_version(global_handle_, &version); + wifi_error status = global_func_table_.wifi_nan_get_version(global_handle_, &version); return {status, version}; } -wifi_error WifiLegacyHal::nanGetCapabilities(const std::string& iface_name, - transaction_id id) { - return global_func_table_.wifi_nan_get_capabilities( - id, getIfaceHandle(iface_name)); +wifi_error WifiLegacyHal::nanGetCapabilities(const std::string& iface_name, transaction_id id) { + return global_func_table_.wifi_nan_get_capabilities(id, getIfaceHandle(iface_name)); } -wifi_error WifiLegacyHal::nanDataInterfaceCreate( - const std::string& iface_name, transaction_id id, - const std::string& data_iface_name) { - return global_func_table_.wifi_nan_data_interface_create( - id, getIfaceHandle(iface_name), makeCharVec(data_iface_name).data()); +wifi_error WifiLegacyHal::nanDataInterfaceCreate(const std::string& iface_name, transaction_id id, + const std::string& data_iface_name) { + return global_func_table_.wifi_nan_data_interface_create(id, getIfaceHandle(iface_name), + makeCharVec(data_iface_name).data()); } -wifi_error WifiLegacyHal::nanDataInterfaceDelete( - const std::string& iface_name, transaction_id id, - const std::string& data_iface_name) { - return global_func_table_.wifi_nan_data_interface_delete( - id, getIfaceHandle(iface_name), makeCharVec(data_iface_name).data()); +wifi_error WifiLegacyHal::nanDataInterfaceDelete(const std::string& iface_name, transaction_id id, + const std::string& data_iface_name) { + return global_func_table_.wifi_nan_data_interface_delete(id, getIfaceHandle(iface_name), + makeCharVec(data_iface_name).data()); } -wifi_error WifiLegacyHal::nanDataRequestInitiator( - const std::string& iface_name, transaction_id id, - const NanDataPathInitiatorRequest& msg) { +wifi_error WifiLegacyHal::nanDataRequestInitiator(const std::string& iface_name, transaction_id id, + const NanDataPathInitiatorRequest& msg) { NanDataPathInitiatorRequest msg_internal(msg); - return global_func_table_.wifi_nan_data_request_initiator( - id, getIfaceHandle(iface_name), &msg_internal); + return global_func_table_.wifi_nan_data_request_initiator(id, getIfaceHandle(iface_name), + &msg_internal); } -wifi_error WifiLegacyHal::nanDataIndicationResponse( - const std::string& iface_name, transaction_id id, - const NanDataPathIndicationResponse& msg) { +wifi_error WifiLegacyHal::nanDataIndicationResponse(const std::string& iface_name, + transaction_id id, + const NanDataPathIndicationResponse& msg) { NanDataPathIndicationResponse msg_internal(msg); - return global_func_table_.wifi_nan_data_indication_response( - id, getIfaceHandle(iface_name), &msg_internal); + return global_func_table_.wifi_nan_data_indication_response(id, getIfaceHandle(iface_name), + &msg_internal); } typedef struct { @@ -1434,29 +1311,27 @@ typedef struct { NanDataPathId ndp_instance_id; } NanDataPathEndSingleNdpIdRequest; -wifi_error WifiLegacyHal::nanDataEnd(const std::string& iface_name, - transaction_id id, +wifi_error WifiLegacyHal::nanDataEnd(const std::string& iface_name, transaction_id id, uint32_t ndpInstanceId) { NanDataPathEndSingleNdpIdRequest msg; msg.num_ndp_instances = 1; msg.ndp_instance_id = ndpInstanceId; - wifi_error status = global_func_table_.wifi_nan_data_end( - id, getIfaceHandle(iface_name), (NanDataPathEndRequest*)&msg); + wifi_error status = global_func_table_.wifi_nan_data_end(id, getIfaceHandle(iface_name), + (NanDataPathEndRequest*)&msg); return status; } wifi_error WifiLegacyHal::setCountryCode(const std::string& iface_name, std::array<int8_t, 2> code) { std::string code_str(code.data(), code.data() + code.size()); - return global_func_table_.wifi_set_country_code(getIfaceHandle(iface_name), - code_str.c_str()); + return global_func_table_.wifi_set_country_code(getIfaceHandle(iface_name), code_str.c_str()); } wifi_error WifiLegacyHal::retrieveIfaceHandles() { wifi_interface_handle* iface_handles = nullptr; int num_iface_handles = 0; - wifi_error status = global_func_table_.wifi_get_ifaces( - global_handle_, &num_iface_handles, &iface_handles); + wifi_error status = + global_func_table_.wifi_get_ifaces(global_handle_, &num_iface_handles, &iface_handles); if (status != WIFI_SUCCESS) { LOG(ERROR) << "Failed to enumerate interface handles"; return status; @@ -1464,8 +1339,8 @@ wifi_error WifiLegacyHal::retrieveIfaceHandles() { iface_name_to_handle_.clear(); for (int i = 0; i < num_iface_handles; ++i) { std::array<char, IFNAMSIZ> iface_name_arr = {}; - status = global_func_table_.wifi_get_iface_name( - iface_handles[i], iface_name_arr.data(), iface_name_arr.size()); + status = global_func_table_.wifi_get_iface_name(iface_handles[i], iface_name_arr.data(), + iface_name_arr.size()); if (status != WIFI_SUCCESS) { LOG(WARNING) << "Failed to get interface handle name"; continue; @@ -1479,8 +1354,7 @@ wifi_error WifiLegacyHal::retrieveIfaceHandles() { return WIFI_SUCCESS; } -wifi_interface_handle WifiLegacyHal::getIfaceHandle( - const std::string& iface_name) { +wifi_interface_handle WifiLegacyHal::getIfaceHandle(const std::string& iface_name) { const auto iface_handle_iter = iface_name_to_handle_.find(iface_name); if (iface_handle_iter == iface_name_to_handle_.end()) { LOG(ERROR) << "Unknown iface name: " << iface_name; @@ -1494,24 +1368,22 @@ void WifiLegacyHal::runEventLoop() { global_func_table_.wifi_event_loop(global_handle_); const auto lock = hidl_sync_util::acquireGlobalLock(); if (!awaiting_event_loop_termination_) { - LOG(FATAL) - << "Legacy HAL event loop terminated, but HAL was not stopping"; + LOG(FATAL) << "Legacy HAL event loop terminated, but HAL was not stopping"; } LOG(DEBUG) << "Legacy HAL event loop terminated"; awaiting_event_loop_termination_ = false; stop_wait_cv_.notify_one(); } -std::pair<wifi_error, std::vector<wifi_cached_scan_results>> -WifiLegacyHal::getGscanCachedResults(const std::string& iface_name) { +std::pair<wifi_error, std::vector<wifi_cached_scan_results>> WifiLegacyHal::getGscanCachedResults( + const std::string& iface_name) { std::vector<wifi_cached_scan_results> cached_scan_results; cached_scan_results.resize(kMaxCachedGscanResults); int32_t num_results = 0; wifi_error status = global_func_table_.wifi_get_cached_gscan_results( - getIfaceHandle(iface_name), true /* always flush */, - cached_scan_results.size(), cached_scan_results.data(), &num_results); - CHECK(num_results >= 0 && - static_cast<uint32_t>(num_results) <= kMaxCachedGscanResults); + getIfaceHandle(iface_name), true /* always flush */, cached_scan_results.size(), + cached_scan_results.data(), &num_results); + CHECK(num_results >= 0 && static_cast<uint32_t>(num_results) <= kMaxCachedGscanResults); cached_scan_results.resize(num_results); // Check for invalid IE lengths in these cached scan results and correct it. for (auto& cached_scan_result : cached_scan_results) { @@ -1519,8 +1391,7 @@ WifiLegacyHal::getGscanCachedResults(const std::string& iface_name) { for (int i = 0; i < num_scan_results; i++) { auto& scan_result = cached_scan_result.results[i]; if (scan_result.ie_length > 0) { - LOG(DEBUG) << "Cached scan result has non-zero IE length " - << scan_result.ie_length; + LOG(DEBUG) << "Cached scan result has non-zero IE length " << scan_result.ie_length; scan_result.ie_length = 0; } } @@ -1532,20 +1403,20 @@ wifi_error WifiLegacyHal::createVirtualInterface(const std::string& ifname, wifi_interface_type iftype) { // Create the interface if it doesn't exist. If interface already exist, // Vendor Hal should return WIFI_SUCCESS. - wifi_error status = global_func_table_.wifi_virtual_interface_create( - global_handle_, ifname.c_str(), iftype); + wifi_error status = global_func_table_.wifi_virtual_interface_create(global_handle_, + ifname.c_str(), iftype); return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status); } wifi_error WifiLegacyHal::deleteVirtualInterface(const std::string& ifname) { // Delete the interface if it was created dynamically. - wifi_error status = global_func_table_.wifi_virtual_interface_delete( - global_handle_, ifname.c_str()); + wifi_error status = + global_func_table_.wifi_virtual_interface_delete(global_handle_, ifname.c_str()); return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status); } -wifi_error WifiLegacyHal::handleVirtualInterfaceCreateOrDeleteStatus( - const std::string& ifname, wifi_error status) { +wifi_error WifiLegacyHal::handleVirtualInterfaceCreateOrDeleteStatus(const std::string& ifname, + wifi_error status) { if (status == WIFI_SUCCESS) { // refresh list of handlers now. status = retrieveIfaceHandles(); @@ -1561,116 +1432,98 @@ wifi_error WifiLegacyHal::handleVirtualInterfaceCreateOrDeleteStatus( return status; } -wifi_error WifiLegacyHal::getSupportedIfaceName(uint32_t iface_type, - std::string& ifname) { +wifi_error WifiLegacyHal::getSupportedIfaceName(uint32_t iface_type, std::string& ifname) { std::array<char, IFNAMSIZ> buffer; wifi_error res = global_func_table_.wifi_get_supported_iface_name( - global_handle_, (uint32_t)iface_type, buffer.data(), buffer.size()); + global_handle_, (uint32_t)iface_type, buffer.data(), buffer.size()); if (res == WIFI_SUCCESS) ifname = buffer.data(); return res; } -wifi_error WifiLegacyHal::multiStaSetPrimaryConnection( - const std::string& ifname) { - return global_func_table_.wifi_multi_sta_set_primary_connection( - global_handle_, getIfaceHandle(ifname)); +wifi_error WifiLegacyHal::multiStaSetPrimaryConnection(const std::string& ifname) { + return global_func_table_.wifi_multi_sta_set_primary_connection(global_handle_, + getIfaceHandle(ifname)); } wifi_error WifiLegacyHal::multiStaSetUseCase(wifi_multi_sta_use_case use_case) { - return global_func_table_.wifi_multi_sta_set_use_case(global_handle_, - use_case); + return global_func_table_.wifi_multi_sta_set_use_case(global_handle_, use_case); } wifi_error WifiLegacyHal::setCoexUnsafeChannels( - std::vector<wifi_coex_unsafe_channel> unsafe_channels, - uint32_t restrictions) { - return global_func_table_.wifi_set_coex_unsafe_channels( - global_handle_, unsafe_channels.size(), unsafe_channels.data(), - restrictions); + std::vector<wifi_coex_unsafe_channel> unsafe_channels, uint32_t restrictions) { + return global_func_table_.wifi_set_coex_unsafe_channels(global_handle_, unsafe_channels.size(), + unsafe_channels.data(), restrictions); } -wifi_error WifiLegacyHal::setVoipMode(const std::string& iface_name, - wifi_voip_mode mode) { - return global_func_table_.wifi_set_voip_mode(getIfaceHandle(iface_name), - mode); +wifi_error WifiLegacyHal::setVoipMode(const std::string& iface_name, wifi_voip_mode mode) { + return global_func_table_.wifi_set_voip_mode(getIfaceHandle(iface_name), mode); } -wifi_error WifiLegacyHal::twtRegisterHandler( - const std::string& iface_name, const TwtCallbackHandlers& user_callbacks) { +wifi_error WifiLegacyHal::twtRegisterHandler(const std::string& iface_name, + const TwtCallbackHandlers& user_callbacks) { on_twt_event_setup_response_callback = user_callbacks.on_setup_response; - on_twt_event_teardown_completion_callback = - user_callbacks.on_teardown_completion; - on_twt_event_info_frame_received_callback = - user_callbacks.on_info_frame_received; + on_twt_event_teardown_completion_callback = user_callbacks.on_teardown_completion; + on_twt_event_info_frame_received_callback = user_callbacks.on_info_frame_received; on_twt_event_device_notify_callback = user_callbacks.on_device_notify; return global_func_table_.wifi_twt_register_handler( - getIfaceHandle(iface_name), - {onAsyncTwtEventSetupResponse, onAsyncTwtEventTeardownCompletion, - onAsyncTwtEventInfoFrameReceived, onAsyncTwtEventDeviceNotify}); + getIfaceHandle(iface_name), + {onAsyncTwtEventSetupResponse, onAsyncTwtEventTeardownCompletion, + onAsyncTwtEventInfoFrameReceived, onAsyncTwtEventDeviceNotify}); } std::pair<wifi_error, TwtCapabilitySet> WifiLegacyHal::twtGetCapability( - const std::string& iface_name) { + const std::string& iface_name) { TwtCapabilitySet capSet; - wifi_error status = global_func_table_.wifi_twt_get_capability( - getIfaceHandle(iface_name), &capSet); + wifi_error status = + global_func_table_.wifi_twt_get_capability(getIfaceHandle(iface_name), &capSet); return {status, capSet}; } wifi_error WifiLegacyHal::twtSetupRequest(const std::string& iface_name, const TwtSetupRequest& msg) { TwtSetupRequest msgInternal(msg); - return global_func_table_.wifi_twt_setup_request(getIfaceHandle(iface_name), - &msgInternal); + return global_func_table_.wifi_twt_setup_request(getIfaceHandle(iface_name), &msgInternal); } wifi_error WifiLegacyHal::twtTearDownRequest(const std::string& iface_name, const TwtTeardownRequest& msg) { TwtTeardownRequest msgInternal(msg); - return global_func_table_.wifi_twt_teardown_request( - getIfaceHandle(iface_name), &msgInternal); + return global_func_table_.wifi_twt_teardown_request(getIfaceHandle(iface_name), &msgInternal); } wifi_error WifiLegacyHal::twtInfoFrameRequest(const std::string& iface_name, const TwtInfoFrameRequest& msg) { TwtInfoFrameRequest msgInternal(msg); - return global_func_table_.wifi_twt_info_frame_request( - getIfaceHandle(iface_name), &msgInternal); + return global_func_table_.wifi_twt_info_frame_request(getIfaceHandle(iface_name), &msgInternal); } -std::pair<wifi_error, TwtStats> WifiLegacyHal::twtGetStats( - const std::string& iface_name, uint8_t configId) { +std::pair<wifi_error, TwtStats> WifiLegacyHal::twtGetStats(const std::string& iface_name, + uint8_t configId) { TwtStats stats; - wifi_error status = global_func_table_.wifi_twt_get_stats( - getIfaceHandle(iface_name), configId, &stats); + wifi_error status = + global_func_table_.wifi_twt_get_stats(getIfaceHandle(iface_name), configId, &stats); return {status, stats}; } -wifi_error WifiLegacyHal::twtClearStats(const std::string& iface_name, - uint8_t configId) { - return global_func_table_.wifi_twt_clear_stats(getIfaceHandle(iface_name), - configId); +wifi_error WifiLegacyHal::twtClearStats(const std::string& iface_name, uint8_t configId) { + return global_func_table_.wifi_twt_clear_stats(getIfaceHandle(iface_name), configId); } -wifi_error WifiLegacyHal::setDtimConfig(const std::string& iface_name, - uint32_t multiplier) { - return global_func_table_.wifi_set_dtim_config(getIfaceHandle(iface_name), - multiplier); +wifi_error WifiLegacyHal::setDtimConfig(const std::string& iface_name, uint32_t multiplier) { + return global_func_table_.wifi_set_dtim_config(getIfaceHandle(iface_name), multiplier); } -std::pair<wifi_error, std::vector<wifi_usable_channel>> -WifiLegacyHal::getUsableChannels(uint32_t band_mask, uint32_t iface_mode_mask, - uint32_t filter_mask) { +std::pair<wifi_error, std::vector<wifi_usable_channel>> WifiLegacyHal::getUsableChannels( + uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask) { std::vector<wifi_usable_channel> channels; channels.resize(kMaxWifiUsableChannels); uint32_t size = 0; wifi_error status = global_func_table_.wifi_get_usable_channels( - global_handle_, band_mask, iface_mode_mask, filter_mask, - channels.size(), &size, - reinterpret_cast<wifi_usable_channel*>(channels.data())); + global_handle_, band_mask, iface_mode_mask, filter_mask, channels.size(), &size, + reinterpret_cast<wifi_usable_channel*>(channels.data())); CHECK(size >= 0 && size <= kMaxWifiUsableChannels); channels.resize(size); return {status, std::move(channels)}; @@ -1719,7 +1572,7 @@ void WifiLegacyHal::invalidate() { } // namespace legacy_hal } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.6/default/wifi_legacy_hal.h index 2bb7631efa..d87242cdd5 100644 --- a/wifi/1.5/default/wifi_legacy_hal.h +++ b/wifi/1.6/default/wifi_legacy_hal.h @@ -29,7 +29,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { // This is in a separate namespace to prevent typename conflicts between // the legacy HAL types and the HIDL interface types. @@ -366,63 +366,53 @@ struct WakeReasonStats { // NAN response and event callbacks struct. struct NanCallbackHandlers { // NotifyResponse invoked to notify the status of the Request. - std::function<void(transaction_id, const NanResponseMsg&)> - on_notify_response; + std::function<void(transaction_id, const NanResponseMsg&)> on_notify_response; // Various event callbacks. - std::function<void(const NanPublishTerminatedInd&)> - on_event_publish_terminated; + std::function<void(const NanPublishTerminatedInd&)> on_event_publish_terminated; std::function<void(const NanMatchInd&)> on_event_match; std::function<void(const NanMatchExpiredInd&)> on_event_match_expired; - std::function<void(const NanSubscribeTerminatedInd&)> - on_event_subscribe_terminated; + std::function<void(const NanSubscribeTerminatedInd&)> on_event_subscribe_terminated; std::function<void(const NanFollowupInd&)> on_event_followup; std::function<void(const NanDiscEngEventInd&)> on_event_disc_eng_event; std::function<void(const NanDisabledInd&)> on_event_disabled; std::function<void(const NanTCAInd&)> on_event_tca; - std::function<void(const NanBeaconSdfPayloadInd&)> - on_event_beacon_sdf_payload; - std::function<void(const NanDataPathRequestInd&)> - on_event_data_path_request; - std::function<void(const NanDataPathConfirmInd&)> - on_event_data_path_confirm; + std::function<void(const NanBeaconSdfPayloadInd&)> on_event_beacon_sdf_payload; + std::function<void(const NanDataPathRequestInd&)> on_event_data_path_request; + std::function<void(const NanDataPathConfirmInd&)> on_event_data_path_confirm; std::function<void(const NanDataPathEndInd&)> on_event_data_path_end; - std::function<void(const NanTransmitFollowupInd&)> - on_event_transmit_follow_up; + std::function<void(const NanTransmitFollowupInd&)> on_event_transmit_follow_up; std::function<void(const NanRangeRequestInd&)> on_event_range_request; std::function<void(const NanRangeReportInd&)> on_event_range_report; - std::function<void(const NanDataPathScheduleUpdateInd&)> - on_event_schedule_update; + std::function<void(const NanDataPathScheduleUpdateInd&)> on_event_schedule_update; }; // Full scan results contain IE info and are hence passed by reference, to // preserve the variable length array member |ie_data|. Callee must not retain // the pointer. using on_gscan_full_result_callback = - std::function<void(wifi_request_id, const wifi_scan_result*, uint32_t)>; + std::function<void(wifi_request_id, const wifi_scan_result*, uint32_t)>; // These scan results don't contain any IE info, so no need to pass by // reference. -using on_gscan_results_callback = std::function<void( - wifi_request_id, const std::vector<wifi_cached_scan_results>&)>; +using on_gscan_results_callback = + std::function<void(wifi_request_id, const std::vector<wifi_cached_scan_results>&)>; // Invoked when the rssi value breaches the thresholds set. using on_rssi_threshold_breached_callback = - std::function<void(wifi_request_id, std::array<uint8_t, 6>, int8_t)>; + std::function<void(wifi_request_id, std::array<uint8_t, 6>, int8_t)>; // Callback for RTT range request results. // Rtt results contain IE info and are hence passed by reference, to // preserve the |LCI| and |LCR| pointers. Callee must not retain // the pointer. -using on_rtt_results_callback = std::function<void( - wifi_request_id, const std::vector<const wifi_rtt_result*>&)>; +using on_rtt_results_callback = + std::function<void(wifi_request_id, const std::vector<const wifi_rtt_result*>&)>; // Callback for ring buffer data. -using on_ring_buffer_data_callback = - std::function<void(const std::string&, const std::vector<uint8_t>&, - const wifi_ring_buffer_status&)>; +using on_ring_buffer_data_callback = std::function<void( + const std::string&, const std::vector<uint8_t>&, const wifi_ring_buffer_status&)>; // Callback for alerts. -using on_error_alert_callback = - std::function<void(int32_t, const std::vector<uint8_t>&)>; +using on_error_alert_callback = std::function<void(int32_t, const std::vector<uint8_t>&)>; // Callback for subsystem restart using on_subsystem_restart_callback = std::function<void(const std::string&)>; @@ -443,8 +433,7 @@ typedef struct { } WifiMacInfo; // Callback for radio mode change -using on_radio_mode_change_callback = - std::function<void(const std::vector<WifiMacInfo>&)>; +using on_radio_mode_change_callback = std::function<void(const std::vector<WifiMacInfo>&)>; // TWT response and event callbacks struct. struct TwtCallbackHandlers { @@ -466,9 +455,9 @@ struct TwtCallbackHandlers { * object and will be valid for the lifetime of the process. */ class WifiLegacyHal { - public: - WifiLegacyHal(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool, - const wifi_hal_fn& fn, bool is_primary); + public: + WifiLegacyHal(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool, const wifi_hal_fn& fn, + bool is_primary); virtual ~WifiLegacyHal() = default; // Initialize the legacy HAL function table. @@ -483,26 +472,22 @@ class WifiLegacyHal { // Checks if legacy HAL has successfully started bool isStarted(); // Wrappers for all the functions in the legacy HAL function table. - virtual std::pair<wifi_error, std::string> getDriverVersion( - const std::string& iface_name); - virtual std::pair<wifi_error, std::string> getFirmwareVersion( - const std::string& iface_name); + virtual std::pair<wifi_error, std::string> getDriverVersion(const std::string& iface_name); + virtual std::pair<wifi_error, std::string> getFirmwareVersion(const std::string& iface_name); std::pair<wifi_error, std::vector<uint8_t>> requestDriverMemoryDump( - const std::string& iface_name); + const std::string& iface_name); std::pair<wifi_error, std::vector<uint8_t>> requestFirmwareMemoryDump( - const std::string& iface_name); - std::pair<wifi_error, uint64_t> getSupportedFeatureSet( - const std::string& iface_name); + const std::string& iface_name); + std::pair<wifi_error, uint64_t> getSupportedFeatureSet(const std::string& iface_name); // APF functions. std::pair<wifi_error, PacketFilterCapabilities> getPacketFilterCapabilities( - const std::string& iface_name); - wifi_error setPacketFilter(const std::string& iface_name, - const std::vector<uint8_t>& program); + const std::string& iface_name); + wifi_error setPacketFilter(const std::string& iface_name, const std::vector<uint8_t>& program); std::pair<wifi_error, std::vector<uint8_t>> readApfPacketFilterData( - const std::string& iface_name); + const std::string& iface_name); // Gscan functions. std::pair<wifi_error, wifi_gscan_capabilities> getGscanCapabilities( - const std::string& iface_name); + const std::string& iface_name); // These API's provides a simplified interface over the legacy Gscan API's: // a) All scan events from the legacy HAL API other than the // |WIFI_SCAN_FAILED| are treated as notification of results. @@ -514,162 +499,121 @@ class WifiLegacyHal { // triggers the externally provided |on_failure_user_callback|. // c) Full scan result event triggers the externally provided // |on_full_result_user_callback|. - wifi_error startGscan( - const std::string& iface_name, wifi_request_id id, - const wifi_scan_cmd_params& params, - const std::function<void(wifi_request_id)>& on_failure_callback, - const on_gscan_results_callback& on_results_callback, - const on_gscan_full_result_callback& on_full_result_callback); + wifi_error startGscan(const std::string& iface_name, wifi_request_id id, + const wifi_scan_cmd_params& params, + const std::function<void(wifi_request_id)>& on_failure_callback, + const on_gscan_results_callback& on_results_callback, + const on_gscan_full_result_callback& on_full_result_callback); wifi_error stopGscan(const std::string& iface_name, wifi_request_id id); std::pair<wifi_error, std::vector<uint32_t>> getValidFrequenciesForBand( - const std::string& iface_name, wifi_band band); + const std::string& iface_name, wifi_band band); virtual wifi_error setDfsFlag(const std::string& iface_name, bool dfs_on); // Link layer stats functions. wifi_error enableLinkLayerStats(const std::string& iface_name, bool debug); wifi_error disableLinkLayerStats(const std::string& iface_name); - std::pair<wifi_error, LinkLayerStats> getLinkLayerStats( - const std::string& iface_name); + std::pair<wifi_error, LinkLayerStats> getLinkLayerStats(const std::string& iface_name); // RSSI monitor functions. - wifi_error startRssiMonitoring(const std::string& iface_name, - wifi_request_id id, int8_t max_rssi, - int8_t min_rssi, - const on_rssi_threshold_breached_callback& - on_threshold_breached_callback); - wifi_error stopRssiMonitoring(const std::string& iface_name, - wifi_request_id id); + wifi_error startRssiMonitoring( + const std::string& iface_name, wifi_request_id id, int8_t max_rssi, int8_t min_rssi, + const on_rssi_threshold_breached_callback& on_threshold_breached_callback); + wifi_error stopRssiMonitoring(const std::string& iface_name, wifi_request_id id); std::pair<wifi_error, wifi_roaming_capabilities> getRoamingCapabilities( - const std::string& iface_name); - wifi_error configureRoaming(const std::string& iface_name, - const wifi_roaming_config& config); - wifi_error enableFirmwareRoaming(const std::string& iface_name, - fw_roaming_state_t state); + const std::string& iface_name); + wifi_error configureRoaming(const std::string& iface_name, const wifi_roaming_config& config); + wifi_error enableFirmwareRoaming(const std::string& iface_name, fw_roaming_state_t state); wifi_error configureNdOffload(const std::string& iface_name, bool enable); - wifi_error startSendingOffloadedPacket( - const std::string& iface_name, uint32_t cmd_id, uint16_t ether_type, - const std::vector<uint8_t>& ip_packet_data, - const std::array<uint8_t, 6>& src_address, - const std::array<uint8_t, 6>& dst_address, uint32_t period_in_ms); - wifi_error stopSendingOffloadedPacket(const std::string& iface_name, - uint32_t cmd_id); + wifi_error startSendingOffloadedPacket(const std::string& iface_name, uint32_t cmd_id, + uint16_t ether_type, + const std::vector<uint8_t>& ip_packet_data, + const std::array<uint8_t, 6>& src_address, + const std::array<uint8_t, 6>& dst_address, + uint32_t period_in_ms); + wifi_error stopSendingOffloadedPacket(const std::string& iface_name, uint32_t cmd_id); virtual wifi_error selectTxPowerScenario(const std::string& iface_name, wifi_power_scenario scenario); virtual wifi_error resetTxPowerScenario(const std::string& iface_name); - wifi_error setLatencyMode(const std::string& iface_name, - wifi_latency_mode mode); - wifi_error setThermalMitigationMode(wifi_thermal_mode mode, - uint32_t completion_window); + wifi_error setLatencyMode(const std::string& iface_name, wifi_latency_mode mode); + wifi_error setThermalMitigationMode(wifi_thermal_mode mode, uint32_t completion_window); wifi_error setDscpToAccessCategoryMapping(uint32_t start, uint32_t end, uint32_t access_category); wifi_error resetDscpToAccessCategoryMapping(); // Logger/debug functions. - std::pair<wifi_error, uint32_t> getLoggerSupportedFeatureSet( - const std::string& iface_name); + std::pair<wifi_error, uint32_t> getLoggerSupportedFeatureSet(const std::string& iface_name); wifi_error startPktFateMonitoring(const std::string& iface_name); - std::pair<wifi_error, std::vector<wifi_tx_report>> getTxPktFates( - const std::string& iface_name); - std::pair<wifi_error, std::vector<wifi_rx_report>> getRxPktFates( - const std::string& iface_name); - std::pair<wifi_error, WakeReasonStats> getWakeReasonStats( - const std::string& iface_name); + std::pair<wifi_error, std::vector<wifi_tx_report>> getTxPktFates(const std::string& iface_name); + std::pair<wifi_error, std::vector<wifi_rx_report>> getRxPktFates(const std::string& iface_name); + std::pair<wifi_error, WakeReasonStats> getWakeReasonStats(const std::string& iface_name); wifi_error registerRingBufferCallbackHandler( - const std::string& iface_name, - const on_ring_buffer_data_callback& on_data_callback); - wifi_error deregisterRingBufferCallbackHandler( - const std::string& iface_name); + const std::string& iface_name, const on_ring_buffer_data_callback& on_data_callback); + wifi_error deregisterRingBufferCallbackHandler(const std::string& iface_name); wifi_error registerSubsystemRestartCallbackHandler( - const on_subsystem_restart_callback& on_restart_callback); - std::pair<wifi_error, std::vector<wifi_ring_buffer_status>> - getRingBuffersStatus(const std::string& iface_name); - wifi_error startRingBufferLogging(const std::string& iface_name, - const std::string& ring_name, - uint32_t verbose_level, - uint32_t max_interval_sec, + const on_subsystem_restart_callback& on_restart_callback); + std::pair<wifi_error, std::vector<wifi_ring_buffer_status>> getRingBuffersStatus( + const std::string& iface_name); + wifi_error startRingBufferLogging(const std::string& iface_name, const std::string& ring_name, + uint32_t verbose_level, uint32_t max_interval_sec, uint32_t min_data_size); - wifi_error getRingBufferData(const std::string& iface_name, - const std::string& ring_name); - wifi_error registerErrorAlertCallbackHandler( - const std::string& iface_name, - const on_error_alert_callback& on_alert_callback); - wifi_error deregisterErrorAlertCallbackHandler( - const std::string& iface_name); + wifi_error getRingBufferData(const std::string& iface_name, const std::string& ring_name); + wifi_error registerErrorAlertCallbackHandler(const std::string& iface_name, + const on_error_alert_callback& on_alert_callback); + wifi_error deregisterErrorAlertCallbackHandler(const std::string& iface_name); // Radio mode functions. virtual wifi_error registerRadioModeChangeCallbackHandler( - const std::string& iface_name, - const on_radio_mode_change_callback& on_user_change_callback); + const std::string& iface_name, + const on_radio_mode_change_callback& on_user_change_callback); // RTT functions. - wifi_error startRttRangeRequest( - const std::string& iface_name, wifi_request_id id, - const std::vector<wifi_rtt_config>& rtt_configs, - const on_rtt_results_callback& on_results_callback); - wifi_error cancelRttRangeRequest( - const std::string& iface_name, wifi_request_id id, - const std::vector<std::array<uint8_t, 6>>& mac_addrs); - std::pair<wifi_error, wifi_rtt_capabilities> getRttCapabilities( - const std::string& iface_name); - std::pair<wifi_error, wifi_rtt_responder> getRttResponderInfo( - const std::string& iface_name); - wifi_error enableRttResponder(const std::string& iface_name, - wifi_request_id id, - const wifi_channel_info& channel_hint, - uint32_t max_duration_secs, + wifi_error startRttRangeRequest(const std::string& iface_name, wifi_request_id id, + const std::vector<wifi_rtt_config>& rtt_configs, + const on_rtt_results_callback& on_results_callback); + wifi_error cancelRttRangeRequest(const std::string& iface_name, wifi_request_id id, + const std::vector<std::array<uint8_t, 6>>& mac_addrs); + std::pair<wifi_error, wifi_rtt_capabilities> getRttCapabilities(const std::string& iface_name); + std::pair<wifi_error, wifi_rtt_responder> getRttResponderInfo(const std::string& iface_name); + wifi_error enableRttResponder(const std::string& iface_name, wifi_request_id id, + const wifi_channel_info& channel_hint, uint32_t max_duration_secs, const wifi_rtt_responder& info); - wifi_error disableRttResponder(const std::string& iface_name, - wifi_request_id id); + wifi_error disableRttResponder(const std::string& iface_name, wifi_request_id id); wifi_error setRttLci(const std::string& iface_name, wifi_request_id id, const wifi_lci_information& info); wifi_error setRttLcr(const std::string& iface_name, wifi_request_id id, const wifi_lcr_information& info); // NAN functions. - virtual wifi_error nanRegisterCallbackHandlers( - const std::string& iface_name, const NanCallbackHandlers& callbacks); - wifi_error nanEnableRequest(const std::string& iface_name, - transaction_id id, const NanEnableRequest& msg); - virtual wifi_error nanDisableRequest(const std::string& iface_name, - transaction_id id); - wifi_error nanPublishRequest(const std::string& iface_name, - transaction_id id, + virtual wifi_error nanRegisterCallbackHandlers(const std::string& iface_name, + const NanCallbackHandlers& callbacks); + wifi_error nanEnableRequest(const std::string& iface_name, transaction_id id, + const NanEnableRequest& msg); + virtual wifi_error nanDisableRequest(const std::string& iface_name, transaction_id id); + wifi_error nanPublishRequest(const std::string& iface_name, transaction_id id, const NanPublishRequest& msg); - wifi_error nanPublishCancelRequest(const std::string& iface_name, - transaction_id id, + wifi_error nanPublishCancelRequest(const std::string& iface_name, transaction_id id, const NanPublishCancelRequest& msg); - wifi_error nanSubscribeRequest(const std::string& iface_name, - transaction_id id, + wifi_error nanSubscribeRequest(const std::string& iface_name, transaction_id id, const NanSubscribeRequest& msg); - wifi_error nanSubscribeCancelRequest(const std::string& iface_name, - transaction_id id, + wifi_error nanSubscribeCancelRequest(const std::string& iface_name, transaction_id id, const NanSubscribeCancelRequest& msg); - wifi_error nanTransmitFollowupRequest( - const std::string& iface_name, transaction_id id, - const NanTransmitFollowupRequest& msg); + wifi_error nanTransmitFollowupRequest(const std::string& iface_name, transaction_id id, + const NanTransmitFollowupRequest& msg); wifi_error nanStatsRequest(const std::string& iface_name, transaction_id id, const NanStatsRequest& msg); - wifi_error nanConfigRequest(const std::string& iface_name, - transaction_id id, const NanConfigRequest& msg); + wifi_error nanConfigRequest(const std::string& iface_name, transaction_id id, + const NanConfigRequest& msg); wifi_error nanTcaRequest(const std::string& iface_name, transaction_id id, const NanTCARequest& msg); - wifi_error nanBeaconSdfPayloadRequest( - const std::string& iface_name, transaction_id id, - const NanBeaconSdfPayloadRequest& msg); + wifi_error nanBeaconSdfPayloadRequest(const std::string& iface_name, transaction_id id, + const NanBeaconSdfPayloadRequest& msg); std::pair<wifi_error, NanVersion> nanGetVersion(); - wifi_error nanGetCapabilities(const std::string& iface_name, - transaction_id id); - wifi_error nanDataInterfaceCreate(const std::string& iface_name, - transaction_id id, + wifi_error nanGetCapabilities(const std::string& iface_name, transaction_id id); + wifi_error nanDataInterfaceCreate(const std::string& iface_name, transaction_id id, const std::string& data_iface_name); - virtual wifi_error nanDataInterfaceDelete( - const std::string& iface_name, transaction_id id, - const std::string& data_iface_name); - wifi_error nanDataRequestInitiator(const std::string& iface_name, - transaction_id id, + virtual wifi_error nanDataInterfaceDelete(const std::string& iface_name, transaction_id id, + const std::string& data_iface_name); + wifi_error nanDataRequestInitiator(const std::string& iface_name, transaction_id id, const NanDataPathInitiatorRequest& msg); - wifi_error nanDataIndicationResponse( - const std::string& iface_name, transaction_id id, - const NanDataPathIndicationResponse& msg); - wifi_error nanDataEnd(const std::string& iface_name, transaction_id id, - uint32_t ndpInstanceId); + wifi_error nanDataIndicationResponse(const std::string& iface_name, transaction_id id, + const NanDataPathIndicationResponse& msg); + wifi_error nanDataEnd(const std::string& iface_name, transaction_id id, uint32_t ndpInstanceId); // AP functions. - wifi_error setCountryCode(const std::string& iface_name, - std::array<int8_t, 2> code); + wifi_error setCountryCode(const std::string& iface_name, std::array<int8_t, 2> code); // interface functions. virtual wifi_error createVirtualInterface(const std::string& ifname, @@ -682,43 +626,36 @@ class WifiLegacyHal { virtual wifi_error multiStaSetUseCase(wifi_multi_sta_use_case use_case); // Coex functions. - virtual wifi_error setCoexUnsafeChannels( - std::vector<wifi_coex_unsafe_channel> unsafe_channels, - uint32_t restrictions); + virtual wifi_error setCoexUnsafeChannels(std::vector<wifi_coex_unsafe_channel> unsafe_channels, + uint32_t restrictions); wifi_error setVoipMode(const std::string& iface_name, wifi_voip_mode mode); wifi_error twtRegisterHandler(const std::string& iface_name, const TwtCallbackHandlers& handler); - std::pair<wifi_error, TwtCapabilitySet> twtGetCapability( - const std::string& iface_name); + std::pair<wifi_error, TwtCapabilitySet> twtGetCapability(const std::string& iface_name); - wifi_error twtSetupRequest(const std::string& iface_name, - const TwtSetupRequest& msg); + wifi_error twtSetupRequest(const std::string& iface_name, const TwtSetupRequest& msg); - wifi_error twtTearDownRequest(const std::string& iface_name, - const TwtTeardownRequest& msg); + wifi_error twtTearDownRequest(const std::string& iface_name, const TwtTeardownRequest& msg); - wifi_error twtInfoFrameRequest(const std::string& iface_name, - const TwtInfoFrameRequest& msg); + wifi_error twtInfoFrameRequest(const std::string& iface_name, const TwtInfoFrameRequest& msg); - std::pair<wifi_error, TwtStats> twtGetStats(const std::string& iface_name, - uint8_t configId); + std::pair<wifi_error, TwtStats> twtGetStats(const std::string& iface_name, uint8_t configId); wifi_error twtClearStats(const std::string& iface_name, uint8_t configId); - wifi_error setDtimConfig(const std::string& iface_name, - uint32_t multiplier); + wifi_error setDtimConfig(const std::string& iface_name, uint32_t multiplier); // Retrieve the list of usable channels in the requested bands // for the requested modes std::pair<wifi_error, std::vector<wifi_usable_channel>> getUsableChannels( - uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask); + uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask); wifi_error triggerSubsystemRestart(); - private: + private: // Retrieve interface handles for all the available interfaces. wifi_error retrieveIfaceHandles(); wifi_interface_handle getIfaceHandle(const std::string& iface_name); @@ -726,12 +663,12 @@ class WifiLegacyHal { void runEventLoop(); // Retrieve the cached gscan results to pass the results back to the // external callbacks. - std::pair<wifi_error, std::vector<wifi_cached_scan_results>> - getGscanCachedResults(const std::string& iface_name); + std::pair<wifi_error, std::vector<wifi_cached_scan_results>> getGscanCachedResults( + const std::string& iface_name); void invalidate(); // Handles wifi (error) status of Virtual interface create/delete - wifi_error handleVirtualInterfaceCreateOrDeleteStatus( - const std::string& ifname, wifi_error status); + wifi_error handleVirtualInterfaceCreateOrDeleteStatus(const std::string& ifname, + wifi_error status); // Global function table of legacy HAL. wifi_hal_fn global_func_table_; @@ -755,7 +692,7 @@ class WifiLegacyHal { } // namespace legacy_hal } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/wifi_legacy_hal_factory.cpp b/wifi/1.6/default/wifi_legacy_hal_factory.cpp index fbaa284f56..147bf4d7cc 100644 --- a/wifi/1.5/default/wifi_legacy_hal_factory.cpp +++ b/wifi/1.6/default/wifi_legacy_hal_factory.cpp @@ -62,22 +62,20 @@ bool isFileExtension(const char* name, const char* ext) { namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace legacy_hal { WifiLegacyHalFactory::WifiLegacyHalFactory( - const std::weak_ptr<wifi_system::InterfaceTool> iface_tool) + const std::weak_ptr<wifi_system::InterfaceTool> iface_tool) : iface_tool_(iface_tool) {} std::vector<std::shared_ptr<WifiLegacyHal>> WifiLegacyHalFactory::getHals() { if (legacy_hals_.empty()) { - if (!initVendorHalDescriptorFromLinked()) - initVendorHalsDescriptorList(); + if (!initVendorHalDescriptorFromLinked()) initVendorHalsDescriptorList(); for (auto& desc : descs_) { std::shared_ptr<WifiLegacyHal> hal = - std::make_shared<WifiLegacyHal>(iface_tool_, desc.fn, - desc.primary); + std::make_shared<WifiLegacyHal>(iface_tool_, desc.fn, desc.primary); legacy_hals_.push_back(hal); } } @@ -99,8 +97,8 @@ bool WifiLegacyHalFactory::initVendorHalDescriptorFromLinked() { bool WifiLegacyHalFactory::initLinkedHalFunctionTable(wifi_hal_fn* hal_fn) { init_wifi_vendor_hal_func_table_t initfn; - initfn = (init_wifi_vendor_hal_func_table_t)dlsym( - RTLD_DEFAULT, "init_wifi_vendor_hal_func_table"); + initfn = (init_wifi_vendor_hal_func_table_t)dlsym(RTLD_DEFAULT, + "init_wifi_vendor_hal_func_table"); if (!initfn) { LOG(INFO) << "no vendor HAL library linked, will try dynamic load"; return false; @@ -136,8 +134,7 @@ void WifiLegacyHalFactory::initVendorHalsDescriptorList() { xmlChar* value; wifi_hal_lib_desc desc; - LOG(INFO) << "processing vendor HALs descriptions in " - << kVendorHalsDescPath; + LOG(INFO) << "processing vendor HALs descriptions in " << kVendorHalsDescPath; DIR* dirPtr = ::opendir(kVendorHalsDescPath); if (dirPtr == NULL) { LOG(ERROR) << "failed to open " << kVendorHalsDescPath; @@ -157,26 +154,23 @@ void WifiLegacyHalFactory::initVendorHalsDescriptorList() { fullPath.append(entryPtr->d_name); xml = xmlReadFile(fullPath.c_str(), "UTF-8", XML_PARSE_RECOVER); if (!xml) { - LOG(ERROR) << "failed to parse: " << entryPtr->d_name - << " skipping..."; + LOG(ERROR) << "failed to parse: " << entryPtr->d_name << " skipping..."; continue; } node = xmlDocGetRootElement(xml); if (!node) { - LOG(ERROR) << "empty config file: " << entryPtr->d_name - << " skipping..."; + LOG(ERROR) << "empty config file: " << entryPtr->d_name << " skipping..."; goto skip; } if (xmlStrcmp(node->name, BAD_CAST "WifiVendorHal")) { - LOG(ERROR) << "bad config, root element not WifiVendorHal: " - << entryPtr->d_name << " skipping..."; + LOG(ERROR) << "bad config, root element not WifiVendorHal: " << entryPtr->d_name + << " skipping..."; goto skip; } version = (char*)xmlGetProp(node, BAD_CAST "version"); if (!version || strtoul(version, NULL, 0) != kVendorHalsDescVersion) { LOG(ERROR) << "conf file: " << entryPtr->d_name - << "must have version: " << kVendorHalsDescVersion - << ", skipping..."; + << "must have version: " << kVendorHalsDescVersion << ", skipping..."; goto skip; } cnode = node->children; @@ -195,8 +189,8 @@ void WifiLegacyHalFactory::initVendorHalsDescriptorList() { cnode = cnode->next; } if (path.empty()) { - LOG(ERROR) << "hal library path not provided in: " - << entryPtr->d_name << ", skipping..."; + LOG(ERROR) << "hal library path not provided in: " << entryPtr->d_name + << ", skipping..."; goto skip; } if (loadVendorHalLib(path, desc)) { @@ -211,8 +205,7 @@ void WifiLegacyHalFactory::initVendorHalsDescriptorList() { ::closedir(dirPtr); } -bool WifiLegacyHalFactory::loadVendorHalLib(const std::string& path, - wifi_hal_lib_desc& desc) { +bool WifiLegacyHalFactory::loadVendorHalLib(const std::string& path, wifi_hal_lib_desc& desc) { void* h = dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL); init_wifi_vendor_hal_func_table_t initfn; wifi_error res; @@ -221,8 +214,7 @@ bool WifiLegacyHalFactory::loadVendorHalLib(const std::string& path, LOG(ERROR) << "failed to open vendor hal library: " << path; return false; } - initfn = (init_wifi_vendor_hal_func_table_t)dlsym( - h, "init_wifi_vendor_hal_func_table"); + initfn = (init_wifi_vendor_hal_func_table_t)dlsym(h, "init_wifi_vendor_hal_func_table"); if (!initfn) { LOG(ERROR) << "init_wifi_vendor_hal_func_table not found in: " << path; goto out_err; @@ -243,8 +235,7 @@ bool WifiLegacyHalFactory::loadVendorHalLib(const std::string& path, // vendor HALs which do not implement early_initialize will return // WIFI_ERROR_NOT_SUPPORTED, treat this as success. if (res != WIFI_SUCCESS && res != WIFI_ERROR_NOT_SUPPORTED) { - LOG(ERROR) << "early initialization failed in: " << path - << " error: " << res; + LOG(ERROR) << "early initialization failed in: " << path << " error: " << res; goto out_err; } @@ -257,7 +248,7 @@ out_err: } // namespace legacy_hal } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/wifi_legacy_hal_factory.h b/wifi/1.6/default/wifi_legacy_hal_factory.h index e3440faff2..9f4423efb7 100644 --- a/wifi/1.5/default/wifi_legacy_hal_factory.h +++ b/wifi/1.6/default/wifi_legacy_hal_factory.h @@ -24,7 +24,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { // This is in a separate namespace to prevent typename conflicts between // the legacy HAL types and the HIDL interface types. @@ -33,14 +33,13 @@ namespace legacy_hal { * Class that creates WifiLegacyHal objects for vendor HALs in the system. */ class WifiLegacyHalFactory { - public: - WifiLegacyHalFactory( - const std::weak_ptr<wifi_system::InterfaceTool> iface_tool); + public: + WifiLegacyHalFactory(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool); virtual ~WifiLegacyHalFactory() = default; std::vector<std::shared_ptr<WifiLegacyHal>> getHals(); - private: + private: typedef struct { wifi_hal_fn fn; bool primary; @@ -59,7 +58,7 @@ class WifiLegacyHalFactory { } // namespace legacy_hal } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp b/wifi/1.6/default/wifi_legacy_hal_stubs.cpp index dd860d6920..e03e1ae1a1 100644 --- a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp +++ b/wifi/1.6/default/wifi_legacy_hal_stubs.cpp @@ -20,7 +20,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace legacy_hal { template <typename> @@ -165,7 +165,7 @@ bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) { } } // namespace legacy_hal } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/wifi_legacy_hal_stubs.h b/wifi/1.6/default/wifi_legacy_hal_stubs.h index 480389b0ce..c9a03bf4c9 100644 --- a/wifi/1.5/default/wifi_legacy_hal_stubs.h +++ b/wifi/1.6/default/wifi_legacy_hal_stubs.h @@ -22,14 +22,14 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace legacy_hal { bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn); } // namespace legacy_hal } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/wifi_mode_controller.cpp b/wifi/1.6/default/wifi_mode_controller.cpp index b1db8b3725..4b8ac7dd1c 100644 --- a/wifi/1.5/default/wifi_mode_controller.cpp +++ b/wifi/1.6/default/wifi_mode_controller.cpp @@ -48,15 +48,14 @@ int convertIfaceTypeToFirmwareMode(IfaceType type) { namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace mode_controller { WifiModeController::WifiModeController() : driver_tool_(new DriverTool) {} bool WifiModeController::isFirmwareModeChangeNeeded(IfaceType type) { - return driver_tool_->IsFirmwareModeChangeNeeded( - convertIfaceTypeToFirmwareMode(type)); + return driver_tool_->IsFirmwareModeChangeNeeded(convertIfaceTypeToFirmwareMode(type)); } bool WifiModeController::initialize() { @@ -68,8 +67,7 @@ bool WifiModeController::initialize() { } bool WifiModeController::changeFirmwareMode(IfaceType type) { - if (!driver_tool_->ChangeFirmwareMode( - convertIfaceTypeToFirmwareMode(type))) { + if (!driver_tool_->ChangeFirmwareMode(convertIfaceTypeToFirmwareMode(type))) { LOG(ERROR) << "Failed to change firmware mode"; return false; } @@ -85,7 +83,7 @@ bool WifiModeController::deinitialize() { } } // namespace mode_controller } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/wifi_mode_controller.h b/wifi/1.6/default/wifi_mode_controller.h index 2eeca78c8b..fee2b66d4e 100644 --- a/wifi/1.5/default/wifi_mode_controller.h +++ b/wifi/1.6/default/wifi_mode_controller.h @@ -24,7 +24,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { namespace mode_controller { using namespace android::hardware::wifi::V1_0; @@ -35,7 +35,7 @@ using namespace android::hardware::wifi::V1_0; * required state (essentially a wrapper over DriverTool). */ class WifiModeController { - public: + public: WifiModeController(); virtual ~WifiModeController() = default; @@ -49,13 +49,13 @@ class WifiModeController { // invoked. virtual bool deinitialize(); - private: + private: std::unique_ptr<wifi_hal::DriverTool> driver_tool_; }; } // namespace mode_controller } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.6/default/wifi_nan_iface.cpp b/wifi/1.6/default/wifi_nan_iface.cpp new file mode 100644 index 0000000000..236cb64e32 --- /dev/null +++ b/wifi/1.6/default/wifi_nan_iface.cpp @@ -0,0 +1,905 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <android-base/logging.h> + +#include "hidl_return_util.h" +#include "hidl_struct_util.h" +#include "wifi_nan_iface.h" +#include "wifi_status_util.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +using hidl_return_util::validateAndCall; + +WifiNanIface::WifiNanIface(const std::string& ifname, bool is_dedicated_iface, + const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal, + const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util) + : ifname_(ifname), + is_dedicated_iface_(is_dedicated_iface), + legacy_hal_(legacy_hal), + iface_util_(iface_util), + is_valid_(true) { + if (is_dedicated_iface_) { + // If using a dedicated iface, set the iface up first. + if (!iface_util_.lock()->setUpState(ifname_, true)) { + // Fatal failure, invalidate the iface object. + invalidate(); + return; + } + } + // Register all the callbacks here. these should be valid for the lifetime + // of the object. Whenever the mode changes legacy HAL will remove + // all of these callbacks. + legacy_hal::NanCallbackHandlers callback_handlers; + android::wp<WifiNanIface> weak_ptr_this(this); + + // Callback for response. + callback_handlers.on_notify_response = [weak_ptr_this](legacy_hal::transaction_id id, + const legacy_hal::NanResponseMsg& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + WifiNanStatus wifiNanStatus; + if (!hidl_struct_util::convertLegacyNanResponseHeaderToHidl(msg, &wifiNanStatus)) { + LOG(ERROR) << "Failed to convert nan response header"; + return; + } + + switch (msg.response_type) { + case legacy_hal::NAN_RESPONSE_ENABLED: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyEnableResponse(id, wifiNanStatus).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_RESPONSE_DISABLED: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyDisableResponse(id, wifiNanStatus).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_RESPONSE_PUBLISH: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyStartPublishResponse(id, wifiNanStatus, + msg.body.publish_response.publish_id) + .isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_RESPONSE_PUBLISH_CANCEL: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyStopPublishResponse(id, wifiNanStatus).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_RESPONSE_TRANSMIT_FOLLOWUP: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyTransmitFollowupResponse(id, wifiNanStatus).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_RESPONSE_SUBSCRIBE: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyStartSubscribeResponse( + id, wifiNanStatus, + msg.body.subscribe_response.subscribe_id) + .isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_RESPONSE_SUBSCRIBE_CANCEL: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyStopSubscribeResponse(id, wifiNanStatus).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_RESPONSE_CONFIG: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyConfigResponse(id, wifiNanStatus).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_GET_CAPABILITIES: { + V1_5::NanCapabilities hidl_struct; + if (!hidl_struct_util::convertLegacyNanCapabilitiesResponseToHidl( + msg.body.nan_capabilities, &hidl_struct)) { + LOG(ERROR) << "Failed to convert nan capabilities response"; + return; + } + for (const auto& callback : shared_ptr_this->getEventCallbacks_1_5()) { + if (!callback->notifyCapabilitiesResponse_1_5(id, wifiNanStatus, hidl_struct) + .isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_DP_INTERFACE_CREATE: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyCreateDataInterfaceResponse(id, wifiNanStatus).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_DP_INTERFACE_DELETE: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyDeleteDataInterfaceResponse(id, wifiNanStatus).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_DP_INITIATOR_RESPONSE: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyInitiateDataPathResponse( + id, wifiNanStatus, + msg.body.data_request_response.ndp_instance_id) + .isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_DP_RESPONDER_RESPONSE: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyRespondToDataPathIndicationResponse(id, wifiNanStatus) + .isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_DP_END: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyTerminateDataPathResponse(id, wifiNanStatus).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_RESPONSE_BEACON_SDF_PAYLOAD: + /* fall through */ + case legacy_hal::NAN_RESPONSE_TCA: + /* fall through */ + case legacy_hal::NAN_RESPONSE_STATS: + /* fall through */ + case legacy_hal::NAN_RESPONSE_ERROR: + /* fall through */ + default: + LOG(ERROR) << "Unknown or unhandled response type: " << msg.response_type; + return; + } + }; + + callback_handlers.on_event_disc_eng_event = + [weak_ptr_this](const legacy_hal::NanDiscEngEventInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + NanClusterEventInd hidl_struct; + // event types defined identically - hence can be cast + hidl_struct.eventType = (NanClusterEventType)msg.event_type; + hidl_struct.addr = msg.data.mac_addr.addr; + + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->eventClusterEvent(hidl_struct).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + + callback_handlers.on_event_disabled = [weak_ptr_this](const legacy_hal::NanDisabledInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + WifiNanStatus status; + hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason, sizeof(msg.nan_reason), + &status); + + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->eventDisabled(status).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + + callback_handlers.on_event_publish_terminated = + [weak_ptr_this](const legacy_hal::NanPublishTerminatedInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + WifiNanStatus status; + hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason, + sizeof(msg.nan_reason), &status); + + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->eventPublishTerminated(msg.publish_id, status).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + + callback_handlers.on_event_subscribe_terminated = + [weak_ptr_this](const legacy_hal::NanSubscribeTerminatedInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + WifiNanStatus status; + hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason, + sizeof(msg.nan_reason), &status); + + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->eventSubscribeTerminated(msg.subscribe_id, status).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + + callback_handlers.on_event_match = [weak_ptr_this](const legacy_hal::NanMatchInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + NanMatchInd hidl_struct; + if (!hidl_struct_util::convertLegacyNanMatchIndToHidl(msg, &hidl_struct)) { + LOG(ERROR) << "Failed to convert nan capabilities response"; + return; + } + + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->eventMatch(hidl_struct).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + + callback_handlers.on_event_match_expired = [weak_ptr_this]( + const legacy_hal::NanMatchExpiredInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->eventMatchExpired(msg.publish_subscribe_id, msg.requestor_instance_id) + .isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + + callback_handlers.on_event_followup = [weak_ptr_this](const legacy_hal::NanFollowupInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + NanFollowupReceivedInd hidl_struct; + if (!hidl_struct_util::convertLegacyNanFollowupIndToHidl(msg, &hidl_struct)) { + LOG(ERROR) << "Failed to convert nan capabilities response"; + return; + } + + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->eventFollowupReceived(hidl_struct).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + + callback_handlers.on_event_transmit_follow_up = + [weak_ptr_this](const legacy_hal::NanTransmitFollowupInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + WifiNanStatus status; + hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason, + sizeof(msg.nan_reason), &status); + + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->eventTransmitFollowup(msg.id, status).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + + callback_handlers.on_event_data_path_request = + [weak_ptr_this](const legacy_hal::NanDataPathRequestInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + NanDataPathRequestInd hidl_struct; + if (!hidl_struct_util::convertLegacyNanDataPathRequestIndToHidl(msg, + &hidl_struct)) { + LOG(ERROR) << "Failed to convert nan capabilities response"; + return; + } + + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->eventDataPathRequest(hidl_struct).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + + callback_handlers.on_event_data_path_confirm = + [weak_ptr_this](const legacy_hal::NanDataPathConfirmInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + V1_2::NanDataPathConfirmInd hidl_struct; + if (!hidl_struct_util::convertLegacyNanDataPathConfirmIndToHidl(msg, + &hidl_struct)) { + LOG(ERROR) << "Failed to convert nan capabilities response"; + return; + } + + for (const auto& callback : shared_ptr_this->getEventCallbacks_1_2()) { + if (!callback->eventDataPathConfirm_1_2(hidl_struct).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + + callback_handlers.on_event_data_path_end = + [weak_ptr_this](const legacy_hal::NanDataPathEndInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + for (int i = 0; i < msg.num_ndp_instances; ++i) { + if (!callback->eventDataPathTerminated(msg.ndp_instance_id[i]).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + } + }; + + callback_handlers.on_event_beacon_sdf_payload = + [weak_ptr_this](const legacy_hal::NanBeaconSdfPayloadInd& /* msg */) { + LOG(ERROR) << "on_event_beacon_sdf_payload - should not be called"; + }; + + callback_handlers.on_event_range_request = + [weak_ptr_this](const legacy_hal::NanRangeRequestInd& /* msg */) { + LOG(ERROR) << "on_event_range_request - should not be called"; + }; + + callback_handlers.on_event_range_report = + [weak_ptr_this](const legacy_hal::NanRangeReportInd& /* msg */) { + LOG(ERROR) << "on_event_range_report - should not be called"; + }; + + callback_handlers.on_event_schedule_update = + [weak_ptr_this](const legacy_hal::NanDataPathScheduleUpdateInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + V1_2::NanDataPathScheduleUpdateInd hidl_struct; + if (!hidl_struct_util::convertLegacyNanDataPathScheduleUpdateIndToHidl( + msg, &hidl_struct)) { + LOG(ERROR) << "Failed to convert nan capabilities response"; + return; + } + + for (const auto& callback : shared_ptr_this->getEventCallbacks_1_2()) { + if (!callback->eventDataPathScheduleUpdate(hidl_struct).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanRegisterCallbackHandlers(ifname_, callback_handlers); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + LOG(ERROR) << "Failed to register nan callbacks. Invalidating object"; + invalidate(); + } + + // Register for iface state toggle events. + iface_util::IfaceEventHandlers event_handlers = {}; + event_handlers.on_state_toggle_off_on = [weak_ptr_this](const std::string& /* iface_name */) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + // Tell framework that NAN has been disabled. + WifiNanStatus status = {NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""}; + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->eventDisabled(status).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + iface_util_.lock()->registerIfaceEventHandlers(ifname_, event_handlers); +} + +void WifiNanIface::invalidate() { + if (!isValid()) { + return; + } + // send commands to HAL to actually disable and destroy interfaces + legacy_hal_.lock()->nanDisableRequest(ifname_, 0xFFFF); + legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFE, "aware_data0"); + legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFD, "aware_data1"); + iface_util_.lock()->unregisterIfaceEventHandlers(ifname_); + legacy_hal_.reset(); + event_cb_handler_.invalidate(); + event_cb_handler_1_2_.invalidate(); + event_cb_handler_1_5_.invalidate(); + is_valid_ = false; + if (is_dedicated_iface_) { + // If using a dedicated iface, set the iface down. + iface_util_.lock()->setUpState(ifname_, false); + } +} + +bool WifiNanIface::isValid() { + return is_valid_; +} + +std::string WifiNanIface::getName() { + return ifname_; +} + +std::set<sp<V1_0::IWifiNanIfaceEventCallback>> WifiNanIface::getEventCallbacks() { + return event_cb_handler_.getCallbacks(); +} + +std::set<sp<V1_2::IWifiNanIfaceEventCallback>> WifiNanIface::getEventCallbacks_1_2() { + return event_cb_handler_1_2_.getCallbacks(); +} + +std::set<sp<V1_5::IWifiNanIfaceEventCallback>> WifiNanIface::getEventCallbacks_1_5() { + return event_cb_handler_1_5_.getCallbacks(); +} + +Return<void> WifiNanIface::getName(getName_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::getNameInternal, hidl_status_cb); +} + +Return<void> WifiNanIface::getType(getType_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::getTypeInternal, hidl_status_cb); +} + +Return<void> WifiNanIface::registerEventCallback( + const sp<V1_0::IWifiNanIfaceEventCallback>& callback, + registerEventCallback_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::registerEventCallbackInternal, hidl_status_cb, callback); +} + +Return<void> WifiNanIface::getCapabilitiesRequest(uint16_t cmd_id, + getCapabilitiesRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::getCapabilitiesRequestInternal, hidl_status_cb, cmd_id); +} + +Return<void> WifiNanIface::enableRequest(uint16_t cmd_id, const V1_0::NanEnableRequest& msg, + enableRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::enableRequestInternal, hidl_status_cb, cmd_id, msg); +} + +Return<void> WifiNanIface::configRequest(uint16_t cmd_id, const V1_0::NanConfigRequest& msg, + configRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::configRequestInternal, hidl_status_cb, cmd_id, msg); +} + +Return<void> WifiNanIface::disableRequest(uint16_t cmd_id, disableRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::disableRequestInternal, hidl_status_cb, cmd_id); +} + +Return<void> WifiNanIface::startPublishRequest(uint16_t cmd_id, const NanPublishRequest& msg, + startPublishRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::startPublishRequestInternal, hidl_status_cb, cmd_id, msg); +} + +Return<void> WifiNanIface::stopPublishRequest(uint16_t cmd_id, uint8_t sessionId, + stopPublishRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::stopPublishRequestInternal, hidl_status_cb, cmd_id, + sessionId); +} + +Return<void> WifiNanIface::startSubscribeRequest(uint16_t cmd_id, const NanSubscribeRequest& msg, + startSubscribeRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::startSubscribeRequestInternal, hidl_status_cb, cmd_id, + msg); +} + +Return<void> WifiNanIface::stopSubscribeRequest(uint16_t cmd_id, uint8_t sessionId, + stopSubscribeRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::stopSubscribeRequestInternal, hidl_status_cb, cmd_id, + sessionId); +} + +Return<void> WifiNanIface::transmitFollowupRequest(uint16_t cmd_id, + const NanTransmitFollowupRequest& msg, + transmitFollowupRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::transmitFollowupRequestInternal, hidl_status_cb, cmd_id, + msg); +} + +Return<void> WifiNanIface::createDataInterfaceRequest( + uint16_t cmd_id, const hidl_string& iface_name, + createDataInterfaceRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::createDataInterfaceRequestInternal, hidl_status_cb, + cmd_id, iface_name); +} + +Return<void> WifiNanIface::deleteDataInterfaceRequest( + uint16_t cmd_id, const hidl_string& iface_name, + deleteDataInterfaceRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::deleteDataInterfaceRequestInternal, hidl_status_cb, + cmd_id, iface_name); +} + +Return<void> WifiNanIface::initiateDataPathRequest(uint16_t cmd_id, + const NanInitiateDataPathRequest& msg, + initiateDataPathRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::initiateDataPathRequestInternal, hidl_status_cb, cmd_id, + msg); +} + +Return<void> WifiNanIface::respondToDataPathIndicationRequest( + uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg, + respondToDataPathIndicationRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::respondToDataPathIndicationRequestInternal, + hidl_status_cb, cmd_id, msg); +} + +Return<void> WifiNanIface::terminateDataPathRequest(uint16_t cmd_id, uint32_t ndpInstanceId, + terminateDataPathRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::terminateDataPathRequestInternal, hidl_status_cb, cmd_id, + ndpInstanceId); +} + +Return<void> WifiNanIface::registerEventCallback_1_2( + const sp<V1_2::IWifiNanIfaceEventCallback>& callback, + registerEventCallback_1_2_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::registerEventCallback_1_2Internal, hidl_status_cb, + callback); +} + +Return<void> WifiNanIface::enableRequest_1_2(uint16_t cmd_id, const V1_0::NanEnableRequest& msg1, + const V1_2::NanConfigRequestSupplemental& msg2, + enableRequest_1_2_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::enableRequest_1_2Internal, hidl_status_cb, cmd_id, msg1, + msg2); +} + +Return<void> WifiNanIface::configRequest_1_2(uint16_t cmd_id, const V1_0::NanConfigRequest& msg1, + const V1_2::NanConfigRequestSupplemental& msg2, + configRequest_1_2_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::configRequest_1_2Internal, hidl_status_cb, cmd_id, msg1, + msg2); +} + +Return<void> WifiNanIface::enableRequest_1_4(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, + const V1_2::NanConfigRequestSupplemental& msg2, + enableRequest_1_4_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::enableRequest_1_4Internal, hidl_status_cb, cmd_id, msg1, + msg2); +} + +Return<void> WifiNanIface::configRequest_1_4(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, + const V1_2::NanConfigRequestSupplemental& msg2, + configRequest_1_4_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::configRequest_1_4Internal, hidl_status_cb, cmd_id, msg1, + msg2); +} + +Return<void> WifiNanIface::registerEventCallback_1_5( + const sp<V1_5::IWifiNanIfaceEventCallback>& callback, + registerEventCallback_1_5_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::registerEventCallback_1_5Internal, hidl_status_cb, + callback); +} + +Return<void> WifiNanIface::enableRequest_1_5(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, + const V1_5::NanConfigRequestSupplemental& msg2, + enableRequest_1_5_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::enableRequest_1_5Internal, hidl_status_cb, cmd_id, msg1, + msg2); +} + +Return<void> WifiNanIface::configRequest_1_5(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, + const V1_5::NanConfigRequestSupplemental& msg2, + configRequest_1_5_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::configRequest_1_5Internal, hidl_status_cb, cmd_id, msg1, + msg2); +} + +Return<void> WifiNanIface::getCapabilitiesRequest_1_5( + uint16_t cmd_id, getCapabilitiesRequest_1_5_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::getCapabilitiesRequest_1_5Internal, hidl_status_cb, + cmd_id); +} + +std::pair<WifiStatus, std::string> WifiNanIface::getNameInternal() { + return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_}; +} + +std::pair<WifiStatus, IfaceType> WifiNanIface::getTypeInternal() { + return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::NAN}; +} + +WifiStatus WifiNanIface::registerEventCallbackInternal( + const sp<V1_0::IWifiNanIfaceEventCallback>& callback) { + if (!event_cb_handler_.addCallback(callback)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +WifiStatus WifiNanIface::getCapabilitiesRequestInternal(uint16_t /* cmd_id */) { + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus WifiNanIface::enableRequestInternal(uint16_t /* cmd_id */, + const V1_0::NanEnableRequest& /* msg */) { + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus WifiNanIface::configRequestInternal(uint16_t /* cmd_id */, + const V1_0::NanConfigRequest& /* msg */) { + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus WifiNanIface::disableRequestInternal(uint16_t cmd_id) { + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->nanDisableRequest(ifname_, cmd_id); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiNanIface::startPublishRequestInternal(uint16_t cmd_id, + const NanPublishRequest& msg) { + legacy_hal::NanPublishRequest legacy_msg; + if (!hidl_struct_util::convertHidlNanPublishRequestToLegacy(msg, &legacy_msg)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanPublishRequest(ifname_, cmd_id, legacy_msg); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiNanIface::stopPublishRequestInternal(uint16_t cmd_id, uint8_t sessionId) { + legacy_hal::NanPublishCancelRequest legacy_msg; + legacy_msg.publish_id = sessionId; + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanPublishCancelRequest(ifname_, cmd_id, legacy_msg); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiNanIface::startSubscribeRequestInternal(uint16_t cmd_id, + const NanSubscribeRequest& msg) { + legacy_hal::NanSubscribeRequest legacy_msg; + if (!hidl_struct_util::convertHidlNanSubscribeRequestToLegacy(msg, &legacy_msg)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanSubscribeRequest(ifname_, cmd_id, legacy_msg); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiNanIface::stopSubscribeRequestInternal(uint16_t cmd_id, uint8_t sessionId) { + legacy_hal::NanSubscribeCancelRequest legacy_msg; + legacy_msg.subscribe_id = sessionId; + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanSubscribeCancelRequest(ifname_, cmd_id, legacy_msg); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiNanIface::transmitFollowupRequestInternal(uint16_t cmd_id, + const NanTransmitFollowupRequest& msg) { + legacy_hal::NanTransmitFollowupRequest legacy_msg; + if (!hidl_struct_util::convertHidlNanTransmitFollowupRequestToLegacy(msg, &legacy_msg)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanTransmitFollowupRequest(ifname_, cmd_id, legacy_msg); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiNanIface::createDataInterfaceRequestInternal(uint16_t cmd_id, + const std::string& iface_name) { + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanDataInterfaceCreate(ifname_, cmd_id, iface_name); + return createWifiStatusFromLegacyError(legacy_status); +} +WifiStatus WifiNanIface::deleteDataInterfaceRequestInternal(uint16_t cmd_id, + const std::string& iface_name) { + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, cmd_id, iface_name); + return createWifiStatusFromLegacyError(legacy_status); +} +WifiStatus WifiNanIface::initiateDataPathRequestInternal(uint16_t cmd_id, + const NanInitiateDataPathRequest& msg) { + legacy_hal::NanDataPathInitiatorRequest legacy_msg; + if (!hidl_struct_util::convertHidlNanDataPathInitiatorRequestToLegacy(msg, &legacy_msg)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanDataRequestInitiator(ifname_, cmd_id, legacy_msg); + return createWifiStatusFromLegacyError(legacy_status); +} +WifiStatus WifiNanIface::respondToDataPathIndicationRequestInternal( + uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg) { + legacy_hal::NanDataPathIndicationResponse legacy_msg; + if (!hidl_struct_util::convertHidlNanDataPathIndicationResponseToLegacy(msg, &legacy_msg)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanDataIndicationResponse(ifname_, cmd_id, legacy_msg); + return createWifiStatusFromLegacyError(legacy_status); +} +WifiStatus WifiNanIface::terminateDataPathRequestInternal(uint16_t cmd_id, uint32_t ndpInstanceId) { + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanDataEnd(ifname_, cmd_id, ndpInstanceId); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiNanIface::registerEventCallback_1_2Internal( + const sp<V1_2::IWifiNanIfaceEventCallback>& callback) { + sp<V1_0::IWifiNanIfaceEventCallback> callback_1_0 = callback; + if (!event_cb_handler_.addCallback(callback_1_0)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + if (!event_cb_handler_1_2_.addCallback(callback)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +WifiStatus WifiNanIface::enableRequest_1_2Internal( + uint16_t /* cmd_id */, const V1_0::NanEnableRequest& /* msg1 */, + const V1_2::NanConfigRequestSupplemental& /* msg2 */) { + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus WifiNanIface::configRequest_1_2Internal( + uint16_t /* cmd_id */, const V1_0::NanConfigRequest& /* msg1 */, + const V1_2::NanConfigRequestSupplemental& /* msg2 */) { + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus WifiNanIface::enableRequest_1_4Internal( + uint16_t /* cmd_id */, const V1_4::NanEnableRequest& /* msg1 */, + const V1_2::NanConfigRequestSupplemental& /* msg2 */) { + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus WifiNanIface::configRequest_1_4Internal( + uint16_t /* cmd_id */, const V1_4::NanConfigRequest& /* msg1 */, + const V1_2::NanConfigRequestSupplemental& /* msg2 */) { + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus WifiNanIface::registerEventCallback_1_5Internal( + const sp<V1_5::IWifiNanIfaceEventCallback>& callback) { + sp<V1_0::IWifiNanIfaceEventCallback> callback_1_0 = callback; + if (!event_cb_handler_.addCallback(callback_1_0)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + sp<V1_2::IWifiNanIfaceEventCallback> callback_1_2 = callback; + if (!event_cb_handler_1_2_.addCallback(callback_1_2)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + if (!event_cb_handler_1_5_.addCallback(callback)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +WifiStatus WifiNanIface::getCapabilitiesRequest_1_5Internal(uint16_t cmd_id) { + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->nanGetCapabilities(ifname_, cmd_id); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiNanIface::enableRequest_1_5Internal(uint16_t cmd_id, + const V1_4::NanEnableRequest& msg1, + const V1_5::NanConfigRequestSupplemental& msg2) { + legacy_hal::NanEnableRequest legacy_msg; + if (!hidl_struct_util::convertHidlNanEnableRequest_1_5ToLegacy(msg1, msg2, &legacy_msg)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanEnableRequest(ifname_, cmd_id, legacy_msg); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiNanIface::configRequest_1_5Internal(uint16_t cmd_id, + const V1_4::NanConfigRequest& msg1, + const V1_5::NanConfigRequestSupplemental& msg2) { + legacy_hal::NanConfigRequest legacy_msg; + if (!hidl_struct_util::convertHidlNanConfigRequest_1_5ToLegacy(msg1, msg2, &legacy_msg)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanConfigRequest(ifname_, cmd_id, legacy_msg); + return createWifiStatusFromLegacyError(legacy_status); +} + +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/wifi_nan_iface.h b/wifi/1.6/default/wifi_nan_iface.h new file mode 100644 index 0000000000..c445afc541 --- /dev/null +++ b/wifi/1.6/default/wifi_nan_iface.h @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WIFI_NAN_IFACE_H_ +#define WIFI_NAN_IFACE_H_ + +#include <android-base/macros.h> +#include <android/hardware/wifi/1.5/IWifiNanIface.h> +#include <android/hardware/wifi/1.5/IWifiNanIfaceEventCallback.h> + +#include "hidl_callback_util.h" +#include "wifi_iface_util.h" +#include "wifi_legacy_hal.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +using namespace android::hardware::wifi::V1_0; +using namespace android::hardware::wifi::V1_2; + +/** + * HIDL interface object used to control a NAN Iface instance. + */ +class WifiNanIface : public V1_5::IWifiNanIface { + public: + WifiNanIface(const std::string& ifname, bool is_dedicated_iface, + const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal, + const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util); + // Refer to |WifiChip::invalidate()|. + void invalidate(); + bool isValid(); + std::string getName(); + + // HIDL methods exposed. + Return<void> getName(getName_cb hidl_status_cb) override; + Return<void> getType(getType_cb hidl_status_cb) override; + Return<void> registerEventCallback(const sp<V1_0::IWifiNanIfaceEventCallback>& callback, + registerEventCallback_cb hidl_status_cb) override; + Return<void> getCapabilitiesRequest(uint16_t cmd_id, + getCapabilitiesRequest_cb hidl_status_cb) override; + Return<void> enableRequest(uint16_t cmd_id, const V1_0::NanEnableRequest& msg, + enableRequest_cb hidl_status_cb) override; + Return<void> configRequest(uint16_t cmd_id, const V1_0::NanConfigRequest& msg, + configRequest_cb hidl_status_cb) override; + Return<void> disableRequest(uint16_t cmd_id, disableRequest_cb hidl_status_cb) override; + Return<void> startPublishRequest(uint16_t cmd_id, const NanPublishRequest& msg, + startPublishRequest_cb hidl_status_cb) override; + Return<void> stopPublishRequest(uint16_t cmd_id, uint8_t sessionId, + stopPublishRequest_cb hidl_status_cb) override; + Return<void> startSubscribeRequest(uint16_t cmd_id, const NanSubscribeRequest& msg, + startSubscribeRequest_cb hidl_status_cb) override; + Return<void> stopSubscribeRequest(uint16_t cmd_id, uint8_t sessionId, + stopSubscribeRequest_cb hidl_status_cb) override; + Return<void> transmitFollowupRequest(uint16_t cmd_id, const NanTransmitFollowupRequest& msg, + transmitFollowupRequest_cb hidl_status_cb) override; + Return<void> createDataInterfaceRequest(uint16_t cmd_id, const hidl_string& iface_name, + createDataInterfaceRequest_cb hidl_status_cb) override; + Return<void> deleteDataInterfaceRequest(uint16_t cmd_id, const hidl_string& iface_name, + deleteDataInterfaceRequest_cb hidl_status_cb) override; + Return<void> initiateDataPathRequest(uint16_t cmd_id, const NanInitiateDataPathRequest& msg, + initiateDataPathRequest_cb hidl_status_cb) override; + Return<void> respondToDataPathIndicationRequest( + uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg, + respondToDataPathIndicationRequest_cb hidl_status_cb) override; + Return<void> terminateDataPathRequest(uint16_t cmd_id, uint32_t ndpInstanceId, + terminateDataPathRequest_cb hidl_status_cb) override; + + Return<void> registerEventCallback_1_2(const sp<V1_2::IWifiNanIfaceEventCallback>& callback, + registerEventCallback_1_2_cb hidl_status_cb) override; + Return<void> enableRequest_1_2(uint16_t cmd_id, const V1_0::NanEnableRequest& msg1, + const V1_2::NanConfigRequestSupplemental& msg2, + enableRequest_1_2_cb hidl_status_cb) override; + Return<void> configRequest_1_2(uint16_t cmd_id, const V1_0::NanConfigRequest& msg1, + const V1_2::NanConfigRequestSupplemental& msg2, + configRequest_1_2_cb hidl_status_cb) override; + Return<void> enableRequest_1_4(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, + const V1_2::NanConfigRequestSupplemental& msg2, + enableRequest_1_4_cb hidl_status_cb) override; + Return<void> configRequest_1_4(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, + const V1_2::NanConfigRequestSupplemental& msg2, + configRequest_1_4_cb hidl_status_cb) override; + Return<void> registerEventCallback_1_5(const sp<V1_5::IWifiNanIfaceEventCallback>& callback, + registerEventCallback_1_5_cb hidl_status_cb) override; + Return<void> enableRequest_1_5(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, + const V1_5::NanConfigRequestSupplemental& msg2, + enableRequest_1_4_cb hidl_status_cb) override; + Return<void> configRequest_1_5(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, + const V1_5::NanConfigRequestSupplemental& msg2, + configRequest_1_4_cb hidl_status_cb) override; + Return<void> getCapabilitiesRequest_1_5(uint16_t cmd_id, + getCapabilitiesRequest_cb hidl_status_cb) override; + + private: + // Corresponding worker functions for the HIDL methods. + std::pair<WifiStatus, std::string> getNameInternal(); + std::pair<WifiStatus, IfaceType> getTypeInternal(); + WifiStatus registerEventCallbackInternal(const sp<V1_0::IWifiNanIfaceEventCallback>& callback); + WifiStatus getCapabilitiesRequestInternal(uint16_t cmd_id); + WifiStatus enableRequestInternal(uint16_t cmd_id, const V1_0::NanEnableRequest& msg); + WifiStatus configRequestInternal(uint16_t cmd_id, const V1_0::NanConfigRequest& msg); + WifiStatus disableRequestInternal(uint16_t cmd_id); + WifiStatus startPublishRequestInternal(uint16_t cmd_id, const NanPublishRequest& msg); + WifiStatus stopPublishRequestInternal(uint16_t cmd_id, uint8_t sessionId); + WifiStatus startSubscribeRequestInternal(uint16_t cmd_id, const NanSubscribeRequest& msg); + WifiStatus stopSubscribeRequestInternal(uint16_t cmd_id, uint8_t sessionId); + WifiStatus transmitFollowupRequestInternal(uint16_t cmd_id, + const NanTransmitFollowupRequest& msg); + WifiStatus createDataInterfaceRequestInternal(uint16_t cmd_id, const std::string& iface_name); + WifiStatus deleteDataInterfaceRequestInternal(uint16_t cmd_id, const std::string& iface_name); + WifiStatus initiateDataPathRequestInternal(uint16_t cmd_id, + const NanInitiateDataPathRequest& msg); + WifiStatus respondToDataPathIndicationRequestInternal( + uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg); + WifiStatus terminateDataPathRequestInternal(uint16_t cmd_id, uint32_t ndpInstanceId); + + WifiStatus registerEventCallback_1_2Internal( + const sp<V1_2::IWifiNanIfaceEventCallback>& callback); + WifiStatus enableRequest_1_2Internal(uint16_t cmd_id, const V1_0::NanEnableRequest& msg1, + const V1_2::NanConfigRequestSupplemental& msg2); + WifiStatus configRequest_1_2Internal(uint16_t cmd_id, const V1_0::NanConfigRequest& msg, + const V1_2::NanConfigRequestSupplemental& msg2); + WifiStatus enableRequest_1_4Internal(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, + const V1_2::NanConfigRequestSupplemental& msg2); + WifiStatus configRequest_1_4Internal(uint16_t cmd_id, const V1_4::NanConfigRequest& msg, + const V1_2::NanConfigRequestSupplemental& msg2); + WifiStatus registerEventCallback_1_5Internal( + const sp<V1_5::IWifiNanIfaceEventCallback>& callback); + WifiStatus enableRequest_1_5Internal(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, + const V1_5::NanConfigRequestSupplemental& msg2); + WifiStatus configRequest_1_5Internal(uint16_t cmd_id, const V1_4::NanConfigRequest& msg, + const V1_5::NanConfigRequestSupplemental& msg2); + WifiStatus getCapabilitiesRequest_1_5Internal(uint16_t cmd_id); + + // all 1_0 and descendant callbacks + std::set<sp<V1_0::IWifiNanIfaceEventCallback>> getEventCallbacks(); + // all 1_2 and descendant callbacks + std::set<sp<V1_2::IWifiNanIfaceEventCallback>> getEventCallbacks_1_2(); + // all 1_5 and descendant callbacks + std::set<sp<V1_5::IWifiNanIfaceEventCallback>> getEventCallbacks_1_5(); + + std::string ifname_; + bool is_dedicated_iface_; + std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_; + std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_; + bool is_valid_; + hidl_callback_util::HidlCallbackHandler<V1_0::IWifiNanIfaceEventCallback> event_cb_handler_; + hidl_callback_util::HidlCallbackHandler<V1_2::IWifiNanIfaceEventCallback> event_cb_handler_1_2_; + hidl_callback_util::HidlCallbackHandler<V1_5::IWifiNanIfaceEventCallback> event_cb_handler_1_5_; + + DISALLOW_COPY_AND_ASSIGN(WifiNanIface); +}; + +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // WIFI_NAN_IFACE_H_ diff --git a/wifi/1.5/default/wifi_p2p_iface.cpp b/wifi/1.6/default/wifi_p2p_iface.cpp index b8893da153..d4b1fcabf1 100644 --- a/wifi/1.5/default/wifi_p2p_iface.cpp +++ b/wifi/1.6/default/wifi_p2p_iface.cpp @@ -23,13 +23,12 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { using hidl_return_util::validateAndCall; -WifiP2pIface::WifiP2pIface( - const std::string& ifname, - const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal) +WifiP2pIface::WifiP2pIface(const std::string& ifname, + const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal) : ifname_(ifname), legacy_hal_(legacy_hal), is_valid_(true) {} void WifiP2pIface::invalidate() { @@ -37,9 +36,13 @@ void WifiP2pIface::invalidate() { is_valid_ = false; } -bool WifiP2pIface::isValid() { return is_valid_; } +bool WifiP2pIface::isValid() { + return is_valid_; +} -std::string WifiP2pIface::getName() { return ifname_; } +std::string WifiP2pIface::getName() { + return ifname_; +} Return<void> WifiP2pIface::getName(getName_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, @@ -60,7 +63,7 @@ std::pair<WifiStatus, IfaceType> WifiP2pIface::getTypeInternal() { } } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/wifi_p2p_iface.h b/wifi/1.6/default/wifi_p2p_iface.h index c1adc50278..00894437cf 100644 --- a/wifi/1.5/default/wifi_p2p_iface.h +++ b/wifi/1.6/default/wifi_p2p_iface.h @@ -25,7 +25,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { using namespace android::hardware::wifi::V1_0; @@ -33,7 +33,7 @@ using namespace android::hardware::wifi::V1_0; * HIDL interface object used to control a P2P Iface instance. */ class WifiP2pIface : public V1_0::IWifiP2pIface { - public: + public: WifiP2pIface(const std::string& ifname, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal); // Refer to |WifiChip::invalidate()|. @@ -45,7 +45,7 @@ class WifiP2pIface : public V1_0::IWifiP2pIface { Return<void> getName(getName_cb hidl_status_cb) override; Return<void> getType(getType_cb hidl_status_cb) override; - private: + private: // Corresponding worker functions for the HIDL methods. std::pair<WifiStatus, std::string> getNameInternal(); std::pair<WifiStatus, IfaceType> getTypeInternal(); @@ -58,7 +58,7 @@ class WifiP2pIface : public V1_0::IWifiP2pIface { }; } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.6/default/wifi_rtt_controller.cpp b/wifi/1.6/default/wifi_rtt_controller.cpp new file mode 100644 index 0000000000..f5e1d5aafc --- /dev/null +++ b/wifi/1.6/default/wifi_rtt_controller.cpp @@ -0,0 +1,311 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <android-base/logging.h> + +#include "hidl_return_util.h" +#include "hidl_struct_util.h" +#include "wifi_rtt_controller.h" +#include "wifi_status_util.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +using hidl_return_util::validateAndCall; + +WifiRttController::WifiRttController(const std::string& iface_name, + const sp<IWifiIface>& bound_iface, + const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal) + : ifname_(iface_name), bound_iface_(bound_iface), legacy_hal_(legacy_hal), is_valid_(true) {} + +void WifiRttController::invalidate() { + legacy_hal_.reset(); + event_callbacks_.clear(); + is_valid_ = false; +} + +bool WifiRttController::isValid() { + return is_valid_; +} + +std::vector<sp<V1_4::IWifiRttControllerEventCallback>> WifiRttController::getEventCallbacks() { + return event_callbacks_; +} + +std::string WifiRttController::getIfaceName() { + return ifname_; +} + +Return<void> WifiRttController::getBoundIface(getBoundIface_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::getBoundIfaceInternal, hidl_status_cb); +} + +Return<void> WifiRttController::registerEventCallback( + const sp<V1_0::IWifiRttControllerEventCallback>& callback, + registerEventCallback_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::registerEventCallbackInternal, hidl_status_cb, + callback); +} + +Return<void> WifiRttController::rangeRequest(uint32_t cmd_id, + const hidl_vec<V1_0::RttConfig>& rtt_configs, + rangeRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::rangeRequestInternal, hidl_status_cb, cmd_id, + rtt_configs); +} + +Return<void> WifiRttController::rangeCancel(uint32_t cmd_id, + const hidl_vec<hidl_array<uint8_t, 6>>& addrs, + rangeCancel_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::rangeCancelInternal, hidl_status_cb, cmd_id, addrs); +} + +Return<void> WifiRttController::getCapabilities(getCapabilities_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::getCapabilitiesInternal, hidl_status_cb); +} + +Return<void> WifiRttController::setLci(uint32_t cmd_id, const RttLciInformation& lci, + setLci_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::setLciInternal, hidl_status_cb, cmd_id, lci); +} + +Return<void> WifiRttController::setLcr(uint32_t cmd_id, const RttLcrInformation& lcr, + setLcr_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::setLcrInternal, hidl_status_cb, cmd_id, lcr); +} + +Return<void> WifiRttController::getResponderInfo(getResponderInfo_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::getResponderInfoInternal, hidl_status_cb); +} + +Return<void> WifiRttController::enableResponder(uint32_t cmd_id, + const WifiChannelInfo& channel_hint, + uint32_t max_duration_seconds, + const V1_0::RttResponder& info, + enableResponder_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::enableResponderInternal, hidl_status_cb, cmd_id, + channel_hint, max_duration_seconds, info); +} + +Return<void> WifiRttController::disableResponder(uint32_t cmd_id, + disableResponder_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::disableResponderInternal, hidl_status_cb, cmd_id); +} + +Return<void> WifiRttController::registerEventCallback_1_4( + const sp<V1_4::IWifiRttControllerEventCallback>& callback, + registerEventCallback_1_4_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::registerEventCallbackInternal_1_4, hidl_status_cb, + callback); +} + +Return<void> WifiRttController::rangeRequest_1_4(uint32_t cmd_id, + const hidl_vec<V1_4::RttConfig>& rtt_configs, + rangeRequest_1_4_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::rangeRequestInternal_1_4, hidl_status_cb, cmd_id, + rtt_configs); +} + +Return<void> WifiRttController::getCapabilities_1_4(getCapabilities_1_4_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::getCapabilitiesInternal_1_4, hidl_status_cb); +} + +Return<void> WifiRttController::getResponderInfo_1_4(getResponderInfo_1_4_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::getResponderInfoInternal_1_4, hidl_status_cb); +} + +Return<void> WifiRttController::enableResponder_1_4(uint32_t cmd_id, + const WifiChannelInfo& channel_hint, + uint32_t max_duration_seconds, + const V1_4::RttResponder& info, + enableResponder_1_4_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::enableResponderInternal_1_4, hidl_status_cb, cmd_id, + channel_hint, max_duration_seconds, info); +} + +std::pair<WifiStatus, sp<IWifiIface>> WifiRttController::getBoundIfaceInternal() { + return {createWifiStatus(WifiStatusCode::SUCCESS), bound_iface_}; +} + +WifiStatus WifiRttController::registerEventCallbackInternal( + const sp<V1_0::IWifiRttControllerEventCallback>& /* callback */) { + // Deprecated support for this api + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus WifiRttController::rangeRequestInternal( + uint32_t /* cmd_id */, const std::vector<V1_0::RttConfig>& /* rtt_configs */) { + // Deprecated support for this api + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus WifiRttController::rangeCancelInternal( + uint32_t cmd_id, const std::vector<hidl_array<uint8_t, 6>>& addrs) { + std::vector<std::array<uint8_t, 6>> legacy_addrs; + for (const auto& addr : addrs) { + legacy_addrs.push_back(addr); + } + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->cancelRttRangeRequest(ifname_, cmd_id, legacy_addrs); + return createWifiStatusFromLegacyError(legacy_status); +} + +std::pair<WifiStatus, V1_0::RttCapabilities> WifiRttController::getCapabilitiesInternal() { + // Deprecated support for this api + return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}}; +} + +WifiStatus WifiRttController::setLciInternal(uint32_t cmd_id, const RttLciInformation& lci) { + legacy_hal::wifi_lci_information legacy_lci; + if (!hidl_struct_util::convertHidlRttLciInformationToLegacy(lci, &legacy_lci)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->setRttLci(ifname_, cmd_id, legacy_lci); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiRttController::setLcrInternal(uint32_t cmd_id, const RttLcrInformation& lcr) { + legacy_hal::wifi_lcr_information legacy_lcr; + if (!hidl_struct_util::convertHidlRttLcrInformationToLegacy(lcr, &legacy_lcr)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->setRttLcr(ifname_, cmd_id, legacy_lcr); + return createWifiStatusFromLegacyError(legacy_status); +} + +std::pair<WifiStatus, V1_0::RttResponder> WifiRttController::getResponderInfoInternal() { + // Deprecated support for this api + return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}}; +} + +WifiStatus WifiRttController::enableResponderInternal(uint32_t /* cmd_id */, + const WifiChannelInfo& /* channel_hint */, + uint32_t /* max_duration_seconds */, + const V1_0::RttResponder& /* info */) { + // Deprecated support for this api + return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED)}; +} + +WifiStatus WifiRttController::disableResponderInternal(uint32_t cmd_id) { + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->disableRttResponder(ifname_, cmd_id); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiRttController::registerEventCallbackInternal_1_4( + const sp<V1_4::IWifiRttControllerEventCallback>& callback) { + // TODO(b/31632518): remove the callback when the client is destroyed + event_callbacks_.emplace_back(callback); + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +WifiStatus WifiRttController::rangeRequestInternal_1_4( + uint32_t cmd_id, const std::vector<V1_4::RttConfig>& rtt_configs) { + std::vector<legacy_hal::wifi_rtt_config> legacy_configs; + if (!hidl_struct_util::convertHidlVectorOfRttConfigToLegacy(rtt_configs, &legacy_configs)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + android::wp<WifiRttController> weak_ptr_this(this); + const auto& on_results_callback = + [weak_ptr_this](legacy_hal::wifi_request_id id, + const std::vector<const legacy_hal::wifi_rtt_result*>& results) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + std::vector<V1_4::RttResult> hidl_results; + if (!hidl_struct_util::convertLegacyVectorOfRttResultToHidl(results, + &hidl_results)) { + LOG(ERROR) << "Failed to convert rtt results to HIDL structs"; + return; + } + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + callback->onResults_1_4(id, hidl_results); + } + }; + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRttRangeRequest( + ifname_, cmd_id, legacy_configs, on_results_callback); + return createWifiStatusFromLegacyError(legacy_status); +} + +std::pair<WifiStatus, V1_4::RttCapabilities> WifiRttController::getCapabilitiesInternal_1_4() { + legacy_hal::wifi_error legacy_status; + legacy_hal::wifi_rtt_capabilities legacy_caps; + std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getRttCapabilities(ifname_); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + return {createWifiStatusFromLegacyError(legacy_status), {}}; + } + V1_4::RttCapabilities hidl_caps; + if (!hidl_struct_util::convertLegacyRttCapabilitiesToHidl(legacy_caps, &hidl_caps)) { + return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps}; +} + +std::pair<WifiStatus, V1_4::RttResponder> WifiRttController::getResponderInfoInternal_1_4() { + legacy_hal::wifi_error legacy_status; + legacy_hal::wifi_rtt_responder legacy_responder; + std::tie(legacy_status, legacy_responder) = legacy_hal_.lock()->getRttResponderInfo(ifname_); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + return {createWifiStatusFromLegacyError(legacy_status), {}}; + } + V1_4::RttResponder hidl_responder; + if (!hidl_struct_util::convertLegacyRttResponderToHidl(legacy_responder, &hidl_responder)) { + return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_responder}; +} + +WifiStatus WifiRttController::enableResponderInternal_1_4(uint32_t cmd_id, + const WifiChannelInfo& channel_hint, + uint32_t max_duration_seconds, + const V1_4::RttResponder& info) { + legacy_hal::wifi_channel_info legacy_channel_info; + if (!hidl_struct_util::convertHidlWifiChannelInfoToLegacy(channel_hint, &legacy_channel_info)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + legacy_hal::wifi_rtt_responder legacy_responder; + if (!hidl_struct_util::convertHidlRttResponderToLegacy(info, &legacy_responder)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableRttResponder( + ifname_, cmd_id, legacy_channel_info, max_duration_seconds, legacy_responder); + return createWifiStatusFromLegacyError(legacy_status); +} +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.5/default/wifi_rtt_controller.h b/wifi/1.6/default/wifi_rtt_controller.h index 9ac3e06fcc..b4a2116f2b 100644 --- a/wifi/1.5/default/wifi_rtt_controller.h +++ b/wifi/1.6/default/wifi_rtt_controller.h @@ -27,17 +27,16 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { /** * HIDL interface object used to control all RTT operations. */ class WifiRttController : public V1_4::IWifiRttController { - public: - WifiRttController( - const std::string& iface_name, const sp<IWifiIface>& bound_iface, - const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal); + public: + WifiRttController(const std::string& iface_name, const sp<IWifiIface>& bound_iface, + const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal); // Refer to |WifiChip::invalidate()|. void invalidate(); bool isValid(); @@ -46,14 +45,11 @@ class WifiRttController : public V1_4::IWifiRttController { // HIDL methods exposed. Return<void> getBoundIface(getBoundIface_cb hidl_status_cb) override; - Return<void> registerEventCallback( - const sp<V1_0::IWifiRttControllerEventCallback>& callback, - registerEventCallback_cb hidl_status_cb) override; - Return<void> rangeRequest(uint32_t cmd_id, - const hidl_vec<V1_0::RttConfig>& rtt_configs, + Return<void> registerEventCallback(const sp<V1_0::IWifiRttControllerEventCallback>& callback, + registerEventCallback_cb hidl_status_cb) override; + Return<void> rangeRequest(uint32_t cmd_id, const hidl_vec<V1_0::RttConfig>& rtt_configs, rangeRequest_cb hidl_status_cb) override; - Return<void> rangeCancel(uint32_t cmd_id, - const hidl_vec<hidl_array<uint8_t, 6>>& addrs, + Return<void> rangeCancel(uint32_t cmd_id, const hidl_vec<hidl_array<uint8_t, 6>>& addrs, rangeCancel_cb hidl_status_cb) override; Return<void> getCapabilities(getCapabilities_cb hidl_status_cb) override; Return<void> setLci(uint32_t cmd_id, const RttLciInformation& lci, @@ -61,54 +57,45 @@ class WifiRttController : public V1_4::IWifiRttController { Return<void> setLcr(uint32_t cmd_id, const RttLcrInformation& lcr, setLcr_cb hidl_status_cb) override; Return<void> getResponderInfo(getResponderInfo_cb hidl_status_cb) override; - Return<void> enableResponder(uint32_t cmd_id, - const WifiChannelInfo& channel_hint, - uint32_t max_duration_seconds, - const V1_0::RttResponder& info, + Return<void> enableResponder(uint32_t cmd_id, const WifiChannelInfo& channel_hint, + uint32_t max_duration_seconds, const V1_0::RttResponder& info, enableResponder_cb hidl_status_cb) override; - Return<void> disableResponder(uint32_t cmd_id, - disableResponder_cb hidl_status_cb) override; + Return<void> disableResponder(uint32_t cmd_id, disableResponder_cb hidl_status_cb) override; Return<void> registerEventCallback_1_4( - const sp<V1_4::IWifiRttControllerEventCallback>& callback, - registerEventCallback_1_4_cb hidl_status_cb) override; - Return<void> rangeRequest_1_4(uint32_t cmd_id, - const hidl_vec<V1_4::RttConfig>& rtt_configs, + const sp<V1_4::IWifiRttControllerEventCallback>& callback, + registerEventCallback_1_4_cb hidl_status_cb) override; + Return<void> rangeRequest_1_4(uint32_t cmd_id, const hidl_vec<V1_4::RttConfig>& rtt_configs, rangeRequest_1_4_cb hidl_status_cb) override; - Return<void> getCapabilities_1_4( - getCapabilities_1_4_cb hidl_status_cb) override; - Return<void> getResponderInfo_1_4( - getResponderInfo_1_4_cb hidl_status_cb) override; - Return<void> enableResponder_1_4( - uint32_t cmd_id, const WifiChannelInfo& channel_hint, - uint32_t max_duration_seconds, const V1_4::RttResponder& info, - enableResponder_1_4_cb hidl_status_cb) override; + Return<void> getCapabilities_1_4(getCapabilities_1_4_cb hidl_status_cb) override; + Return<void> getResponderInfo_1_4(getResponderInfo_1_4_cb hidl_status_cb) override; + Return<void> enableResponder_1_4(uint32_t cmd_id, const WifiChannelInfo& channel_hint, + uint32_t max_duration_seconds, const V1_4::RttResponder& info, + enableResponder_1_4_cb hidl_status_cb) override; - private: + private: // Corresponding worker functions for the HIDL methods. std::pair<WifiStatus, sp<IWifiIface>> getBoundIfaceInternal(); WifiStatus registerEventCallbackInternal( - const sp<V1_0::IWifiRttControllerEventCallback>& callback); - WifiStatus rangeRequestInternal( - uint32_t cmd_id, const std::vector<V1_0::RttConfig>& rtt_configs); - WifiStatus rangeCancelInternal( - uint32_t cmd_id, const std::vector<hidl_array<uint8_t, 6>>& addrs); + const sp<V1_0::IWifiRttControllerEventCallback>& callback); + WifiStatus rangeRequestInternal(uint32_t cmd_id, + const std::vector<V1_0::RttConfig>& rtt_configs); + WifiStatus rangeCancelInternal(uint32_t cmd_id, + const std::vector<hidl_array<uint8_t, 6>>& addrs); std::pair<WifiStatus, V1_0::RttCapabilities> getCapabilitiesInternal(); WifiStatus setLciInternal(uint32_t cmd_id, const RttLciInformation& lci); WifiStatus setLcrInternal(uint32_t cmd_id, const RttLcrInformation& lcr); std::pair<WifiStatus, V1_0::RttResponder> getResponderInfoInternal(); - WifiStatus enableResponderInternal(uint32_t cmd_id, - const WifiChannelInfo& channel_hint, + WifiStatus enableResponderInternal(uint32_t cmd_id, const WifiChannelInfo& channel_hint, uint32_t max_duration_seconds, const V1_0::RttResponder& info); WifiStatus disableResponderInternal(uint32_t cmd_id); WifiStatus registerEventCallbackInternal_1_4( - const sp<V1_4::IWifiRttControllerEventCallback>& callback); - WifiStatus rangeRequestInternal_1_4( - uint32_t cmd_id, const std::vector<V1_4::RttConfig>& rtt_configs); + const sp<V1_4::IWifiRttControllerEventCallback>& callback); + WifiStatus rangeRequestInternal_1_4(uint32_t cmd_id, + const std::vector<V1_4::RttConfig>& rtt_configs); std::pair<WifiStatus, V1_4::RttCapabilities> getCapabilitiesInternal_1_4(); std::pair<WifiStatus, V1_4::RttResponder> getResponderInfoInternal_1_4(); - WifiStatus enableResponderInternal_1_4(uint32_t cmd_id, - const WifiChannelInfo& channel_hint, + WifiStatus enableResponderInternal_1_4(uint32_t cmd_id, const WifiChannelInfo& channel_hint, uint32_t max_duration_seconds, const V1_4::RttResponder& info); @@ -122,7 +109,7 @@ class WifiRttController : public V1_4::IWifiRttController { }; } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/wifi_sta_iface.cpp b/wifi/1.6/default/wifi_sta_iface.cpp index 92c9fe4392..f852d36689 100644 --- a/wifi/1.5/default/wifi_sta_iface.cpp +++ b/wifi/1.6/default/wifi_sta_iface.cpp @@ -24,24 +24,18 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { using hidl_return_util::validateAndCall; -WifiStaIface::WifiStaIface( - const std::string& ifname, - const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal, - const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util) - : ifname_(ifname), - legacy_hal_(legacy_hal), - iface_util_(iface_util), - is_valid_(true) { +WifiStaIface::WifiStaIface(const std::string& ifname, + const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal, + const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util) + : ifname_(ifname), legacy_hal_(legacy_hal), iface_util_(iface_util), is_valid_(true) { // Turn on DFS channel usage for STA iface. - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->setDfsFlag(ifname_, true); + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setDfsFlag(ifname_, true); if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) - << "Failed to set DFS flag; DFS channels may be unavailable."; + LOG(ERROR) << "Failed to set DFS flag; DFS channels may be unavailable."; } } @@ -51,9 +45,13 @@ void WifiStaIface::invalidate() { is_valid_ = false; } -bool WifiStaIface::isValid() { return is_valid_; } +bool WifiStaIface::isValid() { + return is_valid_; +} -std::string WifiStaIface::getName() { return ifname_; } +std::string WifiStaIface::getName() { + return ifname_; +} std::set<sp<IWifiStaIfaceEventCallback>> WifiStaIface::getEventCallbacks() { return event_cb_handler_.getCallbacks(); @@ -69,215 +67,177 @@ Return<void> WifiStaIface::getType(getType_cb hidl_status_cb) { &WifiStaIface::getTypeInternal, hidl_status_cb); } -Return<void> WifiStaIface::registerEventCallback( - const sp<IWifiStaIfaceEventCallback>& callback, - registerEventCallback_cb hidl_status_cb) { +Return<void> WifiStaIface::registerEventCallback(const sp<IWifiStaIfaceEventCallback>& callback, + registerEventCallback_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::registerEventCallbackInternal, - hidl_status_cb, callback); + &WifiStaIface::registerEventCallbackInternal, hidl_status_cb, callback); } Return<void> WifiStaIface::getCapabilities(getCapabilities_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getCapabilitiesInternal, - hidl_status_cb); + &WifiStaIface::getCapabilitiesInternal, hidl_status_cb); } Return<void> WifiStaIface::getApfPacketFilterCapabilities( - getApfPacketFilterCapabilities_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getApfPacketFilterCapabilitiesInternal, hidl_status_cb); + getApfPacketFilterCapabilities_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::getApfPacketFilterCapabilitiesInternal, hidl_status_cb); } -Return<void> WifiStaIface::installApfPacketFilter( - uint32_t cmd_id, const hidl_vec<uint8_t>& program, - installApfPacketFilter_cb hidl_status_cb) { +Return<void> WifiStaIface::installApfPacketFilter(uint32_t cmd_id, const hidl_vec<uint8_t>& program, + installApfPacketFilter_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::installApfPacketFilterInternal, - hidl_status_cb, cmd_id, program); + &WifiStaIface::installApfPacketFilterInternal, hidl_status_cb, cmd_id, + program); } -Return<void> WifiStaIface::readApfPacketFilterData( - readApfPacketFilterData_cb hidl_status_cb) { +Return<void> WifiStaIface::readApfPacketFilterData(readApfPacketFilterData_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::readApfPacketFilterDataInternal, - hidl_status_cb); + &WifiStaIface::readApfPacketFilterDataInternal, hidl_status_cb); } Return<void> WifiStaIface::getBackgroundScanCapabilities( - getBackgroundScanCapabilities_cb hidl_status_cb) { + getBackgroundScanCapabilities_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getBackgroundScanCapabilitiesInternal, - hidl_status_cb); + &WifiStaIface::getBackgroundScanCapabilitiesInternal, hidl_status_cb); } Return<void> WifiStaIface::getValidFrequenciesForBand( - V1_0::WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) { + V1_0::WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getValidFrequenciesForBandInternal, - hidl_status_cb, band); + &WifiStaIface::getValidFrequenciesForBandInternal, hidl_status_cb, band); } -Return<void> WifiStaIface::startBackgroundScan( - uint32_t cmd_id, const StaBackgroundScanParameters& params, - startBackgroundScan_cb hidl_status_cb) { +Return<void> WifiStaIface::startBackgroundScan(uint32_t cmd_id, + const StaBackgroundScanParameters& params, + startBackgroundScan_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::startBackgroundScanInternal, - hidl_status_cb, cmd_id, params); + &WifiStaIface::startBackgroundScanInternal, hidl_status_cb, cmd_id, + params); } -Return<void> WifiStaIface::stopBackgroundScan( - uint32_t cmd_id, stopBackgroundScan_cb hidl_status_cb) { +Return<void> WifiStaIface::stopBackgroundScan(uint32_t cmd_id, + stopBackgroundScan_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::stopBackgroundScanInternal, - hidl_status_cb, cmd_id); + &WifiStaIface::stopBackgroundScanInternal, hidl_status_cb, cmd_id); } Return<void> WifiStaIface::enableLinkLayerStatsCollection( - bool debug, enableLinkLayerStatsCollection_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::enableLinkLayerStatsCollectionInternal, hidl_status_cb, - debug); + bool debug, enableLinkLayerStatsCollection_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::enableLinkLayerStatsCollectionInternal, hidl_status_cb, + debug); } Return<void> WifiStaIface::disableLinkLayerStatsCollection( - disableLinkLayerStatsCollection_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::disableLinkLayerStatsCollectionInternal, hidl_status_cb); + disableLinkLayerStatsCollection_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::disableLinkLayerStatsCollectionInternal, hidl_status_cb); } -Return<void> WifiStaIface::getLinkLayerStats( - getLinkLayerStats_cb hidl_status_cb) { +Return<void> WifiStaIface::getLinkLayerStats(getLinkLayerStats_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getLinkLayerStatsInternal, - hidl_status_cb); + &WifiStaIface::getLinkLayerStatsInternal, hidl_status_cb); } -Return<void> WifiStaIface::getLinkLayerStats_1_3( - getLinkLayerStats_1_3_cb hidl_status_cb) { +Return<void> WifiStaIface::getLinkLayerStats_1_3(getLinkLayerStats_1_3_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getLinkLayerStatsInternal_1_3, - hidl_status_cb); + &WifiStaIface::getLinkLayerStatsInternal_1_3, hidl_status_cb); } -Return<void> WifiStaIface::getLinkLayerStats_1_5( - getLinkLayerStats_1_5_cb hidl_status_cb) { +Return<void> WifiStaIface::getLinkLayerStats_1_5(getLinkLayerStats_1_5_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getLinkLayerStatsInternal_1_5, - hidl_status_cb); + &WifiStaIface::getLinkLayerStatsInternal_1_5, hidl_status_cb); } -Return<void> WifiStaIface::startRssiMonitoring( - uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi, - startRssiMonitoring_cb hidl_status_cb) { +Return<void> WifiStaIface::startRssiMonitoring(uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi, + startRssiMonitoring_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::startRssiMonitoringInternal, - hidl_status_cb, cmd_id, max_rssi, min_rssi); + &WifiStaIface::startRssiMonitoringInternal, hidl_status_cb, cmd_id, + max_rssi, min_rssi); } -Return<void> WifiStaIface::stopRssiMonitoring( - uint32_t cmd_id, stopRssiMonitoring_cb hidl_status_cb) { +Return<void> WifiStaIface::stopRssiMonitoring(uint32_t cmd_id, + stopRssiMonitoring_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::stopRssiMonitoringInternal, - hidl_status_cb, cmd_id); + &WifiStaIface::stopRssiMonitoringInternal, hidl_status_cb, cmd_id); } -Return<void> WifiStaIface::getRoamingCapabilities( - getRoamingCapabilities_cb hidl_status_cb) { +Return<void> WifiStaIface::getRoamingCapabilities(getRoamingCapabilities_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getRoamingCapabilitiesInternal, - hidl_status_cb); + &WifiStaIface::getRoamingCapabilitiesInternal, hidl_status_cb); } -Return<void> WifiStaIface::configureRoaming( - const StaRoamingConfig& config, configureRoaming_cb hidl_status_cb) { +Return<void> WifiStaIface::configureRoaming(const StaRoamingConfig& config, + configureRoaming_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::configureRoamingInternal, - hidl_status_cb, config); + &WifiStaIface::configureRoamingInternal, hidl_status_cb, config); } Return<void> WifiStaIface::setRoamingState(StaRoamingState state, setRoamingState_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::setRoamingStateInternal, - hidl_status_cb, state); + &WifiStaIface::setRoamingStateInternal, hidl_status_cb, state); } -Return<void> WifiStaIface::enableNdOffload(bool enable, - enableNdOffload_cb hidl_status_cb) { +Return<void> WifiStaIface::enableNdOffload(bool enable, enableNdOffload_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::enableNdOffloadInternal, - hidl_status_cb, enable); + &WifiStaIface::enableNdOffloadInternal, hidl_status_cb, enable); } Return<void> WifiStaIface::startSendingKeepAlivePackets( - uint32_t cmd_id, const hidl_vec<uint8_t>& ip_packet_data, - uint16_t ether_type, const hidl_array<uint8_t, 6>& src_address, - const hidl_array<uint8_t, 6>& dst_address, uint32_t period_in_ms, - startSendingKeepAlivePackets_cb hidl_status_cb) { + uint32_t cmd_id, const hidl_vec<uint8_t>& ip_packet_data, uint16_t ether_type, + const hidl_array<uint8_t, 6>& src_address, const hidl_array<uint8_t, 6>& dst_address, + uint32_t period_in_ms, startSendingKeepAlivePackets_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::startSendingKeepAlivePacketsInternal, - hidl_status_cb, cmd_id, ip_packet_data, ether_type, - src_address, dst_address, period_in_ms); + &WifiStaIface::startSendingKeepAlivePacketsInternal, hidl_status_cb, + cmd_id, ip_packet_data, ether_type, src_address, dst_address, + period_in_ms); } Return<void> WifiStaIface::stopSendingKeepAlivePackets( - uint32_t cmd_id, stopSendingKeepAlivePackets_cb hidl_status_cb) { + uint32_t cmd_id, stopSendingKeepAlivePackets_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::stopSendingKeepAlivePacketsInternal, - hidl_status_cb, cmd_id); + &WifiStaIface::stopSendingKeepAlivePacketsInternal, hidl_status_cb, + cmd_id); } -Return<void> WifiStaIface::setScanningMacOui( - const hidl_array<uint8_t, 3>& oui, setScanningMacOui_cb hidl_status_cb) { +Return<void> WifiStaIface::setScanningMacOui(const hidl_array<uint8_t, 3>& oui, + setScanningMacOui_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::setScanningMacOuiInternal, - hidl_status_cb, oui); + &WifiStaIface::setScanningMacOuiInternal, hidl_status_cb, oui); } Return<void> WifiStaIface::startDebugPacketFateMonitoring( - startDebugPacketFateMonitoring_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::startDebugPacketFateMonitoringInternal, hidl_status_cb); + startDebugPacketFateMonitoring_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::startDebugPacketFateMonitoringInternal, hidl_status_cb); } -Return<void> WifiStaIface::getDebugTxPacketFates( - getDebugTxPacketFates_cb hidl_status_cb) { +Return<void> WifiStaIface::getDebugTxPacketFates(getDebugTxPacketFates_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getDebugTxPacketFatesInternal, - hidl_status_cb); + &WifiStaIface::getDebugTxPacketFatesInternal, hidl_status_cb); } -Return<void> WifiStaIface::getDebugRxPacketFates( - getDebugRxPacketFates_cb hidl_status_cb) { +Return<void> WifiStaIface::getDebugRxPacketFates(getDebugRxPacketFates_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getDebugRxPacketFatesInternal, - hidl_status_cb); + &WifiStaIface::getDebugRxPacketFatesInternal, hidl_status_cb); } Return<void> WifiStaIface::setMacAddress(const hidl_array<uint8_t, 6>& mac, setMacAddress_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::setMacAddressInternal, hidl_status_cb, - mac); + &WifiStaIface::setMacAddressInternal, hidl_status_cb, mac); } -Return<void> WifiStaIface::getFactoryMacAddress( - getFactoryMacAddress_cb hidl_status_cb) { +Return<void> WifiStaIface::getFactoryMacAddress(getFactoryMacAddress_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getFactoryMacAddressInternal, - hidl_status_cb); + &WifiStaIface::getFactoryMacAddressInternal, hidl_status_cb); } -Return<void> WifiStaIface::setScanMode(bool enable, - setScanMode_cb hidl_status_cb) { +Return<void> WifiStaIface::setScanMode(bool enable, setScanMode_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::setScanModeInternal, hidl_status_cb, - enable); + &WifiStaIface::setScanModeInternal, hidl_status_cb, enable); } std::pair<WifiStatus, std::string> WifiStaIface::getNameInternal() { @@ -289,7 +249,7 @@ std::pair<WifiStatus, IfaceType> WifiStaIface::getTypeInternal() { } WifiStatus WifiStaIface::registerEventCallbackInternal( - const sp<IWifiStaIfaceEventCallback>& callback) { + const sp<IWifiStaIfaceEventCallback>& callback) { if (!event_cb_handler_.addCallback(callback)) { return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); } @@ -300,20 +260,20 @@ std::pair<WifiStatus, uint32_t> WifiStaIface::getCapabilitiesInternal() { legacy_hal::wifi_error legacy_status; uint64_t legacy_feature_set; std::tie(legacy_status, legacy_feature_set) = - legacy_hal_.lock()->getSupportedFeatureSet(ifname_); + legacy_hal_.lock()->getSupportedFeatureSet(ifname_); if (legacy_status != legacy_hal::WIFI_SUCCESS) { return {createWifiStatusFromLegacyError(legacy_status), 0}; } uint32_t legacy_logger_feature_set; std::tie(legacy_status, legacy_logger_feature_set) = - legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname_); + legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname_); if (legacy_status != legacy_hal::WIFI_SUCCESS) { // some devices don't support querying logger feature set legacy_logger_feature_set = 0; } uint32_t hidl_caps; if (!hidl_struct_util::convertLegacyFeaturesToHidlStaCapabilities( - legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) { + legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) { return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0}; } return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps}; @@ -323,30 +283,25 @@ std::pair<WifiStatus, StaApfPacketFilterCapabilities> WifiStaIface::getApfPacketFilterCapabilitiesInternal() { legacy_hal::wifi_error legacy_status; legacy_hal::PacketFilterCapabilities legacy_caps; - std::tie(legacy_status, legacy_caps) = - legacy_hal_.lock()->getPacketFilterCapabilities(ifname_); + std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getPacketFilterCapabilities(ifname_); if (legacy_status != legacy_hal::WIFI_SUCCESS) { return {createWifiStatusFromLegacyError(legacy_status), {}}; } StaApfPacketFilterCapabilities hidl_caps; - if (!hidl_struct_util::convertLegacyApfCapabilitiesToHidl(legacy_caps, - &hidl_caps)) { + if (!hidl_struct_util::convertLegacyApfCapabilitiesToHidl(legacy_caps, &hidl_caps)) { return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; } return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps}; } -WifiStatus WifiStaIface::installApfPacketFilterInternal( - uint32_t /* cmd_id */, const std::vector<uint8_t>& program) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->setPacketFilter(ifname_, program); +WifiStatus WifiStaIface::installApfPacketFilterInternal(uint32_t /* cmd_id */, + const std::vector<uint8_t>& program) { + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setPacketFilter(ifname_, program); return createWifiStatusFromLegacyError(legacy_status); } -std::pair<WifiStatus, std::vector<uint8_t>> -WifiStaIface::readApfPacketFilterDataInternal() { - const std::pair<legacy_hal::wifi_error, std::vector<uint8_t>> - legacy_status_and_data = +std::pair<WifiStatus, std::vector<uint8_t>> WifiStaIface::readApfPacketFilterDataInternal() { + const std::pair<legacy_hal::wifi_error, std::vector<uint8_t>> legacy_status_and_data = legacy_hal_.lock()->readApfPacketFilterData(ifname_); return {createWifiStatusFromLegacyError(legacy_status_and_data.first), std::move(legacy_status_and_data.second)}; @@ -356,14 +311,12 @@ std::pair<WifiStatus, StaBackgroundScanCapabilities> WifiStaIface::getBackgroundScanCapabilitiesInternal() { legacy_hal::wifi_error legacy_status; legacy_hal::wifi_gscan_capabilities legacy_caps; - std::tie(legacy_status, legacy_caps) = - legacy_hal_.lock()->getGscanCapabilities(ifname_); + std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getGscanCapabilities(ifname_); if (legacy_status != legacy_hal::WIFI_SUCCESS) { return {createWifiStatusFromLegacyError(legacy_status), {}}; } StaBackgroundScanCapabilities hidl_caps; - if (!hidl_struct_util::convertLegacyGscanCapabilitiesToHidl(legacy_caps, - &hidl_caps)) { + if (!hidl_struct_util::convertLegacyGscanCapabilitiesToHidl(legacy_caps, &hidl_caps)) { return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; } return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps}; @@ -371,240 +324,201 @@ WifiStaIface::getBackgroundScanCapabilitiesInternal() { std::pair<WifiStatus, std::vector<WifiChannelInMhz>> WifiStaIface::getValidFrequenciesForBandInternal(V1_0::WifiBand band) { - static_assert(sizeof(WifiChannelInMhz) == sizeof(uint32_t), - "Size mismatch"); + static_assert(sizeof(WifiChannelInMhz) == sizeof(uint32_t), "Size mismatch"); legacy_hal::wifi_error legacy_status; std::vector<uint32_t> valid_frequencies; - std::tie(legacy_status, valid_frequencies) = - legacy_hal_.lock()->getValidFrequenciesForBand( + std::tie(legacy_status, valid_frequencies) = legacy_hal_.lock()->getValidFrequenciesForBand( ifname_, hidl_struct_util::convertHidlWifiBandToLegacy(band)); return {createWifiStatusFromLegacyError(legacy_status), valid_frequencies}; } -WifiStatus WifiStaIface::startBackgroundScanInternal( - uint32_t cmd_id, const StaBackgroundScanParameters& params) { +WifiStatus WifiStaIface::startBackgroundScanInternal(uint32_t cmd_id, + const StaBackgroundScanParameters& params) { legacy_hal::wifi_scan_cmd_params legacy_params; - if (!hidl_struct_util::convertHidlGscanParamsToLegacy(params, - &legacy_params)) { + if (!hidl_struct_util::convertHidlGscanParamsToLegacy(params, &legacy_params)) { return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); } android::wp<WifiStaIface> weak_ptr_this(this); - const auto& on_failure_callback = - [weak_ptr_this](legacy_hal::wifi_request_id id) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->onBackgroundScanFailure(id).isOk()) { - LOG(ERROR) - << "Failed to invoke onBackgroundScanFailure callback"; - } + const auto& on_failure_callback = [weak_ptr_this](legacy_hal::wifi_request_id id) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->onBackgroundScanFailure(id).isOk()) { + LOG(ERROR) << "Failed to invoke onBackgroundScanFailure callback"; } - }; + } + }; const auto& on_results_callback = - [weak_ptr_this]( - legacy_hal::wifi_request_id id, - const std::vector<legacy_hal::wifi_cached_scan_results>& results) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - std::vector<StaScanData> hidl_scan_datas; - if (!hidl_struct_util:: - convertLegacyVectorOfCachedGscanResultsToHidl( - results, &hidl_scan_datas)) { - LOG(ERROR) << "Failed to convert scan results to HIDL structs"; - return; - } - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->onBackgroundScanResults(id, hidl_scan_datas) - .isOk()) { - LOG(ERROR) - << "Failed to invoke onBackgroundScanResults callback"; + [weak_ptr_this](legacy_hal::wifi_request_id id, + const std::vector<legacy_hal::wifi_cached_scan_results>& results) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; } - } - }; + std::vector<StaScanData> hidl_scan_datas; + if (!hidl_struct_util::convertLegacyVectorOfCachedGscanResultsToHidl( + results, &hidl_scan_datas)) { + LOG(ERROR) << "Failed to convert scan results to HIDL structs"; + return; + } + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->onBackgroundScanResults(id, hidl_scan_datas).isOk()) { + LOG(ERROR) << "Failed to invoke onBackgroundScanResults callback"; + } + } + }; const auto& on_full_result_callback = [weak_ptr_this]( - legacy_hal::wifi_request_id id, - const legacy_hal:: - wifi_scan_result* result, - uint32_t buckets_scanned) { + legacy_hal::wifi_request_id id, + const legacy_hal::wifi_scan_result* result, + uint32_t buckets_scanned) { const auto shared_ptr_this = weak_ptr_this.promote(); if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { LOG(ERROR) << "Callback invoked on an invalid object"; return; } StaScanResult hidl_scan_result; - if (!hidl_struct_util::convertLegacyGscanResultToHidl( - *result, true, &hidl_scan_result)) { + if (!hidl_struct_util::convertLegacyGscanResultToHidl(*result, true, &hidl_scan_result)) { LOG(ERROR) << "Failed to convert full scan results to HIDL structs"; return; } for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback - ->onBackgroundFullScanResult(id, buckets_scanned, - hidl_scan_result) - .isOk()) { - LOG(ERROR) - << "Failed to invoke onBackgroundFullScanResult callback"; + if (!callback->onBackgroundFullScanResult(id, buckets_scanned, hidl_scan_result) + .isOk()) { + LOG(ERROR) << "Failed to invoke onBackgroundFullScanResult callback"; } } }; - legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startGscan( - ifname_, cmd_id, legacy_params, on_failure_callback, - on_results_callback, on_full_result_callback); + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->startGscan(ifname_, cmd_id, legacy_params, on_failure_callback, + on_results_callback, on_full_result_callback); return createWifiStatusFromLegacyError(legacy_status); } WifiStatus WifiStaIface::stopBackgroundScanInternal(uint32_t cmd_id) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->stopGscan(ifname_, cmd_id); + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stopGscan(ifname_, cmd_id); return createWifiStatusFromLegacyError(legacy_status); } WifiStatus WifiStaIface::enableLinkLayerStatsCollectionInternal(bool debug) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->enableLinkLayerStats(ifname_, debug); + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableLinkLayerStats(ifname_, debug); return createWifiStatusFromLegacyError(legacy_status); } WifiStatus WifiStaIface::disableLinkLayerStatsCollectionInternal() { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->disableLinkLayerStats(ifname_); + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->disableLinkLayerStats(ifname_); return createWifiStatusFromLegacyError(legacy_status); } -std::pair<WifiStatus, V1_0::StaLinkLayerStats> -WifiStaIface::getLinkLayerStatsInternal() { +std::pair<WifiStatus, V1_0::StaLinkLayerStats> WifiStaIface::getLinkLayerStatsInternal() { return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}}; } -std::pair<WifiStatus, V1_3::StaLinkLayerStats> -WifiStaIface::getLinkLayerStatsInternal_1_3() { +std::pair<WifiStatus, V1_3::StaLinkLayerStats> WifiStaIface::getLinkLayerStatsInternal_1_3() { return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}}; } -std::pair<WifiStatus, V1_5::StaLinkLayerStats> -WifiStaIface::getLinkLayerStatsInternal_1_5() { +std::pair<WifiStatus, V1_5::StaLinkLayerStats> WifiStaIface::getLinkLayerStatsInternal_1_5() { legacy_hal::wifi_error legacy_status; legacy_hal::LinkLayerStats legacy_stats; - std::tie(legacy_status, legacy_stats) = - legacy_hal_.lock()->getLinkLayerStats(ifname_); + std::tie(legacy_status, legacy_stats) = legacy_hal_.lock()->getLinkLayerStats(ifname_); if (legacy_status != legacy_hal::WIFI_SUCCESS) { return {createWifiStatusFromLegacyError(legacy_status), {}}; } V1_5::StaLinkLayerStats hidl_stats; - if (!hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats, - &hidl_stats)) { + if (!hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats, &hidl_stats)) { return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; } return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats}; } -WifiStatus WifiStaIface::startRssiMonitoringInternal(uint32_t cmd_id, - int32_t max_rssi, +WifiStatus WifiStaIface::startRssiMonitoringInternal(uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi) { android::wp<WifiStaIface> weak_ptr_this(this); - const auto& on_threshold_breached_callback = - [weak_ptr_this](legacy_hal::wifi_request_id id, - std::array<uint8_t, 6> bssid, int8_t rssi) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->onRssiThresholdBreached(id, bssid, rssi) - .isOk()) { - LOG(ERROR) - << "Failed to invoke onRssiThresholdBreached callback"; - } + const auto& on_threshold_breached_callback = [weak_ptr_this](legacy_hal::wifi_request_id id, + std::array<uint8_t, 6> bssid, + int8_t rssi) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->onRssiThresholdBreached(id, bssid, rssi).isOk()) { + LOG(ERROR) << "Failed to invoke onRssiThresholdBreached callback"; } - }; - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->startRssiMonitoring(ifname_, cmd_id, max_rssi, - min_rssi, - on_threshold_breached_callback); + } + }; + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRssiMonitoring( + ifname_, cmd_id, max_rssi, min_rssi, on_threshold_breached_callback); return createWifiStatusFromLegacyError(legacy_status); } WifiStatus WifiStaIface::stopRssiMonitoringInternal(uint32_t cmd_id) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->stopRssiMonitoring(ifname_, cmd_id); + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stopRssiMonitoring(ifname_, cmd_id); return createWifiStatusFromLegacyError(legacy_status); } -std::pair<WifiStatus, StaRoamingCapabilities> -WifiStaIface::getRoamingCapabilitiesInternal() { +std::pair<WifiStatus, StaRoamingCapabilities> WifiStaIface::getRoamingCapabilitiesInternal() { legacy_hal::wifi_error legacy_status; legacy_hal::wifi_roaming_capabilities legacy_caps; - std::tie(legacy_status, legacy_caps) = - legacy_hal_.lock()->getRoamingCapabilities(ifname_); + std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getRoamingCapabilities(ifname_); if (legacy_status != legacy_hal::WIFI_SUCCESS) { return {createWifiStatusFromLegacyError(legacy_status), {}}; } StaRoamingCapabilities hidl_caps; - if (!hidl_struct_util::convertLegacyRoamingCapabilitiesToHidl(legacy_caps, - &hidl_caps)) { + if (!hidl_struct_util::convertLegacyRoamingCapabilitiesToHidl(legacy_caps, &hidl_caps)) { return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; } return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps}; } -WifiStatus WifiStaIface::configureRoamingInternal( - const StaRoamingConfig& config) { +WifiStatus WifiStaIface::configureRoamingInternal(const StaRoamingConfig& config) { legacy_hal::wifi_roaming_config legacy_config; - if (!hidl_struct_util::convertHidlRoamingConfigToLegacy(config, - &legacy_config)) { + if (!hidl_struct_util::convertHidlRoamingConfigToLegacy(config, &legacy_config)) { return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); } legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->configureRoaming(ifname_, legacy_config); + legacy_hal_.lock()->configureRoaming(ifname_, legacy_config); return createWifiStatusFromLegacyError(legacy_status); } WifiStatus WifiStaIface::setRoamingStateInternal(StaRoamingState state) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->enableFirmwareRoaming( + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableFirmwareRoaming( ifname_, hidl_struct_util::convertHidlRoamingStateToLegacy(state)); return createWifiStatusFromLegacyError(legacy_status); } WifiStatus WifiStaIface::enableNdOffloadInternal(bool enable) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->configureNdOffload(ifname_, enable); + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->configureNdOffload(ifname_, enable); return createWifiStatusFromLegacyError(legacy_status); } WifiStatus WifiStaIface::startSendingKeepAlivePacketsInternal( - uint32_t cmd_id, const std::vector<uint8_t>& ip_packet_data, - uint16_t ether_type, const std::array<uint8_t, 6>& src_address, - const std::array<uint8_t, 6>& dst_address, uint32_t period_in_ms) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->startSendingOffloadedPacket( - ifname_, cmd_id, ether_type, ip_packet_data, src_address, - dst_address, period_in_ms); + uint32_t cmd_id, const std::vector<uint8_t>& ip_packet_data, uint16_t ether_type, + const std::array<uint8_t, 6>& src_address, const std::array<uint8_t, 6>& dst_address, + uint32_t period_in_ms) { + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startSendingOffloadedPacket( + ifname_, cmd_id, ether_type, ip_packet_data, src_address, dst_address, period_in_ms); return createWifiStatusFromLegacyError(legacy_status); } WifiStatus WifiStaIface::stopSendingKeepAlivePacketsInternal(uint32_t cmd_id) { legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->stopSendingOffloadedPacket(ifname_, cmd_id); + legacy_hal_.lock()->stopSendingOffloadedPacket(ifname_, cmd_id); return createWifiStatusFromLegacyError(legacy_status); } -WifiStatus WifiStaIface::setScanningMacOuiInternal( - const std::array<uint8_t, 3>& /* oui */) { +WifiStatus WifiStaIface::setScanningMacOuiInternal(const std::array<uint8_t, 3>& /* oui */) { // deprecated. return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); } WifiStatus WifiStaIface::startDebugPacketFateMonitoringInternal() { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->startPktFateMonitoring(ifname_); + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startPktFateMonitoring(ifname_); return createWifiStatusFromLegacyError(legacy_status); } @@ -612,14 +526,13 @@ std::pair<WifiStatus, std::vector<WifiDebugTxPacketFateReport>> WifiStaIface::getDebugTxPacketFatesInternal() { legacy_hal::wifi_error legacy_status; std::vector<legacy_hal::wifi_tx_report> legacy_fates; - std::tie(legacy_status, legacy_fates) = - legacy_hal_.lock()->getTxPktFates(ifname_); + std::tie(legacy_status, legacy_fates) = legacy_hal_.lock()->getTxPktFates(ifname_); if (legacy_status != legacy_hal::WIFI_SUCCESS) { return {createWifiStatusFromLegacyError(legacy_status), {}}; } std::vector<WifiDebugTxPacketFateReport> hidl_fates; - if (!hidl_struct_util::convertLegacyVectorOfDebugTxPacketFateToHidl( - legacy_fates, &hidl_fates)) { + if (!hidl_struct_util::convertLegacyVectorOfDebugTxPacketFateToHidl(legacy_fates, + &hidl_fates)) { return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; } return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_fates}; @@ -629,21 +542,19 @@ std::pair<WifiStatus, std::vector<WifiDebugRxPacketFateReport>> WifiStaIface::getDebugRxPacketFatesInternal() { legacy_hal::wifi_error legacy_status; std::vector<legacy_hal::wifi_rx_report> legacy_fates; - std::tie(legacy_status, legacy_fates) = - legacy_hal_.lock()->getRxPktFates(ifname_); + std::tie(legacy_status, legacy_fates) = legacy_hal_.lock()->getRxPktFates(ifname_); if (legacy_status != legacy_hal::WIFI_SUCCESS) { return {createWifiStatusFromLegacyError(legacy_status), {}}; } std::vector<WifiDebugRxPacketFateReport> hidl_fates; - if (!hidl_struct_util::convertLegacyVectorOfDebugRxPacketFateToHidl( - legacy_fates, &hidl_fates)) { + if (!hidl_struct_util::convertLegacyVectorOfDebugRxPacketFateToHidl(legacy_fates, + &hidl_fates)) { return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; } return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_fates}; } -WifiStatus WifiStaIface::setMacAddressInternal( - const std::array<uint8_t, 6>& mac) { +WifiStatus WifiStaIface::setMacAddressInternal(const std::array<uint8_t, 6>& mac) { bool status = iface_util_.lock()->setMacAddress(ifname_, mac); if (!status) { return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); @@ -651,12 +562,9 @@ WifiStatus WifiStaIface::setMacAddressInternal( return createWifiStatus(WifiStatusCode::SUCCESS); } -std::pair<WifiStatus, std::array<uint8_t, 6>> -WifiStaIface::getFactoryMacAddressInternal() { - std::array<uint8_t, 6> mac = - iface_util_.lock()->getFactoryMacAddress(ifname_); - if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 && - mac[4] == 0 && mac[5] == 0) { +std::pair<WifiStatus, std::array<uint8_t, 6>> WifiStaIface::getFactoryMacAddressInternal() { + std::array<uint8_t, 6> mac = iface_util_.lock()->getFactoryMacAddress(ifname_); + if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 && mac[4] == 0 && mac[5] == 0) { return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), mac}; } return {createWifiStatus(WifiStatusCode::SUCCESS), mac}; @@ -669,7 +577,7 @@ WifiStatus WifiStaIface::setScanModeInternal(bool enable) { } } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.6/default/wifi_sta_iface.h b/wifi/1.6/default/wifi_sta_iface.h new file mode 100644 index 0000000000..37358a5fb0 --- /dev/null +++ b/wifi/1.6/default/wifi_sta_iface.h @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WIFI_STA_IFACE_H_ +#define WIFI_STA_IFACE_H_ + +#include <android-base/macros.h> +#include <android/hardware/wifi/1.0/IWifiStaIfaceEventCallback.h> +#include <android/hardware/wifi/1.5/IWifiStaIface.h> + +#include "hidl_callback_util.h" +#include "wifi_iface_util.h" +#include "wifi_legacy_hal.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +using namespace android::hardware::wifi::V1_0; + +/** + * HIDL interface object used to control a STA Iface instance. + */ +class WifiStaIface : public V1_5::IWifiStaIface { + public: + WifiStaIface(const std::string& ifname, + const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal, + const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util); + // Refer to |WifiChip::invalidate()|. + void invalidate(); + bool isValid(); + std::set<sp<IWifiStaIfaceEventCallback>> getEventCallbacks(); + std::string getName(); + + // HIDL methods exposed. + Return<void> getName(getName_cb hidl_status_cb) override; + Return<void> getType(getType_cb hidl_status_cb) override; + Return<void> registerEventCallback(const sp<IWifiStaIfaceEventCallback>& callback, + registerEventCallback_cb hidl_status_cb) override; + Return<void> getCapabilities(getCapabilities_cb hidl_status_cb) override; + Return<void> getApfPacketFilterCapabilities( + getApfPacketFilterCapabilities_cb hidl_status_cb) override; + Return<void> installApfPacketFilter(uint32_t cmd_id, const hidl_vec<uint8_t>& program, + installApfPacketFilter_cb hidl_status_cb) override; + Return<void> readApfPacketFilterData(readApfPacketFilterData_cb hidl_status_cb) override; + Return<void> getBackgroundScanCapabilities( + getBackgroundScanCapabilities_cb hidl_status_cb) override; + Return<void> getValidFrequenciesForBand(V1_0::WifiBand band, + getValidFrequenciesForBand_cb hidl_status_cb) override; + Return<void> startBackgroundScan(uint32_t cmd_id, const StaBackgroundScanParameters& params, + startBackgroundScan_cb hidl_status_cb) override; + Return<void> stopBackgroundScan(uint32_t cmd_id, stopBackgroundScan_cb hidl_status_cb) override; + Return<void> enableLinkLayerStatsCollection( + bool debug, enableLinkLayerStatsCollection_cb hidl_status_cb) override; + Return<void> disableLinkLayerStatsCollection( + disableLinkLayerStatsCollection_cb hidl_status_cb) override; + Return<void> getLinkLayerStats(getLinkLayerStats_cb hidl_status_cb) override; + Return<void> getLinkLayerStats_1_3(getLinkLayerStats_1_3_cb hidl_status_cb) override; + Return<void> getLinkLayerStats_1_5(getLinkLayerStats_1_5_cb hidl_status_cb) override; + Return<void> startRssiMonitoring(uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi, + startRssiMonitoring_cb hidl_status_cb) override; + Return<void> stopRssiMonitoring(uint32_t cmd_id, stopRssiMonitoring_cb hidl_status_cb) override; + Return<void> getRoamingCapabilities(getRoamingCapabilities_cb hidl_status_cb) override; + Return<void> configureRoaming(const StaRoamingConfig& config, + configureRoaming_cb hidl_status_cb) override; + Return<void> setRoamingState(StaRoamingState state, setRoamingState_cb hidl_status_cb) override; + Return<void> enableNdOffload(bool enable, enableNdOffload_cb hidl_status_cb) override; + Return<void> startSendingKeepAlivePackets( + uint32_t cmd_id, const hidl_vec<uint8_t>& ip_packet_data, uint16_t ether_type, + const hidl_array<uint8_t, 6>& src_address, const hidl_array<uint8_t, 6>& dst_address, + uint32_t period_in_ms, startSendingKeepAlivePackets_cb hidl_status_cb) override; + Return<void> stopSendingKeepAlivePackets( + uint32_t cmd_id, stopSendingKeepAlivePackets_cb hidl_status_cb) override; + Return<void> setScanningMacOui(const hidl_array<uint8_t, 3>& oui, + setScanningMacOui_cb hidl_status_cb) override; + Return<void> startDebugPacketFateMonitoring( + startDebugPacketFateMonitoring_cb hidl_status_cb) override; + Return<void> getDebugTxPacketFates(getDebugTxPacketFates_cb hidl_status_cb) override; + Return<void> getDebugRxPacketFates(getDebugRxPacketFates_cb hidl_status_cb) override; + Return<void> setMacAddress(const hidl_array<uint8_t, 6>& mac, + setMacAddress_cb hidl_status_cb) override; + Return<void> getFactoryMacAddress(getFactoryMacAddress_cb hidl_status_cb) override; + Return<void> setScanMode(bool enable, setScanMode_cb hidl_status_cb) override; + + private: + // Corresponding worker functions for the HIDL methods. + std::pair<WifiStatus, std::string> getNameInternal(); + std::pair<WifiStatus, IfaceType> getTypeInternal(); + WifiStatus registerEventCallbackInternal(const sp<IWifiStaIfaceEventCallback>& callback); + std::pair<WifiStatus, uint32_t> getCapabilitiesInternal(); + std::pair<WifiStatus, StaApfPacketFilterCapabilities> getApfPacketFilterCapabilitiesInternal(); + WifiStatus installApfPacketFilterInternal(uint32_t cmd_id, const std::vector<uint8_t>& program); + std::pair<WifiStatus, std::vector<uint8_t>> readApfPacketFilterDataInternal(); + std::pair<WifiStatus, StaBackgroundScanCapabilities> getBackgroundScanCapabilitiesInternal(); + std::pair<WifiStatus, std::vector<WifiChannelInMhz>> getValidFrequenciesForBandInternal( + V1_0::WifiBand band); + WifiStatus startBackgroundScanInternal(uint32_t cmd_id, + const StaBackgroundScanParameters& params); + WifiStatus stopBackgroundScanInternal(uint32_t cmd_id); + WifiStatus enableLinkLayerStatsCollectionInternal(bool debug); + WifiStatus disableLinkLayerStatsCollectionInternal(); + std::pair<WifiStatus, V1_0::StaLinkLayerStats> getLinkLayerStatsInternal(); + std::pair<WifiStatus, V1_3::StaLinkLayerStats> getLinkLayerStatsInternal_1_3(); + std::pair<WifiStatus, V1_5::StaLinkLayerStats> getLinkLayerStatsInternal_1_5(); + WifiStatus startRssiMonitoringInternal(uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi); + WifiStatus stopRssiMonitoringInternal(uint32_t cmd_id); + std::pair<WifiStatus, StaRoamingCapabilities> getRoamingCapabilitiesInternal(); + WifiStatus configureRoamingInternal(const StaRoamingConfig& config); + WifiStatus setRoamingStateInternal(StaRoamingState state); + WifiStatus enableNdOffloadInternal(bool enable); + WifiStatus startSendingKeepAlivePacketsInternal(uint32_t cmd_id, + const std::vector<uint8_t>& ip_packet_data, + uint16_t ether_type, + const std::array<uint8_t, 6>& src_address, + const std::array<uint8_t, 6>& dst_address, + uint32_t period_in_ms); + WifiStatus stopSendingKeepAlivePacketsInternal(uint32_t cmd_id); + WifiStatus setScanningMacOuiInternal(const std::array<uint8_t, 3>& oui); + WifiStatus startDebugPacketFateMonitoringInternal(); + std::pair<WifiStatus, std::vector<WifiDebugTxPacketFateReport>> getDebugTxPacketFatesInternal(); + std::pair<WifiStatus, std::vector<WifiDebugRxPacketFateReport>> getDebugRxPacketFatesInternal(); + WifiStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac); + std::pair<WifiStatus, std::array<uint8_t, 6>> getFactoryMacAddressInternal(); + WifiStatus setScanModeInternal(bool enable); + + std::string ifname_; + std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_; + std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_; + bool is_valid_; + hidl_callback_util::HidlCallbackHandler<IWifiStaIfaceEventCallback> event_cb_handler_; + + DISALLOW_COPY_AND_ASSIGN(WifiStaIface); +}; + +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // WIFI_STA_IFACE_H_ diff --git a/wifi/1.5/default/wifi_status_util.cpp b/wifi/1.6/default/wifi_status_util.cpp index eb8c8694db..3b18e537cd 100644 --- a/wifi/1.5/default/wifi_status_util.cpp +++ b/wifi/1.6/default/wifi_status_util.cpp @@ -19,7 +19,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { std::string legacyErrorToString(legacy_hal::wifi_error error) { @@ -51,8 +51,7 @@ std::string legacyErrorToString(legacy_hal::wifi_error error) { } } -WifiStatus createWifiStatus(WifiStatusCode code, - const std::string& description) { +WifiStatus createWifiStatus(WifiStatusCode code, const std::string& description) { return {code, description}; } @@ -60,8 +59,7 @@ WifiStatus createWifiStatus(WifiStatusCode code) { return createWifiStatus(code, ""); } -WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error, - const std::string& desc) { +WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error, const std::string& desc) { switch (error) { case legacy_hal::WIFI_ERROR_UNINITIALIZED: case legacy_hal::WIFI_ERROR_NOT_AVAILABLE: @@ -75,16 +73,13 @@ WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error, return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS, desc); case legacy_hal::WIFI_ERROR_TIMED_OUT: - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, - desc + ", timed out"); + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", timed out"); case legacy_hal::WIFI_ERROR_TOO_MANY_REQUESTS: - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, - desc + ", too many requests"); + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", too many requests"); case legacy_hal::WIFI_ERROR_OUT_OF_MEMORY: - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, - desc + ", out of memory"); + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", out of memory"); case legacy_hal::WIFI_ERROR_BUSY: return createWifiStatus(WifiStatusCode::ERROR_BUSY); @@ -96,8 +91,7 @@ WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error, return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, "unknown"); default: - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, - "unknown error"); + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, "unknown error"); } } @@ -106,7 +100,7 @@ WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error) { } } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.5/default/wifi_status_util.h b/wifi/1.6/default/wifi_status_util.h index 68f21689c5..ea1c29486b 100644 --- a/wifi/1.5/default/wifi_status_util.h +++ b/wifi/1.6/default/wifi_status_util.h @@ -24,20 +24,19 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_5 { +namespace V1_6 { namespace implementation { using namespace android::hardware::wifi::V1_0; std::string legacyErrorToString(legacy_hal::wifi_error error); -WifiStatus createWifiStatus(WifiStatusCode code, - const std::string& description); +WifiStatus createWifiStatus(WifiStatusCode code, const std::string& description); WifiStatus createWifiStatus(WifiStatusCode code); WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error, const std::string& description); WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error); } // namespace implementation -} // namespace V1_5 +} // namespace V1_6 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Bandwidth.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Bandwidth.aidl index 890d986f77..4d78640fdb 100644 --- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Bandwidth.aidl +++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Bandwidth.aidl @@ -41,8 +41,9 @@ enum Bandwidth { BANDWIDTH_80 = 4, BANDWIDTH_80P80 = 5, BANDWIDTH_160 = 6, - BANDWIDTH_2160 = 7, - BANDWIDTH_4320 = 8, - BANDWIDTH_6480 = 9, - BANDWIDTH_8640 = 10, + BANDWIDTH_320 = 7, + BANDWIDTH_2160 = 8, + BANDWIDTH_4320 = 9, + BANDWIDTH_6480 = 10, + BANDWIDTH_8640 = 11, } diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Generation.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Generation.aidl index 6b60d17400..af0e960df8 100644 --- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Generation.aidl +++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Generation.aidl @@ -40,4 +40,5 @@ enum Generation { WIFI_STANDARD_11AC = 2, WIFI_STANDARD_11AX = 3, WIFI_STANDARD_11AD = 4, + WIFI_STANDARD_11BE = 5, } diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/HwModeParams.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/HwModeParams.aidl index 844c838c44..8d8d7bb0f6 100644 --- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/HwModeParams.aidl +++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/HwModeParams.aidl @@ -43,4 +43,5 @@ parcelable HwModeParams { boolean enableHeMultiUserBeamformer; boolean enableHeTargetWakeTime; boolean enableEdmg; + boolean enable80211BE; } diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/NetworkParams.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/NetworkParams.aidl index ffe2f33475..4554223751 100644 --- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/NetworkParams.aidl +++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/NetworkParams.aidl @@ -39,4 +39,5 @@ parcelable NetworkParams { android.hardware.wifi.hostapd.EncryptionType encryptionType; String passphrase; boolean isMetered; + byte[] vendorElements; } diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Bandwidth.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Bandwidth.aidl index c9824027e9..e605153b83 100644 --- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Bandwidth.aidl +++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Bandwidth.aidl @@ -29,8 +29,9 @@ enum Bandwidth { BANDWIDTH_80 = 4, BANDWIDTH_80P80 = 5, BANDWIDTH_160 = 6, - BANDWIDTH_2160 = 7, - BANDWIDTH_4320 = 8, - BANDWIDTH_6480 = 9, - BANDWIDTH_8640 = 10, + BANDWIDTH_320 = 7, + BANDWIDTH_2160 = 8, + BANDWIDTH_4320 = 9, + BANDWIDTH_6480 = 10, + BANDWIDTH_8640 = 11, } diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Generation.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Generation.aidl index 2cda55bd97..f4e3eb0668 100644 --- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Generation.aidl +++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Generation.aidl @@ -27,6 +27,7 @@ package android.hardware.wifi.hostapd; * WIFI_STANDARD_11AC = hw_mode is HOSTAPD_MODE_IEEE80211A and VHT is 1. * WIFI_STANDARD_11AX = hw_mode is HOSTAPD_MODE_IEEE80211A and High Efficiency supported. * WIFI_STANDARD_11AD = hw_mode is HOSTAPD_MODE_IEEE80211AD. + * WIFI_STANDARD_11BE = hw_mode is HOSTAPD_MODE_IEEE80211A and Extreme High Throughput supported. */ @VintfStability @Backing(type="int") @@ -37,4 +38,5 @@ enum Generation { WIFI_STANDARD_11AC = 2, WIFI_STANDARD_11AX = 3, WIFI_STANDARD_11AD = 4, + WIFI_STANDARD_11BE = 5, } diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/HwModeParams.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/HwModeParams.aidl index 210e99ff1f..e66a24af8c 100644 --- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/HwModeParams.aidl +++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/HwModeParams.aidl @@ -68,4 +68,10 @@ parcelable HwModeParams { * Enable EDMG (802.11ay), this option is only allowed for the 60GHz band. */ boolean enableEdmg; + /** + * Whether IEEE 802.11be (Extreme High Throughput) is enabled or not. + * Note: hw_mode=a is used to specify that 5 GHz band or 6 GHz band is + * used with Extreme High Throughput. + */ + boolean enable80211BE; } diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/NetworkParams.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/NetworkParams.aidl index df84eca23d..47d9e6f96b 100644 --- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/NetworkParams.aidl +++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/NetworkParams.aidl @@ -44,4 +44,12 @@ parcelable NetworkParams { * CHARGEABLE_PUBLIC_NETWORK when set to true. */ boolean isMetered; + /** + * Additional vendor specific elements for Beacon and Probe Response frames + * This parameter can be used to add additional vendor specific element(s) into + * the end of the Beacon and Probe Response frames. The format for these + * element(s) is a binary dump of the raw information elements (id+len+payload for + * one or more elements). Example: byte[]{ 221, 4, 17, 34, 51, 1 } + */ + byte[] vendorElements; } diff --git a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp index dad708567c..cd7ff82156 100644 --- a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp +++ b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp @@ -431,6 +431,7 @@ TEST_P(HostapdAidl, AddAccessPointWithDualBandConfig) { EXPECT_TRUE(status.isOk()); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HostapdAidl); INSTANTIATE_TEST_SUITE_P( Hostapd, HostapdAidl, testing::ValuesIn(android::getAidlHalInstanceNames(IHostapd::descriptor)), diff --git a/wifi/supplicant/aidl/Android.bp b/wifi/supplicant/aidl/Android.bp index c97a6f917c..d00dd2189f 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, diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl index ed435e2097..826d9167b9 100644 --- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl +++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl @@ -50,4 +50,5 @@ interface ISupplicantP2pIfaceCallback { oneway void onServiceDiscoveryResponse(in byte[] srcAddress, in char updateIndicator, in byte[] tlvs); oneway void onStaAuthorized(in byte[] srcAddress, in byte[] p2pDeviceAddress); oneway void onStaDeauthorized(in byte[] srcAddress, in byte[] p2pDeviceAddress); + oneway void onGroupFrequencyChanged(in String groupIfname, in int frequency); } diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl index 4f7584d938..6276a3521b 100644 --- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl +++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl @@ -38,4 +38,5 @@ interface ISupplicantStaNetworkCallback { oneway void onNetworkEapSimGsmAuthRequest(in android.hardware.wifi.supplicant.NetworkRequestEapSimGsmAuthParams params); oneway void onNetworkEapSimUmtsAuthRequest(in android.hardware.wifi.supplicant.NetworkRequestEapSimUmtsAuthParams params); oneway void onTransitionDisable(in android.hardware.wifi.supplicant.TransitionDisableIndication ind); + oneway void onServerCertificateAvailable(in int depth, in byte[] subject, in byte[] certHash, in byte[] certBlob); } diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WifiTechnology.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WifiTechnology.aidl index ad36e68564..bf5081ea70 100644 --- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WifiTechnology.aidl +++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WifiTechnology.aidl @@ -39,4 +39,5 @@ enum WifiTechnology { HT = 2, VHT = 3, HE = 4, + EHT = 5, } diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl index 43772af0c0..9a0a924c66 100644 --- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl +++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl @@ -38,4 +38,5 @@ enum WpaDriverCapabilitiesMask { OCE = 2, SAE_PK = 4, WFD_R2 = 8, + TRUST_ON_FIRST_USE = 16, } diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AuthAlgMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AuthAlgMask.aidl index e8101ea3af..039d41dc43 100644 --- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AuthAlgMask.aidl +++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AuthAlgMask.aidl @@ -19,7 +19,7 @@ package android.hardware.wifi.supplicant; /** * Possible mask of values for AuthAlg param. * See /external/wpa_supplicant_8/src/common/defs.h for - * all possible values (starting at WPA_AUTH_ALG_OPEN). + * the historical values (starting at WPA_AUTH_ALG_OPEN). */ @VintfStability @Backing(type="int") diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GroupCipherMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GroupCipherMask.aidl index d5b26adc99..99e9da07f1 100644 --- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GroupCipherMask.aidl +++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GroupCipherMask.aidl @@ -19,7 +19,7 @@ package android.hardware.wifi.supplicant; /** * Possible mask of values for GroupCipher param. * See /external/wpa_supplicant_8/src/common/defs.h for - * all possible values (starting at WPA_CIPHER_WEP40). + * the historical values (starting at WPA_CIPHER_WEP40). */ @VintfStability @Backing(type="int") diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl index f0cabd6ff8..2b58cc2c82 100644 --- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl +++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl @@ -205,4 +205,12 @@ interface ISupplicantP2pIfaceCallback { * @param p2pDeviceAddress P2P device address. */ oneway void onStaDeauthorized(in byte[] srcAddress, in byte[] p2pDeviceAddress); + + /** + * Used to indicate that operating frequency has changed for this P2P group interface. + * + * @param groupIfName Interface name of the group. (For ex: p2p-p2p0-1) + * @param frequency New operating frequency in MHz. + */ + oneway void onGroupFrequencyChanged(in String groupIfname, in int frequency); } diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl index c28b494d6a..4024c35fed 100644 --- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl +++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl @@ -62,4 +62,13 @@ interface ISupplicantStaNetworkCallback { * Used to notify WPA3 transition disable. */ oneway void onTransitionDisable(in TransitionDisableIndication ind); + + /** + * Used to notify EAP certificate event. + * + * On receiving a server certifidate from TLS handshake, send this certificate + * to the framework for Trust On First Use. + */ + oneway void onServerCertificateAvailable( + in int depth, in byte[] subject, in byte[] certHash, in byte[] certBlob); } diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl index 322558529e..f0c3345b93 100644 --- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl +++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl @@ -19,7 +19,7 @@ package android.hardware.wifi.supplicant; /** * Possible mask of values for KeyMgmt param. * See /external/wpa_supplicant_8/src/common/defs.h for - * all possible values (starting at WPA_KEY_MGMT_IEEE8021X). + * the historical values (starting at WPA_KEY_MGMT_IEEE8021X). */ @VintfStability @Backing(type="int") diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl index ad134fa240..7179fea9e2 100644 --- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl +++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl @@ -19,7 +19,7 @@ package android.hardware.wifi.supplicant; /** * Possible mask of values for PairwiseCipher param. * See /external/wpa_supplicant_8/src/common/defs.h for - * all possible values (starting at WPA_CIPHER_NONE). + * the historical values (starting at WPA_CIPHER_NONE). */ @VintfStability @Backing(type="int") diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ProtoMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ProtoMask.aidl index 65c832bece..dc3d80bf1f 100644 --- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ProtoMask.aidl +++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ProtoMask.aidl @@ -19,7 +19,7 @@ package android.hardware.wifi.supplicant; /** * Possible mask of values for Proto param. * See /external/wpa_supplicant_8/src/common/defs.h for - * all possible values (starting at WPA_PROTO_WPA). + * the historical values (starting at WPA_PROTO_WPA). */ @VintfStability @Backing(type="int") diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WifiTechnology.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WifiTechnology.aidl index 00c16b4278..d364c7509a 100644 --- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WifiTechnology.aidl +++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WifiTechnology.aidl @@ -39,4 +39,8 @@ enum WifiTechnology { * For 802.11ax */ HE = 4, + /** + * For 802.11be + */ + EHT = 5, } diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl index e174199c78..08006cffba 100644 --- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl +++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl @@ -38,4 +38,8 @@ enum WpaDriverCapabilitiesMask { * Wi-Fi Display R2 */ WFD_R2 = 1 << 3, + /** + * Trust On First Use + */ + TRUST_ON_FIRST_USE = 1 << 4, } diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp index 2f4f06d355..10aab4d414 100644 --- a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp +++ b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp @@ -159,6 +159,10 @@ class SupplicantP2pIfaceCallback : public BnSupplicantP2pIfaceCallback { const std::vector<uint8_t>& /* p2pDeviceAddress */) override { return ndk::ScopedAStatus::ok(); } + ::ndk::ScopedAStatus onGroupFrequencyChanged(const std::string& /* groupIfname */, + int32_t /* frequency */) override { + return ndk::ScopedAStatus::ok(); + } }; class SupplicantP2pIfaceAidlTest : public testing::TestWithParam<std::string> { @@ -620,6 +624,7 @@ TEST_P(SupplicantP2pIfaceAidlTest, AddAndRemoveUpnpService) { p2p_iface_->removeUpnpService(0 /* version */, upnpServiceName).isOk()); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantP2pIfaceAidlTest); INSTANTIATE_TEST_SUITE_P(Supplicant, SupplicantP2pIfaceAidlTest, testing::ValuesIn(android::getAidlHalInstanceNames( ISupplicant::descriptor)), diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp index f51c07f1ad..6e6955fd75 100644 --- a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp +++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp @@ -769,6 +769,7 @@ TEST_P(SupplicantStaIfaceAidlTest, StartDppConfiguratorInitiator) { EXPECT_TRUE(sta_iface_->removeDppUri(peer_id).isOk()); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaIfaceAidlTest); INSTANTIATE_TEST_SUITE_P(Supplicant, SupplicantStaIfaceAidlTest, testing::ValuesIn(android::getAidlHalInstanceNames( ISupplicant::descriptor)), diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp index 66c88073cc..0a35f666f4 100644 --- a/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp +++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp @@ -92,6 +92,12 @@ class SupplicantStaNetworkCallback : public BnSupplicantStaNetworkCallback { TransitionDisableIndication /* ind */) override { return ndk::ScopedAStatus::ok(); } + ::ndk::ScopedAStatus onServerCertificateAvailable( + int32_t /* depth */, const std::vector<uint8_t>& /* subject */, + const std::vector<uint8_t>& /* certHash */, + const std::vector<uint8_t>& /* certBlob */) override { + return ndk::ScopedAStatus::ok(); + } }; class SupplicantStaNetworkAidlTest @@ -778,6 +784,7 @@ TEST_P(SupplicantStaNetworkAidlTest, GetWpsNfcConfigurationToken) { EXPECT_NE(retrievedToken.size(), 0); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaNetworkAidlTest); INSTANTIATE_TEST_SUITE_P(Supplicant, SupplicantStaNetworkAidlTest, testing::ValuesIn(android::getAidlHalInstanceNames( ISupplicant::descriptor)), |